From 5d2d36b0686d7253f9d61c00a63d273aba17677a Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Fri, 25 May 2018 22:24:24 +0530 Subject: Applied soc-2017-normal-tools --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- .../scripts/modules/bpy_extras/keyconfig_utils.py | 1 + release/scripts/startup/bl_operators/mesh.py | 50 - .../startup/bl_ui/properties_data_modifier.py | 16 + release/scripts/startup/bl_ui/space_view3d.py | 24 + .../scripts/startup/bl_ui/space_view3d_toolbar.py | 21 + source/blender/blenkernel/BKE_editmesh.h | 1 + source/blender/blenkernel/BKE_mesh.h | 3 + source/blender/blenkernel/intern/editderivedmesh.c | 2 +- source/blender/blenkernel/intern/editmesh.c | 23 + source/blender/blenkernel/intern/mesh_evaluate.c | 9 +- source/blender/bmesh/bmesh_class.h | 29 + source/blender/bmesh/intern/bmesh_mesh.c | 407 +++++- source/blender/bmesh/intern/bmesh_mesh.h | 20 +- source/blender/bmesh/intern/bmesh_operator_api.h | 1 + source/blender/draw/intern/draw_cache_impl_mesh.c | 4 +- source/blender/editors/include/ED_screen.h | 1 + source/blender/editors/include/ED_transform.h | 2 + source/blender/editors/mesh/editmesh_tools.c | 1375 ++++++++++++++++++++ source/blender/editors/mesh/editmesh_undo.c | 2 + source/blender/editors/mesh/editmesh_utils.c | 5 +- source/blender/editors/mesh/mesh_intern.h | 10 + source/blender/editors/mesh/mesh_ops.c | 12 + source/blender/editors/screen/screen_ops.c | 10 + .../blender/editors/space_outliner/outliner_draw.c | 1 + source/blender/editors/transform/transform.c | 220 +++- source/blender/editors/transform/transform.h | 4 + source/blender/editors/transform/transform_ops.c | 24 + source/blender/makesdna/DNA_modifier_types.h | 27 + source/blender/makesdna/DNA_scene_types.h | 11 + source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/rna_modifier.c | 67 + source/blender/makesrna/intern/rna_scene.c | 15 + source/blender/modifiers/CMakeLists.txt | 1 + source/blender/modifiers/MOD_modifiertypes.h | 1 + source/blender/modifiers/intern/MOD_util.c | 1 + .../blender/modifiers/intern/MOD_weighted_normal.c | 670 ++++++++++ source/tools | 2 +- 40 files changed, 2997 insertions(+), 82 deletions(-) create mode 100644 source/blender/modifiers/intern/MOD_weighted_normal.c diff --git a/release/datafiles/locale b/release/datafiles/locale index d3349b42856..59495b4b590 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit d3349b42856d00c278f72f2a5909a6c96b9cdb5e +Subproject commit 59495b4b59077aa1cc68fffbdae1463af980f08e diff --git a/release/scripts/addons b/release/scripts/addons index 8f2fd7e23f0..27970761a18 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 8f2fd7e23f0b5ce023440182f51c40e88d663325 +Subproject commit 27970761a18926abe1b0020aa350305e3109a537 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 34a27a42d78..6a4f93c9b8f 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 34a27a42d781d80f9f1833bad8cc5b2abcac2933 +Subproject commit 6a4f93c9b8f36b19bd02087abf3d7f5983df035a diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index b0e4d65a3ce..b8fd96e2ec8 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -56,6 +56,7 @@ KM_HIERARCHY = [ ('Particle', 'EMPTY', 'WINDOW', []), ('Knife Tool Modal Map', 'EMPTY', 'WINDOW', []), + ('Custom Normals Modal Map', 'EMPTY', 'WINDOW', []), ('Paint Stroke Modal', 'EMPTY', 'WINDOW', []), ('Paint Curve', 'EMPTY', 'WINDOW', []), diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index c7a11c23c3f..8543847122d 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -203,57 +203,7 @@ class MeshSelectPrev(Operator): return {'FINISHED'} -# XXX This is hackish (going forth and back from Object mode...), to be redone once we have proper support of -# custom normals in BMesh/edit mode. -class MehsSetNormalsFromFaces(Operator): - """Set the custom vertex normals from the selected faces ones""" - bl_idname = "mesh.set_normals_from_faces" - bl_label = "Set Normals From Faces" - bl_options = {'REGISTER', 'UNDO'} - - @classmethod - def poll(cls, context): - return (context.mode == 'EDIT_MESH' and context.edit_object.data.polygons) - - def execute(self, context): - import mathutils - - bpy.ops.object.mode_set(mode='OBJECT') - obj = context.active_object - me = obj.data - - v2nors = {} - for p in me.polygons: - if not p.select: - continue - for lidx, vidx in zip(p.loop_indices, p.vertices): - assert(me.loops[lidx].vertex_index == vidx) - v2nors.setdefault(vidx, []).append(p.normal) - - for nors in v2nors.values(): - nors[:] = [sum(nors, mathutils.Vector((0, 0, 0))).normalized()] - - if not me.has_custom_normals: - me.create_normals_split() - me.calc_normals_split() - - normals = [] - for l in me.loops: - nor = v2nors.get(l.vertex_index, [None])[0] - if nor is None: - nor = l.normal - normals.append(nor.to_tuple()) - - me.normals_split_custom_set(normals) - - me.free_normals_split() - bpy.ops.object.mode_set(mode='EDIT') - - return {'FINISHED'} - - classes = ( - MehsSetNormalsFromFaces, MeshMirrorUV, MeshSelectNext, MeshSelectPrev, diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 28e39959c7e..fb1d62a92db 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1557,6 +1557,22 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): if md.rest_source == 'BIND': layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind") + def WEIGHTED_NORMAL(self, layout, ob, md): + layout.label("Weighting Mode:") + split = layout.split(align=True) + col = split.column(align=True) + col.prop(md, "mode", text="") + col.prop(md, "weight", text="Weight") + col.prop(md, "keep_sharp") + + col = split.column(align=True) + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.active = bool(md.vertex_group) + row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT') + col.prop(md, "thresh", text="Threshold") + col.prop(md, "face_influence") + classes = ( DATA_PT_modifiers, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 324a4259e38..4f5791101a9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2777,6 +2777,30 @@ class VIEW3D_MT_edit_mesh_normals(Menu): layout.operator("mesh.flip_normals") layout.operator("mesh.set_normals_from_faces", text="Set From Faces") + layout.operator("transform.rotate_normal", text="Rotate Normal") + layout.operator("mesh.point_normals", text="Point normals to target") + + layout.operator("mesh.merge_normals", text="Merge") + layout.operator("mesh.split_normals", text="Split") + + layout.operator("mesh.average_normals", text="Average Normals") + + layout.label(text="Normal Vector") + + layout.operator("mesh.normals_tools", text="Copy").mode = 'COPY' + layout.operator("mesh.normals_tools", text="Paste").mode = 'PASTE' + + layout.operator("mesh.normals_tools", text="Multiply").mode = 'MULTIPLY' + layout.operator("mesh.normals_tools", text="Add").mode = 'ADD' + + layout.operator("mesh.normals_tools", text="Reset").mode = 'RESET' + + layout.operator("mesh.smoothen_normals", text="Smoothen") + + layout.label(text="Face Strength") + layout.operator("mesh.mod_weighted_strength", text="Face select", icon = "FACESEL").set = False + layout.operator("mesh.mod_weighted_strength", text="Set Strength", icon = "ZOOMIN").set = True + class VIEW3D_MT_edit_mesh_shading(Menu): bl_label = "Shading" diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 004ea8b0e52..9a1bff86ed3 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1297,6 +1297,26 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): sub.prop(pe, "fade_frames", slider=True) +class VIEW3D_PT_tools_normal(View3DPanel, Panel): + bl_category = "" + bl_context = ".mesh_edit" + bl_label = "Normal Tools" + + def draw(self, context): + layout = self.layout + toolsettings = context.tool_settings + + col = layout.column(align=True) + col.label(text="Normal Vector") + col.prop(toolsettings, "normal_vector", text="") + + layout.separator() + layout.label(text="Face Strength") + layout.prop(toolsettings, "face_strength", text="") + + col = layout.column(align=True) + + # Grease Pencil drawing tools class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'VIEW_3D' @@ -1361,6 +1381,7 @@ classes = ( VIEW3D_PT_tools_grease_pencil_sculpt, VIEW3D_PT_tools_grease_pencil_brush, VIEW3D_PT_tools_grease_pencil_brushcurves, + VIEW3D_PT_tools_normal, ) if __name__ == "__main__": # only for live edit. diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h index 5e456fea64f..39986129c61 100644 --- a/source/blender/blenkernel/BKE_editmesh.h +++ b/source/blender/blenkernel/BKE_editmesh.h @@ -93,6 +93,7 @@ void BKE_editmesh_free(BMEditMesh *em); void BKE_editmesh_color_free(BMEditMesh *em); void BKE_editmesh_color_ensure(BMEditMesh *em, const char htype); float (*BKE_editmesh_vertexCos_get_orco(BMEditMesh *em, int *r_numVerts))[3]; +void BKE_editmesh_lnorspace_update(BMEditMesh *em); /* editderivedmesh.c */ /* should really be defined in editmesh.c, but they use 'EditDerivedBMesh' */ diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index f1326974f10..6e0514fd009 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -269,6 +269,8 @@ typedef struct MLoopNorSpace { * - BMLoop pointers. */ struct LinkNode *loops; char flags; + + void *user_data; /* To be used for extended processing related to loop normal spaces (aka smooth fans). */ } MLoopNorSpace; /** * MLoopNorSpace.flags @@ -284,6 +286,7 @@ typedef struct MLoopNorSpaceArray { MLoopNorSpace **lspacearr; /* MLoop aligned array */ struct LinkNode *loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */ char data_type; /* Whether we store loop indices, or pointers to BMLoop. */ + int num_spaces; /* Number of clnors spaces defined in this array. */ struct MemArena *mem; } MLoopNorSpaceArray; /** diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index f5e5a37c7d7..657461e3bf5 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -202,7 +202,7 @@ static void emDM_calcLoopNormalsSpaceArray( cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos, - r_lnors_spacearr, clnors_data, cd_loop_clnors_offset); + r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, false); #ifdef DEBUG_CLNORS if (r_lnors_spacearr) { int i; diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index b63ab276b14..a7f93ca6c49 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -246,3 +246,26 @@ float (*BKE_editmesh_vertexCos_get_orco(BMEditMesh *em, int *r_numVerts))[3] return orco; } + +void BKE_editmesh_lnorspace_update(BMEditMesh *em) +{ + BMesh *bm = em->bm; + + /* We need to create clnors data is none exist yet, otherwise there is no way to edit them. */ + /* Similar code to MESH_OT_customdata_custom_splitnormals_add operator, we want to keep same shading + * in case we were using autosmooth so far... */ + /* Note: there is a problem here, which is that is someone starts a normal editing operation on previously + * autosmooth-ed mesh, and cancel that operation, generated clnors data remain, with related sharp edges + * (and hence autosmooth is 'lost'). + * Not sure how critical this is, and how to fix that issue? */ + if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + Mesh *me = em->ob->data; + if (me->flag & ME_AUTOSMOOTH) { + BM_edges_sharp_from_angle_set(bm, me->smoothresh); + + me->drawflag |= ME_DRAWSHARP; + } + } + + BM_lnorspace_update(bm); +} diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 068be0ef304..997201fc4d0 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -465,6 +465,8 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoo mem = lnors_spacearr->mem; lnors_spacearr->lspacearr = BLI_memarena_calloc(mem, sizeof(MLoopNorSpace *) * (size_t)numLoops); lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops); + + lnors_spacearr->num_spaces = 0; } BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX)); lnors_spacearr->data_type = data_type; @@ -472,21 +474,24 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoo void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) { - BLI_memarena_clear(lnors_spacearr->mem); + lnors_spacearr->num_spaces = 0; lnors_spacearr->lspacearr = NULL; lnors_spacearr->loops_pool = NULL; + BLI_memarena_clear(lnors_spacearr->mem); } void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) { - BLI_memarena_free(lnors_spacearr->mem); + lnors_spacearr->num_spaces = 0; lnors_spacearr->lspacearr = NULL; lnors_spacearr->loops_pool = NULL; + BLI_memarena_free(lnors_spacearr->mem); lnors_spacearr->mem = NULL; } MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr) { + lnors_spacearr->num_spaces++; return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); } diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index bec2c7a1f45..8159aae1ab8 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -38,6 +38,8 @@ struct BMEdge; struct BMLoop; struct BMFace; +struct MLoopNorSpaceArray; + struct BLI_mempool; /* note: it is very important for BMHeader to start with two @@ -236,6 +238,9 @@ typedef struct BMesh { struct BLI_mempool *looplistpool; #endif + struct MLoopNorSpaceArray *lnor_spacearr; /* Stores MLoopNorSpaceArray for this BMesh */ + char spacearr_dirty; + /* should be copy of scene select mode */ /* stored in BMEditMesh too, this is a bit confusing, * make sure they're in sync! @@ -263,9 +268,33 @@ enum { BM_FACE = 8 }; +typedef struct BMLoopNorEditData { + int loop_index; + BMLoop *loop; + float niloc[3]; + float nloc[3]; + float *loc; + short *clnors_data; +} BMLoopNorEditData; + +typedef struct BMLoopNorEditDataArray { + BMLoopNorEditData *lnor_editdata; + /* This one has full amount of loops, used to map loop index to actual BMLoopNorEditData struct. */ + BMLoopNorEditData **lidx_to_lnor_editdata; + + int cd_custom_normal_offset; + int totloop; +} BMLoopNorEditDataArray; + #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE) #define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE) +enum { + BM_SPACEARR_DIRTY = 1 << 0, + BM_SPACEARR_DIRTY_ALL = 1 << 1, + BM_SPACEARR_BMO_SET = 1 << 2, +}; + /* args for _Generic */ #define _BM_GENERIC_TYPE_ELEM_NONCONST \ void *, BMVert *, BMEdge *, BMLoop *, BMFace *, \ diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 8071637d95e..79c835cca11 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -30,6 +30,7 @@ #include "DNA_listBase.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BLI_linklist_stack.h" #include "BLI_listbase.h" @@ -260,6 +261,11 @@ void BM_mesh_data_free(BMesh *bm) BLI_freelistN(&bm->selected); + if (bm->lnor_spacearr) { + BKE_lnor_spacearr_free(bm->lnor_spacearr); + MEM_freeN(bm->lnor_spacearr); + } + BMO_error_clear(bm); } @@ -313,6 +319,10 @@ void BM_mesh_free(BMesh *bm) * Helpers for #BM_mesh_normals_update and #BM_verts_calc_normal_vcos */ +/* We use that existing internal API flag, assuming no other tool using it would run concurrently to clnors editing. */ +/* XXX Should we rather add a new internal flag? */ +#define BM_LNORSPACE_UPDATE _FLAG_MF + typedef struct BMEdgesCalcVectorsData { /* Read-only data. */ const float (*vcos)[3]; @@ -638,7 +648,8 @@ bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr) * Will use first clnors_data array, and fallback to cd_loop_clnors_offset (use NULL and -1 to not use clnors). */ static void bm_mesh_loops_calc_normals( BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3], - MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset) + MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], + const int cd_loop_clnors_offset, const bool do_rebuild) { BMIter fiter; BMFace *f_curr; @@ -694,6 +705,11 @@ static void bm_mesh_loops_calc_normals( l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr); do { + if (do_rebuild && !BM_ELEM_API_FLAG_TEST(l_curr, BM_LNORSPACE_UPDATE) && + !(bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL)) + { + continue; + } /* A smooth edge, we have to check for cyclic smooth fan case. * If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge as * 'entry point', otherwise we can skip it. */ @@ -894,7 +910,10 @@ static void bm_mesh_loops_calc_normals( clnors_avg[0] /= clnors_nbr; clnors_avg[1] /= clnors_nbr; /* Fix/update all clnors of this fan with computed average value. */ - printf("Invalid clnors in this fan!\n"); + + /* Prints continuously when merge custom normals, so commenting. */ + /* printf("Invalid clnors in this fan!\n"); */ + while ((clnor = BLI_SMALLSTACK_POP(clnors))) { //print_v2("org clnor", clnor); clnor[0] = (short)clnors_avg[0]; @@ -1009,7 +1028,8 @@ void BM_mesh_loop_normals_update( void BM_loops_calc_normal_vcos( BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3], const bool use_split_normals, const float split_angle, float (*r_lnos)[3], - MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset) + MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], + const int cd_loop_clnors_offset, const bool do_rebuild) { const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1); @@ -1019,7 +1039,8 @@ void BM_loops_calc_normal_vcos( bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos, has_clnors ? (float)M_PI : split_angle, false); /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */ - bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset); + bm_mesh_loops_calc_normals( + bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, do_rebuild); } else { BLI_assert(!r_lnors_spacearr); @@ -1041,6 +1062,380 @@ void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle) bm_mesh_edges_sharp_tag(bm, NULL, NULL, NULL, split_angle, true); } +void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]) +{ + BLI_assert(bm->lnor_spacearr != NULL); + + if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); + } + + int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_loops_calc_normal_vcos( + bm, NULL, NULL, NULL, true, M_PI, r_lnors, bm->lnor_spacearr, NULL, cd_loop_clnors_offset, false); + bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL); +} + +/* will change later */ +#define CLEAR_SPACEARRAY_THRESHOLD(x) ((x) / 2) + +void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) +{ + if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) { + return; + } + if (do_invalidate_all || bm->totvertsel > CLEAR_SPACEARRAY_THRESHOLD(bm->totvert)) { + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + return; + } + if (bm->lnor_spacearr == NULL) { + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + return; + } + + BMVert *v; + BMLoop *l; + BMIter viter, liter; + /* Note: we could use temp tag of BMItem for that, but probably better not use it in such a low-level func? + * --mont29 */ + BLI_bitmap *done_verts = BLI_BITMAP_NEW(bm->totvert, __func__); + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + /* When we affect a given vertex, we may affect following smooth fans: + * - all smooth fans of said vertex; + * - all smooth fans of all immediate loop-neighbors vertices; + * This can be simplified as 'all loops of selected vertices and their immediate neighbors' + * need to be tagged for update. +*/ +BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + BM_ELEM_API_FLAG_ENABLE(l, BM_LNORSPACE_UPDATE); + + /* Note that we only handle unselected neighbor vertices here, main loop will take care of + * selected ones. */ + if (!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT) && + !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) + { + BMLoop *l_prev; + BMIter liter_prev; + BM_ITER_ELEM(l_prev, &liter_prev, l->prev->v, BM_LOOPS_OF_VERT) { + BM_ELEM_API_FLAG_ENABLE(l_prev, BM_LNORSPACE_UPDATE); + } + BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_prev->v)); + } + + if (!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT) && + !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) + { + BMLoop *l_next; + BMIter liter_next; + BM_ITER_ELEM(l_next, &liter_next, l->next->v, BM_LOOPS_OF_VERT) { + BM_ELEM_API_FLAG_ENABLE(l_next, BM_LNORSPACE_UPDATE); + } + BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_next->v)); + } + } + + BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(v)); + } +} + +MEM_freeN(done_verts); +bm->spacearr_dirty |= BM_SPACEARR_DIRTY; +} + +void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) +{ + BLI_assert(bm->lnor_spacearr != NULL); + + if (!(bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL))) { + return; + } + BMFace *f; + BMLoop *l; + BMIter fiter, liter; + + float(*r_lnors)[3] = MEM_callocN(sizeof(*r_lnors) * bm->totloop, __func__); + float(*oldnors)[3] = preserve_clnor ? MEM_mallocN(sizeof(*oldnors) * bm->totloop, __func__) : NULL; + + int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_mesh_elem_index_ensure(bm, BM_LOOP); + + if (preserve_clnor) { + BLI_assert(bm->lnor_spacearr->lspacearr != NULL); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { + if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) || bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) { + short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); + int l_index = BM_elem_index_get(l); + + BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], *clnor, oldnors[l_index]); + } + } + } + } + + if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) { + BKE_lnor_spacearr_clear(bm->lnor_spacearr); + } + BM_loops_calc_normal_vcos( + bm, NULL, NULL, NULL, true, M_PI, r_lnors, bm->lnor_spacearr, NULL, cd_loop_clnors_offset, true); + MEM_freeN(r_lnors); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { + if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) || bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) { + if (preserve_clnor) { + short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); + int l_index = BM_elem_index_get(l); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], *clnor); + } + BM_ELEM_API_FLAG_DISABLE(l, BM_LNORSPACE_UPDATE); + } + } + } + + MEM_SAFE_FREE(oldnors); + bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL); + +#ifndef NDEBUG + BM_lnorspace_err(bm); +#endif +} + +void BM_lnorspace_update(BMesh *bm) +{ + if (bm->lnor_spacearr == NULL) { + bm->lnor_spacearr = MEM_callocN(sizeof(*bm->lnor_spacearr), __func__); + } + if (bm->lnor_spacearr->lspacearr == NULL) { + float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__); + + BM_lnorspacearr_store(bm, lnors); + + MEM_freeN(lnors); + } + else if (bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL)) { + BM_lnorspace_rebuild(bm, false); + } +} + +/** +* Auxillary function only used by rebuild to detect if any spaces were not marked as invalid. +* Reports error if any of the lnor spaces change after rebuilding, meaning that all the possible +* lnor spaces to be rebuilt were not correctly marked. +*/ +#ifndef NDEBUG +void BM_lnorspace_err(BMesh *bm) +{ + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + bool clear = true; + + MLoopNorSpaceArray *temp = MEM_callocN(sizeof(*temp), __func__); + temp->lspacearr = NULL; + + BKE_lnor_spacearr_init(temp, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR); + + int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__); + BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, lnors, temp, NULL, cd_loop_clnors_offset, true); + + for (int i = 0; i < bm->totloop; i++) { + int j = 0; + j += compare_ff(temp->lspacearr[i]->ref_alpha, bm->lnor_spacearr->lspacearr[i]->ref_alpha, 1e-4f); + j += compare_ff(temp->lspacearr[i]->ref_beta, bm->lnor_spacearr->lspacearr[i]->ref_beta, 1e-4f); + j += compare_v3v3(temp->lspacearr[i]->vec_lnor, bm->lnor_spacearr->lspacearr[i]->vec_lnor, 1e-4f); + j += compare_v3v3(temp->lspacearr[i]->vec_ortho, bm->lnor_spacearr->lspacearr[i]->vec_ortho, 1e-4f); + j += compare_v3v3(temp->lspacearr[i]->vec_ref, bm->lnor_spacearr->lspacearr[i]->vec_ref, 1e-4f); + + if (j != 5) { + clear = false; + break; + } + } + BKE_lnor_spacearr_free(temp); + MEM_freeN(temp); + MEM_freeN(lnors); + BLI_assert(clear); + + bm->spacearr_dirty &= ~BM_SPACEARR_DIRTY_ALL; +} +#endif + +static void bm_loop_normal_mark_indiv_do_loop( + BMLoop *l, BLI_bitmap *loops, MLoopNorSpaceArray *lnor_spacearr, int *totloopsel) +{ + if (l != NULL) { + const int l_idx = BM_elem_index_get(l); + + if (!BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) { + /* If vert and face selected share a loop, mark it for editing. */ + BLI_BITMAP_ENABLE(loops, l_idx); + (*totloopsel)++; + + /* Mark all loops in same loop normal space (aka smooth fan). */ + if ((lnor_spacearr->lspacearr[l_idx]->flags & MLNOR_SPACE_IS_SINGLE) == 0) { + for (LinkNode *node = lnor_spacearr->lspacearr[l_idx]->loops; node; node = node->next) { + const int lfan_idx = BM_elem_index_get((BMLoop *)node->link); + if (!BLI_BITMAP_TEST(loops, lfan_idx)) { + BLI_BITMAP_ENABLE(loops, lfan_idx); + (*totloopsel)++; + } + } + } + } + } +} + +/* Mark the individual clnors to be edited, if multiple selection methods are used. */ +static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops) +{ + BMEditSelection *ese, *ese_prev; + int totloopsel = 0; + + BM_mesh_elem_index_ensure(bm, BM_LOOP); + + BLI_assert(bm->lnor_spacearr != NULL); + BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR); + + /* Goes from last selected to the first selected element. */ + for (ese = bm->selected.last; ese; ese = ese->prev) { + if (ese->htype == BM_FACE) { + ese_prev = ese; + /* If current face is selected, then any verts to be edited must have been selected before it. */ + while ((ese_prev = ese_prev->prev)) { + if (ese_prev->htype == BM_VERT) { + bm_loop_normal_mark_indiv_do_loop( + BM_face_vert_share_loop((BMFace *)ese->ele, (BMVert *)ese_prev->ele), + loops, bm->lnor_spacearr, &totloopsel); + } + else if (ese_prev->htype == BM_EDGE) { + bm_loop_normal_mark_indiv_do_loop( + BM_face_vert_share_loop((BMFace *)ese->ele, ((BMEdge *)ese_prev->ele)->v1), + loops, bm->lnor_spacearr, &totloopsel); + + bm_loop_normal_mark_indiv_do_loop( + BM_face_vert_share_loop((BMFace *)ese->ele, ((BMEdge *)ese_prev->ele)->v2), + loops, bm->lnor_spacearr, &totloopsel); + } + } + } + } + + return totloopsel; +} + +static void loop_normal_editdata_init(BMesh *bm, BMLoopNorEditData *lnor_ed, BMVert *v, BMLoop *l, const int offset) +{ + BLI_assert(bm->lnor_spacearr != NULL); + BLI_assert(bm->lnor_spacearr->lspacearr != NULL); + + const int l_index = BM_elem_index_get(l); + short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, offset); + + lnor_ed->loop_index = l_index; + lnor_ed->loop = l; + + float custom_normal[3]; + BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], clnors_data, custom_normal); + + lnor_ed->clnors_data = clnors_data; + copy_v3_v3(lnor_ed->nloc, custom_normal); + copy_v3_v3(lnor_ed->niloc, custom_normal); + + lnor_ed->loc = v->co; +} + +BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm) +{ + BMLoop *l; + BMVert *v; + BMIter liter, viter; + + bool verts = (bm->selectmode & SCE_SELECT_VERTEX) != 0; + bool edges = (bm->selectmode & SCE_SELECT_EDGE) != 0; + bool faces = (bm->selectmode & SCE_SELECT_FACE) != 0; + int totloopsel = 0; + + BLI_assert(bm->spacearr_dirty == 0); + + BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN(sizeof(*lnors_ed_arr), __func__); + lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, __func__); + + if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { + BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); + } + const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_mesh_elem_index_ensure(bm, BM_LOOP); + + BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__); + if (faces && (verts || edges)) { + /* More than one selection mode, check for individual normals to edit. */ + totloopsel = bm_loop_normal_mark_indiv(bm, loops); + } + + if (totloopsel) { + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata = MEM_mallocN(sizeof(*lnor_ed) * totloopsel, __func__); + + BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + if (BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) { + loop_normal_editdata_init(bm, lnor_ed, v, l, cd_custom_normal_offset); + lnors_ed_arr->lidx_to_lnor_editdata[BM_elem_index_get(l)] = lnor_ed; + lnor_ed++; + } + } + } + lnors_ed_arr->totloop = totloopsel; + } + else { /* If multiple selection modes are inactive OR no such loop is found, fall back to editing all loops. */ + totloopsel = BM_total_loop_select(bm); + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata = MEM_mallocN(sizeof(*lnor_ed) * totloopsel, __func__); + + BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + loop_normal_editdata_init(bm, lnor_ed, v, l, cd_custom_normal_offset); + lnors_ed_arr->lidx_to_lnor_editdata[BM_elem_index_get(l)] = lnor_ed; + lnor_ed++; + } + } + } + lnors_ed_arr->totloop = totloopsel; + } + + MEM_freeN(loops); + lnors_ed_arr->cd_custom_normal_offset = cd_custom_normal_offset; + return lnors_ed_arr; +} + +void BM_loop_normal_editdata_array_free(BMLoopNorEditDataArray *lnors_ed_arr) +{ + MEM_SAFE_FREE(lnors_ed_arr->lnor_editdata); + MEM_SAFE_FREE(lnors_ed_arr->lidx_to_lnor_editdata); + MEM_freeN(lnors_ed_arr); +} + +int BM_total_loop_select(BMesh *bm) +{ + int r_sel = 0; + BMVert *v; + BMIter viter; + + BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + r_sel += BM_vert_face_count(v); + } + } + return r_sel; +} + static void UNUSED_FUNCTION(bm_mdisps_space_set)( Object *ob, BMesh *bm, int from, int to) { @@ -1142,6 +1537,7 @@ void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag) /* compute normals, clear temp flags and flush selections */ if (type_flag & BMO_OPTYPE_FLAG_NORMALS_CALC) { + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; BM_mesh_normals_update(bm); } @@ -1158,6 +1554,9 @@ void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag) if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) { bm->selected = select_history; } + if (type_flag & BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL) { + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + } } void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4]) diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index b4443c748ce..44887e81157 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -29,6 +29,7 @@ struct BMAllocTemplate; struct MLoopNorSpaceArray; +struct BMLoopNorEditDataArray; void BM_mesh_elem_toolflags_ensure(BMesh *bm); void BM_mesh_elem_toolflags_clear(BMesh *bm); @@ -48,11 +49,24 @@ void BM_mesh_clear(BMesh *bm); void BM_mesh_normals_update(BMesh *bm); void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]); void BM_loops_calc_normal_vcos( - BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3], - const bool use_split_normals, const float split_angle, float (*r_lnos)[3], - struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset); + BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*pnos)[3], + const bool use_split_normals, const float split_angle, float(*r_lnos)[3], + struct MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], + const int cd_loop_clnors_offset, const bool do_rebuild); bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr); +void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]); +void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all); +void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor); +void BM_lnorspace_update(BMesh *bm); +#ifndef NDEBUG +void BM_lnorspace_err(BMesh *bm); +#endif + +/* Loop Generics */ +struct BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm); +void BM_loop_normal_editdata_array_free(struct BMLoopNorEditDataArray *lnors_ed_arr); +int BM_total_loop_select(BMesh *bm); void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle); diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 30cd1df9c4e..de87da71e8d 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -244,6 +244,7 @@ typedef enum { BMO_OPTYPE_FLAG_NORMALS_CALC = (1 << 1), BMO_OPTYPE_FLAG_SELECT_FLUSH = (1 << 2), BMO_OPTYPE_FLAG_SELECT_VALIDATE = (1 << 3), + BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL = (1 << 4), } BMOpTypeFlag; typedef struct BMOperator { diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 00d404e1571..e8add4890d8 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -423,7 +423,7 @@ static MeshRenderData *mesh_render_data_create_ex( int totloop = bm->totloop; if (is_auto_smooth) { rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__); - BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1); + BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1, false); } rdata->loop_len = totloop; bm_ensure_types |= BM_LOOP; @@ -720,7 +720,7 @@ static MeshRenderData *mesh_render_data_create_ex( /* Should we store the previous array of `loop_normals` in somewhere? */ rdata->loop_len = bm->totloop; rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * rdata->loop_len, __func__); - BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1); + BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1, false); } bool calc_active_tangent = false; diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 749d1347eb3..a91d373ac46 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -277,6 +277,7 @@ int ED_operator_object_active_editable_font(struct bContext *C); int ED_operator_editmesh(struct bContext *C); int ED_operator_editmesh_view3d(struct bContext *C); int ED_operator_editmesh_region_view3d(struct bContext *C); +int ED_operator_editmesh_auto_smooth(struct bContext *C); int ED_operator_editarmature(struct bContext *C); int ED_operator_editcurve(struct bContext *C); int ED_operator_editcurve_3d(struct bContext *C); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index e17d02abcd7..36f87e1b494 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -89,6 +89,7 @@ enum TfmMode { TFM_VERT_SLIDE, TFM_SEQ_SLIDE, TFM_BONE_ENVELOPE_DIST, + TFM_NORMAL_ROTATION, }; /* TRANSFORM CONTEXTS */ @@ -152,6 +153,7 @@ int BIF_countTransformOrientation(const struct bContext *C); #define P_NO_TEXSPACE (1 << 11) #define P_CENTER (1 << 12) #define P_GPENCIL_EDIT (1 << 13) +#define P_CLNOR_INVALIDATE (1 << 14) void Transform_Properties(struct wmOperatorType *ot, int flags); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 8438375a97f..77c90a6591b 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -41,11 +41,16 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BLI_bitmap.h" +#include "BLI_heap.h" #include "BLI_listbase.h" +#include "BLI_linklist.h" +#include "BLI_linklist_stack.h" #include "BLI_noise.h" #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_sort_utils.h" +#include "BLI_string.h" #include "BKE_layer.h" #include "BKE_material.h" @@ -54,6 +59,7 @@ #include "BKE_report.h" #include "BKE_texture.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_editmesh.h" #include "DEG_depsgraph.h" @@ -6916,3 +6922,1372 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot) /** \} */ #endif /* WITH_FREESTYLE */ + +/********************** Loop normals editing tools modal map. **********************/ + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +/* NOTE: We could add more here, like e.g. a switch between local or global coordinates of target, + * use numinput to type in explicit vector values... */ +enum { + /* Generic commands. */ + EDBM_CLNOR_MODAL_CANCEL = 1, + EDBM_CLNOR_MODAL_CONFIRM = 2, + + /* Point To operator. */ + EDBM_CLNOR_MODAL_POINTTO_RESET = 101, + EDBM_CLNOR_MODAL_POINTTO_INVERT = 102, + EDBM_CLNOR_MODAL_POINTTO_SPHERIZE = 103, + EDBM_CLNOR_MODAL_POINTTO_ALIGN = 104, + + EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE = 110, + EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT = 111, + EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT = 112, + EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR = 113, + EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED = 114, +}; + +/* called in transform_ops.c, on each regeneration of keymaps */ +wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf) +{ + static const EnumPropertyItem modal_items[] = { + {EDBM_CLNOR_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {EDBM_CLNOR_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + /* Point To operator. */ + {EDBM_CLNOR_MODAL_POINTTO_RESET, "RESET", 0, "Reset", "Reset normals to initial ones"}, + {EDBM_CLNOR_MODAL_POINTTO_INVERT, "INVERT", 0, "Invert", "Toggle inversion of affected normals"}, + {EDBM_CLNOR_MODAL_POINTTO_SPHERIZE, "SPHERIZE", 0, "Spherize", "Interpolate between new and original normals"}, + {EDBM_CLNOR_MODAL_POINTTO_ALIGN, "ALIGN", 0, "Align", "Make all affected normals parallel"}, + + {EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE, "USE_MOUSE", 0, "Use Mouse", "Follow mouse cursor position"}, + {EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT, "USE_PIVOT", 0, "Use Pivot", + "Use current rotation/scaling pivot point coordinates"}, + {EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT, "USE_OBJECT", 0, "Use Object", "Use current edited object's location"}, + {EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR, "SET_USE_3DCURSOR", 0, "Set and Use 3D Cursor", + "Set new 3D cursor position and use it"}, + {EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED, "SET_USE_SELECTED", 0, "Select and Use Mesh Item", + "Select new active mesh element and use its location"}, + {0, NULL, 0, NULL, NULL} + }; + static const char *keymap_name = "Custom Normals Modal Map"; + + wmKeyMap *keymap = WM_modalkeymap_get(keyconf, keymap_name); + + /* We only need to add map once */ + if (keymap && keymap->modal_items) + return NULL; + + keymap = WM_modalkeymap_add(keyconf, keymap_name, modal_items); + + /* Generic items for modal map. */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, EDBM_CLNOR_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CONFIRM); + + /* Point To items for modal map */ + WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_RESET); + WM_modalkeymap_add_item(keymap, IKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_INVERT); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_SPHERIZE); + WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_ALIGN); + + WM_modalkeymap_add_item(keymap, MKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE); + WM_modalkeymap_add_item(keymap, LKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT); + WM_modalkeymap_add_item(keymap, OKEY, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_CLICK, KM_CTRL, 0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_CLICK, KM_CTRL, 0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED); + + WM_modalkeymap_assign(keymap, "MESH_OT_point_normals"); + + return keymap; +} + +#define CLNORS_VALID_VEC_LEN (1e-4f) + +/********************** 'Point to' Loop Normals **********************/ + +enum { + EDBM_CLNOR_POINTTO_MODE_COORDINATES = 1, + EDBM_CLNOR_POINTTO_MODE_MOUSE = 2, +}; + +static EnumPropertyItem clnors_pointto_mode_items[] = { + {EDBM_CLNOR_POINTTO_MODE_COORDINATES, "COORDINATES", 0, "Coordinates", + "Use static coordinates (defined by various means)"}, + {EDBM_CLNOR_POINTTO_MODE_MOUSE, "MOUSE", 0, "Mouse", "Follow mouse cursor"}, + {0, NULL, 0, NULL, NULL} +}; + +/* Initialize loop normal data */ +static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + + BKE_editmesh_lnorspace_update(em); + BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); + + op->customdata = lnors_ed_arr; + + return lnors_ed_arr->totloop; +} + +static void point_normals_free(bContext *C, wmOperator *op) +{ + BMLoopNorEditDataArray *lnors_ed_arr = op->customdata; + BM_loop_normal_editdata_array_free(lnors_ed_arr); + op->customdata = NULL; + ED_area_headerprint(CTX_wm_area(C), NULL); +} + +static void point_normals_update_header(bContext *C, wmOperator *op) +{ + char header[UI_MAX_DRAW_STR]; + char buf[UI_MAX_DRAW_STR]; + + char *p = buf; + int available_len = sizeof(buf); + +#define WM_MODALKEY(_id) \ + WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p) + + BLI_snprintf(header, sizeof(header), IFACE_("%s: confirm, %s: cancel, " + "%s: point to mouse (%s), %s: point to Pivot, " + "%s: point to object origin, %s: reset normals, " + "%s: set & point to 3D cursor, %s: select & point to mesh item, " + "%s: invert normals (%s), %s: spherize (%s), %s: align (%s)"), + WM_MODALKEY(EDBM_CLNOR_MODAL_CONFIRM), WM_MODALKEY(EDBM_CLNOR_MODAL_CANCEL), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE), + WM_bool_as_string(RNA_enum_get(op->ptr, "mode") == EDBM_CLNOR_POINTTO_MODE_MOUSE), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_RESET), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align"))); + +#undef WM_MODALKEY + + ED_area_headerprint(CTX_wm_area(C), header); +} + +/* TODO move that to generic function in BMesh? */ +static void bmesh_selected_verts_center_calc(BMesh *bm, float *r_center) +{ + BMVert *v; + BMIter viter; + int i = 0; + + zero_v3(r_center); + BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + add_v3_v3(r_center, v->co); + i++; + } + } + mul_v3_fl(r_center, 1.0f / (float)i); +} + +static void point_normals_apply(bContext *C, wmOperator *op, float target[3], const bool do_reset) +{ + Object *obedit = CTX_data_edit_object(C); + BMesh *bm = BKE_editmesh_from_object(obedit)->bm; + BMLoopNorEditDataArray *lnors_ed_arr = op->customdata; + + const bool do_invert = RNA_boolean_get(op->ptr, "invert"); + const bool do_spherize = RNA_boolean_get(op->ptr, "spherize"); + const bool do_align = RNA_boolean_get(op->ptr, "align"); + float center[3]; + + if (do_align && !do_reset) { + bmesh_selected_verts_center_calc(bm, center); + } + + sub_v3_v3(target, obedit->loc); /* Move target to local coordinates. */ + + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + if (do_reset) { + copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc); + } + else if (do_spherize) { + /* Note that this is *not* real spherical interpolation. Probably good enough in this case though? */ + const float strength = RNA_float_get(op->ptr, "spherize_strength"); + float spherized_normal[3]; + + sub_v3_v3v3(spherized_normal, target, lnor_ed->loc); + normalize_v3(spherized_normal); /* otherwise, multiplication by strength is meaningless... */ + mul_v3_fl(spherized_normal, strength); + mul_v3_v3fl(lnor_ed->nloc, lnor_ed->niloc, 1.0f - strength); + add_v3_v3(lnor_ed->nloc, spherized_normal); + } + else if (do_align) { + sub_v3_v3v3(lnor_ed->nloc, target, center); + } + else { + sub_v3_v3v3(lnor_ed->nloc, target, lnor_ed->loc); + } + + if (do_invert && !do_reset) { + negate_v3(lnor_ed->nloc); + } + if (normalize_v3(lnor_ed->nloc) >= CLNORS_VALID_VEC_LEN) { + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data); + } + } +} + +static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + + float target[3]; + + int ret = OPERATOR_PASS_THROUGH; + int mode = RNA_enum_get(op->ptr, "mode"); + int new_mode = mode; + bool force_mousemove = false; + bool do_reset = false; + + PropertyRNA *prop_target = RNA_struct_find_property(op->ptr, "target_location"); + + if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case EDBM_CLNOR_MODAL_CONFIRM: + RNA_property_float_get_array(op->ptr, prop_target, target); + ret = OPERATOR_FINISHED; + break; + + case EDBM_CLNOR_MODAL_CANCEL: + do_reset = true; + ret = OPERATOR_CANCELLED; + break; + + case EDBM_CLNOR_MODAL_POINTTO_RESET: + do_reset = true; + ret = OPERATOR_RUNNING_MODAL; + break; + + case EDBM_CLNOR_MODAL_POINTTO_INVERT: + { + PropertyRNA *prop_invert = RNA_struct_find_property(op->ptr, "invert"); + RNA_property_boolean_set(op->ptr, prop_invert, !RNA_property_boolean_get(op->ptr, prop_invert)); + RNA_property_float_get_array(op->ptr, prop_target, target); + ret = OPERATOR_RUNNING_MODAL; + break; + } + + case EDBM_CLNOR_MODAL_POINTTO_SPHERIZE: + { + PropertyRNA *prop_spherize = RNA_struct_find_property(op->ptr, "spherize"); + RNA_property_boolean_set(op->ptr, prop_spherize, !RNA_property_boolean_get(op->ptr, prop_spherize)); + RNA_property_float_get_array(op->ptr, prop_target, target); + ret = OPERATOR_RUNNING_MODAL; + break; + } + + case EDBM_CLNOR_MODAL_POINTTO_ALIGN: + { + PropertyRNA *prop_align = RNA_struct_find_property(op->ptr, "align"); + RNA_property_boolean_set(op->ptr, prop_align, !RNA_property_boolean_get(op->ptr, prop_align)); + RNA_property_float_get_array(op->ptr, prop_target, target); + ret = OPERATOR_RUNNING_MODAL; + break; + } + + case EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE: + new_mode = EDBM_CLNOR_POINTTO_MODE_MOUSE; + force_mousemove = true; /* We want to immediately update to mouse cursor position... */ + ret = OPERATOR_RUNNING_MODAL; + break; + + case EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT: + new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES; + copy_v3_v3(target, obedit->loc); + ret = OPERATOR_RUNNING_MODAL; + break; + + case EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR: + new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES; + ED_view3d_cursor3d_update(C, event->mval); + copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d)->location); + break; + + case EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED: + new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES; + view3d_operator_needs_opengl(C); + if (EDBM_select_pick(C, event->mval, false, false, false)) { + ED_object_editmode_calc_active_center(obedit, false, target); /* Point to newly selected active. */ + add_v3_v3(target, obedit->loc); + ret = OPERATOR_RUNNING_MODAL; + } + break; + + case EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT: + new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES; + switch (scene->toolsettings->transform_pivot_point) { + case V3D_AROUND_CENTER_BOUNDS: /* calculateCenterBound */ + { + BMVert *v; + BMIter viter; + float min[3], max[3]; + int i = 0; + + BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + if (i) { + minmax_v3v3_v3(min, max, v->co); + } + else { + copy_v3_v3(min, v->co); + copy_v3_v3(max, v->co); + } + i++; + } + } + mid_v3_v3v3(target, min, max); + add_v3_v3(target, obedit->loc); + break; + } + + case V3D_AROUND_CENTER_MEAN: + { + bmesh_selected_verts_center_calc(bm, target); + add_v3_v3(target, obedit->loc); + break; + } + + case V3D_AROUND_CURSOR: + copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d)->location); + break; + + case V3D_AROUND_ACTIVE: + if (!ED_object_editmode_calc_active_center(obedit, false, target)) { + zero_v3(target); + } + add_v3_v3(target, obedit->loc); + break; + + default: + BKE_report(op->reports, RPT_WARNING, "Does not support Individual Origin as pivot"); + copy_v3_v3(target, obedit->loc); + } + ret = OPERATOR_RUNNING_MODAL; + break; + default: + break; + } + } + + if (new_mode != mode) { + mode = new_mode; + RNA_enum_set(op->ptr, "mode", mode); + } + + /* Only handle mousemove event in case we are in mouse mode. */ + if (event->type == MOUSEMOVE || force_mousemove) { + if (mode == EDBM_CLNOR_POINTTO_MODE_MOUSE) { + ARegion *ar = CTX_wm_region(C); + float center[3]; + + bmesh_selected_verts_center_calc(bm, center); + + ED_view3d_win_to_3d_int(v3d, ar, center, event->mval, target); + + ret = OPERATOR_RUNNING_MODAL; + } + } + + if (ret != OPERATOR_PASS_THROUGH) { + if (!ELEM(ret, OPERATOR_CANCELLED, OPERATOR_FINISHED)) { + RNA_property_float_set_array(op->ptr, prop_target, target); + } + point_normals_apply(C, op, target, do_reset); + EDBM_update_generic(em, true, false); /* Recheck bools. */ + + point_normals_update_header(C, op); + } + + if (ELEM(ret, OPERATOR_CANCELLED, OPERATOR_FINISHED)) { + point_normals_free(C, op); + } + + return ret; +} + +static int edbm_point_normals_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + if (!point_normals_init(C, op, event)) { + point_normals_free(C, op); + return OPERATOR_CANCELLED; + } + + WM_event_add_modal_handler(C, op); + + point_normals_update_header(C, op); + + op->flag |= OP_IS_MODAL_GRAB_CURSOR; + return OPERATOR_RUNNING_MODAL; +} + +static int edbm_point_normals_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + + if (!point_normals_init(C, op, NULL)) { + point_normals_free(C, op); + return OPERATOR_CANCELLED; + } + + /* Note that 'mode' is ignored in exec case, we directly use vector stored in target_location, whatever that is. */ + + float target[3]; + RNA_float_get_array(op->ptr, "target_location", target); + + point_normals_apply(C, op, target, false); + + EDBM_update_generic(em, true, false); + point_normals_free(C, op); + + return OPERATOR_FINISHED; +} + +static bool point_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + + /* Only show strength option if spherize is enabled. */ + if (STREQ(prop_id, "spherize_strength")) { + return (bool)RNA_boolean_get(ptr, "spherize"); + } + + /* Else, show it! */ + return true; +} + +static void edbm_point_normals_ui(bContext *C, wmOperator *op) +{ + uiLayout *layout = op->layout; + wmWindowManager *wm = CTX_wm_manager(C); + PointerRNA ptr; + + RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); + + /* Main auto-draw call */ + uiDefAutoButsRNA(layout, &ptr, point_normals_draw_check_prop, '\0', false); +} + +void MESH_OT_point_normals(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Point Normals to Target"; + ot->description = "Point selected custom normals to specified Target"; + ot->idname = "MESH_OT_point_normals"; + + /* api callbacks */ + ot->exec = edbm_point_normals_exec; + ot->invoke = edbm_point_normals_invoke; + ot->modal = edbm_point_normals_modal; + ot->poll = ED_operator_editmesh_auto_smooth; + ot->ui = edbm_point_normals_ui; + ot->cancel = point_normals_free; + + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "mode", clnors_pointto_mode_items, EDBM_CLNOR_POINTTO_MODE_COORDINATES, + "Mode", "How to define coordinates to point custom normals to"); + RNA_def_property_flag(ot->prop, PROP_HIDDEN); + + RNA_def_boolean(ot->srna, "invert", false, "Invert", "Invert affected normals"); + + RNA_def_boolean(ot->srna, "align", false, "Align", "Make all affected normals parallel"); + + RNA_def_float_vector(ot->srna, "target_location", 3, (float[3]){0.0f, 0.0f, 0.0f}, -FLT_MAX, FLT_MAX, + "Target", "Target location to which normals will point", -1000.0f, 1000.0f); + + RNA_def_boolean(ot->srna, "spherize", false, + "Spherize", "Interpolate between original and new normals"); + + RNA_def_float(ot->srna, "spherize_strength", 0.1, 0.0f, 1.0f, + "Spherize Strength", "Ratio of spherized normal to original normal", 0.0f, 1.0f); +} + +/********************** Split/Merge Loop Normals **********************/ + +static void normals_splitmerge_loops_edges_tag(BMesh *bm, const bool do_edges) +{ + BMFace *f; + BMEdge *e; + BMIter fiter, eiter; + BMLoop *l_curr, *l_first; + + if (do_edges) { + int index_edge; + BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) { + BMLoop *l_a, *l_b; + + BM_elem_index_set(e, index_edge); /* set_inline */ + BM_elem_flag_disable(e, BM_ELEM_TAG); + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + } + } + bm->elem_index_dirty &= ~BM_EDGE; + } + + int index_face, index_loop = 0; + BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) { + BM_elem_index_set(f, index_face); /* set_inline */ + l_curr = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_elem_index_set(l_curr, index_loop++); /* set_inline */ + BM_elem_flag_disable(l_curr, BM_ELEM_TAG); + } while ((l_curr = l_curr->next) != l_first); + } + bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); +} + +static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr) +{ + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + + BLI_SMALLSTACK_DECLARE(clnors, short *); + + BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR); + + normals_splitmerge_loops_edges_tag(bm, false); + + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + if (BM_elem_flag_test(lnor_ed->loop, BM_ELEM_TAG)) { + continue; + } + + MLoopNorSpace *lnor_space = bm->lnor_spacearr->lspacearr[lnor_ed->loop_index]; + + if ((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0) { + LinkNode *loops = lnor_space->loops; + float avg_normal[3] = {0.0f, 0.0f, 0.0f}; + short *clnors_data; + + for (; loops; loops = loops->next) { + BMLoop *l = loops->link; + const int loop_index = BM_elem_index_get(l); + + BMLoopNorEditData *lnor_ed_tmp = lnors_ed_arr->lidx_to_lnor_editdata[loop_index]; + BLI_assert(lnor_ed_tmp->loop_index == loop_index && lnor_ed_tmp->loop == l); + add_v3_v3(avg_normal, lnor_ed_tmp->nloc); + BLI_SMALLSTACK_PUSH(clnors, lnor_ed_tmp->clnors_data); + BM_elem_flag_enable(l, BM_ELEM_TAG); + } + if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) { + /* If avg normal is nearly 0, set clnor to default value. */ + zero_v3(avg_normal); + } + while ((clnors_data = BLI_SMALLSTACK_POP(clnors))) { + BKE_lnor_space_custom_normal_to_data(lnor_space, avg_normal, clnors_data); + } + } + } +} + +static void normals_split(BMesh *bm) +{ + BMFace *f; + BMLoop *l, *l_curr, *l_first; + BMIter fiter; + + BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR); + + normals_splitmerge_loops_edges_tag(bm, true); + + const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + l_curr = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (BM_elem_flag_test(l_curr->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) || + (!BM_elem_flag_test(l_curr, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_curr)))) + { + if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG)) { + const int loop_index = BM_elem_index_get(l_curr); + short *clnors = BM_ELEM_CD_GET_VOID_P(l_curr, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors); + } + else { + BMVert *v_pivot = l_curr->v; + BMEdge *e_next; + const BMEdge *e_org = l_curr->e; + BMLoop *lfan_pivot, *lfan_pivot_next; + + lfan_pivot = l_curr; + e_next = lfan_pivot->e; + BLI_SMALLSTACK_DECLARE(loops, BMLoop *); + float avg_normal[3] = { 0.0f }; + + while (true) { + lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); + if (lfan_pivot_next) { + BLI_assert(lfan_pivot_next->v == v_pivot); + } + else { + e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e; + } + + BLI_SMALLSTACK_PUSH(loops, lfan_pivot); + add_v3_v3(avg_normal, lfan_pivot->f->no); + + if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { + break; + } + lfan_pivot = lfan_pivot_next; + } + if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) { + /* If avg normal is nearly 0, set clnor to default value. */ + zero_v3(avg_normal); + } + while ((l = BLI_SMALLSTACK_POP(loops))) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], avg_normal, clnors); + } + } + } + } while ((l_curr = l_curr->next) != l_first); + } +} + +static int normals_split_merge(bContext *C, const bool do_merge) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMEdge *e; + BMIter eiter; + + BKE_editmesh_lnorspace_update(em); + + BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm) : NULL; + + mesh_set_smooth_faces(em, do_merge); + + BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { + BM_elem_flag_set(e, BM_ELEM_SMOOTH, do_merge); + } + } + if (do_merge == 0) { + Mesh *me = obedit->data; + me->drawflag |= ME_DRAWSHARP; + } + + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + BKE_editmesh_lnorspace_update(em); + + if (do_merge) { + normals_merge(bm, lnors_ed_arr); + } + else { + normals_split(bm); + } + + if (lnors_ed_arr) { + BM_loop_normal_editdata_array_free(lnors_ed_arr); + } + + EDBM_update_generic(em, true, false); + + return OPERATOR_FINISHED; +} + +static int edbm_merge_normals_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return normals_split_merge(C, true); +} + +void MESH_OT_merge_normals(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Merge Normals"; + ot->description = "Merge custom normals of selected vertices"; + ot->idname = "MESH_OT_merge_normals"; + + /* api callbacks */ + ot->exec = edbm_merge_normals_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int edbm_split_normals_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return normals_split_merge(C, false); +} + +void MESH_OT_split_normals(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Split Normals"; + ot->description = "Split custom normals of selected vertices"; + ot->idname = "MESH_OT_split_normals"; + + /* api callbacks */ + ot->exec = edbm_split_normals_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/********************** Average Loop Normals **********************/ + +enum { + EDBM_CLNOR_AVERAGE_LOOP = 1, + EDBM_CLNOR_AVERAGE_FACE_AREA = 2, + EDBM_CLNOR_AVERAGE_ANGLE = 3, +}; + +static EnumPropertyItem average_method_items[] = { + {EDBM_CLNOR_AVERAGE_LOOP, "CUSTOM_NORMAL", 0, "Custom Normal", "Take Average of vert Normals"}, + {EDBM_CLNOR_AVERAGE_FACE_AREA, "FACE_AREA", 0, "Face Area", "Set all vert normals by Face Area"}, + {EDBM_CLNOR_AVERAGE_ANGLE, "CORNER_ANGLE", 0, "Corner Angle", "Set all vert normals by Corner Angle"}, + {0, NULL, 0, NULL, NULL} +}; + +static int edbm_average_normals_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMFace *f; + BMLoop *l, *l_curr, *l_first; + BMIter fiter; + + bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; + BKE_editmesh_lnorspace_update(em); + + const int average_type = RNA_enum_get(op->ptr, "average_type"); + const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const float absweight = (float) RNA_int_get(op->ptr, "weight"); + const float threshold = RNA_float_get(op->ptr, "threshold"); + + float weight = absweight / 50.0f; + if (absweight == 100.0f) { + weight = (float)SHRT_MAX; + } + else if (absweight == 1.0f) { + weight = 1 / (float)SHRT_MAX; + } + else if ((weight - 1) * 25 > 1) { + weight = (weight - 1) * 25; + } + + normals_splitmerge_loops_edges_tag(bm, true); + + Heap *loop_weight = BLI_heap_new(); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + l_curr = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (BM_elem_flag_test(l_curr->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) || + (!BM_elem_flag_test(l_curr, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_curr)))) + { + if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG)) { + const int loop_index = BM_elem_index_get(l_curr); + short *clnors = BM_ELEM_CD_GET_VOID_P(l_curr, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors); + } + else { + BMVert *v_pivot = l_curr->v; + BMEdge *e_next; + const BMEdge *e_org = l_curr->e; + BMLoop *lfan_pivot, *lfan_pivot_next; + + lfan_pivot = l_curr; + e_next = lfan_pivot->e; + + while (true) { + lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); + if (lfan_pivot_next) { + BLI_assert(lfan_pivot_next->v == v_pivot); + } + else { + e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e; + } + + float val = 1.0f; + if (average_type == EDBM_CLNOR_AVERAGE_FACE_AREA) { + val = 1.0f / BM_face_calc_area(lfan_pivot->f); + } + else if (average_type == EDBM_CLNOR_AVERAGE_ANGLE) { + val = 1.0f / BM_loop_calc_face_angle(lfan_pivot); + } + + BLI_heap_insert(loop_weight, val, lfan_pivot); + + if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { + break; + } + lfan_pivot = lfan_pivot_next; + } + + BLI_SMALLSTACK_DECLARE(loops, BMLoop *); + float wnor[3], avg_normal[3] = { 0.0f }, count = 0; + float val = BLI_heap_node_value(BLI_heap_top(loop_weight)); + + while (!BLI_heap_is_empty(loop_weight)) { + const float cur_val = BLI_heap_node_value(BLI_heap_top(loop_weight)); + if (!compare_ff(val, cur_val, threshold)) { + count++; + val = cur_val; + } + l = BLI_heap_pop_min(loop_weight); + BLI_SMALLSTACK_PUSH(loops, l); + + const float n_weight = pow(weight, count); + + if (average_type == EDBM_CLNOR_AVERAGE_LOOP) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], clnors, wnor); + } + else { + copy_v3_v3(wnor, l->f->no); + } + mul_v3_fl(wnor, (1.0f / cur_val) * (1.0f / n_weight)); + add_v3_v3(avg_normal, wnor); + } + + if (normalize_v3(avg_normal) < CLNORS_VALID_VEC_LEN) { + /* If avg normal is nearly 0, set clnor to default value. */ + zero_v3(avg_normal); + } + while ((l = BLI_SMALLSTACK_POP(loops))) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], avg_normal, clnors); + } + } + } + } while ((l_curr = l_curr->next) != l_first); + } + + BLI_heap_free(loop_weight, NULL); + EDBM_update_generic(em, true, false); + + return OPERATOR_FINISHED; +} + +static bool average_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + const int average_type = RNA_enum_get(ptr, "average_type"); + + /* Only show weight/threshold options in loop average type. */ + if (STREQ(prop_id, "weight")) { + return (average_type == EDBM_CLNOR_AVERAGE_LOOP); + } + else if (STREQ(prop_id, "threshold")) { + return (average_type == EDBM_CLNOR_AVERAGE_LOOP); + } + + /* Else, show it! */ + return true; +} + +static void edbm_average_normals_ui(bContext *C, wmOperator *op) +{ + uiLayout *layout = op->layout; + wmWindowManager *wm = CTX_wm_manager(C); + PointerRNA ptr; + + RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); + + /* Main auto-draw call */ + uiDefAutoButsRNA(layout, &ptr, average_normals_draw_check_prop, '\0', false); +} + +void MESH_OT_average_normals(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Average Normals"; + ot->description = "Average custom normals of selected vertices"; + ot->idname = "MESH_OT_average_normals"; + + /* api callbacks */ + ot->exec = edbm_average_normals_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + ot->ui = edbm_average_normals_ui; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "average_type", average_method_items, EDBM_CLNOR_AVERAGE_LOOP, + "Type", "Averaging method"); + RNA_def_property_flag(ot->prop, PROP_HIDDEN); + + RNA_def_int(ot->srna, "weight", 50, 1, 100, "Weight", "Weight applied per face", 1, 100); + + RNA_def_float(ot->srna, "threshold", 0.01f, 0, 10, "Threshold", + "Threshold value for different weights to be considered equal", 0, 5); +} + +/********************** Custom Normal Interface Tools **********************/ + +enum { + EDBM_CLNOR_TOOLS_COPY = 1, + EDBM_CLNOR_TOOLS_PASTE = 2, + EDBM_CLNOR_TOOLS_MULTIPLY = 3, + EDBM_CLNOR_TOOLS_ADD = 4, + EDBM_CLNOR_TOOLS_RESET = 5, +}; + +static EnumPropertyItem normal_vector_tool_items[] = { + {EDBM_CLNOR_TOOLS_COPY, "COPY", 0, "Copy Normal", "Copy normal to buffer"}, + {EDBM_CLNOR_TOOLS_PASTE, "PASTE", 0, "Paste Normal", "Paste normal from buffer"}, + {EDBM_CLNOR_TOOLS_ADD, "ADD", 0, "Add Normal", "Add normal vector with selection"}, + {EDBM_CLNOR_TOOLS_MULTIPLY, "MULTIPLY", 0, "Multiply Normal", "Multiply normal vector with selection"}, + {EDBM_CLNOR_TOOLS_RESET, "RESET", 0, "Reset Normal", "Reset buffer and/or normal of selected element"}, + {0, NULL, 0, NULL, NULL} +}; + +static int edbm_normals_tools_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Scene *scene = CTX_data_scene(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + + const int mode = RNA_enum_get(op->ptr, "mode"); + const bool absolute = RNA_boolean_get(op->ptr, "absolute"); + + BKE_editmesh_lnorspace_update(em); + BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + + float *normal_vector = scene->toolsettings->normal_vector; + + switch (mode) { + case EDBM_CLNOR_TOOLS_COPY: + if (bm->totfacesel != 1 && lnors_ed_arr->totloop != 1 && bm->totvertsel != 1) { + BKE_report(op->reports, RPT_ERROR, "Can only copy custom normal, vertex normal or face normal"); + BM_loop_normal_editdata_array_free(lnors_ed_arr); + return OPERATOR_CANCELLED; + } + bool join = true; + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + if (!compare_v3v3(lnors_ed_arr->lnor_editdata->nloc, lnor_ed->nloc, 1e-4f)) { + join = false; + } + } + if (lnors_ed_arr->totloop == 1) { + copy_v3_v3(scene->toolsettings->normal_vector, lnors_ed_arr->lnor_editdata->nloc); + } + else if (bm->totfacesel == 1) { + BMFace *f; + BMIter fiter; + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + copy_v3_v3(scene->toolsettings->normal_vector, f->no); + } + } + } + else if (join) { + copy_v3_v3(scene->toolsettings->normal_vector, lnors_ed_arr->lnor_editdata->nloc); + } + break; + + case EDBM_CLNOR_TOOLS_PASTE: + if (!absolute) { + if (normalize_v3(normal_vector) < CLNORS_VALID_VEC_LEN) { + /* If normal is nearly 0, do nothing. */ + break; + } + } + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + if (absolute) { + float abs_normal[3]; + copy_v3_v3(abs_normal, lnor_ed->loc); + negate_v3(abs_normal); + add_v3_v3(abs_normal, normal_vector); + + if (normalize_v3(abs_normal) < CLNORS_VALID_VEC_LEN) { + /* If abs normal is nearly 0, set clnor to initial value. */ + copy_v3_v3(abs_normal, lnor_ed->niloc); + } + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], abs_normal, lnor_ed->clnors_data); + } + else { + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], normal_vector, lnor_ed->clnors_data); + } + } + break; + + case EDBM_CLNOR_TOOLS_MULTIPLY: + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + mul_v3_v3(lnor_ed->nloc, normal_vector); + + if (normalize_v3(lnor_ed->nloc) < CLNORS_VALID_VEC_LEN) { + /* If abs normal is nearly 0, set clnor to initial value. */ + copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc); + } + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data); + } + break; + + case EDBM_CLNOR_TOOLS_ADD: + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + add_v3_v3(lnor_ed->nloc, normal_vector); + + if (normalize_v3(lnor_ed->nloc) < CLNORS_VALID_VEC_LEN) { + /* If abs normal is nearly 0, set clnor to initial value. */ + copy_v3_v3(lnor_ed->nloc, lnor_ed->niloc); + } + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data); + } + break; + + case EDBM_CLNOR_TOOLS_RESET: + zero_v3(normal_vector); + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], normal_vector, lnor_ed->clnors_data); + } + break; + + default: + BLI_assert(0); + break; + } + + BM_loop_normal_editdata_array_free(lnors_ed_arr); + + EDBM_update_generic(em, true, false); + return OPERATOR_FINISHED; +} + +static bool normals_tools_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + const int mode = RNA_enum_get(ptr, "mode"); + + /* Only show absolute option in paste mode. */ + if (STREQ(prop_id, "absolute")) { + return (mode == EDBM_CLNOR_TOOLS_PASTE); + } + + /* Else, show it! */ + return true; +} + +static void edbm_normals_tools_ui(bContext *C, wmOperator *op) +{ + uiLayout *layout = op->layout; + wmWindowManager *wm = CTX_wm_manager(C); + PointerRNA ptr; + + RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); + + /* Main auto-draw call */ + uiDefAutoButsRNA(layout, &ptr, normals_tools_draw_check_prop, '\0', false); +} + +void MESH_OT_normals_tools(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Normals Vector Tools"; + ot->description = "Custom normals tools using Normal Vector of UI"; + ot->idname = "MESH_OT_normals_tools"; + + /* api callbacks */ + ot->exec = edbm_normals_tools_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + ot->ui = edbm_normals_tools_ui; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "mode", normal_vector_tool_items, EDBM_CLNOR_TOOLS_COPY, + "Mode", "Mode of tools taking input from Interface"); + RNA_def_property_flag(ot->prop, PROP_HIDDEN); + + RNA_def_boolean(ot->srna, "absolute", false, "Absolute Coordinates", "Copy Absolute coordinates or Normal vector"); +} + +static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) +{ + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMFace *f; + BMVert *v; + BMEdge *e; + BMLoop *l; + BMIter fiter, viter, eiter, liter; + + const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp"); + + BKE_editmesh_lnorspace_update(em); + + float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, __func__); + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + BM_ITER_ELEM(v, &viter, f, BM_VERTS_OF_FACE) { + const int v_index = BM_elem_index_get(v); + add_v3_v3(vnors[v_index], f->no); + } + } + } + for (int i = 0; i < bm->totvert; i++) { + if (!is_zero_v3(vnors[i]) && normalize_v3(vnors[i]) < CLNORS_VALID_VEC_LEN) { + zero_v3(vnors[i]); + } + } + + BLI_bitmap *loop_set = BLI_BITMAP_NEW(bm->totloop, __func__); + const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM(e, &eiter, f, BM_EDGES_OF_FACE) { + if (!keep_sharp || (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && BM_elem_flag_test(e, BM_ELEM_SELECT))) { + BM_ITER_ELEM(v, &viter, e, BM_VERTS_OF_EDGE) { + l = BM_face_vert_share_loop(f, v); + const int l_index = BM_elem_index_get(l); + const int v_index = BM_elem_index_get(l->v); + + if (!is_zero_v3(vnors[v_index])) { + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], vnors[v_index], clnors); + + if (bm->lnor_spacearr->lspacearr[l_index]->flags & MLNOR_SPACE_IS_SINGLE) { + BLI_BITMAP_ENABLE(loop_set, l_index); + } + else { + LinkNode *loops = bm->lnor_spacearr->lspacearr[l_index]->loops; + for (; loops; loops = loops->next) { + BLI_BITMAP_ENABLE(loop_set, BM_elem_index_get((BMLoop *)loops->link)); + } + } + } + } + } + } + } + + int v_index; + BM_ITER_MESH_INDEX(v, &viter, bm, BM_VERTS_OF_MESH, v_index) { + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + if (BLI_BITMAP_TEST(loop_set, BM_elem_index_get(l))) { + const int loop_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], clnors); + } + } + } + + MEM_freeN(loop_set); + MEM_freeN(vnors); + EDBM_update_generic(em, true, false); + } + + return OPERATOR_FINISHED; +} + +void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Normals From Faces"; + ot->description = "Set the custom normals from the selected faces ones"; + ot->idname = "MESH_OT_set_normals_from_faces"; + + /* api callbacks */ + ot->exec = edbm_set_normals_from_faces_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "keep_sharp", 0, "Keep Sharp Edges", "Do not set sharp edges to face"); +} + +static int edbm_smoothen_normals_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMFace *f; + BMLoop *l; + BMIter fiter, liter; + + BKE_editmesh_lnorspace_update(em); + BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); + + float(*smooth_normal)[3] = MEM_callocN(sizeof(*smooth_normal) * lnors_ed_arr->totloop, __func__); + + /* This is weird choice of operation, taking all loops of faces of current vertex... Could lead to some rather + * far away loops weighting as much as very close ones (topologically speaking), with complex polygons. + * Using topological distance here (rather than geometrical one) makes sense imho, but would rather go with + * a more consistent and flexible code, we could even add max topological distance to take into account, + * and a weighting curve... + * Would do that later though, think for now we can live with that choice. --mont29 */ + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + l = lnor_ed->loop; + float loop_normal[3]; + + BM_ITER_ELEM(f, &fiter, l->v, BM_FACES_OF_VERT) { + BMLoop *l_other; + BM_ITER_ELEM(l_other, &liter, f, BM_LOOPS_OF_FACE) { + const int l_index_other = BM_elem_index_get(l_other); + short *clnors = BM_ELEM_CD_GET_VOID_P(l_other, lnors_ed_arr->cd_custom_normal_offset); + BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index_other], clnors, loop_normal); + add_v3_v3(smooth_normal[i], loop_normal); + } + } + } + + const float factor = RNA_float_get(op->ptr, "factor"); + + lnor_ed = lnors_ed_arr->lnor_editdata; + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + float current_normal[3]; + + if (normalize_v3(smooth_normal[i]) < CLNORS_VALID_VEC_LEN) { + /* Skip in case smoothen normal is invalid... */ + continue; + } + + BKE_lnor_space_custom_data_to_normal( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->clnors_data, current_normal); + + /* Note: again, this is not true spherical interpolation that normals would need... + * But it's probably good enough for now. */ + mul_v3_fl(current_normal, 1.0f - factor); + mul_v3_fl(smooth_normal[i], factor); + add_v3_v3(current_normal, smooth_normal[i]); + + if (normalize_v3(current_normal) < CLNORS_VALID_VEC_LEN) { + /* Skip in case smoothen normal is invalid... */ + continue; + } + + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], current_normal, lnor_ed->clnors_data); + } + + BM_loop_normal_editdata_array_free(lnors_ed_arr); + MEM_freeN(smooth_normal); + + EDBM_update_generic(em, true, false); + + return OPERATOR_FINISHED; +} + +void MESH_OT_smoothen_normals(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Smoothen Normals"; + ot->description = "Smoothen custom normals based on adjacent vertex normals"; + ot->idname = "MESH_OT_smoothen_normals"; + + /* api callbacks */ + ot->exec = edbm_smoothen_normals_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0f, "Factor", + "Specifies weight of smooth vs original normal", 0.0f, 1.0f); +} + +/********************** Weighted Normal Modifier Face Strength **********************/ + +static int edbm_mod_weighted_strength_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + BMFace *f; + BMIter fiter; + + BM_select_history_clear(bm); + + const char *layer_id = MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID; + int cd_prop_int_index = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, layer_id); + if (cd_prop_int_index == -1) { + BM_data_layer_add_named(bm, &bm->pdata, CD_PROP_INT, layer_id); + cd_prop_int_index = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, layer_id); + } + cd_prop_int_index -= CustomData_get_layer_index(&bm->pdata, CD_PROP_INT); + const int cd_prop_int_offset = CustomData_get_n_offset(&bm->pdata, CD_PROP_INT, cd_prop_int_index); + + const int face_strength = scene->toolsettings->face_strength; + const bool set = RNA_boolean_get(op->ptr, "set"); + BM_mesh_elem_index_ensure(bm, BM_FACE); + + if (set) { + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { + int *strength = BM_ELEM_CD_GET_VOID_P(f, cd_prop_int_offset); + *strength = face_strength; + } + } + } + else { + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + int *strength = BM_ELEM_CD_GET_VOID_P(f, cd_prop_int_offset); + if (*strength == face_strength) { + BM_face_select_set(bm, f, true); + BM_select_history_store(bm, f); + } + else { + BM_face_select_set(bm, f, false); + } + } + } + + EDBM_update_generic(em, false, false); + return OPERATOR_FINISHED; +} + +void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Face Strength"; + ot->description = "Set/Get strength of face (used in Weighted Normal modifier)"; + ot->idname = "MESH_OT_mod_weighted_strength"; + + /* api callbacks */ + ot->exec = edbm_mod_weighted_strength_exec; + ot->poll = ED_operator_editmesh_auto_smooth; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_boolean(ot->srna, "set", 0, "Set value", "Set Value of faces"); + RNA_def_property_flag(ot->prop, PROP_HIDDEN); +} \ No newline at end of file diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 4d4b7a098b0..6fb7a713ce0 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -598,6 +598,8 @@ static void undomesh_to_editmesh(UndoMesh *um, BMEditMesh *em, Mesh *obmesh) bm->selectmode = um->selectmode; em->ob = ob; + bm->spacearr_dirty = BM_SPACEARR_DIRTY_ALL; + /* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens * if the active is a basis for any other. */ if (key && (key->type == KEY_RELATIVE)) { diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index ab44e017fc6..16c1a2c45ec 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1343,7 +1343,10 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d /* in debug mode double check we didn't need to recalculate */ BLI_assert(BM_mesh_elem_table_check(em->bm) == true); } - + if (em->bm->spacearr_dirty & BM_SPACEARR_BMO_SET) { + BM_lnorspace_invalidate(em->bm, false); + em->bm->spacearr_dirty &= ~BM_SPACEARR_BMO_SET; + } /* don't keep stale derivedMesh data around, see: [#38872] */ BKE_editmesh_free_derivedmesh(em); diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index b9e9ae9c1fd..e585f407052 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -240,6 +240,16 @@ void MESH_OT_duplicate(struct wmOperatorType *ot); void MESH_OT_merge(struct wmOperatorType *ot); void MESH_OT_remove_doubles(struct wmOperatorType *ot); void MESH_OT_poke(struct wmOperatorType *ot); +void MESH_OT_point_normals(struct wmOperatorType *ot); +void MESH_OT_merge_normals(struct wmOperatorType *ot); +void MESH_OT_split_normals(struct wmOperatorType *ot); +void MESH_OT_normals_tools(struct wmOperatorType *ot); +void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot); +void MESH_OT_average_normals(struct wmOperatorType *ot); +void MESH_OT_smoothen_normals(struct wmOperatorType *ot); +void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot); + +struct wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf); #ifdef WITH_FREESTYLE void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 9f3ef6f958d..60200313b8c 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -200,6 +200,15 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_bisect); WM_operatortype_append(MESH_OT_symmetrize); WM_operatortype_append(MESH_OT_symmetry_snap); + + WM_operatortype_append(MESH_OT_point_normals); + WM_operatortype_append(MESH_OT_merge_normals); + WM_operatortype_append(MESH_OT_split_normals); + WM_operatortype_append(MESH_OT_normals_tools); + WM_operatortype_append(MESH_OT_set_normals_from_faces); + WM_operatortype_append(MESH_OT_average_normals); + WM_operatortype_append(MESH_OT_smoothen_normals); + WM_operatortype_append(MESH_OT_mod_weighted_strength); } #if 0 /* UNUSED, remove? */ @@ -446,6 +455,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "MESH_OT_vert_connect_path", JKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_point_normals", LKEY, KM_PRESS, KM_ALT, 0); + /* Vertex Slide */ WM_keymap_add_item(keymap, "TRANSFORM_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT, 0); /* use KM_CLICK because same key is used for tweaks */ @@ -489,5 +500,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) ED_keymap_proportional_editmode(keyconf, keymap, true); knifetool_modal_keymap(keyconf); + point_normals_modal_keymap(keyconf); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 2063191658b..6392af2a5e0 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -47,6 +47,7 @@ #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_meta_types.h" +#include "DNA_mesh_types.h" #include "DNA_mask_types.h" #include "DNA_node_types.h" #include "DNA_workspace_types.h" @@ -351,6 +352,15 @@ int ED_operator_editmesh_region_view3d(bContext *C) return 0; } +int ED_operator_editmesh_auto_smooth(bContext *C) +{ + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) { + return NULL != BKE_editmesh_from_object(obedit); + } + return 0; +} + int ED_operator_editarmature(bContext *C) { Object *obedit = CTX_data_edit_object(C); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 7d200c904cd..883078bc83c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1006,6 +1006,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto ICON_DRAW(ICON_MOD_DATA_TRANSFER); break; case eModifierType_NormalEdit: + case eModifierType_WeightedNormal: ICON_DRAW(ICON_MOD_NORMALEDIT); break; /* Default */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index e20ef264a93..569cd4efafc 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -41,6 +41,7 @@ #include "DNA_armature_types.h" #include "DNA_constraint_types.h" #include "DNA_mask_types.h" +#include "DNA_mesh_types.h" #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ #include "DNA_workspace_types.h" @@ -64,6 +65,7 @@ #include "BKE_unit.h" #include "BKE_scene.h" #include "BKE_mask.h" +#include "BKE_mesh.h" #include "BKE_report.h" #include "BKE_workspace.h" @@ -94,6 +96,7 @@ #include "UI_resources.h" #include "RNA_access.h" +#include "RNA_define.h" #include "BLF_api.h" #include "BLT_translation.h" @@ -114,6 +117,7 @@ static void postInputRotation(TransInfo *t, float values[3]); static void ElementRotation(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3], const short around); static void initSnapSpatial(TransInfo *t, float r_snap[3]); +static void storeCustomLNorValue(TransDataContainer *t, BMesh *bm); /* Transform Callbacks */ static void initBend(TransInfo *t); @@ -139,6 +143,9 @@ static void applyToSphere(TransInfo *t, const int mval[2]); static void initRotation(TransInfo *t); static void applyRotation(TransInfo *t, const int mval[2]); +static void initNormalRotation(TransInfo *t); +static void applyNormalRotation(TransInfo *t, const int mval[2]); + static void initShrinkFatten(TransInfo *t); static void applyShrinkFatten(TransInfo *t, const int mval[2]); @@ -1481,6 +1488,18 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } break; + case NKEY: + if (ELEM(t->mode, TFM_ROTATION)) { + if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) { + restoreTransObjects(t); + resetTransModal(t); + resetTransRestrictions(t); + initNormalRotation(t); + t->redraw = TREDRAW_HARD; + handled = true; + } + } + break; default: break; } @@ -2430,6 +2449,9 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve case TFM_SEQ_SLIDE: initSeqSlide(t); break; + case TFM_NORMAL_ROTATION: + initNormalRotation(t); + break; } if (t->state == TRANS_CANCEL) { @@ -2437,6 +2459,39 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve return 0; } + if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) { + if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) { + + FOREACH_TRANS_DATA_CONTAINER(t, tc) { + if ((((Mesh *)(tc->obedit->data))->flag & ME_AUTOSMOOTH)) { + BMEditMesh *em = NULL;// BKE_editmesh_from_object(t->obedit); + bool do_skip = false; + + /* Currently only used for two of three most frequent transform ops, can include more ops. + * Note that scaling cannot be included here, non-uniform scaling will affect normals. */ + if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) { + if (em->bm->totvertsel == em->bm->totvert) { + /* No need to invalidate if whole mesh is selected. */ + do_skip = true; + } + } + + if (t->flag & T_MODAL) { + RNA_property_boolean_set(op->ptr, prop, false); + } + else if (!do_skip) { + const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop); + if (preserve_clnor) { + BKE_editmesh_lnorspace_update(em); + t->flag |= T_CLNOR_REBUILD; + } + BM_lnorspace_invalidate(em->bm, true); + } + } + } + } + } + t->context = NULL; return 1; @@ -2497,6 +2552,12 @@ int transformEnd(bContext *C, TransInfo *t) restoreTransObjects(t); // calls recalcData() } else { + if (t->flag & T_CLNOR_REBUILD) { + FOREACH_TRANS_DATA_CONTAINER(t, tc) { + BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); + BM_lnorspace_rebuild(em->bm, true); + } + } exit_code = OPERATOR_FINISHED; } @@ -3815,6 +3876,28 @@ static void initRotation(TransInfo *t) copy_v3_v3(t->axis_orig, t->axis); } +/* Used by Transform Rotation and Transform Normal Rotation */ +static void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final) +{ + size_t ofs = 0; + + if (hasNumInput(&t->num)) { + char c[NUM_STR_REP_LEN]; + + outputNumInput(&(t->num), c, &t->scene->unit); + + ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext); + } + else { + ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_("Rot: %.2f%s %s"), + RAD2DEGF(final), t->con.text, t->proptext); + } + + if (t->flag & T_PROP_EDIT_ALL) { + ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size); + } +} + /** * Applies values of rotation to `td->loc` and `td->ext->quat` * based on a rotation matrix (mat) and a pivot (center). @@ -4101,21 +4184,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) t->values[0] = final; - if (hasNumInput(&t->num)) { - char c[NUM_STR_REP_LEN]; - - outputNumInput(&(t->num), c, &t->scene->unit); - - ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext); - } - else { - ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Rot: %.2f%s %s"), - RAD2DEGF(final), t->con.text, t->proptext); - } - - if (t->flag & T_PROP_EDIT_ALL) { - ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size); - } + headerRotation(t, str, final); applyRotationValue(t, final, t->axis); @@ -4243,6 +4312,127 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2])) /** \} */ +/* -------------------------------------------------------------------- */ +/* Transform (Normal Rotation) */ + +/** \name Transform Normal Rotation +* \{ */ + +static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm) +{ + BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + + tc->custom.mode.data = lnors_ed_arr; + tc->custom.mode.free_cb = freeCustomNormalArray; +} + +void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data) +{ + BMLoopNorEditDataArray *lnors_ed_arr = custom_data->data; + + if (t->state == TRANS_CANCEL) { + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); + BMesh *bm = em->bm; + + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { /* Restore custom loop normal on cancel */ + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->niloc, lnor_ed->clnors_data); + } + } + + BM_loop_normal_editdata_array_free(lnors_ed_arr); + + tc->custom.mode.data = NULL; + tc->custom.mode.free_cb = NULL; +} + +static void initNormalRotation(TransInfo *t) +{ + t->mode = TFM_NORMAL_ROTATION; + t->transform = applyNormalRotation; + + setInputPostFct(&t->mouse, postInputRotation); + initMouseInputMode(t, &t->mouse, INPUT_ANGLE); + + t->idx_max = 0; + t->num.idx_max = 0; + t->snap[0] = 0.0f; + t->snap[1] = DEG2RAD(5.0); + t->snap[2] = DEG2RAD(1.0); + + copy_v3_fl(t->num.val_inc, t->snap[2]); + t->num.unit_sys = t->scene->unit.system; + t->num.unit_use_radians = (t->scene->unit.system_rotation == USER_UNIT_ROT_RADIANS); + t->num.unit_type[0] = B_UNIT_ROTATION; + + FOREACH_TRANS_DATA_CONTAINER(t, tc) { + BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); + BMesh *bm = em->bm; + + BKE_editmesh_lnorspace_update(em); + + storeCustomLNorValue(tc, bm); + } + + negate_v3_v3(t->axis, t->viewinv[2]); + normalize_v3(t->axis); + + copy_v3_v3(t->axis_orig, t->axis); +} + +/* Works by getting custom normal from clnor_data, transform, then store */ +static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2])) +{ + char str[UI_MAX_DRAW_STR]; + + if ((t->con.mode & CON_APPLY) && t->con.applyRot) { + t->con.applyRot(t, NULL, NULL, t->axis, NULL); + } + else { + /* reset axis if constraint is not set */ + copy_v3_v3(t->axis, t->axis_orig); + } + + FOREACH_TRANS_DATA_CONTAINER(t, tc) { + BMEditMesh *em = BKE_editmesh_from_object(tc->obedit); + BMesh *bm = em->bm; + + BMLoopNorEditDataArray *lnors_ed_arr = tc->custom.mode.data; + BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + + float axis[3]; + float mat[3][3]; + float angle = t->values[0]; + copy_v3_v3(axis, t->axis); + + snapGridIncrement(t, &angle); + + applySnapping(t, &angle); + + applyNumInput(&t->num, &angle); + + headerRotation(t, str, angle); + + axis_angle_normalized_to_mat3(mat, axis, angle); + + for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { + mul_v3_m3v3(lnor_ed->nloc, mat, lnor_ed->niloc); + + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->nloc, lnor_ed->clnors_data); + } + } + + recalcData(t); + + ED_area_headerprint(t->sa, str); +} + +/** \} */ + + /* -------------------------------------------------------------------- */ /* Transform (Translation) */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2cf66794709..136512516e8 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -601,6 +601,8 @@ typedef struct TransInfo { /** #TransInfo.center has been set, don't change it. */ #define T_OVERRIDE_CENTER (1 << 25) +#define T_CLNOR_REBUILD (1 << 26) + /* TransInfo->modifiers */ #define MOD_CONSTRAINT_SELECT 0x01 #define MOD_PRECISION 0x02 @@ -869,6 +871,8 @@ bool applyTransformOrientation(const struct TransformOrientation *ts, float r_ma int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around); int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]); +void freeCustomNormalArray(TransInfo *t, TransCustomData *custom_data); + void freeEdgeSlideTempFaces(EdgeSlideData *sld); void freeEdgeSlideVerts(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data); void projectEdgeSlideData(TransInfo *t, bool is_final); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 36c444a0ca3..4fbb50d678e 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -81,6 +81,7 @@ static const char OP_VERT_SLIDE[] = "TRANSFORM_OT_vert_slide"; static const char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease"; static const char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight"; static const char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide"; +static const char OP_NORMAL_ROTATION[] = "TRANSFORM_OT_rotate_normal"; static void TRANSFORM_OT_translate(struct wmOperatorType *ot); static void TRANSFORM_OT_rotate(struct wmOperatorType *ot); @@ -99,6 +100,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot); static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot); static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot); static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot); +static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot); static TransformModeItem transform_modes[] = { @@ -119,6 +121,7 @@ static TransformModeItem transform_modes[] = {OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease}, {OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight}, {OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide}, + {OP_NORMAL_ROTATION, TFM_NORMAL_ROTATION, TRANSFORM_OT_rotate_normal}, {NULL, 0} }; @@ -1020,6 +1023,27 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot) Transform_Properties(ot, P_SNAP); } +static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Normal Rotate"; + ot->description = "Rotate split normal of selected items"; + ot->idname = OP_NORMAL_ROTATION; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* api callbacks */ + ot->invoke = transform_invoke; + ot->exec = transform_exec; + ot->modal = transform_modal; + ot->cancel = transform_cancel; + ot->poll = ED_operator_editmesh_auto_smooth; + + RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + + Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_MIRROR); +} + + static void TRANSFORM_OT_transform(struct wmOperatorType *ot) { PropertyRNA *prop; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 7faf1cfe193..989e0768fc1 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -89,6 +89,7 @@ typedef enum ModifierType { eModifierType_CorrectiveSmooth = 51, eModifierType_MeshSequenceCache = 52, eModifierType_SurfaceDeform = 53, + eModifierType_WeightedNormal = 54, NUM_MODIFIER_TYPES } ModifierType; @@ -1638,6 +1639,32 @@ enum { MOD_SDEF_MODE_CENTROID = 2, }; +typedef struct WeightedNormalModifierData { + ModifierData modifier; + + char defgrp_name[64]; /* MAX_VGROUP_NAME */ + char mode, flag; + short weight; + float thresh; +} WeightedNormalModifierData; + +/* Name/id of the generic PROP_INT cdlayer storing face weights. */ +#define MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID "__mod_weightednormals_faceweight" + +/* WeightedNormalModifierData.mode */ +enum { + MOD_WEIGHTEDNORMAL_MODE_FACE = 0, + MOD_WEIGHTEDNORMAL_MODE_ANGLE = 1, + MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE = 2, +}; + +/* WeightedNormalModifierData.flag */ +enum { + MOD_WEIGHTEDNORMAL_KEEP_SHARP = (1 << 0), + MOD_WEIGHTEDNORMAL_INVERT_VGROUP = (1 << 1), + MOD_WEIGHTEDNORMAL_FACE_INFLUENCE = (1 << 2), +}; + #define MOD_MESHSEQ_READ_ALL \ (MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 96876e0d0bc..2c39576d0c9 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1309,6 +1309,10 @@ typedef struct ToolSettings { struct CurvePaintSettings curve_paint_settings; struct MeshStatVis statvis; + + /* Normal Editing */ + float normal_vector[3]; + int face_strength; } ToolSettings; /* *************************************************************** */ @@ -1837,6 +1841,13 @@ enum { OB_DRAW_GROUPUSER_ALL = 2 }; +/* toolsettings->face_strength */ +enum { + FACE_STRENGTH_WEAK = -16384, + FACE_STRENGTH_MEDIUM = 0, + FACE_STRENGTH_STRONG = 16384, +}; + /* object_vgroup.c */ /* ToolSettings.vgroupsubset */ typedef enum eVGroupSelect { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 4744b2e33df..8e0264e208d 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -691,6 +691,7 @@ extern StructRNA RNA_WaveModifier; extern StructRNA RNA_VertexWeightEditModifier; extern StructRNA RNA_VertexWeightMixModifier; extern StructRNA RNA_VertexWeightProximityModifier; +extern StructRNA RNA_WeightedNormalModifier; extern StructRNA RNA_View3DOverlay; extern StructRNA RNA_View3DShading; extern StructRNA RNA_ViewLayer; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index b1716f6a176..c665442a82f 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -68,6 +68,7 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = { {eModifierType_MeshCache, "MESH_CACHE", ICON_MOD_MESHDEFORM, "Mesh Cache", ""}, {eModifierType_MeshSequenceCache, "MESH_SEQUENCE_CACHE", ICON_MOD_MESHDEFORM, "Mesh Sequence Cache", ""}, {eModifierType_NormalEdit, "NORMAL_EDIT", ICON_MOD_NORMALEDIT, "Normal Edit", ""}, + {eModifierType_WeightedNormal, "WEIGHTED_NORMAL", ICON_MOD_NORMALEDIT, "Weighted Normal", ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, {eModifierType_UVWarp, "UV_WARP", ICON_MOD_UVPROJECT, "UV Warp", ""}, {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""}, @@ -413,6 +414,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) return &RNA_MeshSequenceCacheModifier; case eModifierType_SurfaceDeform: return &RNA_SurfaceDeformModifier; + case eModifierType_WeightedNormal: + return &RNA_WeightedNormalModifier; /* Default */ case eModifierType_None: case eModifierType_ShapeKey: @@ -503,6 +506,7 @@ RNA_MOD_VGROUP_NAME_SET(WeightVGMix, defgrp_name_b); RNA_MOD_VGROUP_NAME_SET(WeightVGMix, mask_defgrp_name); RNA_MOD_VGROUP_NAME_SET(WeightVGProximity, defgrp_name); RNA_MOD_VGROUP_NAME_SET(WeightVGProximity, mask_defgrp_name); +RNA_MOD_VGROUP_NAME_SET(WeightedNormal, defgrp_name); RNA_MOD_VGROUP_NAME_SET(Wireframe, defgrp_name); static void rna_ExplodeModifier_vgroup_get(PointerRNA *ptr, char *value) @@ -4892,6 +4896,68 @@ static void rna_def_modifier_surfacedeform(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); } +static void rna_def_modifier_weightednormal(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_weighting_mode_items[] = { + {MOD_WEIGHTEDNORMAL_MODE_FACE, "FACE_AREA", 0, "Face Area", "Generate face area weighted normals"}, + {MOD_WEIGHTEDNORMAL_MODE_ANGLE, "CORNER_ANGLE", 0, "Corner Angle", "Generate corner angle weighted normals"}, + {MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE, "FACE_AREA_WITH_ANGLE", 0, "Face Area And Angle", + "Generated normals weighted by both face area and angle"}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "WeightedNormalModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "WeightedNormal Modifier", ""); + RNA_def_struct_sdna(srna, "WeightedNormalModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_NORMALEDIT); + + prop = RNA_def_property(srna, "weight", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 1, 100); + RNA_def_property_ui_range(prop, 1, 100, 1, -1); + RNA_def_property_ui_text(prop, "Weight", + "Corrective factor applied to faces' weights, 50 is neutral, " + "lower values increase weight of weak faces, " + "higher values increase weight of strong faces"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_weighting_mode_items); + RNA_def_property_ui_text(prop, "Weighting Mode", "Weighted vertex normal mode to use"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "thresh", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0, 10); + RNA_def_property_ui_range(prop, 0, 10, 1, 2); + RNA_def_property_ui_text(prop, "Threshold", "Threshold value for different weights to be considered equal"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "keep_sharp", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WEIGHTEDNORMAL_KEEP_SHARP); + RNA_def_property_ui_text(prop, "Keep Sharp", + "Keep sharp edges as computed for default split normals, " + "instead of setting a single weighted normal for each vertex."); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "defgrp_name"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modifying the selected areas"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WeightedNormalModifier_defgrp_name_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WEIGHTEDNORMAL_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "face_influence", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WEIGHTEDNORMAL_FACE_INFLUENCE); + RNA_def_property_ui_text(prop, "Face Influence", "Use influence of face for weighting"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +} + void RNA_def_modifier(BlenderRNA *brna) { StructRNA *srna; @@ -5012,6 +5078,7 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_normaledit(brna); rna_def_modifier_meshseqcache(brna); rna_def_modifier_surfacedeform(brna); + rna_def_modifier_weightednormal(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 8ac3b8c0a5c..27f9932ebde 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2416,6 +2416,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem mod_weighted_strength[] = { + {FACE_STRENGTH_WEAK, "Weak", 0, "Weak", ""}, + {FACE_STRENGTH_MEDIUM, "Medium", 0, "Medium", ""}, + {FACE_STRENGTH_STRONG, "Strong", 0, "Strong", ""}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem draw_groupuser_items[] = { {OB_DRAW_GROUPUSER_NONE, "NONE", 0, "None", ""}, {OB_DRAW_GROUPUSER_ACTIVE, "ACTIVE", 0, "Active", "Show vertices with no weights in the active group"}, @@ -2816,6 +2823,14 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "edge_mode_live_unwrap", 1); RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edges seam re-calculates UV unwrap"); + prop = RNA_def_property(srna, "normal_vector", PROP_FLOAT, PROP_XYZ); + RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply"); + RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3); + + prop = RNA_def_property(srna, "face_strength", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, mod_weighted_strength); + RNA_def_property_ui_text(prop, "Face Strength", "Set strength of face to specified value"); + /* Unified Paint Settings */ prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 397a3263e22..0a619ecf9c7 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -100,6 +100,7 @@ set(SRC intern/MOD_uvproject.c intern/MOD_warp.c intern/MOD_wave.c + intern/MOD_weighted_normal.c intern/MOD_weightvg_util.c intern/MOD_weightvgedit.c intern/MOD_weightvgmix.c diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index bf121af2bd1..3511b0edbec 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -86,6 +86,7 @@ extern ModifierTypeInfo modifierType_NormalEdit; extern ModifierTypeInfo modifierType_CorrectiveSmooth; extern ModifierTypeInfo modifierType_MeshSequenceCache; extern ModifierTypeInfo modifierType_SurfaceDeform; +extern ModifierTypeInfo modifierType_WeightedNormal; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 4a62d17fa27..5d740ae9e20 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -444,5 +444,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(CorrectiveSmooth); INIT_TYPE(MeshSequenceCache); INIT_TYPE(SurfaceDeform); + INIT_TYPE(WeightedNormal); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c new file mode 100644 index 00000000000..b43ef698cc4 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -0,0 +1,670 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_weighted_normal.c + * \ingroup modifiers + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_deform.h" +#include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_mesh.h" + +#include "BLI_math.h" +#include "BLI_linklist.h" + +#include "MOD_modifiertypes.h" +#include "MOD_util.h" + +#define CLNORS_VALID_VEC_LEN (1e-6f) + +typedef struct ModePair { + float val; /* Contains mode based value (face area / corner angle). */ + int index; /* Index value per poly or per loop. */ +} ModePair; + +/* Sorting function used in modifier, sorts in decreasing order. */ +static int modepair_cmp_by_val_inverse(const void *p1, const void *p2) +{ + ModePair *r1 = (ModePair *)p1; + ModePair *r2 = (ModePair *)p2; + + return (r1->val < r2->val) ? 1 : ((r1->val > r2->val) ? -1 : 0); +} + +/* There will be one of those per vertex (simple case, computing one normal per vertex), or per smooth fan. */ +typedef struct WeightedNormalDataAggregateItem { + float normal[3]; + + int num_loops; /* Count number of loops using this item so far. */ + float curr_val; /* Current max val for this item. */ + int curr_strength; /* Current max strength encountered for this item. */ +} WeightedNormalDataAggregateItem; + +#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128 + +typedef struct WeightedNormalData { + const int numVerts; + const int numEdges; + const int numLoops; + const int numPolys; + + MVert *mvert; + MEdge *medge; + + MLoop *mloop; + short (*clnors)[2]; + const bool has_clnors; /* True if clnors already existed, false if we had to create them. */ + const float split_angle; + + MPoly *mpoly; + float (*polynors)[3]; + int *poly_strength; + + MDeformVert *dvert; + const int defgrp_index; + const bool use_invert_vgroup; + + const float weight; + const short mode; + + /* Lower-level, internal processing data. */ + float cached_inverse_powers_of_weight[NUM_CACHED_INVERSE_POWERS_OF_WEIGHT]; + + WeightedNormalDataAggregateItem *items_data; + + ModePair *mode_pair; + + int *loop_to_poly; +} WeightedNormalData; + +/* Check strength of given poly compared to those found so far for that given item (vertex or smooth fan), + * and reset matching item_data in case we get a stronger new strength. */ +static bool check_item_poly_strength( + WeightedNormalData *wn_data, WeightedNormalDataAggregateItem *item_data, const int mp_index) +{ + BLI_assert (wn_data->poly_strength != NULL); + + const int mp_strength = wn_data->poly_strength[mp_index]; + + if (mp_strength > item_data->curr_strength) { + item_data->curr_strength = mp_strength; + item_data->curr_val = 0.0f; + item_data->num_loops = 0; + zero_v3(item_data->normal); + } + + return mp_strength == item_data->curr_strength; +} + +static void aggregate_item_normal( + WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data, + WeightedNormalDataAggregateItem *item_data, + const int mv_index, const int mp_index, + const float curr_val, const bool use_face_influence) +{ + float (*polynors)[3] = wn_data->polynors; + + MDeformVert *dvert = wn_data->dvert; + const int defgrp_index = wn_data->defgrp_index; + const bool use_invert_vgroup = wn_data->use_invert_vgroup; + + const float weight = wn_data->weight; + + float *cached_inverse_powers_of_weight = wn_data->cached_inverse_powers_of_weight; + + const bool has_vgroup = dvert != NULL; + const bool vert_of_group = has_vgroup && defvert_find_index(&dvert[mv_index], defgrp_index) != NULL; + + if (has_vgroup && ((vert_of_group && use_invert_vgroup) || (!vert_of_group && !use_invert_vgroup))) { + return; + } + + if (use_face_influence && !check_item_poly_strength(wn_data, item_data, mp_index)) { + return; + } + + /* If item's curr_val is 0 init it to present value. */ + if (item_data->curr_val == 0.0f) { + item_data->curr_val = curr_val; + } + if (!compare_ff(item_data->curr_val, curr_val, wnmd->thresh)) { + /* item's curr_val and present value differ more than threshold, update. */ + item_data->num_loops++; + item_data->curr_val = curr_val; + } + + /* Exponentially divided weight for each normal (since a few values will be used by most cases, we cache those). */ + const int num_loops = item_data->num_loops; + if (num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT && cached_inverse_powers_of_weight[num_loops] == 0.0f) { + cached_inverse_powers_of_weight[num_loops] = 1.0f / powf(weight, num_loops); + } + const float inverted_n_weight = num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ? + cached_inverse_powers_of_weight[num_loops] : 1.0f / powf(weight, num_loops); + + madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight); +} + +static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) +{ + const int numVerts = wn_data->numVerts; + const int numEdges = wn_data->numEdges; + const int numLoops = wn_data->numLoops; + const int numPolys = wn_data->numPolys; + + MVert *mvert = wn_data->mvert; + MEdge *medge = wn_data->medge; + + MLoop *mloop = wn_data->mloop; + short (*clnors)[2] = wn_data->clnors; + int *loop_to_poly = wn_data->loop_to_poly; + + MPoly *mpoly = wn_data->mpoly; + float (*polynors)[3] = wn_data->polynors; + int *poly_strength = wn_data->poly_strength; + + MDeformVert *dvert = wn_data->dvert; + + const short mode = wn_data->mode; + ModePair *mode_pair = wn_data->mode_pair; + + const bool has_clnors = wn_data->has_clnors; + const float split_angle = wn_data->split_angle; + MLoopNorSpaceArray lnors_spacearr = {NULL}; + + const bool keep_sharp = (wnmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0; + const bool use_face_influence = (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) != 0 && poly_strength != NULL; + const bool has_vgroup = dvert != NULL; + + float (*loop_normals)[3] = NULL; + + WeightedNormalDataAggregateItem *items_data = NULL; + int num_items = 0; + if (keep_sharp) { + BLI_bitmap *done_loops = BLI_BITMAP_NEW(numLoops, __func__); + + /* This will give us loop normal spaces, we do not actually care about computed loop_normals for now... */ + loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__); + BKE_mesh_normals_loop_split(mvert, numVerts, medge, numEdges, + mloop, loop_normals, numLoops, mpoly, polynors, numPolys, + true, split_angle, &lnors_spacearr, has_clnors ? clnors : NULL, loop_to_poly); + + num_items = lnors_spacearr.num_spaces; + items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__); + + /* In this first loop, we assign each WeightedNormalDataAggregateItem to its smooth fan of loops (aka lnor space). */ + MPoly *mp; + int mp_index; + int item_index; + for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < numPolys; mp++, mp_index++) { + int ml_index = mp->loopstart; + const int ml_end_index = ml_index + mp->totloop; + + for (; ml_index < ml_end_index; ml_index++) { + if (BLI_BITMAP_TEST(done_loops, ml_index)) { + /* Smooth fan of this loop has already been processed, skip it. */ + continue; + } + BLI_assert(item_index < num_items); + + WeightedNormalDataAggregateItem *itdt = &items_data[item_index]; + itdt->curr_strength = FACE_STRENGTH_WEAK; + + MLoopNorSpace *lnor_space = lnors_spacearr.lspacearr[ml_index]; + lnor_space->user_data = itdt; + + if (!(lnor_space->flags & MLNOR_SPACE_IS_SINGLE)) { + for (LinkNode *lnode = lnor_space->loops; lnode; lnode = lnode->next) { + const int ml_fan_index = GET_INT_FROM_POINTER(lnode->link); + BLI_BITMAP_ENABLE(done_loops, ml_fan_index); + } + } + else { + BLI_BITMAP_ENABLE(done_loops, ml_index); + } + + item_index++; + } + } + + MEM_freeN(done_loops); + } + else { + num_items = numVerts; + items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__); + if (use_face_influence) { + for (int item_index = 0; item_index < num_items; item_index++) { + items_data[item_index].curr_strength = FACE_STRENGTH_WEAK; + } + } + } + wn_data->items_data = items_data; + + switch (mode) { + case MOD_WEIGHTEDNORMAL_MODE_FACE: + for (int i = 0; i < numPolys; i++) { + const int mp_index = mode_pair[i].index; + const float mp_val = mode_pair[i].val; + + int ml_index = mpoly[mp_index].loopstart; + const int ml_index_end = ml_index + mpoly[mp_index].totloop; + for (; ml_index < ml_index_end; ml_index++) { + const int mv_index = mloop[ml_index].v; + WeightedNormalDataAggregateItem *item_data = keep_sharp ? + lnors_spacearr.lspacearr[ml_index]->user_data: + &items_data[mv_index]; + + aggregate_item_normal(wnmd, wn_data, item_data, mv_index, mp_index, mp_val, use_face_influence); + } + } + break; + case MOD_WEIGHTEDNORMAL_MODE_ANGLE: + case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE: + BLI_assert(loop_to_poly != NULL); + + for (int i = 0; i < numLoops; i++) { + const int ml_index = mode_pair[i].index; + const float ml_val = mode_pair[i].val; + + const int mp_index = loop_to_poly[ml_index]; + const int mv_index = mloop[ml_index].v; + WeightedNormalDataAggregateItem *item_data = keep_sharp ? + lnors_spacearr.lspacearr[ml_index]->user_data: + &items_data[mv_index]; + + aggregate_item_normal(wnmd, wn_data, item_data, mv_index, mp_index, ml_val, use_face_influence); + } + break; + default: + BLI_assert(0); + } + + /* Validate computed weighted normals. */ + for (int item_index = 0; item_index < num_items; item_index++) { + if (normalize_v3(items_data[item_index].normal) < CLNORS_VALID_VEC_LEN) { + zero_v3(items_data[item_index].normal); + } + } + + if (keep_sharp) { + /* Set loop normals for normal computed for each lnor space (smooth fan). + * Note that loop_normals is already populated with clnors (before this modifier is applied, at start of + * this function), so no need to recompute them here. */ + for (int ml_index = 0; ml_index < numLoops; ml_index++) { + WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data; + if (!is_zero_v3(item_data->normal)) { + copy_v3_v3(loop_normals[ml_index], item_data->normal); + } + } + + BKE_mesh_normals_loop_custom_set(mvert, numVerts, medge, numEdges, + mloop, loop_normals, numLoops, mpoly, polynors, numPolys, clnors); + } + else { + /* TODO: Ideally, we could add an option to BKE_mesh_normals_loop_custom_[from_vertices_]set() to keep current + * clnors instead of resetting them to default autocomputed ones, when given new custom normal is zero-vec. + * But this is not exactly trivial change, better to keep this optimization for later... + */ + if (!has_vgroup) { + /* Note: in theory, we could avoid this extra allocation & copying... But think we can live with it for now, + * and it makes code simpler & cleaner. */ + float (*vert_normals)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*loop_normals), __func__); + + for (int ml_index = 0; ml_index < numLoops; ml_index++) { + const int mv_index = mloop[ml_index].v; + copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal); + } + + BKE_mesh_normals_loop_custom_from_vertices_set(mvert, vert_normals, numVerts, medge, numEdges, + mloop, numLoops, mpoly, polynors, numPolys, clnors); + + MEM_freeN(vert_normals); + } + else { + loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__); + + BKE_mesh_normals_loop_split(mvert, numVerts, medge, numEdges, + mloop, loop_normals, numLoops, mpoly, polynors, numPolys, + true, split_angle, NULL, has_clnors ? clnors : NULL, loop_to_poly); + + for (int ml_index = 0; ml_index < numLoops; ml_index++) { + const int item_index = mloop[ml_index].v; + if (!is_zero_v3(items_data[item_index].normal)) { + copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal); + } + } + + BKE_mesh_normals_loop_custom_set(mvert, numVerts, medge, numEdges, + mloop, loop_normals, numLoops, mpoly, polynors, numPolys, clnors); + } + } + + if (keep_sharp) { + BKE_lnor_spacearr_free(&lnors_spacearr); + } + MEM_SAFE_FREE(loop_normals); +} + +static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) +{ + const int numPolys = wn_data->numPolys; + + MVert *mvert = wn_data->mvert; + MLoop *mloop = wn_data->mloop; + MPoly *mpoly = wn_data->mpoly; + + MPoly *mp; + int mp_index; + + ModePair *face_area = MEM_malloc_arrayN((size_t)numPolys, sizeof(*face_area), __func__); + + ModePair *f_area = face_area; + for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++, f_area++) { + f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert); + f_area->index = mp_index; + } + + qsort(face_area, numPolys, sizeof(*face_area), modepair_cmp_by_val_inverse); + + wn_data->mode_pair = face_area; + apply_weights_vertex_normal(wnmd, wn_data); +} + +static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) +{ + const int numLoops = wn_data->numLoops; + const int numPolys = wn_data->numPolys; + + MVert *mvert = wn_data->mvert; + MLoop *mloop = wn_data->mloop; + MPoly *mpoly = wn_data->mpoly; + + MPoly *mp; + int mp_index; + + int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + + ModePair *corner_angle = MEM_malloc_arrayN((size_t)numLoops, sizeof(*corner_angle), __func__); + + for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) { + MLoop *ml_start = &mloop[mp->loopstart]; + + float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__); + BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle); + + ModePair *c_angl = &corner_angle[mp->loopstart]; + float *angl = index_angle; + for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop; ml_index++, c_angl++, angl++) { + c_angl->val = (float)M_PI - *angl; + c_angl->index = ml_index; + + loop_to_poly[ml_index] = mp_index; + } + MEM_freeN(index_angle); + } + + qsort(corner_angle, numLoops, sizeof(*corner_angle), modepair_cmp_by_val_inverse); + + wn_data->loop_to_poly = loop_to_poly; + wn_data->mode_pair = corner_angle; + apply_weights_vertex_normal(wnmd, wn_data); +} + +static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data) +{ + const int numLoops = wn_data->numLoops; + const int numPolys = wn_data->numPolys; + + MVert *mvert = wn_data->mvert; + MLoop *mloop = wn_data->mloop; + MPoly *mpoly = wn_data->mpoly; + + MPoly *mp; + int mp_index; + + int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + + ModePair *combined = MEM_malloc_arrayN((size_t)numLoops, sizeof(*combined), __func__); + + for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) { + MLoop *ml_start = &mloop[mp->loopstart]; + + float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert); + float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__); + BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle); + + ModePair *cmbnd = &combined[mp->loopstart]; + float *angl = index_angle; + for (int ml_index = mp->loopstart; ml_index < mp->loopstart + mp->totloop; ml_index++, cmbnd++, angl++) { + /* In this case val is product of corner angle and face area. */ + cmbnd->val = ((float)M_PI - *angl) * face_area; + cmbnd->index = ml_index; + + loop_to_poly[ml_index] = mp_index; + } + MEM_freeN(index_angle); + } + + qsort(combined, numLoops, sizeof(*combined), modepair_cmp_by_val_inverse); + + wn_data->loop_to_poly = loop_to_poly; + wn_data->mode_pair = combined; + apply_weights_vertex_normal(wnmd, wn_data); +} + +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +{ + WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; + Object *ob = ctx->object; + + /* XXX TODO ARG GRRR XYQWNMPRXTYY + * Once we fully switch to Mesh evaluation of modifiers, we can expect to get that flag from the COW copy. + * But for now, it is lost in the DM intermediate step, so we need to directly check orig object's data. */ +#if 0 + if (!(mesh->flag & ME_AUTOSMOOTH)) { +#else + if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) { +#endif + modifier_setError((ModifierData *)wnmd, "Enable 'Auto Smooth' option in mesh settings"); + return mesh; + } + + Mesh *result; + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&result, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + + const int numVerts = result->totvert; + const int numEdges = result->totedge; + const int numLoops = result->totloop; + const int numPolys = result->totpoly; + + MEdge *medge = result->medge; + MPoly *mpoly = result->mpoly; + MVert *mvert = result->mvert; + MLoop *mloop = result->mloop; + + bool free_polynors = false; + + /* Right now: + * If weight = 50 then all faces are given equal weight. + * If weight > 50 then more weight given to faces with larger vals (face area / corner angle). + * If weight < 50 then more weight given to faces with lesser vals. However current calculation + * does not converge to min/max. + */ + float weight = ((float)wnmd->weight) / 50.0f; + if (wnmd->weight == 100) { + weight = (float)SHRT_MAX; + } + else if (wnmd->weight == 1) { + weight = 1 / (float)SHRT_MAX; + } + else if ((weight - 1) * 25 > 1) { + weight = (weight - 1) * 25; + } + + CustomData *pdata = &result->pdata; + float (*polynors)[3] = CustomData_get_layer(pdata, CD_NORMAL); + if (!polynors) { + polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys); + } + BKE_mesh_calc_normals_poly(mvert, NULL, numVerts, mloop, mpoly, numLoops, numPolys, polynors, false); + + + const float split_angle = mesh->smoothresh; + short (*clnors)[2]; + CustomData *ldata = &result->ldata; + clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); + + /* Keep info whether we had clnors, it helps when generating clnor spaces and default normals. */ + const bool has_clnors = clnors != NULL; + if (!clnors) { + clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numLoops); + clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); + } + + MDeformVert *dvert; + int defgrp_index; + modifier_get_vgroup_mesh(ob, result, wnmd->defgrp_name, &dvert, &defgrp_index); + + WeightedNormalData wn_data = { + .numVerts = numVerts, + .numEdges = numEdges, + .numLoops = numLoops, + .numPolys = numPolys, + + .mvert = mvert, + .medge = medge, + + .mloop = mloop, + .clnors = clnors, + .has_clnors = has_clnors, + .split_angle = split_angle, + + .mpoly = mpoly, + .polynors = polynors, + .poly_strength = CustomData_get_layer_named(&result->pdata, CD_PROP_INT, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID), + + .dvert = dvert, + .defgrp_index = defgrp_index, + .use_invert_vgroup = (wnmd->flag & MOD_WEIGHTEDNORMAL_INVERT_VGROUP) != 0, + + .weight = weight, + .mode = wnmd->mode, + }; + + switch (wnmd->mode) { + case MOD_WEIGHTEDNORMAL_MODE_FACE: + wn_face_area(wnmd, &wn_data); + break; + case MOD_WEIGHTEDNORMAL_MODE_ANGLE: + wn_corner_angle(wnmd, &wn_data); + break; + case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE: + wn_face_with_angle(wnmd, &wn_data); + break; + } + + MEM_SAFE_FREE(wn_data.loop_to_poly); + MEM_SAFE_FREE(wn_data.mode_pair); + MEM_SAFE_FREE(wn_data.items_data); + + return result; +} + +static void initData(ModifierData *md) +{ + WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; + wnmd->mode = MOD_WEIGHTEDNORMAL_MODE_FACE; + wnmd->weight = 50; + wnmd->thresh = 1e-2f; + wnmd->flag = 0; +} + +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md; + CustomDataMask dataMask = CD_CUSTOMLOOPNORMAL; + + if (wnmd->defgrp_name[0]) { + dataMask |= CD_MASK_MDEFORMVERT; + } + + if (wnmd->flag & MOD_WEIGHTEDNORMAL_FACE_INFLUENCE) { + dataMask |= CD_MASK_PROP_INT; + } + + return dataMask; +} + +static bool dependsOnNormals(ModifierData *UNUSED(md)) +{ + return true; +} + +ModifierTypeInfo modifierType_WeightedNormal = { + /* name */ "Weighted Normal", + /* structName */ "WeightedNormalModifierData", + /* structSize */ sizeof(WeightedNormalModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh | + eModifierTypeFlag_SupportsMapping | + eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_EnableInEditmode, + + /* copyData */ modifier_copyData_generic, + + /* deformVerts_DM */ NULL, + /* deformMatrices_DM */ NULL, + /* deformVertsEM_DM */ NULL, + /* deformMatricesEM_DM*/NULL, + /* applyModifier_DM */ NULL, + /* applyModifierEM_DM */NULL, + + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + /* applyModifierEM */ NULL, + + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ dependsOnNormals, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/tools b/source/tools index 6bcd05cf6aa..88a1758d2d2 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 6bcd05cf6aaafae07b8a15313d7fdda1471ff59e +Subproject commit 88a1758d2d2e862cc69c08b5b40a4e75f71592d3 -- cgit v1.2.3 From 9084c57a65854b5ac50583527ecd58ebf6f4f7c6 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Thu, 31 May 2018 14:42:50 +0530 Subject: Mark edges that can have seams in Bevel. Works by going clockwise from first edgehalf in BevVert and marking seam length each time it encounters a pair of edges with seams --- source/blender/bmesh/tools/bmesh_bevel.c | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index ca96e5b4b78..ad0e3b9c36e 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -150,6 +150,7 @@ typedef struct BoundVert { Profile profile; /* edge profile between this and next BoundVert */ bool any_seam; /* are any of the edges attached here seams? */ bool visited; /* used during delta adjust pass */ + int add_seam; // int _pad; } BoundVert; @@ -1522,6 +1523,38 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin co[2] = z; } +#define BEV_SEAM(eh) (BM_elem_flag_test(eh->e, BM_ELEM_SEAM)) + +static void set_bound_vert_extend_seam_sharp_edges(BevVert *bv) +{ + EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; + + while (!BEV_SEAM(e)) { + e = e->next; + if (e == efirst) + break; + } + if (!BEV_SEAM(e)) + return; + + efirst = e; + do { + int seam_length = 0; + EdgeHalf *ne = e->next; + + while (!BEV_SEAM(ne) && ne != efirst) { + if(ne->is_bev) + seam_length++; + ne = ne->next; + } + if (ne == e || (ne == efirst && !BEV_SEAM(efirst))) { + break; + } + e->rightv->add_seam = seam_length ? seam_length : 0; + e = ne; + } while (e != efirst); +} + /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv) { @@ -1539,6 +1572,8 @@ static void set_bound_vert_seams(BevVert *bv) } bv->any_seam |= v->any_seam; } while ((v = v->next) != bv->vmesh->boundstart); + + set_bound_vert_extend_seam_sharp_edges(bv); } static int count_bound_vert_seams(BevVert *bv) -- cgit v1.2.3 From 2f5704486d50f94619f02497475b344250d03213 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Fri, 1 Jun 2018 21:18:26 +0530 Subject: Added ability to apply seams to all middle edges between the 2 marked edges. currently does not make changes to material or sharpness of edges --- source/blender/bmesh/tools/bmesh_bevel.c | 49 +++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index ad0e3b9c36e..999639877a7 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1555,6 +1555,51 @@ static void set_bound_vert_extend_seam_sharp_edges(BevVert *bv) } while (e != efirst); } +static void bevel_add_seams(BevVert *bv) +{ + VMesh *vm = bv->vmesh; + + BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; + + do { + if (bcur->add_seam) { + if (!bv->vmesh->boundstart->add_seam && start == bv->vmesh->boundstart) + start = bcur; + + int idxlen = bcur->index + bcur->add_seam; + for (int i = bcur->index; i < idxlen; i++) { + BMVert *v1 = mesh_vert(vm, i % vm->count, 0, 0)->v, *v2; + BMEdge *e; + for (int k = 1; k < vm->seg; k++) { + v2 = mesh_vert(vm, i % vm->count, 0, k)->v; + + e = v1->e; + while (e->v1 != v2 && e->v2 != v2) { + if (e->v1 == v1) + e = e->v1_disk_link.next; + else + e = e->v2_disk_link.next; + } + BM_elem_flag_set(e, BM_ELEM_SEAM, true); + v1 = v2; + } + BMVert *v3 = mesh_vert(vm, (i + 1) % vm->count, 0, 0)->v; + e = v1->e; + while (e->v1 != v3 && e->v2 != v3) { + if (e->v1 == v1) + e = e->v1_disk_link.next; + else + e = e->v2_disk_link.next; + } + BM_elem_flag_set(e, BM_ELEM_SEAM, true); + bcur = bcur->next; + } + } + else + bcur = bcur->next; + } while (bcur != start); +} + /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv) { @@ -5471,7 +5516,9 @@ void BM_mesh_bevel( BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { - BLI_assert(find_bevvert(&bp, v) != NULL); + BevVert *bv = find_bevvert(&bp, v); + BLI_assert(bv != NULL); + bevel_add_seams(bv); BM_vert_kill(bm, v); } } -- cgit v1.2.3 From 79c0ac7c78878434aa01b54edbca9c7db6527831 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sun, 3 Jun 2018 22:50:35 +0530 Subject: Added support for extending sharp edges with bevel --- source/blender/bmesh/tools/bmesh_bevel.c | 78 ++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 999639877a7..102d563c90c 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -151,6 +151,7 @@ typedef struct BoundVert { bool any_seam; /* are any of the edges attached here seams? */ bool visited; /* used during delta adjust pass */ int add_seam; + int sharp_len; // int _pad; } BoundVert; @@ -1523,39 +1524,49 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin co[2] = z; } -#define BEV_SEAM(eh) (BM_elem_flag_test(eh->e, BM_ELEM_SEAM)) +#define EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag)) -static void set_bound_vert_extend_seam_sharp_edges(BevVert *bv) +static void check_edge_data(BevVert *bv, int flag, bool neg) { EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; - while (!BEV_SEAM(e)) { + while (neg ^ !EDGE_DATA_CHECK(e, flag)) { e = e->next; if (e == efirst) break; } - if (!BEV_SEAM(e)) + if (neg ^ !EDGE_DATA_CHECK(e, flag)) return; efirst = e; do { - int seam_length = 0; + int flag_count = 0; EdgeHalf *ne = e->next; - - while (!BEV_SEAM(ne) && ne != efirst) { - if(ne->is_bev) - seam_length++; + + while ((neg ^ !EDGE_DATA_CHECK(ne, flag)) && ne != efirst) { + if (ne->is_bev) + flag_count++; ne = ne->next; } - if (ne == e || (ne == efirst && !BEV_SEAM(efirst))) { + if (ne == e || (ne == efirst && (neg ^ !EDGE_DATA_CHECK(efirst, flag)))) { break; } - e->rightv->add_seam = seam_length ? seam_length : 0; + if (flag == BM_ELEM_SEAM) + e->rightv->add_seam = flag_count; + else if (flag == BM_ELEM_SMOOTH) + e->rightv->sharp_len = flag_count; e = ne; } while (e != efirst); + } -static void bevel_add_seams(BevVert *bv) +static void set_bound_vert_extend_seam_sharp_edges(BevVert *bv) +{ + check_edge_data(bv, BM_ELEM_SEAM, false); + check_edge_data(bv, BM_ELEM_SMOOTH, true); +} + +static void bevel_extend_edge_data(BevVert *bv) { VMesh *vm = bv->vmesh; @@ -1598,6 +1609,47 @@ static void bevel_add_seams(BevVert *bv) else bcur = bcur->next; } while (bcur != start); + + + bcur = bv->vmesh->boundstart; + start = bcur; + do { + if (bcur->sharp_len) { + if (!bv->vmesh->boundstart->sharp_len && start == bv->vmesh->boundstart) + start = bcur; + + int idxlen = bcur->index + bcur->sharp_len; + for (int i = bcur->index; i < idxlen; i++) { + BMVert *v1 = mesh_vert(vm, i % vm->count, 0, 0)->v, *v2; + BMEdge *e; + for (int k = 1; k < vm->seg; k++) { + v2 = mesh_vert(vm, i % vm->count, 0, k)->v; + + e = v1->e; + while (e->v1 != v2 && e->v2 != v2) { + if (e->v1 == v1) + e = e->v1_disk_link.next; + else + e = e->v2_disk_link.next; + } + BM_elem_flag_set(e, BM_ELEM_SMOOTH, false); + v1 = v2; + } + BMVert *v3 = mesh_vert(vm, (i + 1) % vm->count, 0, 0)->v; + e = v1->e; + while (e->v1 != v3 && e->v2 != v3) { + if (e->v1 == v1) + e = e->v1_disk_link.next; + else + e = e->v2_disk_link.next; + } + BM_elem_flag_set(e, BM_ELEM_SMOOTH, false); + bcur = bcur->next; + } + } + else + bcur = bcur->next; + } while (bcur != start); } /* Set the any_seam property for a BevVert and all its BoundVerts */ @@ -5518,7 +5570,7 @@ void BM_mesh_bevel( if (BM_elem_flag_test(v, BM_ELEM_TAG)) { BevVert *bv = find_bevvert(&bp, v); BLI_assert(bv != NULL); - bevel_add_seams(bv); + bevel_extend_edge_data(bv); BM_vert_kill(bm, v); } } -- cgit v1.2.3 From 2903146826a3e88bb9f001c7ce6678057fb7b1f3 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 4 Jun 2018 15:13:54 +0530 Subject: Added UI support for seams and sharp edges and cleanup --- .../startup/bl_ui/properties_data_modifier.py | 2 ++ source/blender/bmesh/intern/bmesh_opdefines.c | 2 ++ source/blender/bmesh/operators/bmo_bevel.c | 4 ++- source/blender/bmesh/tools/bmesh_bevel.c | 31 ++++++++++++---------- source/blender/bmesh/tools/bmesh_bevel.h | 2 +- source/blender/editors/mesh/editmesh_bevel.c | 28 +++++++++++++++++-- source/blender/makesdna/DNA_modifier_types.h | 8 +++++- source/blender/makesrna/intern/rna_modifier.c | 10 +++++++ source/blender/modifiers/intern/MOD_bevel.c | 5 +++- 9 files changed, 72 insertions(+), 20 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index abdf1ed2db1..45dda12f39b 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -140,6 +140,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "use_only_vertices") col.prop(md, "use_clamp_overlap") col.prop(md, "loop_slide") + col.prop(md, "mark_seam") + col.prop(md, "mark_sharp") layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index b5e6fe168e5..e6a66372274 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1736,6 +1736,8 @@ static BMOpDefine bmo_bevel_def = { {"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */ {"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */ {"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */ + {"mark_seam", BMO_OP_SLOT_BOOL}, + {"mark_sharp", BMO_OP_SLOT_BOOL}, {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 2ae87b64286..cf063f7b0a8 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -43,6 +43,8 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) const bool clamp_overlap = BMO_slot_bool_get(op->slots_in, "clamp_overlap"); const int material = BMO_slot_int_get(op->slots_in, "material"); const bool loop_slide = BMO_slot_bool_get(op->slots_in, "loop_slide"); + const bool mark_seam = BMO_slot_bool_get(op->slots_in, "mark_seam"); + const bool mark_sharp = BMO_slot_bool_get(op->slots_in, "mark_sharp"); if (offset > 0) { BMOIter siter; @@ -63,7 +65,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide); + BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 102d563c90c..8a2a022852d 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -202,6 +202,8 @@ typedef struct BevelParams { bool loop_slide; /* should bevel prefer to slide along edges rather than keep widths spec? */ bool limit_offset; /* should offsets be limited by collisions? */ bool offset_adjust; /* should offsets be adjusted to try to get even widths? */ + bool mark_seam; + bool mark_sharp; const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */ int vertex_group; /* vertex group index, maybe set if vertex_only */ int mat_nr; /* if >= 0, material number for bevel; else material comes from adjacent faces */ @@ -1526,7 +1528,7 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin #define EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag)) -static void check_edge_data(BevVert *bv, int flag, bool neg) +static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) { EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; @@ -1560,12 +1562,6 @@ static void check_edge_data(BevVert *bv, int flag, bool neg) } -static void set_bound_vert_extend_seam_sharp_edges(BevVert *bv) -{ - check_edge_data(bv, BM_ELEM_SEAM, false); - check_edge_data(bv, BM_ELEM_SMOOTH, true); -} - static void bevel_extend_edge_data(BevVert *bv) { VMesh *vm = bv->vmesh; @@ -1653,7 +1649,7 @@ static void bevel_extend_edge_data(BevVert *bv) } /* Set the any_seam property for a BevVert and all its BoundVerts */ -static void set_bound_vert_seams(BevVert *bv) +static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp) { BoundVert *v; EdgeHalf *e; @@ -1670,7 +1666,12 @@ static void set_bound_vert_seams(BevVert *bv) bv->any_seam |= v->any_seam; } while ((v = v->next) != bv->vmesh->boundstart); - set_bound_vert_extend_seam_sharp_edges(bv); + if (mark_seam) { + check_edge_data_seam_sharp_edges(bv, BM_ELEM_SEAM, false); + } + if (mark_sharp) { + check_edge_data_seam_sharp_edges(bv, BM_ELEM_SMOOTH, true); + } } static int count_bound_vert_seams(BevVert *bv) @@ -1741,7 +1742,7 @@ static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool constr calculate_vm_profiles(bp, bv, vm); if (construct) { - set_bound_vert_seams(bv); + set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp); if (vm->count == 2) vm->mesh_kind = M_NONE; else if (bp->seg == 1) @@ -1796,7 +1797,7 @@ static void build_boundary_terminal_edge(BevelParams *bp, BevVert *bv, EdgeHalf e->next->leftv = e->next->rightv = v; /* could use M_POLY too, but tri-fan looks nicer)*/ vm->mesh_kind = M_TRI_FAN; - set_bound_vert_seams(bv); + set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp); } else { adjust_bound_vert(e->next->leftv, co); @@ -1855,7 +1856,7 @@ static void build_boundary_terminal_edge(BevelParams *bp, BevVert *bv, EdgeHalf } if (construct) { - set_bound_vert_seams(bv); + set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp); if (vm->count == 2 && bv->edgecount == 3) { vm->mesh_kind = M_NONE; @@ -1997,7 +1998,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) calculate_vm_profiles(bp, bv, vm); if (construct) { - set_bound_vert_seams(bv); + set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp); if (vm->count == 2) { vm->mesh_kind = M_NONE; @@ -5481,7 +5482,7 @@ void BM_mesh_bevel( const float segments, const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, - const bool loop_slide) + const bool loop_slide, const bool mark_seam, const bool mark_sharp) { BMIter iter; BMVert *v, *v_next; @@ -5502,6 +5503,8 @@ void BM_mesh_bevel( bp.dvert = dvert; bp.vertex_group = vertex_group; bp.mat_nr = mat; + bp.mark_seam = mark_seam; + bp.mark_sharp = mark_sharp; if (profile >= 0.999f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ bp.pro_super_r = PRO_SQUARE_R; diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index 386dc8a1fce..d932ac381a6 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -33,6 +33,6 @@ void BM_mesh_bevel( BMesh *bm, const float offset, const int offset_type, const float segments, const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, - const int mat, const bool loop_slide); + const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index e75b133b5bd..86aff48615c 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -224,6 +224,8 @@ static bool edbm_bevel_calc(wmOperator *op) const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap"); int material = RNA_int_get(op->ptr, "material"); const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide"); + const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam"); + const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { @@ -240,9 +242,9 @@ static bool edbm_bevel_calc(wmOperator *op) EDBM_op_init(em, &bmop, op, "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " - "material=%i loop_slide=%b", + "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b", BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide); + clamp_overlap, material, loop_slide, mark_seam, mark_sharp); BMO_op_exec(em->bm, &bmop); @@ -603,6 +605,26 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event) edbm_bevel_update_header(C, op); handled = true; break; + case UKEY: + if (event->val == KM_RELEASE) + break; + else { + bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam"); + RNA_boolean_set(op->ptr, "mark_seam", !mark_seam); + edbm_bevel_calc(op); + handled = true; + break; + } + case KKEY: + if (event->val == KM_RELEASE) + break; + else { + bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); + RNA_boolean_set(op->ptr, "mark_sharp", !mark_sharp); + edbm_bevel_calc(op); + handled = true; + break; + } } @@ -666,6 +688,8 @@ void MESH_OT_bevel(wmOperatorType *ot) RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap", "Do not allow beveled edges/vertices to overlap each other"); RNA_def_boolean(ot->srna, "loop_slide", true, "Loop Slide", "Prefer slide along edge to even widths"); + RNA_def_boolean(ot->srna, "mark_seam", false, "Mark Seams", "Mark Seams along beveled edges"); + RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp"); RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100); } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 1d7d1b34f6b..433d75706bb 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -328,7 +328,7 @@ typedef struct BevelModifierData { short lim_flags; /* flags to tell the tool how to limit the bevel */ short e_flags; /* flags to direct how edge weights are applied to verts */ short mat; /* material index if >= 0, else material inherited from surrounding faces */ - short pad; + short edge_flags; int pad2; float profile; /* controls profile shape (0->1, .5 is round) */ /* if the MOD_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */ @@ -365,6 +365,12 @@ enum { MOD_BEVEL_AMT_PERCENT = 3, }; +/* BevelModifierData->edge_flags */ +enum { + MOD_BEVEL_MARK_SEAM = (1 << 0), + MOD_BEVEL_MARK_SHARP = (1 << 1), +}; + typedef struct SmokeModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index c665442a82f..a9bf7b18f73 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3104,6 +3104,16 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", MOD_BEVEL_EVEN_WIDTHS); RNA_def_property_ui_text(prop, "Loop Slide", "Prefer sliding along edges to having even widths"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "mark_seam", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "edge_flags", MOD_BEVEL_MARK_SEAM); + RNA_def_property_ui_text(prop, "Mark Seams", "Mark Seams along beveled edges"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "mark_sharp", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "edge_flags", MOD_BEVEL_MARK_SHARP); + RNA_def_property_ui_text(prop, "Mark Sharp", "Mark beveled edges as sharp"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 81a4e94386f..61ecc5c734e 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -59,6 +59,7 @@ static void initData(ModifierData *md) bmd->val_flags = MOD_BEVEL_AMT_OFFSET; bmd->lim_flags = 0; bmd->e_flags = 0; + bmd->edge_flags = 0; bmd->mat = -1; bmd->profile = 0.5f; bmd->bevel_angle = DEG2RADF(30.0f); @@ -96,6 +97,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes const int offset_type = bmd->val_flags; const int mat = CLAMPIS(bmd->mat, -1, ctx->object->totcol - 1); const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0; + const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM); + const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP); bm = BKE_mesh_to_bmesh_ex( mesh, @@ -166,7 +169,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, - dvert, vgroup, mat, loop_slide); + dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp); result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0}); -- cgit v1.2.3 From 18a8bb5c16f9a14dafbdcbec328c334416541425 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 5 Jun 2018 23:21:08 +0530 Subject: Fix compilation error due to different params in freeCustomNormalArray declaration and definition --- source/blender/editors/transform/transform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 3718f1be9a8..62356cd4ba6 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -875,7 +875,7 @@ bool applyTransformOrientation(const struct TransformOrientation *ts, float r_ma int getTransformOrientation_ex(const struct bContext *C, float normal[3], float plane[3], const short around); int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]); -void freeCustomNormalArray(TransInfo *t, TransCustomData *custom_data); +void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data); void freeEdgeSlideTempFaces(EdgeSlideData *sld); void freeEdgeSlideVerts(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data); -- cgit v1.2.3 From 0c6410ec0cffdcb0641fa85d8394f7c682c44143 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 11 Jun 2018 11:58:26 +0530 Subject: Added ability to harden normals. Uses 2 different params: mode and strength. There are still some hiccups with how 2.8 interacts with normals. Will resolve as support gets better --- source/blender/bmesh/intern/bmesh_mesh.c | 35 +++++++++ source/blender/bmesh/intern/bmesh_mesh.h | 1 + source/blender/bmesh/intern/bmesh_opdefines.c | 3 + source/blender/bmesh/intern/bmesh_operators.h | 5 ++ source/blender/bmesh/operators/bmo_bevel.c | 3 +- source/blender/bmesh/tools/bmesh_bevel.c | 87 ++++++++++++++++++++-- source/blender/bmesh/tools/bmesh_bevel.h | 3 +- source/blender/editors/mesh/editmesh_bevel.c | 100 +++++++++++++++++++++++++- source/blender/editors/mesh/editmesh_tools.c | 41 +---------- source/blender/makesdna/DNA_modifier_types.h | 8 +++ source/blender/makesrna/intern/rna_modifier.c | 17 +++++ source/blender/modifiers/intern/MOD_bevel.c | 2 +- 12 files changed, 258 insertions(+), 47 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 79c835cca11..3a4aec8cc69 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -1225,6 +1225,41 @@ void BM_lnorspace_update(BMesh *bm) } } +void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges) +{ + BMFace *f; + BMEdge *e; + BMIter fiter, eiter; + BMLoop *l_curr, *l_first; + + if (do_edges) { + int index_edge; + BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) { + BMLoop *l_a, *l_b; + + BM_elem_index_set(e, index_edge); /* set_inline */ + BM_elem_flag_disable(e, BM_ELEM_TAG); + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) { + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + } + } + bm->elem_index_dirty &= ~BM_EDGE; + } + + int index_face, index_loop = 0; + BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) { + BM_elem_index_set(f, index_face); /* set_inline */ + l_curr = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_elem_index_set(l_curr, index_loop++); /* set_inline */ + BM_elem_flag_disable(l_curr, BM_ELEM_TAG); + } while ((l_curr = l_curr->next) != l_first); + } + bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); +} + /** * Auxillary function only used by rebuild to detect if any spaces were not marked as invalid. * Reports error if any of the lnor spaces change after rebuilding, meaning that all the possible diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 44887e81157..43029e370c6 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -59,6 +59,7 @@ void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]); void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all); void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor); void BM_lnorspace_update(BMesh *bm); +void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges); #ifndef NDEBUG void BM_lnorspace_err(BMesh *bm); #endif diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index e6a66372274..49d160f5d4a 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1738,12 +1738,15 @@ static BMOpDefine bmo_bevel_def = { {"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */ {"mark_seam", BMO_OP_SLOT_BOOL}, {"mark_sharp", BMO_OP_SLOT_BOOL}, + {"strength", BMO_OP_SLOT_FLT}, + {"hnmode", BMO_OP_SLOT_INT}, {{'\0'}}, }, /* slots_out */ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ + {"normals.out", BMO_OP_SLOT_MAPPING}, {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 80b57eb3565..3ae9a77a761 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -127,6 +127,11 @@ enum { BEVEL_AMT_PERCENT }; +enum { + BEVEL_HN_FACE, + BEVEL_HN_ADJ, +}; + extern const BMOpDefine *bmo_opdefines[]; extern const int bmo_opdefines_total; diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index cf063f7b0a8..cd27b486929 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -45,6 +45,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) const bool loop_slide = BMO_slot_bool_get(op->slots_in, "loop_slide"); const bool mark_seam = BMO_slot_bool_get(op->slots_in, "mark_seam"); const bool mark_sharp = BMO_slot_bool_get(op->slots_in, "mark_sharp"); + const int hnmode = BMO_slot_int_get(op->slots_in, "hnmode"); if (offset > 0) { BMOIter siter; @@ -65,7 +66,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp); + BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp, 0/*hnmode*/, op); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 8a2a022852d..18039261735 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -37,6 +37,7 @@ #include "BLI_array.h" #include "BLI_alloca.h" +#include "BLI_bitmap.h" #include "BLI_gsqueue.h" #include "BLI_math.h" #include "BLI_memarena.h" @@ -207,6 +208,7 @@ typedef struct BevelParams { const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */ int vertex_group; /* vertex group index, maybe set if vertex_only */ int mat_nr; /* if >= 0, material number for bevel; else material comes from adjacent faces */ + int hnmode; } BevelParams; // #pragma GCC diagnostic ignored "-Wpadded" @@ -1648,6 +1650,76 @@ static void bevel_extend_edge_data(BevVert *bv) } while (bcur != start); } +static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, BMOperator *op) +{ + int mode = 1; + + VMesh *vm = bv->vmesh; + BoundVert *bcur = vm->boundstart, *bstart = bcur; + int ns = vm->seg, ns2 = ns / 2; + + BMEdge *e; + BMIter eiter; + + BMOpSlot *nslot = BMO_slot_get(op->slots_out, "normals.out"); + float n_final[3] = { 0.0f, 0.0f, 0.0f }; + + if (bp->hnmode == BEVEL_HN_FACE) { + BLI_bitmap *faces = BLI_BITMAP_NEW(bm->totface, __func__); + BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + + BMFace *f_a, *f_b; + BM_edge_face_pair(e, &f_a, &f_b); + + if (f_a && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_a))) { + int f_area = BM_face_calc_area(f_a); + float f_no[3]; + copy_v3_v3(f_no, f_a->no); + mul_v3_fl(f_no, f_area); + add_v3_v3(n_final, f_no); + BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_a)); + } + if (f_b && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_b))) { + int f_area = BM_face_calc_area(f_b); + float f_no[3]; + copy_v3_v3(f_no, f_b->no); + mul_v3_fl(f_no, f_area); + add_v3_v3(n_final, f_no); + BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_b)); + } + } + } + MEM_freeN(faces); + normalize_v3(n_final); + } + else if (bp->hnmode == BEVEL_HN_ADJ) { + BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (e->v1 == bv->v) { + add_v3_v3(n_final, e->v2->no); + } + else { + add_v3_v3(n_final, e->v1->no); + } + } + } + normalize_v3(n_final); + } + + do { + if (BMO_slot_map_contains(nslot, bcur->nv.v) != true) { + + float(*custom_normal) = MEM_callocN(sizeof(*custom_normal) * 3, __func__); + add_v3_v3(custom_normal, n_final); + normalize_v3(custom_normal); + + BMO_slot_map_insert(op, nslot, bcur->nv.v, custom_normal); + } + bcur = bcur->next; + } while (bcur != bstart); +} + /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp) { @@ -5482,7 +5554,8 @@ void BM_mesh_bevel( const float segments, const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, - const bool loop_slide, const bool mark_seam, const bool mark_sharp) + const bool loop_slide, const bool mark_seam, const bool mark_sharp, + const int hnmode, BMOperator *op) { BMIter iter; BMVert *v, *v_next; @@ -5505,6 +5578,7 @@ void BM_mesh_bevel( bp.mat_nr = mat; bp.mark_seam = mark_seam; bp.mark_sharp = mark_sharp; + bp.hnmode = hnmode; if (profile >= 0.999f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ bp.pro_super_r = PRO_SQUARE_R; @@ -5561,6 +5635,13 @@ void BM_mesh_bevel( } } + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + bevel_extend_edge_data(bv); + if(bm->use_toolflags) + bevel_harden_normals_mode(bm, &bp, bv, op); + } + /* Rebuild face polygons around affected vertices */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5571,9 +5652,7 @@ void BM_mesh_bevel( BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { - BevVert *bv = find_bevvert(&bp, v); - BLI_assert(bv != NULL); - bevel_extend_edge_data(bv); + BLI_assert(find_bevvert(&bp, v) != NULL); BM_vert_kill(bm, v); } } diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index d932ac381a6..f43289aac27 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -33,6 +33,7 @@ void BM_mesh_bevel( BMesh *bm, const float offset, const int offset_type, const float segments, const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, - const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp); + const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, + const int hnmode, BMOperator *op); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 86aff48615c..859b0942e55 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -30,6 +30,7 @@ #include "BLI_string.h" #include "BLI_math.h" +#include "BLI_linklist_stack.h" #include "BLT_translation.h" @@ -38,6 +39,7 @@ #include "BKE_editmesh.h" #include "BKE_unit.h" #include "BKE_layer.h" +#include "BKE_mesh.h" #include "RNA_define.h" #include "RNA_access.h" @@ -134,6 +136,88 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op) } } +static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_strength, int hnmode) +{ + BKE_editmesh_lnorspace_update(em); + BM_normals_loops_edges_tag(em->bm, true); + int cd_clnors_offset = CustomData_get_offset(&em->bm->ldata, CD_CUSTOMLOOPNORMAL); + + BMesh *bm = em->bm; + BMFace *f; + BMLoop *l, *l_cur, *l_first; + BMIter fiter; + + BMOpSlot *nslot = BMO_slot_get(bmop->slots_out, "normals.out"); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + l_cur = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || + (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur)))) + { + if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) { + const int loop_index = BM_elem_index_get(l_cur); + short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors); + } + else { + BMVert *v_pivot = l_cur->v; + float *calc_n = BLI_ghash_lookup(nslot->data.ghash, v_pivot); + + BMEdge *e_next; + const BMEdge *e_org = l_cur->e; + BMLoop *lfan_pivot, *lfan_pivot_next; + + lfan_pivot = l_cur; + e_next = lfan_pivot->e; + BLI_SMALLSTACK_DECLARE(loops, BMLoop *); + float cn_wght[3] = { 0.0f, 0.0f, 0.0f }, cn_unwght[3] = { 0.0f, 0.0f, 0.0f }; + + while (true) { + lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); + if (lfan_pivot_next) { + BLI_assert(lfan_pivot_next->v == v_pivot); + } + else { + e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e; + } + BLI_SMALLSTACK_PUSH(loops, lfan_pivot); + float cur[3]; + mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); + add_v3_v3(cn_wght, cur); + if(BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT)) + add_v3_v3(cn_unwght, cur); + + if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { + break; + } + lfan_pivot = lfan_pivot_next; + } + + normalize_v3(cn_wght); + normalize_v3(cn_unwght); + if (calc_n) { + mul_v3_fl(calc_n, face_strength); + mul_v3_fl(cn_wght, 1.0f - face_strength); + add_v3_v3(calc_n, cn_wght); + normalize_v3(calc_n); + } + while ((l = BLI_SMALLSTACK_POP(loops))) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + if (calc_n) { + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors); + } + else + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], cn_unwght, clnors); + } + BLI_ghash_remove(nslot->data.ghash, v_pivot, NULL, MEM_freeN); + } + } + } while ((l_cur = l_cur->next) != l_first); + } +} + static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) { Scene *scene = CTX_data_scene(C); @@ -226,6 +310,8 @@ static bool edbm_bevel_calc(wmOperator *op) const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide"); const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam"); const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); + const float strength = RNA_float_get(op->ptr, "strength"); + const int hnmode = RNA_enum_get(op->ptr, "hnmode"); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { @@ -242,9 +328,9 @@ static bool edbm_bevel_calc(wmOperator *op) EDBM_op_init(em, &bmop, op, "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " - "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b", + "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b strength=%f hnmode=%i", BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide, mark_seam, mark_sharp); + clamp_overlap, material, loop_slide, mark_seam, mark_sharp, strength, hnmode); BMO_op_exec(em->bm, &bmop); @@ -255,6 +341,8 @@ static bool edbm_bevel_calc(wmOperator *op) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); } + bevel_harden_normals(em, &bmop, strength, hnmode); + /* no need to de-select existing geometry */ if (!EDBM_op_finish(em, &bmop, op, true)) { continue; @@ -663,6 +751,12 @@ void MESH_OT_bevel(wmOperatorType *ot) {0, NULL, 0, NULL, NULL}, }; + static EnumPropertyItem harden_normals_items[] = { + { BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" }, + { BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" }, + { 0, NULL, 0, NULL, NULL }, + }; + /* identifiers */ ot->name = "Bevel"; ot->description = "Edge Bevel"; @@ -692,4 +786,6 @@ void MESH_OT_bevel(wmOperatorType *ot) RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp"); RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100); + RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength", "Strength of calculated normal", 0.0f, 1.0f); + RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_FACE, "Normal Mode", "Weighting mode for Harden Normals"); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 07812cefb6b..afa89b11974 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7426,41 +7426,6 @@ void MESH_OT_point_normals(struct wmOperatorType *ot) /********************** Split/Merge Loop Normals **********************/ -static void normals_splitmerge_loops_edges_tag(BMesh *bm, const bool do_edges) -{ - BMFace *f; - BMEdge *e; - BMIter fiter, eiter; - BMLoop *l_curr, *l_first; - - if (do_edges) { - int index_edge; - BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) { - BMLoop *l_a, *l_b; - - BM_elem_index_set(e, index_edge); /* set_inline */ - BM_elem_flag_disable(e, BM_ELEM_TAG); - if (BM_edge_loop_pair(e, &l_a, &l_b)) { - if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) { - BM_elem_flag_enable(e, BM_ELEM_TAG); - } - } - } - bm->elem_index_dirty &= ~BM_EDGE; - } - - int index_face, index_loop = 0; - BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) { - BM_elem_index_set(f, index_face); /* set_inline */ - l_curr = l_first = BM_FACE_FIRST_LOOP(f); - do { - BM_elem_index_set(l_curr, index_loop++); /* set_inline */ - BM_elem_flag_disable(l_curr, BM_ELEM_TAG); - } while ((l_curr = l_curr->next) != l_first); - } - bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); -} - static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr) { BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; @@ -7469,7 +7434,7 @@ static void normals_merge(BMesh *bm, BMLoopNorEditDataArray *lnors_ed_arr) BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR); - normals_splitmerge_loops_edges_tag(bm, false); + BM_normals_loops_edges_tag(bm, false); for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) { if (BM_elem_flag_test(lnor_ed->loop, BM_ELEM_TAG)) { @@ -7512,7 +7477,7 @@ static void normals_split(BMesh *bm) BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR); - normals_splitmerge_loops_edges_tag(bm, true); + BM_normals_loops_edges_tag(bm, true); const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { @@ -7695,7 +7660,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op) weight = (weight - 1) * 25; } - normals_splitmerge_loops_edges_tag(bm, true); + BM_normals_loops_edges_tag(bm, true); Heap *loop_weight = BLI_heap_new(); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 433d75706bb..2400069a49a 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -334,6 +334,8 @@ typedef struct BevelModifierData { /* if the MOD_BEVEL_ANGLE is set, this will be how "sharp" an edge must be before it gets beveled */ float bevel_angle; /* if the MOD_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */ + int hnmode; + float strength; char defgrp_name[64]; } BevelModifierData; @@ -371,6 +373,12 @@ enum { MOD_BEVEL_MARK_SHARP = (1 << 1), }; +/* BevelModifierData->hnmode */ +enum { + MOD_BEVEL_HN_FACE, + MOD_BEVEL_HN_ADJ, +}; + typedef struct SmokeModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index a9bf7b18f73..37bb54cbe9e 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3028,6 +3028,12 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem prop_harden_normals_items[] = { + { MOD_BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" }, + { MOD_BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" }, + { 0, NULL, 0, NULL, NULL }, + }; + srna = RNA_def_struct(brna, "BevelModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Bevel Modifier", "Bevel modifier to make edges and vertices more rounded"); RNA_def_struct_sdna(srna, "BevelModifierData"); @@ -3114,6 +3120,17 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "edge_flags", MOD_BEVEL_MARK_SHARP); RNA_def_property_ui_text(prop, "Mark Sharp", "Mark beveled edges as sharp"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "hnmode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_harden_normals_items); + RNA_def_property_ui_text(prop, "Normal Mode", "Weighting mode for Harden Normals"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0, 10); + RNA_def_property_ui_range(prop, 0, 10, 1, 2); + RNA_def_property_ui_text(prop, "Normal Strength", "Strength of calculated normal"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 61ecc5c734e..4df8f1d06ae 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -169,7 +169,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, - dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp); + dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0}); -- cgit v1.2.3 From 29221319716d6588a2ad27977a1a6d86dcd96c37 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 13 Jun 2018 21:53:15 +0530 Subject: Corrected bevel of vertex by using profiles for curve of bevel --- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/blender/bmesh/tools/bmesh_bevel.c | 11 +++++++++++ source/tools | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index ebd058d7a64..27970761a18 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit ebd058d7a6438d137522063bb3286c8acc325ca6 +Subproject commit 27970761a18926abe1b0020aa350305e3109a537 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 47470215783..6a4f93c9b8f 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 474702157831f1a58bb50f5240ab8b1b02b6ba37 +Subproject commit 6a4f93c9b8f36b19bd02087abf3d7f5983df035a diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 39ca5a2d1ca..0fdf3a8868c 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -3647,6 +3647,17 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) odd = ns % 2; BLI_assert(n >= 3 && ns > 1); + /* Add support for profiles in vertex only in-plane bevels */ + if (bp->vertex_only) { + v = bv->vmesh->boundstart; + do { + Profile *pro = &v->profile; + pro->super_r = bp->pro_super_r; + copy_v3_v3(pro->midco, bv->v->co); + calculate_profile(bp, v); + v = v->next; + } while (v != bv->vmesh->boundstart); + } vpipe = pipe_test(bv); diff --git a/source/tools b/source/tools index 9d7d338cb25..88a1758d2d2 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 9d7d338cb25a071f9646cf9ba16f17004c963f77 +Subproject commit 88a1758d2d2e862cc69c08b5b40a4e75f71592d3 -- cgit v1.2.3 From e5880eb1ffdccc3295ca6a27fec8bb55fd20c27d Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 13 Jun 2018 21:56:15 +0530 Subject: Fix exception in superellipse where precision_reached is used with proper initialization --- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 0fdf3a8868c..148196ec505 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -5146,7 +5146,7 @@ static void find_even_superellipse_chords_general(int seg, float r, double *xval double sum; double temp; - bool precision_reached; + bool precision_reached = true; /* Exception: var used without being initialized */ bool seg_odd = seg % 2; bool rbig; -- cgit v1.2.3 From dd752476b97aa3b35d1359422ca42e33d99ac851 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 19 Jun 2018 19:27:08 +0530 Subject: Added face strength in bevel modifier The selected face strength (Weak/Medium/High) can be used by the WN Modifier to determine influence of current face in --- .../startup/bl_ui/properties_data_modifier.py | 2 ++ source/blender/bmesh/tools/bmesh_bevel.c | 1 + source/blender/makesdna/DNA_modifier_types.h | 3 ++- source/blender/makesrna/intern/rna_modifier.c | 7 +++++- source/blender/modifiers/intern/MOD_bevel.c | 29 ++++++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index acd1edc022a..428c45697a3 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -142,6 +142,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "loop_slide") col.prop(md, "mark_seam") col.prop(md, "mark_sharp") + + col.prop(md, "set_wn_strength") layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 148196ec505..d8a7f59cf65 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -5661,6 +5661,7 @@ void BM_mesh_bevel( } } + BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { BLI_assert(find_bevvert(&bp, v) != NULL); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 2400069a49a..3cf1d9f30f2 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -335,7 +335,7 @@ typedef struct BevelModifierData { float bevel_angle; /* if the MOD_BEVEL_VWEIGHT option is set, this will be the name of the vert group, MAX_VGROUP_NAME */ int hnmode; - float strength; + float hn_strength; char defgrp_name[64]; } BevelModifierData; @@ -357,6 +357,7 @@ enum { /* MOD_BEVEL_DIST = (1 << 12), */ /* same as above */ MOD_BEVEL_OVERLAP_OK = (1 << 13), MOD_BEVEL_EVEN_WIDTHS = (1 << 14), + MOD_BEVEL_SET_WN_STR = (1 << 15), }; /* BevelModifierData->val_flags (not used as flags any more) */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 04d8613c8d8..568b5b81ade 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3127,11 +3127,16 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Normal Mode", "Weighting mode for Harden Normals"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "hn_strength", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 0, 10); RNA_def_property_ui_range(prop, 0, 10, 1, 2); RNA_def_property_ui_text(prop, "Normal Strength", "Strength of calculated normal"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "set_wn_strength", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_BEVEL_SET_WN_STR); + RNA_def_property_ui_text(prop, "Face Strength", "Set face strength of beveled faces for use in WN Modifier"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); } static void rna_def_modifier_shrinkwrap(BlenderRNA *brna) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 4df8f1d06ae..7a20eb005f3 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -34,6 +34,7 @@ #include "DNA_object_types.h" #include "DNA_mesh_types.h" +#include "DNA_scene_types.h" #include "BLI_utildefines.h" #include "BLI_math.h" @@ -77,6 +78,30 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) return dataMask; } +static void bevel_set_weighted_normal_face_strength(BMesh *bm, Scene *scene) +{ + BMFace *f; + BMIter fiter; + const char *wn_layer_id = MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID; + int cd_prop_int_idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, wn_layer_id); + + if (cd_prop_int_idx == -1) { + BM_data_layer_add_named(bm, &bm->pdata, CD_PROP_INT, wn_layer_id); + cd_prop_int_idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT, wn_layer_id); + } + cd_prop_int_idx -= CustomData_get_layer_index(&bm->pdata, CD_PROP_INT); + const int cd_prop_int_offset = CustomData_get_n_offset(&bm->pdata, CD_PROP_INT, cd_prop_int_idx); + + const int face_strength = scene->toolsettings->face_strength; + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_TAG)) { + int *strength = BM_ELEM_CD_GET_VOID_P(f, cd_prop_int_offset); + *strength = face_strength; + } + } +} + /* * This calls the new bevel code (added since 2.64) */ @@ -99,6 +124,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0; const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM); const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP); + const bool set_wn_strength = (bmd->flags & MOD_BEVEL_SET_WN_STR); bm = BKE_mesh_to_bmesh_ex( mesh, @@ -171,6 +197,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); + if(set_wn_strength) + bevel_set_weighted_normal_face_strength(bm, md->scene); + result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0}); BLI_assert(bm->vtoolflagpool == NULL && -- cgit v1.2.3 From 0f66fe5732d7b6260b39e7aef9e406783c20b796 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Fri, 22 Jun 2018 23:22:44 +0530 Subject: Fix normal shading continuity for in-plane bevels --- source/blender/bmesh/tools/bmesh_bevel.c | 32 +++++++++++++++++++++----------- source/tools | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index d8a7f59cf65..c63fe69762a 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -3124,29 +3124,34 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp) } /* Is this a good candidate for using tri_corner_adj_vmesh? */ -static bool tri_corner_test(BevelParams *bp, BevVert *bv) +static int tri_corner_test(BevelParams *bp, BevVert *bv) { float ang, totang, angdiff; EdgeHalf *e; int i; + int in_plane_e = 0; - if (bv->edgecount != 3 || bv->selcount != 3) - return false; totang = 0.0f; - for (i = 0; i < 3; i++) { + for (i = 0; i < bv->edgecount; i++) { e = &bv->edges[i]; ang = BM_edge_calc_face_angle_signed_ex(e->e, 0.0f); - if (ang <= (float) M_PI_4 || ang >= 3.0f * (float) M_PI_4) - return false; + if (ang <= M_PI_4) + in_plane_e++; + else if (ang >= 3.0f * (float) M_PI_4) + return -1; totang += ang; } + if (in_plane_e != bv->edgecount - 3) + return -1; angdiff = fabsf(totang - 3.0f * (float)M_PI_2); if ((bp->pro_super_r == PRO_SQUARE_R && angdiff > (float)M_PI / 16.0f) || (angdiff > (float)M_PI_4)) { - return false; + return -1; } - return true; + if (bv->edgecount != 3 || bv->selcount != 3) + return 0; + return 1; } static VMesh *tri_corner_adj_vmesh(BevelParams *bp, BevVert *bv) @@ -3157,7 +3162,7 @@ static VMesh *tri_corner_adj_vmesh(BevelParams *bp, BevVert *bv) VMesh *vm; BoundVert *bndv; - BLI_assert(bv->edgecount == 3 && bv->selcount == 3); + /*BLI_assert(bv->edgecount == 3 && bv->selcount == 3); Add support for in plane edges */ bndv = bv->vmesh->boundstart; copy_v3_v3(co0, bndv->nv.co); bndv = bndv->next; @@ -3190,9 +3195,14 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv) BoundVert *bndv; MemArena *mem_arena = bp->mem_arena; float r, fac, fullness; + n = bv->vmesh->count; + + /* Same bevel as that of 3 edges of vert in a cube */ + if (n == 3 && tri_corner_test(bp, bv) != -1 && bp->pro_super_r != PRO_SQUARE_IN_R) { + return tri_corner_adj_vmesh(bp, bv); + } /* First construct an initial control mesh, with nseg==2 */ - n = bv->vmesh->count; ns = bv->vmesh->seg; vm0 = new_adj_vmesh(mem_arena, n, 2, bv->vmesh->boundstart); @@ -3667,7 +3677,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) else if (vpipe) { vm1 = pipe_adj_vmesh(bp, bv, vpipe); } - else if (tri_corner_test(bp, bv)) { + else if (tri_corner_test(bp, bv) == 1) { vm1 = tri_corner_adj_vmesh(bp, bv); /* the PRO_SQUARE_IN_R profile has boundary edges that merge * and no internal ring polys except possibly center ngon */ diff --git a/source/tools b/source/tools index 87f7038ee8c..88a1758d2d2 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 87f7038ee8c4b46a5e73a1a9065e2a9b7367f594 +Subproject commit 88a1758d2d2e862cc69c08b5b40a4e75f71592d3 -- cgit v1.2.3 From 1757b381790cd490e14b7ff7b6c4c84e4f1132e9 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 23 Jun 2018 01:46:42 +0530 Subject: Added UI for harden normals and normal control in bevel modifier --- .../startup/bl_ui/properties_data_modifier.py | 8 +- source/blender/bmesh/intern/bmesh_operators.h | 1 + source/blender/editors/mesh/editmesh_bevel.c | 1 + source/blender/makesdna/DNA_modifier_types.h | 1 + source/blender/makesrna/intern/rna_modifier.c | 5 +- source/blender/modifiers/intern/MOD_bevel.c | 109 +++++++++++++++++++++ 6 files changed, 121 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 581f3ca91bc..b79e594095d 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -143,8 +143,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "mark_seam") col.prop(md, "mark_sharp") - col.prop(md, "set_wn_strength") - layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) if md.limit_method == 'ANGLE': @@ -155,6 +153,12 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.label(text="Width Method:") layout.row().prop(md, "offset_type", expand=True) + + layout.label(text="Normal Mode") + layout.row().prop(md, "hnmode", expand=True) + layout.prop(md, "hn_strength") + layout.prop(md, "set_wn_strength") + def BOOLEAN(self, layout, ob, md): split = layout.split() diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 3ae9a77a761..1b5694c3ee8 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -128,6 +128,7 @@ enum { }; enum { + BEVEL_HN_NONE, BEVEL_HN_FACE, BEVEL_HN_ADJ, }; diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 1daf020dc7b..40be91aada1 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -752,6 +752,7 @@ void MESH_OT_bevel(wmOperatorType *ot) }; static EnumPropertyItem harden_normals_items[] = { + { BEVEL_HN_NONE, "HN_NONE", 0, "Off", "Do not use Harden Normals" }, { BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" }, { BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" }, { 0, NULL, 0, NULL, NULL }, diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 891f854c9eb..83f98c1181e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -376,6 +376,7 @@ enum { /* BevelModifierData->hnmode */ enum { + MOD_BEVEL_HN_NONE, MOD_BEVEL_HN_FACE, MOD_BEVEL_HN_ADJ, }; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index c29e40cba56..497125476a2 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3025,6 +3025,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) }; static EnumPropertyItem prop_harden_normals_items[] = { + { MOD_BEVEL_HN_NONE, "HN_NONE", 0, "Off", "Do not use Harden Normals" }, { MOD_BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" }, { MOD_BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" }, { 0, NULL, 0, NULL, NULL }, @@ -3123,8 +3124,8 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "hn_strength", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0, 10); - RNA_def_property_ui_range(prop, 0, 10, 1, 2); + RNA_def_property_range(prop, 0, 1); + RNA_def_property_ui_range(prop, 0, 1, 1, 2); RNA_def_property_ui_text(prop, "Normal Strength", "Strength of calculated normal"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 6902b811c26..77b306466c3 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -32,11 +32,14 @@ * \ingroup modifiers */ +#include "MEM_guardedalloc.h" + #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" #include "BLI_utildefines.h" +#include "BLI_linklist_stack.h" #include "BLI_math.h" #include "BLI_string.h" @@ -102,6 +105,109 @@ static void bevel_set_weighted_normal_face_strength(BMesh *bm, Scene *scene) } } +static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn_strength, int hnmode, MDeformVert *dvert, int vgroup) +{ + if (bmd->res > 20) + return; + BM_mesh_normals_update(bm); + BM_lnorspace_update(bm); + BM_normals_loops_edges_tag(bm, true); + + int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BMFace *f; + BMLoop *l, *l_cur, *l_first; + BMIter fiter; + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + l_cur = l_first = BM_FACE_FIRST_LOOP(f); + do { + if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && + BM_loop_check_cyclic_smooth_fan(l_cur)))) { + + if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) { + const int loop_index = BM_elem_index_get(l_cur); + short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors); + } + else { + BMVert *v_pivot = l_cur->v; + BMEdge *e_next; + const BMEdge *e_org = l_cur->e; + BMLoop *lfan_pivot, *lfan_pivot_next; + + lfan_pivot = l_cur; + e_next = lfan_pivot->e; + BLI_SMALLSTACK_DECLARE(loops, BMLoop *); + float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; + + while (true) { + lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); + if (lfan_pivot_next) { + BLI_assert(lfan_pivot_next->v == v_pivot); + } + else { + e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e; + } + + BLI_SMALLSTACK_PUSH(loops, lfan_pivot); + + if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { + int weight = BM_elem_float_data_get(&bm->edata, lfan_pivot->f, CD_BWEIGHT); + if (weight) { + if (bmd->hnmode == MOD_BEVEL_HN_FACE) { + float cur[3]; + mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); + add_v3_v3(cn_wght, cur); + } + else + add_v3_v3(cn_wght, lfan_pivot->f->no); + } + else + add_v3_v3(cn_wght, lfan_pivot->f->no); + + } + else if (bmd->lim_flags & MOD_BEVEL_VGROUP) { + const bool has_vgroup = dvert != NULL; + const bool vert_of_group = has_vgroup && defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL; + if (vert_of_group && bmd->hnmode == MOD_BEVEL_HN_FACE) { + float cur[3]; + mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); + add_v3_v3(cn_wght, cur); + } + else + add_v3_v3(cn_wght, lfan_pivot->f->no); + } + else { + float cur[3]; + mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); + add_v3_v3(cn_wght, cur); + } + if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { + break; + } + lfan_pivot = lfan_pivot_next; + } + + normalize_v3(cn_wght); + mul_v3_fl(cn_wght, hn_strength); + float n_final[3]; + + while ((l = BLI_SMALLSTACK_POP(loops))) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + copy_v3_v3(n_final, l->f->no); + mul_v3_fl(n_final, 1.0f - hn_strength); + add_v3_v3(n_final, cn_wght); + normalize_v3(n_final); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + } + } + } while ((l_cur = l_cur->next) != l_first); + } +} + /* * This calls the new bevel code (added since 2.64) */ @@ -197,6 +303,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); + if (bmd->hnmode != MOD_BEVEL_HN_NONE) + bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); + if(set_wn_strength) bevel_set_weighted_normal_face_strength(bm, md->scene); -- cgit v1.2.3 From e8a1b4d6452fc6ea3582f0f178f4da696c0e9c20 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 25 Jun 2018 13:47:46 +0530 Subject: Change bitmap to GHash in bevel_harden_normals_mode --- source/blender/bmesh/tools/bmesh_bevel.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index c63fe69762a..186d3a3c8e0 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1665,32 +1665,33 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B float n_final[3] = { 0.0f, 0.0f, 0.0f }; if (bp->hnmode == BEVEL_HN_FACE) { - BLI_bitmap *faces = BLI_BITMAP_NEW(bm->totface, __func__); + GHash *faceHash = BLI_ghash_int_new(__func__); + BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_TAG)) { BMFace *f_a, *f_b; BM_edge_face_pair(e, &f_a, &f_b); - if (f_a && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_a))) { + if(f_a && !BLI_ghash_haskey(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)))) { int f_area = BM_face_calc_area(f_a); float f_no[3]; copy_v3_v3(f_no, f_a->no); mul_v3_fl(f_no, f_area); add_v3_v3(n_final, f_no); - BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_a)); + BLI_ghash_insert(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)), NULL); } - if (f_b && !BLI_BITMAP_TEST(faces, BM_elem_index_get(f_b))) { + if(f_b && !BLI_ghash_haskey(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)))) { int f_area = BM_face_calc_area(f_b); float f_no[3]; copy_v3_v3(f_no, f_b->no); mul_v3_fl(f_no, f_area); add_v3_v3(n_final, f_no); - BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f_b)); + BLI_ghash_insert(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)), NULL); } } } - MEM_freeN(faces); + BLI_ghash_free(faceHash, NULL, NULL); normalize_v3(n_final); } else if (bp->hnmode == BEVEL_HN_ADJ) { -- cgit v1.2.3 From 3504b27c5074d49ed19f86c212c584f37a343d33 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 27 Jun 2018 20:19:15 +0530 Subject: Patch to fix shading continuity. Added it as extension to harden. Tried out different methods to fix normals, Though as with width and segments changes shape, orientation of new polys a non-smooth method of fix was not possible. Current method aggregates vertex normals into a smooth fan without affecting edge shading. Still need to fix the crease at new vertex edges --- source/blender/bmesh/intern/bmesh_operators.h | 1 + source/blender/bmesh/tools/bmesh_bevel.c | 102 ++++++++++++++++++++++++++ source/blender/makesdna/DNA_modifier_types.h | 1 + source/blender/makesrna/intern/rna_modifier.c | 1 + source/blender/modifiers/intern/MOD_bevel.c | 2 +- 5 files changed, 106 insertions(+), 1 deletion(-) diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 1b5694c3ee8..9f6ac50a3e5 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -131,6 +131,7 @@ enum { BEVEL_HN_NONE, BEVEL_HN_FACE, BEVEL_HN_ADJ, + BEVEL_HN_FIX_SHA, }; extern const BMOpDefine *bmo_opdefines[]; diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 186d3a3c8e0..132436c70f0 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -44,6 +44,7 @@ #include "BKE_customdata.h" #include "BKE_deform.h" +#include "BKE_mesh.h" #include "eigen_capi.h" @@ -1721,6 +1722,85 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B } while (bcur != bstart); } +static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevVert *bv, GHash *faceHash) +{ + VMesh *vm = bv->vmesh; + BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; + int ns = vm->seg; + int ns2 = ns / 2; + int count = 0; + + BMFace *f; + BMLoop *l; + BMIter liter, fiter; + + int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + + if (BLI_ghash_haskey(faceHash, f)) { + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); + } + } + } + + do { + for (int i = 0; i <= ns; i++) { + BMVert *v1 = mesh_vert(vm, bcur->index, 0, i)->v, *v2; + BMEdge *e; + BMIter eiter; + + BM_ITER_ELEM(e, &eiter, v1, BM_EDGES_OF_VERT) { + BMFace *f_a, *f_b; + BM_edge_face_pair(e, &f_a, &f_b); + + bool _f_a = false, _f_b = false; + if (f_a) + _f_a = BLI_ghash_haskey(faceHash, f_a); + if (f_b) + _f_b = BLI_ghash_haskey(faceHash, f_b); + if (_f_a ^ _f_b) { + + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + + if (l->f == f_a || l->f == f_b) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + float res[3]; + copy_v3_v3(res, f_a->no); + add_v3_v3(res, f_b->no); + mul_v3_fl(res, 0.5f); + normalize_v3(res); + + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], res, clnors); + } + } + } + } + + float res_n[3]; + zero_v3(res_n); + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + if (!BLI_ghash_haskey(faceHash, l->f)) { + add_v3_v3(res_n, l->f->no); + } + } + normalize_v3(res_n); + BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { + if (BLI_ghash_haskey(faceHash, l->f)) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + BKE_lnor_space_custom_normal_to_data(bm ->lnor_spacearr->lspacearr[l_index], res_n, clnors); + } + } + } + bcur = bcur->next; + } while (bcur != start); +} + /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp) { @@ -5648,6 +5728,17 @@ void BM_mesh_bevel( } } + GHash *faceHash; + if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { + faceHash = BLI_ghash_ptr_new(__func__); + BMFace *f; + BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(f, BM_ELEM_TAG)) { + BLI_ghash_insert(faceHash, f, NULL); + } + } + } + /* Build polygons for edges */ if (!bp.vertex_only) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -5664,6 +5755,7 @@ void BM_mesh_bevel( bevel_harden_normals_mode(bm, &bp, bv, op); } + /* Rebuild face polygons around affected vertices */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5672,6 +5764,16 @@ void BM_mesh_bevel( } } + if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { + BM_mesh_normals_update(bm); + BM_lnorspace_update(bm); + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + if (!bm->use_toolflags) + bevel_fix_normal_shading_continuity(&bp, bm, bv, faceHash); + } + BLI_ghash_free(faceHash, NULL, NULL); + } BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 83f98c1181e..7ae9383a907 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -379,6 +379,7 @@ enum { MOD_BEVEL_HN_NONE, MOD_BEVEL_HN_FACE, MOD_BEVEL_HN_ADJ, + MOD_BEVEL_FIX_SHA, }; typedef struct SmokeModifierData { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 497125476a2..87c28115325 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3028,6 +3028,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) { MOD_BEVEL_HN_NONE, "HN_NONE", 0, "Off", "Do not use Harden Normals" }, { MOD_BEVEL_HN_FACE, "HN_FACE", 0, "Face Area", "Use faces as weight" }, { MOD_BEVEL_HN_ADJ, "HN_ADJ", 0, "Vertex average", "Use adjacent vertices as weight" }, + { MOD_BEVEL_FIX_SHA, "FIX_SHA", 0, "Fix shading", "Fix normal shading continuity" }, { 0, NULL, 0, NULL, NULL }, }; diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 77b306466c3..735436f3971 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -303,7 +303,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); - if (bmd->hnmode != MOD_BEVEL_HN_NONE) + if (bmd->hnmode != MOD_BEVEL_HN_NONE && bmd->hnmode != MOD_BEVEL_FIX_SHA) bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); if(set_wn_strength) -- cgit v1.2.3 From 0c25881c391b84e238fa9503ec8c6a6fa0e2e439 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sun, 29 Jul 2018 19:52:23 +0530 Subject: Cleanup of fix_normal_shading Fixed the edge crease that was present and also made significant performance improvements. --- source/blender/bmesh/tools/bmesh_bevel.c | 114 ++++++++++++++----------------- 1 file changed, 51 insertions(+), 63 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 132436c70f0..bf32e8e6970 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -185,6 +185,7 @@ typedef struct BevVert { EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */ BMEdge **wire_edges; /* array of size wirecount of wire edges */ VMesh *vmesh; /* mesh structure for replacing vertex */ + bool fix_shading; } BevVert; /* Bevel parameters and state */ @@ -192,6 +193,8 @@ typedef struct BevelParams { /* hash of BevVert for each vertex involved in bevel * GHash: (key=(BMVert *), value=(BevVert *)) */ GHash *vert_hash; + /* Hash set used to store resultant beveled faces for VMesh when poly is ring */ + GHash *faceHash; MemArena *mem_arena; /* use for all allocs while bevel runs, if we need to free we can switch to mempool */ ProfileSpacing pro_spacing; /* parameter values for evenly spaced profiles */ @@ -1722,34 +1725,23 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B } while (bcur != bstart); } -static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevVert *bv, GHash *faceHash) +static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevVert *bv) { + GHash *faceHash = bp->faceHash; VMesh *vm = bv->vmesh; BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; int ns = vm->seg; int ns2 = ns / 2; - int count = 0; - BMFace *f; BMLoop *l; - BMIter liter, fiter; + BMIter liter; int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); - - BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { - - if (BLI_ghash_haskey(faceHash, f)) { - BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { - const int l_index = BM_elem_index_get(l); - short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); - } - } - } + float ref = 20.0f; do { for (int i = 0; i <= ns; i++) { - BMVert *v1 = mesh_vert(vm, bcur->index, 0, i)->v, *v2; + BMVert *v1 = mesh_vert(vm, bcur->index, 0, i)->v; BMEdge *e; BMIter eiter; @@ -1769,33 +1761,28 @@ static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevV if (l->f == f_a || l->f == f_b) { const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - float res[3]; - copy_v3_v3(res, f_a->no); - add_v3_v3(res, f_b->no); - mul_v3_fl(res, 0.5f); - normalize_v3(res); + float n_final[3], pow_a[3], pow_b[3]; + + zero_v3(n_final); + copy_v3_v3(pow_a, f_a->no); + copy_v3_v3(pow_b, f_b->no); + if (_f_a) { + mul_v3_fl(pow_a, ns / ref); + mul_v3_fl(pow_b, ref / ns); + } + else { + mul_v3_fl(pow_b, ns / ref); + mul_v3_fl(pow_a, ref / ns); + } + add_v3_v3(n_final, pow_a); + add_v3_v3(n_final, pow_b); + normalize_v3(n_final); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], res, clnors); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); } } } } - - float res_n[3]; - zero_v3(res_n); - BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { - if (!BLI_ghash_haskey(faceHash, l->f)) { - add_v3_v3(res_n, l->f->no); - } - } - normalize_v3(res_n); - BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { - if (BLI_ghash_haskey(faceHash, l->f)) { - const int l_index = BM_elem_index_get(l); - short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - BKE_lnor_space_custom_normal_to_data(bm ->lnor_spacearr->lspacearr[l_index], res_n, clnors); - } - } } bcur = bcur->next; } while (bcur != start); @@ -3283,6 +3270,8 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv) return tri_corner_adj_vmesh(bp, bv); } + bv->fix_shading = true; + /* First construct an initial control mesh, with nseg==2 */ ns = bv->vmesh->seg; vm0 = new_adj_vmesh(mem_arena, n, 2, bv->vmesh->boundstart); @@ -3726,7 +3715,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) VMesh *vm1, *vm; BoundVert *v; BMVert *bmv1, *bmv2, *bmv3, *bmv4; - BMFace *f, *f2; + BMFace *f, *f2, *r_f; BMEdge *bme, *bme1, *bme2, *bme3; EdgeHalf *e; BoundVert *vpipe; @@ -3771,6 +3760,8 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) vm1 = adj_vmesh(bp, bv); } + bool do_fix_shading_bv = ((bp->faceHash != NULL) && bv->fix_shading); + /* copy final vmesh into bv->vmesh, make BMVerts and BMFaces */ vm = bv->vmesh; for (i = 0; i < n; i++) { @@ -3812,24 +3803,24 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) if (bp->vertex_only) { if (j < k) { if (k == ns2 && j == ns2 - 1) { - bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, + r_f = bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, NULL, NULL, v->next->efirst->e, bme, mat_nr); } else { - bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); + r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); } } else if (j > k) { - bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); + r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); } else { /* j == k */ /* only one edge attached to v, since vertex_only */ if (e->is_seam) { - bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, + r_f = bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, bme, NULL, bme, NULL, mat_nr); } else { - bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f, + r_f = bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f, bme, NULL, bme, NULL, mat_nr); } } @@ -3838,25 +3829,27 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) if (odd) { if (k == ns2) { if (e->is_seam) { - bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, + r_f = bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme, bme, NULL, mat_nr); } else { - bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f2, f2, f, mat_nr); + r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f2, f2, f, mat_nr); } } else { - bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, mat_nr); + r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, mat_nr); } } else { bme1 = k == ns2 - 1 ? bme : NULL; bme3 = j == ns2 - 1 ? v->prev->ebev->e : NULL; bme2 = bme1 != NULL ? bme1 : bme3; - bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, + r_f = bev_create_quad_ex(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme1, bme2, bme3, mat_nr); } } + if(do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, r_f, NULL); } } } while ((v = v->next) != vm->boundstart); @@ -5681,6 +5674,7 @@ void BM_mesh_bevel( bp.mark_seam = mark_seam; bp.mark_sharp = mark_sharp; bp.hnmode = hnmode; + bp.faceHash = NULL; if (profile >= 0.999f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ bp.pro_super_r = PRO_SQUARE_R; @@ -5718,6 +5712,11 @@ void BM_mesh_bevel( adjust_offsets(&bp); } + const bool do_fix_shading = (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA); + if (do_fix_shading) { + bp.faceHash = BLI_ghash_ptr_new(__func__); + } + /* Build the meshes around vertices, now that positions are final */ /* Note: could use GHASH_ITER over bp.vert_hash when backward compatibility no longer matters */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -5728,17 +5727,6 @@ void BM_mesh_bevel( } } - GHash *faceHash; - if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { - faceHash = BLI_ghash_ptr_new(__func__); - BMFace *f; - BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(f, BM_ELEM_TAG)) { - BLI_ghash_insert(faceHash, f, NULL); - } - } - } - /* Build polygons for edges */ if (!bp.vertex_only) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -5764,15 +5752,15 @@ void BM_mesh_bevel( } } - if (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA) { + if (do_fix_shading) { BM_mesh_normals_update(bm); BM_lnorspace_update(bm); GHASH_ITER(giter, bp.vert_hash) { bv = BLI_ghashIterator_getValue(&giter); - if (!bm->use_toolflags) - bevel_fix_normal_shading_continuity(&bp, bm, bv, faceHash); + if (bv->fix_shading) + bevel_fix_normal_shading_continuity(&bp, bm, bv); } - BLI_ghash_free(faceHash, NULL, NULL); + BLI_ghash_free(bp.faceHash, NULL, NULL); } BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { -- cgit v1.2.3 From 74ace41160bd6e98c904b34e5efe0893b1719387 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 2 Jul 2018 21:47:15 +0530 Subject: Minor cleanup and fixed normal updating erasing entire mesh --- source/blender/bmesh/tools/bmesh_bevel.c | 34 ++++++++++++++-------------- source/blender/editors/mesh/editmesh_bevel.c | 9 ++++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index bf32e8e6970..9259be7b240 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -37,7 +37,6 @@ #include "BLI_array.h" #include "BLI_alloca.h" -#include "BLI_bitmap.h" #include "BLI_gsqueue.h" #include "BLI_math.h" #include "BLI_memarena.h" @@ -1538,12 +1537,12 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) { EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; - while (neg ^ !EDGE_DATA_CHECK(e, flag)) { + while ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag)))) { e = e->next; if (e == efirst) break; } - if (neg ^ !EDGE_DATA_CHECK(e, flag)) + if ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag)))) return; efirst = e; @@ -1551,12 +1550,13 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) int flag_count = 0; EdgeHalf *ne = e->next; - while ((neg ^ !EDGE_DATA_CHECK(ne, flag)) && ne != efirst) { + while ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag))) && ne != efirst) { if (ne->is_bev) flag_count++; ne = ne->next; } - if (ne == e || (ne == efirst && (neg ^ !EDGE_DATA_CHECK(efirst, flag)))) { + if (ne == e || (ne == efirst && (!neg && !EDGE_DATA_CHECK(e, flag) || + (neg && EDGE_DATA_CHECK(e, flag))))) { break; } if (flag == BM_ELEM_SEAM) @@ -5736,14 +5736,14 @@ void BM_mesh_bevel( } } - GHASH_ITER(giter, bp.vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - bevel_extend_edge_data(bv); - if(bm->use_toolflags) + if (bm->use_toolflags) { + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + bevel_extend_edge_data(bv); bevel_harden_normals_mode(bm, &bp, bv, op); + } } - /* Rebuild face polygons around affected vertices */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5752,6 +5752,13 @@ void BM_mesh_bevel( } } + BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + BLI_assert(find_bevvert(&bp, v) != NULL); + BM_vert_kill(bm, v); + } + } + if (do_fix_shading) { BM_mesh_normals_update(bm); BM_lnorspace_update(bm); @@ -5763,13 +5770,6 @@ void BM_mesh_bevel( BLI_ghash_free(bp.faceHash, NULL, NULL); } - BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_TAG)) { - BLI_assert(find_bevvert(&bp, v) != NULL); - BM_vert_kill(bm, v); - } - } - /* When called from operator (as opposed to modifier), bm->use_toolflags * will be set, and we to transfer the oflags to BM_ELEM_TAGs */ if (bm->use_toolflags) { diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 40be91aada1..d92d655641f 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -197,8 +197,8 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st normalize_v3(cn_wght); normalize_v3(cn_unwght); if (calc_n) { - mul_v3_fl(calc_n, face_strength); - mul_v3_fl(cn_wght, 1.0f - face_strength); + mul_v3_fl(cn_wght, face_strength); + mul_v3_fl(calc_n, 1.0f - face_strength); add_v3_v3(calc_n, cn_wght); normalize_v3(calc_n); } @@ -341,7 +341,8 @@ static bool edbm_bevel_calc(wmOperator *op) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); } - bevel_harden_normals(em, &bmop, strength, hnmode); + if(hnmode != BEVEL_HN_NONE) + bevel_harden_normals(em, &bmop, strength, hnmode); /* no need to de-select existing geometry */ if (!EDBM_op_finish(em, &bmop, op, true)) { @@ -788,5 +789,5 @@ void MESH_OT_bevel(wmOperatorType *ot) RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100); RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength", "Strength of calculated normal", 0.0f, 1.0f); - RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_FACE, "Normal Mode", "Weighting mode for Harden Normals"); + RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_NONE, "Normal Mode", "Weighting mode for Harden Normals"); } -- cgit v1.2.3 From 368a64fe041ee0950584f5b51e2f64036edb31d0 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 2 Jul 2018 22:55:33 +0530 Subject: Refactored bevel normal editing functionality. --- source/blender/bmesh/tools/bmesh_bevel.c | 39 ++++++++-------- source/blender/bmesh/tools/bmesh_bevel.h | 2 +- source/blender/makesdna/DNA_modifier_types.h | 6 +++ source/blender/modifiers/intern/MOD_bevel.c | 69 ++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 25 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 9259be7b240..789c2ae4c63 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -34,6 +34,7 @@ #include "DNA_object_types.h" #include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" #include "BLI_array.h" #include "BLI_alloca.h" @@ -5650,7 +5651,7 @@ void BM_mesh_bevel( const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, BMOperator *op) + const int hnmode, void *mod_bmop_customdata) { BMIter iter; BMVert *v, *v_next; @@ -5659,6 +5660,9 @@ void BM_mesh_bevel( BevelParams bp = {NULL}; GHashIterator giter; + BMOperator *op; + BevelModNorEditData *clnordata; + bp.offset = offset; bp.offset_type = offset_type; bp.seg = segments; @@ -5687,6 +5691,14 @@ void BM_mesh_bevel( BLI_memarena_use_calloc(bp.mem_arena); set_profile_spacing(&bp); + if (bm->use_toolflags) + op = mod_bmop_customdata; + else { + clnordata = mod_bmop_customdata; + clnordata->faceHash = BLI_ghash_ptr_new(__func__); + bp.faceHash = clnordata->faceHash; + } + /* Analyze input vertices, sorting edges and assigning initial new vertex positions */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { @@ -5712,11 +5724,6 @@ void BM_mesh_bevel( adjust_offsets(&bp); } - const bool do_fix_shading = (!bm->use_toolflags && bp.hnmode == BEVEL_HN_FIX_SHA); - if (do_fix_shading) { - bp.faceHash = BLI_ghash_ptr_new(__func__); - } - /* Build the meshes around vertices, now that positions are final */ /* Note: could use GHASH_ITER over bp.vert_hash when backward compatibility no longer matters */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -5736,10 +5743,11 @@ void BM_mesh_bevel( } } - if (bm->use_toolflags) { - GHASH_ITER(giter, bp.vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - bevel_extend_edge_data(bv); + /* Extend edge data like sharp edges and precompute normals for harden */ + GHASH_ITER(giter, bp.vert_hash) { + bv = BLI_ghashIterator_getValue(&giter); + bevel_extend_edge_data(bv); + if (bm->use_toolflags) { bevel_harden_normals_mode(bm, &bp, bv, op); } } @@ -5759,17 +5767,6 @@ void BM_mesh_bevel( } } - if (do_fix_shading) { - BM_mesh_normals_update(bm); - BM_lnorspace_update(bm); - GHASH_ITER(giter, bp.vert_hash) { - bv = BLI_ghashIterator_getValue(&giter); - if (bv->fix_shading) - bevel_fix_normal_shading_continuity(&bp, bm, bv); - } - BLI_ghash_free(bp.faceHash, NULL, NULL); - } - /* When called from operator (as opposed to modifier), bm->use_toolflags * will be set, and we to transfer the oflags to BM_ELEM_TAGs */ if (bm->use_toolflags) { diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index f43289aac27..5cf8b1e78bb 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -34,6 +34,6 @@ void BM_mesh_bevel( const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, BMOperator *op); + const int hnmode, void *mod_bmop_customdata); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 7ae9383a907..33381be0ef5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -318,6 +318,11 @@ enum { MOD_EDGESPLIT_FROMFLAG = (1 << 2), }; +typedef struct BevelModNorEditData { + struct GHash *faceHash; + struct GHash *vert_hash; +} BevelModNorEditData; + typedef struct BevelModifierData { ModifierData modifier; @@ -337,6 +342,7 @@ typedef struct BevelModifierData { int hnmode; float hn_strength; char defgrp_name[64]; + struct BevelModNorEditData clnordata; } BevelModifierData; /* BevelModifierData->flags and BevelModifierData->lim_flags */ diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 735436f3971..b30d6c2e669 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -140,6 +140,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn e_next = lfan_pivot->e; BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; + bool normal_to_recon_face = false; while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); @@ -208,6 +209,62 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn } } +static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *bm) +{ + BM_mesh_normals_update(bm); + BM_lnorspace_update(bm); + + GHash *faceHash = bmd->clnordata.faceHash; + BMEdge *e; + BMLoop *l; + BMIter liter, eiter; + + int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + float ref = 10.0f; + + BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) { + BMFace *f_a, *f_b; + BM_edge_face_pair(e, &f_a, &f_b); + + bool _f_a = false, _f_b = false; + if (f_a) + _f_a = BLI_ghash_haskey(faceHash, f_a); + if (f_b) + _f_b = BLI_ghash_haskey(faceHash, f_b); + if (_f_a ^ _f_b) { + + for (int i = 0; i < 2; i++) { + BMVert *v = (i == 0) ? e->v1 : e->v2; + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + + if (l->f == f_a || l->f == f_b) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + float n_final[3], pow_a[3], pow_b[3]; + + zero_v3(n_final); + copy_v3_v3(pow_a, f_a->no); + copy_v3_v3(pow_b, f_b->no); + if (_f_a) { + mul_v3_fl(pow_a, bmd->res / ref); + mul_v3_fl(pow_b, ref / bmd->res); + } + else { + mul_v3_fl(pow_b, bmd->res / ref); + mul_v3_fl(pow_a, ref / bmd->res); + } + add_v3_v3(n_final, pow_a); + add_v3_v3(n_final, pow_b); + normalize_v3(n_final); + + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + } + } + } + } +} + /* * This calls the new bevel code (added since 2.64) */ @@ -301,10 +358,14 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, - dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, NULL); + dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, &bmd->clnordata); - if (bmd->hnmode != MOD_BEVEL_HN_NONE && bmd->hnmode != MOD_BEVEL_FIX_SHA) - bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); + if (bmd->hnmode != MOD_BEVEL_HN_NONE) { + if (bmd->hnmode != BEVEL_HN_FIX_SHA) + bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); + else + bevel_fix_normal_shading_continuity(bmd, bm); + } if(set_wn_strength) bevel_set_weighted_normal_face_strength(bm, md->scene); @@ -316,6 +377,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BM_mesh_free(bm); + BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL); + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; return result; -- cgit v1.2.3 From 190d1b2f7ae04cbe244b581f78dfdeb3387c9ea0 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 3 Jul 2018 19:01:20 +0530 Subject: Fixed merge errors --- source/blender/editors/mesh/editmesh_tools.c | 8 ++++---- source/blender/editors/transform/transform.c | 2 +- source/blender/modifiers/intern/MOD_bevel.c | 11 ++++++++--- source/blender/modifiers/intern/MOD_weighted_normal.c | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index f8c1db30276..9683bf43968 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7049,7 +7049,7 @@ static void point_normals_free(bContext *C, wmOperator *op) BMLoopNorEditDataArray *lnors_ed_arr = op->customdata; BM_loop_normal_editdata_array_free(lnors_ed_arr); op->customdata = NULL; - ED_area_headerprint(CTX_wm_area(C), NULL); + ED_area_status_text(CTX_wm_area(C), NULL); } static void point_normals_update_header(bContext *C, wmOperator *op) @@ -7080,7 +7080,7 @@ static void point_normals_update_header(bContext *C, wmOperator *op) #undef WM_MODALKEY - ED_area_headerprint(CTX_wm_area(C), header); + ED_area_status_text(CTX_wm_area(C), header); } /* TODO move that to generic function in BMesh? */ @@ -7226,7 +7226,7 @@ static int edbm_point_normals_modal(bContext *C, wmOperator *op, const wmEvent * case EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR: new_mode = EDBM_CLNOR_POINTTO_MODE_COORDINATES; - ED_view3d_cursor3d_update(C, event->mval); + ED_view3d_cursor3d_update(C, event->mval, false, V3D_CURSOR_ORIENT_NONE); copy_v3_v3(target, ED_view3d_cursor3d_get(scene, v3d)->location); break; @@ -8263,4 +8263,4 @@ void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot) ot->prop = RNA_def_boolean(ot->srna, "set", 0, "Set value", "Set Value of faces"); RNA_def_property_flag(ot->prop, PROP_HIDDEN); -} \ No newline at end of file +} diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ba9430c46f7..9a52127b201 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4428,7 +4428,7 @@ static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2])) recalcData(t); - ED_area_headerprint(t->sa, str); + ED_area_status_text(t->sa, str); } /** \} */ diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index aa12093b505..67634dba170 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -53,6 +53,8 @@ #include "bmesh.h" #include "bmesh_tools.h" +#include "DEG_depsgraph_query.h" + static void initData(ModifierData *md) { BevelModifierData *bmd = (BevelModifierData *) md; @@ -289,6 +291,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP); const bool set_wn_strength = (bmd->flags & MOD_BEVEL_SET_WN_STR); + struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + bm = BKE_mesh_to_bmesh_ex( mesh, &(struct BMeshCreateParams){0}, @@ -363,12 +367,12 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (bmd->hnmode != MOD_BEVEL_HN_NONE) { if (bmd->hnmode != BEVEL_HN_FIX_SHA) bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); - else + else if(bmd->clnordata.faceHash) bevel_fix_normal_shading_continuity(bmd, bm); } if(set_wn_strength) - bevel_set_weighted_normal_face_strength(bm, md->scene); + bevel_set_weighted_normal_face_strength(bm, scene); result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0}); @@ -377,7 +381,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BM_mesh_free(bm); - BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL); + if(bmd->clnordata.faceHash) + BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL); result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index b43ef698cc4..a2ace1aadc4 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -554,7 +554,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MDeformVert *dvert; int defgrp_index; - modifier_get_vgroup_mesh(ob, result, wnmd->defgrp_name, &dvert, &defgrp_index); + MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index); WeightedNormalData wn_data = { .numVerts = numVerts, -- cgit v1.2.3 From 1c699d75a03c76ac6922906e8b13e6dc53d8075a Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 3 Jul 2018 21:51:01 +0530 Subject: Fixed bugs in normal shading continuity and added support to have corner vertices of a vmesh to have same normal as reconstructed face in harden --- source/blender/modifiers/intern/MOD_bevel.c | 56 ++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 67634dba170..f89494f7c71 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -111,15 +111,18 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn { if (bmd->res > 20) return; + BM_mesh_normals_update(bm); BM_lnorspace_update(bm); BM_normals_loops_edges_tag(bm, true); + const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); BMFace *f; BMLoop *l, *l_cur, *l_first; BMIter fiter; + GHash *faceHash = bmd->clnordata.faceHash; BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { l_cur = l_first = BM_FACE_FIRST_LOOP(f); @@ -142,7 +145,8 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn e_next = lfan_pivot->e; BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; - bool normal_to_recon_face = false; + int recon_face_count = 0; /* Reconstructed face */ + BMFace *recon_face; while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); @@ -190,6 +194,10 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn break; } lfan_pivot = lfan_pivot_next; + if (!BLI_ghash_haskey(faceHash, f)) { + recon_face = f; + recon_face_count++; + } } normalize_v3(cn_wght); @@ -199,11 +207,19 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn while ((l = BLI_SMALLSTACK_POP(loops))) { const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - copy_v3_v3(n_final, l->f->no); - mul_v3_fl(n_final, 1.0f - hn_strength); - add_v3_v3(n_final, cn_wght); - normalize_v3(n_final); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + + if (!vertex_only || !recon_face_count) { + copy_v3_v3(n_final, l->f->no); + mul_v3_fl(n_final, 1.0f - hn_strength); + add_v3_v3(n_final, cn_wght); + normalize_v3(n_final); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + else if (recon_face_count == 1) { + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, clnors); + } + else if(BLI_ghash_haskey(faceHash, l->f)) + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); } } } @@ -222,6 +238,7 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b BMIter liter, eiter; int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const float hn_strength = bmd->hn_strength; float ref = 10.0f; BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) { @@ -264,6 +281,29 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b } } } + else if(_f_a == true && _f_b == true) { + for (int i = 0; i < 2; i++) { + BMVert *v = (i == 0) ? e->v1 : e->v2; + BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { + + if(l->f == f_a || l->f == f_b) { + const int l_index = BM_elem_index_get(l); + short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + float n_final[3], cn_wght[3]; + + copy_v3_v3(n_final, v->no); + mul_v3_fl(n_final, hn_strength); + + copy_v3_v3(cn_wght, l->f->no); + mul_v3_fl(cn_wght, 1.0f - hn_strength); + + add_v3_v3(n_final, cn_wght); + normalize_v3(n_final); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + } + } + } } } @@ -364,10 +404,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, &bmd->clnordata); - if (bmd->hnmode != MOD_BEVEL_HN_NONE) { + if (bmd->value > 0 && bmd->hnmode != MOD_BEVEL_HN_NONE) { if (bmd->hnmode != BEVEL_HN_FIX_SHA) bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); - else if(bmd->clnordata.faceHash) + else if(bmd->clnordata.faceHash && !vertex_only) bevel_fix_normal_shading_continuity(bmd, bm); } -- cgit v1.2.3 From b360c9d7f9d1fbb85b6cb71109da39731e3870c6 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 4 Jul 2018 00:04:03 +0530 Subject: cleanup of extend edge data and fixed minor errors --- source/blender/bmesh/tools/bmesh_bevel.c | 73 +++-------------------------- source/blender/modifiers/intern/MOD_bevel.c | 8 ++-- 2 files changed, 10 insertions(+), 71 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 789c2ae4c63..0a8ff3546be 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1551,13 +1551,13 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) int flag_count = 0; EdgeHalf *ne = e->next; - while ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag))) && ne != efirst) { + while ((!neg && !EDGE_DATA_CHECK(ne, flag) || (neg && EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { if (ne->is_bev) flag_count++; ne = ne->next; } - if (ne == e || (ne == efirst && (!neg && !EDGE_DATA_CHECK(e, flag) || - (neg && EDGE_DATA_CHECK(e, flag))))) { + if (ne == e || (ne == efirst && (!neg && !EDGE_DATA_CHECK(efirst, flag) || + (neg && EDGE_DATA_CHECK(efirst, flag))))) { break; } if (flag == BM_ELEM_SEAM) @@ -1657,6 +1657,8 @@ static void bevel_extend_edge_data(BevVert *bv) static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, BMOperator *op) { + if (bp->hnmode == BEVEL_HN_NONE) + return; int mode = 1; VMesh *vm = bv->vmesh; @@ -1726,69 +1728,6 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B } while (bcur != bstart); } -static void bevel_fix_normal_shading_continuity(BevelParams *bp, BMesh *bm, BevVert *bv) -{ - GHash *faceHash = bp->faceHash; - VMesh *vm = bv->vmesh; - BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; - int ns = vm->seg; - int ns2 = ns / 2; - - BMLoop *l; - BMIter liter; - - int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); - float ref = 20.0f; - - do { - for (int i = 0; i <= ns; i++) { - BMVert *v1 = mesh_vert(vm, bcur->index, 0, i)->v; - BMEdge *e; - BMIter eiter; - - BM_ITER_ELEM(e, &eiter, v1, BM_EDGES_OF_VERT) { - BMFace *f_a, *f_b; - BM_edge_face_pair(e, &f_a, &f_b); - - bool _f_a = false, _f_b = false; - if (f_a) - _f_a = BLI_ghash_haskey(faceHash, f_a); - if (f_b) - _f_b = BLI_ghash_haskey(faceHash, f_b); - if (_f_a ^ _f_b) { - - BM_ITER_ELEM(l, &liter, v1, BM_LOOPS_OF_VERT) { - - if (l->f == f_a || l->f == f_b) { - const int l_index = BM_elem_index_get(l); - short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - float n_final[3], pow_a[3], pow_b[3]; - - zero_v3(n_final); - copy_v3_v3(pow_a, f_a->no); - copy_v3_v3(pow_b, f_b->no); - if (_f_a) { - mul_v3_fl(pow_a, ns / ref); - mul_v3_fl(pow_b, ref / ns); - } - else { - mul_v3_fl(pow_b, ns / ref); - mul_v3_fl(pow_a, ref / ns); - } - add_v3_v3(n_final, pow_a); - add_v3_v3(n_final, pow_b); - normalize_v3(n_final); - - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); - } - } - } - } - } - bcur = bcur->next; - } while (bcur != start); -} - /* Set the any_seam property for a BevVert and all its BoundVerts */ static void set_bound_vert_seams(BevVert *bv, bool mark_seam, bool mark_sharp) { @@ -3761,7 +3700,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) vm1 = adj_vmesh(bp, bv); } - bool do_fix_shading_bv = ((bp->faceHash != NULL) && bv->fix_shading); + bool do_fix_shading_bv = bp->faceHash != NULL; /* copy final vmesh into bv->vmesh, make BMVerts and BMFaces */ vm = bv->vmesh; diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index f89494f7c71..a61705646e6 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -190,14 +190,14 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); } - if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { - break; - } - lfan_pivot = lfan_pivot_next; if (!BLI_ghash_haskey(faceHash, f)) { recon_face = f; recon_face_count++; } + if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { + break; + } + lfan_pivot = lfan_pivot_next; } normalize_v3(cn_wght); -- cgit v1.2.3 From 13741792abdaa2ea4f65d26988d40cb9483f0450 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Mon, 9 Jul 2018 21:55:08 +0530 Subject: Fixed artifacts in bevel with high profile and segments --- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 0a8ff3546be..694581bfab2 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -5619,7 +5619,7 @@ void BM_mesh_bevel( bp.hnmode = hnmode; bp.faceHash = NULL; - if (profile >= 0.999f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ + if (profile >= 0.950f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ bp.pro_super_r = PRO_SQUARE_R; } -- cgit v1.2.3 From 962f89d487da41107d7d1b1ccf7e720767359cd0 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 10 Jul 2018 22:21:28 +0530 Subject: Changed default strength in harden --- source/blender/makesrna/intern/rna_modifier.c | 1 + source/blender/modifiers/intern/MOD_bevel.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index c1b271e9214..70bd685dc56 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -3125,6 +3125,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "hn_strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_range(prop, 0, 1, 1, 2); RNA_def_property_ui_text(prop, "Normal Strength", "Strength of calculated normal"); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index a61705646e6..3418922e812 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -70,6 +70,7 @@ static void initData(ModifierData *md) bmd->profile = 0.5f; bmd->bevel_angle = DEG2RADF(30.0f); bmd->defgrp_name[0] = '\0'; + bmd->hn_strength = 0.5f; } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) -- cgit v1.2.3 From 75149b429f1567e3358750a62eadeb1c32fef032 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Wed, 11 Jul 2018 22:36:44 +0530 Subject: Added support for beveling curves --- source/blender/modifiers/intern/MOD_bevel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 3418922e812..f19443f2d5c 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -442,8 +442,9 @@ ModifierTypeInfo modifierType_Bevel = { /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | - eModifierTypeFlag_EnableInEditmode, - + eModifierTypeFlag_EnableInEditmode | + eModifierTypeFlag_AcceptsCVs, + /* copyData */ modifier_copyData_generic, /* deformVerts_DM */ NULL, -- cgit v1.2.3 From 10c1f3fbfeadf009bac8b7f145ae6d55be0f30be Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Thu, 12 Jul 2018 23:30:29 +0530 Subject: Fixed shading errors with normals and added proper weighting to harden normals to make it consistent with wn modifier --- source/blender/bmesh/tools/bmesh_bevel.c | 37 ++++++++++++++++++++++++----- source/blender/modifiers/intern/MOD_bevel.c | 14 +++++++---- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 694581bfab2..c8a82eac743 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -3862,6 +3862,8 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) BLI_array_staticdeclare(vf, BM_DEFAULT_NGON_STACK_SIZE); BLI_array_staticdeclare(ve, BM_DEFAULT_NGON_STACK_SIZE); + bool do_fix_shading_bv = bp->faceHash != NULL; + if (bv->any_seam) { frep = boundvert_rep_face(vm->boundstart, &frep2); if (frep2 && frep && is_bad_uv_poly(bv, frep)) { @@ -3907,6 +3909,8 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) } while ((v = v->next) != vm->boundstart); if (n > 2) { f = bev_create_ngon(bm, vv, n, vf, frep, ve, bp->mat_nr, true); + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, f, NULL); } else { f = NULL; @@ -3921,6 +3925,7 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv) { BMFace *f; BLI_assert(next_bev(bv, NULL)->seg == 1 || bv->selcount == 1); + bool do_fix_shading_bv = bp->faceHash != NULL; f = bevel_build_poly(bp, bm, bv); @@ -3929,6 +3934,11 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv) BMLoop *l_fan = BM_FACE_FIRST_LOOP(f)->prev; BMVert *v_fan = l_fan->v; + if (f->len == 3) { + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, f, NULL); + } + while (f->len > 3) { BMLoop *l_new; BMFace *f_new; @@ -3949,6 +3959,8 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv) else if (l_fan->prev->v == v_fan) { l_fan = l_fan->prev; } else { BLI_assert(0); } } + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, f_new, NULL); } } } @@ -3957,6 +3969,7 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv) { BMFace *f; BLI_assert(bv->selcount == 2); + bool do_fix_shading_bv = bp->faceHash != NULL; f = bevel_build_poly(bp, bm, bv); @@ -3968,6 +3981,11 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv) BMLoop *l_b = BM_face_vert_share_loop(f, eh_b->leftv->nv.v); int split_count = bv->vmesh->seg + 1; /* ensure we don't walk past the segments */ + if (f->len == 4) { + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, f, NULL); + } + while (f->len > 4 && split_count > 0) { BMLoop *l_new; BLI_assert(l_a->f == f); @@ -3986,6 +4004,9 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv) /* walk around the new face to get the next verts to split */ l_a = l_new->prev; l_b = l_new->next->next; + + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, f, NULL); } split_count--; } @@ -4962,13 +4983,15 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) VMesh *vm1, *vm2; EdgeHalf *e1, *e2; BMEdge *bme1, *bme2, *center_bme; - BMFace *f1, *f2, *f; + BMFace *f1, *f2, *f, *r_f; BMVert *verts[4]; BMFace *faces[4]; BMEdge *edges[4]; int k, nseg, i1, i2, odd, mid; int mat_nr = bp->mat_nr; + bool do_fix_shading_bv = bp->faceHash != NULL; + if (!BM_edge_is_manifold(bme)) return; @@ -5024,18 +5047,18 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) /* straddles a seam: choose to interpolate in f1 and snap right edge to bme */ edges[0] = edges[1] = NULL; edges[2] = edges[3] = bme; - bev_create_ngon(bm, verts, 4, NULL, f1, edges, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, NULL, f1, edges, mat_nr, true); } else { /* straddles but not a seam: interpolate left half in f1, right half in f2 */ - bev_create_ngon(bm, verts, 4, faces, NULL, NULL, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, faces, NULL, NULL, mat_nr, true); } } else if (!odd && k == mid) { /* left poly that touches an even center line on right */ edges[0] = edges[1] = NULL; edges[2] = edges[3] = bme; - bev_create_ngon(bm, verts, 4, NULL, f1, edges, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, NULL, f1, edges, mat_nr, true); center_bme = BM_edge_exists(verts[2], verts[3]); BLI_assert(center_bme != NULL); } @@ -5043,13 +5066,15 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) /* right poly that touches an even center line on left */ edges[0] = edges[1] = bme; edges[2] = edges[3] = NULL; - bev_create_ngon(bm, verts, 4, NULL, f2, edges, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, NULL, f2, edges, mat_nr, true); } else { /* doesn't cross or touch the center line, so interpolate in appropriate f1 or f2 */ f = (k <= mid) ? f1 : f2; - bev_create_ngon(bm, verts, 4, NULL, f, NULL, mat_nr, true); + r_f = bev_create_ngon(bm, verts, 4, NULL, f, NULL, mat_nr, true); } + if (do_fix_shading_bv) + BLI_ghash_insert(bp->faceHash, r_f, NULL); verts[0] = verts[3]; verts[1] = verts[2]; } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index f19443f2d5c..06c4f8c57fd 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -119,6 +119,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + bool do_normal_to_recon = (hn_strength == 1.0f); BMFace *f; BMLoop *l, *l_cur, *l_first; @@ -126,6 +127,9 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn GHash *faceHash = bmd->clnordata.faceHash; BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (!BLI_ghash_haskey(faceHash, f)) { + BM_elem_flag_set(f, BM_ELEM_HIDDEN, true); + } l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && @@ -191,7 +195,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); } - if (!BLI_ghash_haskey(faceHash, f)) { + if (!BLI_ghash_haskey(faceHash, lfan_pivot->f)) { recon_face = f; recon_face_count++; } @@ -209,16 +213,16 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - if (!vertex_only || !recon_face_count) { + if (recon_face_count == 1 || do_normal_to_recon) { + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, clnors); + } + else if (vertex_only == false || recon_face_count == 0) { copy_v3_v3(n_final, l->f->no); mul_v3_fl(n_final, 1.0f - hn_strength); add_v3_v3(n_final, cn_wght); normalize_v3(n_final); BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); } - else if (recon_face_count == 1) { - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, clnors); - } else if(BLI_ghash_haskey(faceHash, l->f)) BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); } -- cgit v1.2.3 From b457cae397054a1be4e60f3007995f97c198b2b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2018 14:24:10 +0200 Subject: Cleanup: use variable names based on term gizmo --- .../startup/bl_ui/space_toolsystem_toolbar.py | 14 +- .../scripts/templates_py/gizmo_custom_geometry.py | 4 +- release/scripts/templates_py/gizmo_operator.py | 6 +- .../scripts/templates_py/gizmo_operator_target.py | 4 +- release/scripts/templates_py/gizmo_simple.py | 4 +- source/blender/blenkernel/BKE_context.h | 2 +- source/blender/blenkernel/intern/context.c | 4 +- source/blender/draw/intern/draw_manager.c | 2 +- .../editors/gizmo_library/gizmo_library_intern.h | 10 +- .../editors/gizmo_library/gizmo_library_presets.c | 24 +- .../editors/gizmo_library/gizmo_library_utils.c | 36 +- .../gizmo_library/gizmo_types/arrow2d_gizmo.c | 66 +-- .../gizmo_library/gizmo_types/arrow3d_gizmo.c | 124 ++--- .../gizmo_library/gizmo_types/button2d_gizmo.c | 94 ++-- .../gizmo_library/gizmo_types/cage2d_gizmo.c | 208 ++++---- .../gizmo_library/gizmo_types/cage3d_gizmo.c | 188 +++---- .../gizmo_library/gizmo_types/dial3d_gizmo.c | 136 ++--- .../gizmo_library/gizmo_types/grab3d_gizmo.c | 124 ++--- .../gizmo_library/gizmo_types/primitive3d_gizmo.c | 50 +- source/blender/editors/include/ED_gizmo_library.h | 12 +- source/blender/editors/include/ED_transform.h | 12 +- source/blender/editors/include/UI_interface.h | 2 +- .../editors/interface/interface_region_tooltip.c | 26 +- source/blender/editors/mesh/editmesh_add_gizmo.c | 100 ++-- source/blender/editors/mesh/editmesh_bevel.c | 8 +- source/blender/editors/mesh/editmesh_bisect.c | 110 ++-- source/blender/editors/mesh/editmesh_extrude.c | 58 +-- .../blender/editors/mesh/editmesh_extrude_spin.c | 118 ++--- source/blender/editors/mesh/editmesh_inset.c | 8 +- source/blender/editors/space_image/space_image.c | 20 +- source/blender/editors/space_node/node_gizmo.c | 202 ++++---- source/blender/editors/space_node/node_intern.h | 8 +- source/blender/editors/space_node/space_node.c | 20 +- source/blender/editors/space_view3d/space_view3d.c | 50 +- source/blender/editors/space_view3d/view3d_draw.c | 2 +- .../editors/space_view3d/view3d_gizmo_armature.c | 66 +-- .../editors/space_view3d/view3d_gizmo_camera.c | 180 +++---- .../editors/space_view3d/view3d_gizmo_empty.c | 80 +-- .../editors/space_view3d/view3d_gizmo_forcefield.c | 54 +- .../editors/space_view3d/view3d_gizmo_lamp.c | 148 +++--- .../editors/space_view3d/view3d_gizmo_navigate.c | 138 ++--- .../space_view3d/view3d_gizmo_navigate_type.c | 74 +-- .../editors/space_view3d/view3d_gizmo_ruler.c | 162 +++--- .../blender/editors/space_view3d/view3d_intern.h | 26 +- source/blender/editors/transform/transform.h | 2 +- .../blender/editors/transform/transform_generics.c | 6 +- .../blender/editors/transform/transform_gizmo_2d.c | 28 +- .../blender/editors/transform/transform_gizmo_3d.c | 172 +++---- source/blender/makesdna/DNA_view3d_types.h | 2 +- source/blender/makesrna/intern/rna_space.c | 8 +- source/blender/makesrna/intern/rna_wm_api.c | 20 +- source/blender/makesrna/intern/rna_wm_gizmo.c | 389 +++++++------- source/blender/makesrna/intern/rna_wm_gizmo_api.c | 66 +-- source/blender/python/intern/bpy_gizmo_wrap.c | 56 +- source/blender/python/intern/bpy_gizmo_wrap.h | 4 +- source/blender/python/intern/bpy_rna_gizmo.c | 94 ++-- source/blender/windowmanager/gizmo/WM_gizmo_api.h | 192 +++---- .../blender/windowmanager/gizmo/WM_gizmo_types.h | 6 +- .../blender/windowmanager/gizmo/intern/wm_gizmo.c | 352 ++++++------- .../windowmanager/gizmo/intern/wm_gizmo_group.c | 422 +++++++-------- .../gizmo/intern/wm_gizmo_group_type.c | 82 +-- .../windowmanager/gizmo/intern/wm_gizmo_intern.h | 38 +- .../windowmanager/gizmo/intern/wm_gizmo_map.c | 564 ++++++++++----------- .../gizmo/intern/wm_gizmo_target_props.c | 216 ++++---- .../windowmanager/gizmo/intern/wm_gizmo_type.c | 80 +-- .../blender/windowmanager/gizmo/wm_gizmo_wmapi.h | 20 +- .../blender/windowmanager/intern/wm_event_system.c | 48 +- .../blender/windowmanager/intern/wm_toolsystem.c | 14 +- 68 files changed, 2833 insertions(+), 2832 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index dbab7c7e037..eeb47595213 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -118,7 +118,7 @@ class _defs_view3d_generic: return dict( text="Ruler", icon="ops.view3d.ruler", - widget="VIEW3D_WGT_ruler", + widget="VIEW3D_GGT_ruler", keymap=( ("view3d.ruler_add", dict(), dict(type='EVT_TWEAK_A', value='ANY')), ), @@ -133,7 +133,7 @@ class _defs_transform: text="Grab", # cursor='SCROLL_XY', icon="ops.transform.translate", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.translate", # TODO, implement as optional fallback gizmo # keymap=( @@ -147,7 +147,7 @@ class _defs_transform: text="Rotate", # cursor='SCROLL_XY', icon="ops.transform.rotate", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.rotate", # TODO, implement as optional fallback gizmo # keymap=( @@ -161,7 +161,7 @@ class _defs_transform: text="Scale", # cursor='SCROLL_XY', icon="ops.transform.resize", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", operator="transform.resize", # TODO, implement as optional fallback gizmo # keymap=( @@ -174,7 +174,7 @@ class _defs_transform: return dict( text="Scale Cage", icon="ops.transform.resize.cage", - widget="VIEW3D_WGT_xform_cage", + widget="VIEW3D_GGT_xform_cage", operator="transform.resize", ) @@ -187,7 +187,7 @@ class _defs_transform: return dict( text="Transform", icon="ops.transform.transform", - widget="TRANSFORM_WGT_gizmo", + widget="TRANSFORM_GGT_gizmo", # No keymap default action, only for gizmo! draw_settings=draw_settings, ) @@ -462,7 +462,7 @@ class _defs_edit_mesh: return dict( text="Extrude Region", icon="ops.mesh.extrude_region_move", - widget="MESH_WGT_extrude", + widget="MESH_GGT_extrude", operator="view3d.edit_mesh_extrude_move_normal", keymap=( ("mesh.extrude_context_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)), diff --git a/release/scripts/templates_py/gizmo_custom_geometry.py b/release/scripts/templates_py/gizmo_custom_geometry.py index f71237f52f7..8125498fa85 100644 --- a/release/scripts/templates_py/gizmo_custom_geometry.py +++ b/release/scripts/templates_py/gizmo_custom_geometry.py @@ -63,7 +63,7 @@ custom_shape_verts = ( class MyCustomShapeWidget(Gizmo): - bl_idname = "VIEW3D_WT_auto_facemap" + bl_idname = "VIEW3D_GT_auto_facemap" bl_target_properties = ( {"id": "offset", "type": 'FLOAT', "array_length": 1}, ) @@ -113,7 +113,7 @@ class MyCustomShapeWidget(Gizmo): class MyCustomShapeWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_light_test" + bl_idname = "OBJECT_GGT_light_test" bl_label = "Test Light Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' diff --git a/release/scripts/templates_py/gizmo_operator.py b/release/scripts/templates_py/gizmo_operator.py index 3cbb0801e9c..bdc1bc9893c 100644 --- a/release/scripts/templates_py/gizmo_operator.py +++ b/release/scripts/templates_py/gizmo_operator.py @@ -80,7 +80,7 @@ class SelectSideOfPlane(Operator): # Gizmos for plane_co, plane_no class SelectSideOfPlaneGizmoGroup(GizmoGroup): - bl_idname = "MESH_WGT_select_side_of_plane" + bl_idname = "MESH_GGT_select_side_of_plane" bl_label = "Side of Plane Gizmo" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -126,7 +126,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup): # XXX, this may change! op.execute(context) - mpr = self.gizmos.new("GIZMO_WT_grab_3d") + mpr = self.gizmos.new("GIZMO_GT_grab_3d") mpr.target_set_handler("offset", get=grab_get_cb, set=grab_set_cb) mpr.use_draw_value = True @@ -161,7 +161,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup): op.plane_no = no op.execute(context) - mpr = self.gizmos.new("GIZMO_WT_dial_3d") + mpr = self.gizmos.new("GIZMO_GT_dial_3d") mpr.target_set_handler("offset", get=direction_get_cb, set=direction_set_cb) mpr.draw_options = {'ANGLE_START_Y'} diff --git a/release/scripts/templates_py/gizmo_operator_target.py b/release/scripts/templates_py/gizmo_operator_target.py index 08fe63ef0b7..28465ad2fa5 100644 --- a/release/scripts/templates_py/gizmo_operator_target.py +++ b/release/scripts/templates_py/gizmo_operator_target.py @@ -10,7 +10,7 @@ from bpy.types import ( class MyCameraWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_test_camera" + bl_idname = "OBJECT_GGT_test_camera" bl_label = "Object Camera Test Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -24,7 +24,7 @@ class MyCameraWidgetGroup(GizmoGroup): def setup(self, context): # Run an operator using the dial gizmo ob = context.object - mpr = self.gizmos.new("GIZMO_WT_dial_3d") + mpr = self.gizmos.new("GIZMO_GGT_dial_3d") props = mpr.target_set_operator("transform.rotate") props.constraint_axis = False, False, True props.constraint_orientation = 'LOCAL' diff --git a/release/scripts/templates_py/gizmo_simple.py b/release/scripts/templates_py/gizmo_simple.py index 0fd1e0b386b..df80acea0ae 100644 --- a/release/scripts/templates_py/gizmo_simple.py +++ b/release/scripts/templates_py/gizmo_simple.py @@ -11,7 +11,7 @@ from bpy.types import ( class MyLightWidgetGroup(GizmoGroup): - bl_idname = "OBJECT_WGT_light_test" + bl_idname = "OBJECT_GGT_light_test" bl_label = "Test Light Widget" bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -25,7 +25,7 @@ class MyLightWidgetGroup(GizmoGroup): def setup(self, context): # Arrow gizmo has one 'offset' property we can assign to the light energy. ob = context.object - mpr = self.gizmos.new("GIZMO_WT_arrow_3d") + mpr = self.gizmos.new("GIZMO_GGT_arrow_3d") mpr.target_set_prop("offset", ob.data, "energy") mpr.matrix_basis = ob.matrix_world.normalized() mpr.draw_style = 'BOX' diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 6703d828bf0..9f57859d318 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -185,7 +185,7 @@ void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */ void CTX_wm_area_set(bContext *C, struct ScrArea *sa); void CTX_wm_region_set(bContext *C, struct ARegion *region); void CTX_wm_menu_set(bContext *C, struct ARegion *menu); -void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *mgroup); +void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup); const char *CTX_wm_operator_poll_msg_get(struct bContext *C); void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 68a1e607517..3dfe9732062 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -876,9 +876,9 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu) C->wm.menu = menu; } -void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *mgroup) +void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup) { - C->wm.gizmo_group = mgroup; + C->wm.gizmo_group = gzgroup; } void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 98d6f167d30..a16d0bab104 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1440,7 +1440,7 @@ void DRW_draw_render_loop_ex( if (DST.draw_ctx.evil_C) { /* needed so gizmo isn't obscured */ if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - ((v3d->mpr_flag & V3D_GIZMO_HIDE) == 0)) + ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) { glDisable(GL_DEPTH_TEST); DRW_draw_gizmo_3d(); diff --git a/source/blender/editors/gizmo_library/gizmo_library_intern.h b/source/blender/editors/gizmo_library/gizmo_library_intern.h index f1689ee93db..f5584d86847 100644 --- a/source/blender/editors/gizmo_library/gizmo_library_intern.h +++ b/source/blender/editors/gizmo_library/gizmo_library_intern.h @@ -76,25 +76,25 @@ float gizmo_value_from_offset( const bool constrained, const bool inverted, const bool use_precision); void gizmo_property_data_update( - struct wmGizmo *mpr, GizmoCommonData *data, wmGizmoProperty *mpr_prop, + struct wmGizmo *gz, GizmoCommonData *data, wmGizmoProperty *gz_prop, const bool constrained, const bool inverted); void gizmo_property_value_reset( - bContext *C, const struct wmGizmo *mpr, GizmoInteraction *inter, wmGizmoProperty *mpr_prop); + bContext *C, const struct wmGizmo *gz, GizmoInteraction *inter, wmGizmoProperty *gz_prop); /* -------------------------------------------------------------------- */ void gizmo_color_get( - const struct wmGizmo *mpr, const bool highlight, + const struct wmGizmo *gz, const bool highlight, float r_color[4]); bool gizmo_window_project_2d( - bContext *C, const struct wmGizmo *mpr, const float mval[2], int axis, bool use_offset, + bContext *C, const struct wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2]); bool gizmo_window_project_3d( - bContext *C, const struct wmGizmo *mpr, const float mval[2], bool use_offset, + bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3]); /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c index 8a6b92e48d6..e16f8ed21bf 100644 --- a/source/blender/editors/gizmo_library/gizmo_library_presets.c +++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c @@ -81,14 +81,14 @@ static void single_axis_convert( * Use for all geometry. */ static void ed_gizmo_draw_preset_geometry( - const struct wmGizmo *mpr, float mat[4][4], int select_id, + const struct wmGizmo *gz, float mat[4][4], int select_id, const GizmoGeomInfo *info) { const bool is_select = (select_id != -1); - const bool is_highlight = is_select && (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; float color[4]; - gizmo_color_get(mpr, is_highlight, color); + gizmo_color_get(gz, is_highlight, color); if (is_select) { GPU_select_load_id(select_id); @@ -105,35 +105,35 @@ static void ed_gizmo_draw_preset_geometry( } void ED_gizmo_draw_preset_box( - const struct wmGizmo *mpr, float mat[4][4], int select_id) + const struct wmGizmo *gz, float mat[4][4], int select_id) { - ed_gizmo_draw_preset_geometry(mpr, mat, select_id, &wm_gizmo_geom_data_cube); + ed_gizmo_draw_preset_geometry(gz, mat, select_id, &wm_gizmo_geom_data_cube); } void ED_gizmo_draw_preset_arrow( - const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id) + const struct wmGizmo *gz, float mat[4][4], int axis, int select_id) { float mat_rotate[4][4]; single_axis_convert(OB_POSZ, mat, axis, mat_rotate); - ed_gizmo_draw_preset_geometry(mpr, mat_rotate, select_id, &wm_gizmo_geom_data_arrow); + ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_arrow); } void ED_gizmo_draw_preset_circle( - const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id) + const struct wmGizmo *gz, float mat[4][4], int axis, int select_id) { float mat_rotate[4][4]; single_axis_convert(OB_POSZ, mat, axis, mat_rotate); - ed_gizmo_draw_preset_geometry(mpr, mat_rotate, select_id, &wm_gizmo_geom_data_dial); + ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_dial); } void ED_gizmo_draw_preset_facemap( - const bContext *C, const struct wmGizmo *mpr, struct Scene *scene, Object *ob, const int facemap, int select_id) + const bContext *C, const struct wmGizmo *gz, struct Scene *scene, Object *ob, const int facemap, int select_id) { const bool is_select = (select_id != -1); - const bool is_highlight = is_select && (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; float color[4]; - gizmo_color_get(mpr, is_highlight, color); + gizmo_color_get(gz, is_highlight, color); if (is_select) { GPU_select_load_id(select_id); diff --git a/source/blender/editors/gizmo_library/gizmo_library_utils.c b/source/blender/editors/gizmo_library/gizmo_library_utils.c index 6e6bc2ed824..07c230c5503 100644 --- a/source/blender/editors/gizmo_library/gizmo_library_utils.c +++ b/source/blender/editors/gizmo_library/gizmo_library_utils.c @@ -107,13 +107,13 @@ float gizmo_value_from_offset( } void gizmo_property_data_update( - wmGizmo *mpr, GizmoCommonData *data, wmGizmoProperty *mpr_prop, + wmGizmo *gz, GizmoCommonData *data, wmGizmoProperty *gz_prop, const bool constrained, const bool inverted) { - if (mpr_prop->custom_func.value_get_fn != NULL) { + if (gz_prop->custom_func.value_get_fn != NULL) { /* pass */ } - else if (mpr_prop->prop != NULL) { + else if (gz_prop->prop != NULL) { /* pass */ } else { @@ -121,12 +121,12 @@ void gizmo_property_data_update( return; } - float value = WM_gizmo_target_property_value_get(mpr, mpr_prop); + float value = WM_gizmo_target_property_value_get(gz, gz_prop); if (constrained) { if ((data->flag & GIZMO_CUSTOM_RANGE_SET) == 0) { float range[2]; - if (WM_gizmo_target_property_range_get(mpr, mpr_prop, range)) { + if (WM_gizmo_target_property_range_get(gz, gz_prop, range)) { data->range = range[1] - range[0]; data->min = range[0]; } @@ -142,23 +142,23 @@ void gizmo_property_data_update( } void gizmo_property_value_reset( - bContext *C, const wmGizmo *mpr, GizmoInteraction *inter, - wmGizmoProperty *mpr_prop) + bContext *C, const wmGizmo *gz, GizmoInteraction *inter, + wmGizmoProperty *gz_prop) { - WM_gizmo_target_property_value_set(C, mpr, mpr_prop, inter->init_value); + WM_gizmo_target_property_value_set(C, gz, gz_prop, inter->init_value); } /* -------------------------------------------------------------------- */ void gizmo_color_get( - const wmGizmo *mpr, const bool highlight, + const wmGizmo *gz, const bool highlight, float r_col[4]) { - if (highlight && !(mpr->flag & WM_GIZMO_DRAW_HOVER)) { - copy_v4_v4(r_col, mpr->color_hi); + if (highlight && !(gz->flag & WM_GIZMO_DRAW_HOVER)) { + copy_v4_v4(r_col, gz->color_hi); } else { - copy_v4_v4(r_col, mpr->color); + copy_v4_v4(r_col, gz->color); } } @@ -169,7 +169,7 @@ void gizmo_color_get( * Both 2D & 3D supported, use so we can use 2D gizmos in the 3D view. */ bool gizmo_window_project_2d( - bContext *C, const struct wmGizmo *mpr, const float mval[2], int axis, bool use_offset, + bContext *C, const struct wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2]) { float mat[4][4]; @@ -180,11 +180,11 @@ bool gizmo_window_project_2d( unit_m4(mat_identity); params.matrix_offset = mat_identity; } - WM_gizmo_calc_matrix_final_params(mpr, ¶ms, mat); + WM_gizmo_calc_matrix_final_params(gz, ¶ms, mat); } /* rotate mouse in relation to the center and relocate it */ - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { /* For 3d views, transform 2D mouse pos onto plane. */ View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); @@ -221,7 +221,7 @@ bool gizmo_window_project_2d( } bool gizmo_window_project_3d( - bContext *C, const struct wmGizmo *mpr, const float mval[2], bool use_offset, + bContext *C, const struct wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3]) { float mat[4][4]; @@ -232,10 +232,10 @@ bool gizmo_window_project_3d( unit_m4(mat_identity); params.matrix_offset = mat_identity; } - WM_gizmo_calc_matrix_final_params(mpr, ¶ms, mat); + WM_gizmo_calc_matrix_final_params(gz, ¶ms, mat); } - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); /* Note: we might want a custom reference point passed in, diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c index dfa2eeeb38b..0faeeefb4a3 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c @@ -61,14 +61,14 @@ #include "../gizmo_library_intern.h" -static void arrow2d_draw_geom(wmGizmo *mpr, const float matrix[4][4], const float color[4]) +static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float color[4]) { const float size = 0.11f; const float size_breadth = size / 2.0f; const float size_length = size * 1.7f; /* Subtract the length so the arrow fits in the hotspot. */ - const float arrow_length = RNA_float_get(mpr->ptr, "length") - size_length; - const float arrow_angle = RNA_float_get(mpr->ptr, "angle"); + const float arrow_length = RNA_float_get(gz->ptr, "length") - size_length; + const float arrow_angle = RNA_float_get(gz->ptr, "angle"); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -96,60 +96,60 @@ static void arrow2d_draw_geom(wmGizmo *mpr, const float matrix[4][4], const floa gpuPopMatrix(); } -static void gizmo_arrow2d_draw(const bContext *UNUSED(C), wmGizmo *mpr) +static void gizmo_arrow2d_draw(const bContext *UNUSED(C), wmGizmo *gz) { float color[4]; float matrix_final[4][4]; - gizmo_color_get(mpr, mpr->state & WM_GIZMO_STATE_HIGHLIGHT, color); + gizmo_color_get(gz, gz->state & WM_GIZMO_STATE_HIGHLIGHT, color); - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); - WM_gizmo_calc_matrix_final(mpr, matrix_final); + WM_gizmo_calc_matrix_final(gz, matrix_final); GPU_blend(true); - arrow2d_draw_geom(mpr, matrix_final, color); + arrow2d_draw_geom(gz, matrix_final, color); GPU_blend(false); - if (mpr->interaction_data) { - GizmoInteraction *inter = mpr->interaction_data; + if (gz->interaction_data) { + GizmoInteraction *inter = gz->interaction_data; GPU_blend(true); - arrow2d_draw_geom(mpr, inter->init_matrix_final, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}); + arrow2d_draw_geom(gz, inter->init_matrix_final, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}); GPU_blend(false); } } -static void gizmo_arrow2d_setup(wmGizmo *mpr) +static void gizmo_arrow2d_setup(wmGizmo *gz) { - mpr->flag |= WM_GIZMO_DRAW_MODAL; + gz->flag |= WM_GIZMO_DRAW_MODAL; } static int gizmo_arrow2d_invoke( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *UNUSED(event)) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event)) { GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__); - copy_m4_m4(inter->init_matrix_basis, mpr->matrix_basis); - WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final); + copy_m4_m4(inter->init_matrix_basis, gz->matrix_basis); + WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final); - mpr->interaction_data = inter; + gz->interaction_data = inter; return OPERATOR_RUNNING_MODAL; } static int gizmo_arrow2d_test_select( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { const float mval[2] = {event->mval[0], event->mval[1]}; - const float arrow_length = RNA_float_get(mpr->ptr, "length"); - const float arrow_angle = RNA_float_get(mpr->ptr, "angle"); - const float line_len = arrow_length * mpr->scale_final; + const float arrow_length = RNA_float_get(gz->ptr, "length"); + const float arrow_angle = RNA_float_get(gz->ptr, "angle"); + const float line_len = arrow_length * gz->scale_final; float mval_local[2]; copy_v2_v2(mval_local, mval); - sub_v2_v2(mval_local, mpr->matrix_basis[3]); + sub_v2_v2(mval_local, gz->matrix_basis[3]); float line[2][2]; line[0][0] = line[0][1] = line[1][0] = 0.0f; @@ -165,7 +165,7 @@ static int gizmo_arrow2d_test_select( /* arrow line intersection check */ float isect_1[2], isect_2[2]; const int isect = isect_line_sphere_v2( - line[0], line[1], mval_local, GIZMO_HOTSPOT + mpr->line_width * 0.5f, + line[0], line[1], mval_local, GIZMO_HOTSPOT + gz->line_width * 0.5f, isect_1, isect_2); if (isect > 0) { @@ -197,29 +197,29 @@ static int gizmo_arrow2d_test_select( * * \{ */ -static void GIZMO_WT_arrow_2d(wmGizmoType *wt) +static void GIZMO_GT_arrow_2d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_arrow_2d"; + gzt->idname = "GIZMO_GT_arrow_2d"; /* api callbacks */ - wt->draw = gizmo_arrow2d_draw; - wt->setup = gizmo_arrow2d_setup; - wt->invoke = gizmo_arrow2d_invoke; - wt->test_select = gizmo_arrow2d_test_select; + gzt->draw = gizmo_arrow2d_draw; + gzt->setup = gizmo_arrow2d_setup; + gzt->invoke = gizmo_arrow2d_invoke; + gzt->test_select = gizmo_arrow2d_test_select; - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); /* rna */ - RNA_def_float(wt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX); + RNA_def_float(gzt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX); RNA_def_float_rotation( - wt->srna, "angle", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f), + gzt->srna, "angle", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f), "Roll", "", DEG2RADF(-360.0f), DEG2RADF(360.0f)); } void ED_gizmotypes_arrow_2d(void) { - WM_gizmotype_append(GIZMO_WT_arrow_2d); + WM_gizmotype_append(GIZMO_GT_arrow_2d); } /** \} */ diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index 9807a111d26..09c6485c29e 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -80,9 +80,9 @@ typedef struct ArrowGizmo3D { /* -------------------------------------------------------------------- */ -static void gizmo_arrow_matrix_basis_get(const wmGizmo *mpr, float r_matrix[4][4]) +static void gizmo_arrow_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4]) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; copy_m4_m4(r_matrix, arrow->gizmo.matrix_basis); madd_v3_v3fl(r_matrix[3], arrow->gizmo.matrix_basis[2], arrow->data.offset); @@ -182,13 +182,13 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool highlight) { - wmGizmo *mpr = &arrow->gizmo; + wmGizmo *gz = &arrow->gizmo; float color[4]; float matrix_final[4][4]; - gizmo_color_get(mpr, highlight, color); + gizmo_color_get(gz, highlight, color); - WM_gizmo_calc_matrix_final(mpr, matrix_final); + WM_gizmo_calc_matrix_final(gz, matrix_final); gpuPushMatrix(); gpuMultMatrix(matrix_final); @@ -198,8 +198,8 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool gpuPopMatrix(); - if (mpr->interaction_data) { - GizmoInteraction *inter = mpr->interaction_data; + if (gz->interaction_data) { + GizmoInteraction *inter = gz->interaction_data; gpuPushMatrix(); gpuMultMatrix(inter->init_matrix_final); @@ -214,16 +214,16 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool } static void gizmo_arrow_draw_select( - const bContext *UNUSED(C), wmGizmo *mpr, + const bContext *UNUSED(C), wmGizmo *gz, int select_id) { GPU_select_load_id(select_id); - arrow_draw_intern((ArrowGizmo3D *)mpr, true, false); + arrow_draw_intern((ArrowGizmo3D *)gz, true, false); } -static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *mpr) +static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *gz) { - arrow_draw_intern((ArrowGizmo3D *)mpr, false, (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0); + arrow_draw_intern((ArrowGizmo3D *)gz, false, (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0); } /** @@ -231,11 +231,11 @@ static void gizmo_arrow_draw(const bContext *UNUSED(C), wmGizmo *mpr) * meaning the range will not be offset by min value first. */ static int gizmo_arrow_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; - GizmoInteraction *inter = mpr->interaction_data; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; + GizmoInteraction *inter = gz->interaction_data; View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; @@ -299,19 +299,19 @@ static int gizmo_arrow_modal( GizmoCommonData *data = &arrow->data; const float ofs_new = facdir * len_v3(offset); - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); /* set the property for the operator and call its modal function */ - if (WM_gizmo_target_property_is_valid(mpr_prop)) { + if (WM_gizmo_target_property_is_valid(gz_prop)) { const int transform_flag = RNA_enum_get(arrow->gizmo.ptr, "transform"); const bool constrained = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED) != 0; const bool inverted = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_INVERTED) != 0; const bool use_precision = (tweak_flag & WM_GIZMO_TWEAK_PRECISE) != 0; float value = gizmo_value_from_offset(data, inter, ofs_new, constrained, inverted, use_precision); - WM_gizmo_target_property_value_set(C, mpr, mpr_prop, value); + WM_gizmo_target_property_value_set(C, gz, gz_prop, value); /* get clamped value */ - value = WM_gizmo_target_property_value_get(mpr, mpr_prop); + value = WM_gizmo_target_property_value_get(gz, gz_prop); data->offset = gizmo_offset_from_value(data, value, constrained, inverted); } @@ -326,9 +326,9 @@ static int gizmo_arrow_modal( return OPERATOR_RUNNING_MODAL; } -static void gizmo_arrow_setup(wmGizmo *mpr) +static void gizmo_arrow_setup(wmGizmo *gz) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; arrow->gizmo.flag |= WM_GIZMO_DRAW_MODAL; @@ -336,15 +336,15 @@ static void gizmo_arrow_setup(wmGizmo *mpr) } static int gizmo_arrow_invoke( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__); - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); /* Some gizmos don't use properties. */ - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - inter->init_value = WM_gizmo_target_property_value_get(mpr, mpr_prop); + if (WM_gizmo_target_property_is_valid(gz_prop)) { + inter->init_value = WM_gizmo_target_property_value_get(gz, gz_prop); } inter->init_offset = arrow->data.offset; @@ -352,42 +352,42 @@ static int gizmo_arrow_invoke( inter->init_mval[0] = event->mval[0]; inter->init_mval[1] = event->mval[1]; - gizmo_arrow_matrix_basis_get(mpr, inter->init_matrix_basis); - WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final); + gizmo_arrow_matrix_basis_get(gz, inter->init_matrix_basis); + WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final); - mpr->interaction_data = inter; + gz->interaction_data = inter; return OPERATOR_RUNNING_MODAL; } -static void gizmo_arrow_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop) +static void gizmo_arrow_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; const int transform_flag = RNA_enum_get(arrow->gizmo.ptr, "transform"); const bool constrained = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED) != 0; const bool inverted = (transform_flag & ED_GIZMO_ARROW_XFORM_FLAG_INVERTED) != 0; - gizmo_property_data_update(mpr, &arrow->data, mpr_prop, constrained, inverted); + gizmo_property_data_update(gz, &arrow->data, gz_prop, constrained, inverted); } -static void gizmo_arrow_exit(bContext *C, wmGizmo *mpr, const bool cancel) +static void gizmo_arrow_exit(bContext *C, wmGizmo *gz, const bool cancel) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; GizmoCommonData *data = &arrow->data; - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); - const bool is_prop_valid = WM_gizmo_target_property_is_valid(mpr_prop); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); + const bool is_prop_valid = WM_gizmo_target_property_is_valid(gz_prop); if (!cancel) { /* Assign incase applying the opetration needs an updated offset * editmesh bisect needs this. */ if (is_prop_valid) { - data->offset = WM_gizmo_target_property_value_get(mpr, mpr_prop); + data->offset = WM_gizmo_target_property_value_get(gz, gz_prop); } return; } - GizmoInteraction *inter = mpr->interaction_data; + GizmoInteraction *inter = gz->interaction_data; if (is_prop_valid) { - gizmo_property_value_reset(C, mpr, inter, mpr_prop); + gizmo_property_value_reset(C, gz, inter, gz_prop); } data->offset = inter->init_offset; } @@ -403,12 +403,12 @@ static void gizmo_arrow_exit(bContext *C, wmGizmo *mpr, const bool cancel) * * \note Needs to be called before WM_gizmo_target_property_def_rna! */ -void ED_gizmo_arrow3d_set_ui_range(wmGizmo *mpr, const float min, const float max) +void ED_gizmo_arrow3d_set_ui_range(wmGizmo *gz, const float min, const float max) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; BLI_assert(min < max); - BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(mpr, "offset")) && + BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(gz, "offset")) && "Make sure this function is called before WM_gizmo_target_property_def_rna")); arrow->data.range = max - min; @@ -421,31 +421,31 @@ void ED_gizmo_arrow3d_set_ui_range(wmGizmo *mpr, const float min, const float ma * * \note Needs to be called before WM_gizmo_target_property_def_rna! */ -void ED_gizmo_arrow3d_set_range_fac(wmGizmo *mpr, const float range_fac) +void ED_gizmo_arrow3d_set_range_fac(wmGizmo *gz, const float range_fac) { - ArrowGizmo3D *arrow = (ArrowGizmo3D *)mpr; - BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(mpr, "offset")) && + ArrowGizmo3D *arrow = (ArrowGizmo3D *)gz; + BLI_assert(!(WM_gizmo_target_property_is_valid(WM_gizmo_target_property_find(gz, "offset")) && "Make sure this function is called before WM_gizmo_target_property_def_rna")); arrow->data.range_fac = range_fac; } -static void GIZMO_WT_arrow_3d(wmGizmoType *wt) +static void GIZMO_GT_arrow_3d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_arrow_3d"; + gzt->idname = "GIZMO_GT_arrow_3d"; /* api callbacks */ - wt->draw = gizmo_arrow_draw; - wt->draw_select = gizmo_arrow_draw_select; - wt->matrix_basis_get = gizmo_arrow_matrix_basis_get; - wt->modal = gizmo_arrow_modal; - wt->setup = gizmo_arrow_setup; - wt->invoke = gizmo_arrow_invoke; - wt->property_update = gizmo_arrow_property_update; - wt->exit = gizmo_arrow_exit; + gzt->draw = gizmo_arrow_draw; + gzt->draw_select = gizmo_arrow_draw_select; + gzt->matrix_basis_get = gizmo_arrow_matrix_basis_get; + gzt->modal = gizmo_arrow_modal; + gzt->setup = gizmo_arrow_setup; + gzt->invoke = gizmo_arrow_invoke; + gzt->property_update = gizmo_arrow_property_update; + gzt->exit = gizmo_arrow_exit; - wt->struct_size = sizeof(ArrowGizmo3D); + gzt->struct_size = sizeof(ArrowGizmo3D); /* rna */ static EnumPropertyItem rna_enum_draw_style_items[] = { @@ -466,27 +466,27 @@ static void GIZMO_WT_arrow_3d(wmGizmoType *wt) }; RNA_def_enum( - wt->srna, "draw_style", rna_enum_draw_style_items, + gzt->srna, "draw_style", rna_enum_draw_style_items, ED_GIZMO_ARROW_STYLE_NORMAL, "Draw Style", ""); RNA_def_enum_flag( - wt->srna, "draw_options", rna_enum_draw_options_items, + gzt->srna, "draw_options", rna_enum_draw_options_items, ED_GIZMO_ARROW_DRAW_FLAG_STEM, "Draw Options", ""); RNA_def_enum_flag( - wt->srna, "transform", rna_enum_transform_items, + gzt->srna, "transform", rna_enum_transform_items, 0, "Transform", ""); - RNA_def_float(wt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX); - RNA_def_float_vector(wt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX); + RNA_def_float(gzt->srna, "length", 1.0f, 0.0f, FLT_MAX, "Arrow Line Length", "", 0.0f, FLT_MAX); + RNA_def_float_vector(gzt->srna, "aspect", 2, NULL, 0, FLT_MAX, "Aspect", "Cone/box style only", 0.0f, FLT_MAX); - WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 1); + WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 1); } void ED_gizmotypes_arrow_3d(void) { - WM_gizmotype_append(GIZMO_WT_arrow_3d); + WM_gizmotype_append(GIZMO_GT_arrow_3d); } /** \} */ diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index ede070f0bed..dfe2c8b2413 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -80,9 +80,9 @@ typedef struct ButtonGizmo2D { /* -------------------------------------------------------------------- */ static void button2d_geom_draw_backdrop( - const wmGizmo *mpr, const float color[4], const bool select) + const wmGizmo *gz, const float color[4], const bool select) { - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); Gwn_VertFormat *format = immVertexFormat(); uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -100,24 +100,24 @@ static void button2d_geom_draw_backdrop( } static void button2d_draw_intern( - const bContext *C, wmGizmo *mpr, + const bContext *C, wmGizmo *gz, const bool select, const bool highlight) { - ButtonGizmo2D *button = (ButtonGizmo2D *)mpr; + ButtonGizmo2D *button = (ButtonGizmo2D *)gz; - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); if (button->is_init == false) { button->is_init = true; - PropertyRNA *prop = RNA_struct_find_property(mpr->ptr, "icon"); - if (RNA_property_is_set(mpr->ptr, prop)) { - button->icon = RNA_property_enum_get(mpr->ptr, prop); + PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "icon"); + if (RNA_property_is_set(gz->ptr, prop)) { + button->icon = RNA_property_enum_get(gz->ptr, prop); } else { - prop = RNA_struct_find_property(mpr->ptr, "shape"); - const uint polys_len = RNA_property_string_length(mpr->ptr, prop); + prop = RNA_struct_find_property(gz->ptr, "shape"); + const uint polys_len = RNA_property_string_length(gz->ptr, prop); /* We shouldn't need the +1, but a NULL char is set. */ char *polys = MEM_mallocN(polys_len + 1, __func__); - RNA_property_string_get(mpr->ptr, prop, polys); + RNA_property_string_get(gz->ptr, prop, polys); button->shape_batch[0] = GPU_batch_tris_from_poly_2d_encoded((uchar *)polys, polys_len, NULL); button->shape_batch[1] = GPU_batch_wire_from_poly_2d_encoded((uchar *)polys, polys_len, NULL); MEM_freeN(polys); @@ -127,20 +127,20 @@ static void button2d_draw_intern( float color[4]; float matrix_final[4][4]; - gizmo_color_get(mpr, highlight, color); - WM_gizmo_calc_matrix_final(mpr, matrix_final); + gizmo_color_get(gz, highlight, color); + WM_gizmo_calc_matrix_final(gz, matrix_final); - bool is_3d = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0; + bool is_3d = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) != 0; if (draw_options & ED_GIZMO_BUTTON_SHOW_HELPLINE) { float matrix_final_no_offset[4][4]; - WM_gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset); + WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(color); - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); immUniformColor4fv(color); immBegin(GWN_PRIM_LINE_STRIP, 2); immVertex3fv(pos, matrix_final[3]); @@ -166,7 +166,7 @@ static void button2d_draw_intern( if (select) { BLI_assert(is_3d); - button2d_geom_draw_backdrop(mpr, color, select); + button2d_geom_draw_backdrop(gz, color, select); } else { @@ -191,7 +191,7 @@ static void button2d_draw_intern( GPU_polygon_smooth(true); } else if (button->icon != ICON_NONE) { - button2d_geom_draw_backdrop(mpr, color, select); + button2d_geom_draw_backdrop(gz, color, select); float size[2]; if (is_3d) { const float fac = 2.0f; @@ -201,8 +201,8 @@ static void button2d_draw_intern( size[1] = 1.0f; } else { - size[0] = mpr->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * UI_DPI_FAC; - size[1] = mpr->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * UI_DPI_FAC; + size[0] = gz->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * UI_DPI_FAC; + size[1] = gz->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * UI_DPI_FAC; gpuPopMatrix(); need_to_pop = false; } @@ -216,40 +216,40 @@ static void button2d_draw_intern( } } -static void gizmo_button2d_draw_select(const bContext *C, wmGizmo *mpr, int select_id) +static void gizmo_button2d_draw_select(const bContext *C, wmGizmo *gz, int select_id) { GPU_select_load_id(select_id); - button2d_draw_intern(C, mpr, true, false); + button2d_draw_intern(C, gz, true, false); } -static void gizmo_button2d_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz) { - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; GPU_blend(true); - button2d_draw_intern(C, mpr, false, is_highlight); + button2d_draw_intern(C, gz, false, is_highlight); GPU_blend(false); } static int gizmo_button2d_test_select( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { float point_local[2]; if (0) { /* correct, but unnecessarily slow. */ if (gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) { return -1; } } else { copy_v2_v2(point_local, (float[2]){UNPACK2(event->mval)}); - sub_v2_v2(point_local, mpr->matrix_basis[3]); - mul_v2_fl(point_local, 1.0f / (mpr->scale_basis * UI_DPI_FAC)); + sub_v2_v2(point_local, gz->matrix_basis[3]); + mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC)); } - /* The 'mpr->scale_final' is already applied when projecting. */ + /* The 'gz->scale_final' is already applied when projecting. */ if (len_squared_v2(point_local) < 1.0f) { return 0; } @@ -257,17 +257,17 @@ static int gizmo_button2d_test_select( return -1; } -static int gizmo_button2d_cursor_get(wmGizmo *mpr) +static int gizmo_button2d_cursor_get(wmGizmo *gz) { - if (RNA_boolean_get(mpr->ptr, "show_drag")) { + if (RNA_boolean_get(gz->ptr, "show_drag")) { return BC_NSEW_SCROLLCURSOR; } return CURSOR_STD; } -static void gizmo_button2d_free(wmGizmo *mpr) +static void gizmo_button2d_free(wmGizmo *gz) { - ButtonGizmo2D *shape = (ButtonGizmo2D *)mpr; + ButtonGizmo2D *shape = (ButtonGizmo2D *)gz; for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) { GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]); @@ -281,19 +281,19 @@ static void gizmo_button2d_free(wmGizmo *mpr) * * \{ */ -static void GIZMO_WT_button_2d(wmGizmoType *wt) +static void GIZMO_GT_button_2d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_button_2d"; + gzt->idname = "GIZMO_GT_button_2d"; /* api callbacks */ - wt->draw = gizmo_button2d_draw; - wt->draw_select = gizmo_button2d_draw_select; - wt->test_select = gizmo_button2d_test_select; - wt->cursor_get = gizmo_button2d_cursor_get; - wt->free = gizmo_button2d_free; + gzt->draw = gizmo_button2d_draw; + gzt->draw_select = gizmo_button2d_draw_select; + gzt->test_select = gizmo_button2d_test_select; + gzt->cursor_get = gizmo_button2d_cursor_get; + gzt->free = gizmo_button2d_free; - wt->struct_size = sizeof(ButtonGizmo2D); + gzt->struct_size = sizeof(ButtonGizmo2D); /* rna */ static EnumPropertyItem rna_enum_draw_options[] = { @@ -303,21 +303,21 @@ static void GIZMO_WT_button_2d(wmGizmoType *wt) }; PropertyRNA *prop; - RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); + RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); - prop = RNA_def_property(wt->srna, "icon", PROP_ENUM, PROP_NONE); + prop = RNA_def_property(gzt->srna, "icon", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_icon_items); /* Passed to 'GPU_batch_tris_from_poly_2d_encoded' */ - RNA_def_property(wt->srna, "shape", PROP_STRING, PROP_BYTESTRING); + RNA_def_property(gzt->srna, "shape", PROP_STRING, PROP_BYTESTRING); /* Currently only used for cursor display. */ - RNA_def_boolean(wt->srna, "show_drag", true, "Show Drag", ""); + RNA_def_boolean(gzt->srna, "show_drag", true, "Show Drag", ""); } void ED_gizmotypes_button_2d(void) { - WM_gizmotype_append(GIZMO_WT_button_2d); + WM_gizmotype_append(GIZMO_GT_button_2d); } /** \} */ // Button Gizmo API diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index a037727de58..8a830302f51 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -68,7 +68,7 @@ #define GIZMO_MARGIN_OFFSET_SCALE 1.5f static void gizmo_calc_rect_view_scale( - const wmGizmo *mpr, const float dims[2], float scale[2]) + const wmGizmo *gz, const float dims[2], float scale[2]) { float matrix_final_no_offset[4][4]; float asp[2] = {1.0f, 1.0f}; @@ -79,9 +79,9 @@ static void gizmo_calc_rect_view_scale( asp[1] = dims[0] / dims[1]; } float x_axis[3], y_axis[3]; - WM_gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset); - mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, mpr->matrix_offset[0]); - mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, mpr->matrix_offset[1]); + WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset); + mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]); + mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]); mul_v2_v2(x_axis, asp); mul_v2_v2(y_axis, asp); @@ -91,18 +91,18 @@ static void gizmo_calc_rect_view_scale( } static void gizmo_calc_rect_view_margin( - const wmGizmo *mpr, const float dims[2], float margin[2]) + const wmGizmo *gz, const float dims[2], float margin[2]) { float handle_size; - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { handle_size = 0.15f; } else { handle_size = GIZMO_RESIZER_SIZE; } - handle_size *= mpr->scale_final; + handle_size *= gz->scale_final; float scale_xy[2]; - gizmo_calc_rect_view_scale(mpr, dims, scale_xy); + gizmo_calc_rect_view_scale(gz, dims, scale_xy); margin[0] = ((handle_size * scale_xy[0])); margin[1] = ((handle_size * scale_xy[1])); } @@ -536,26 +536,26 @@ static void cage2d_draw_circle_handles( /** \} */ static void gizmo_cage2d_draw_intern( - wmGizmo *mpr, const bool select, const bool highlight, const int select_id) + wmGizmo *gz, const bool select, const bool highlight, const int select_id) { - // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; + // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; float dims[2]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); float matrix_final[4][4]; - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - const int draw_style = RNA_enum_get(mpr->ptr, "draw_style"); - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f}; - WM_gizmo_calc_matrix_final(mpr, matrix_final); + WM_gizmo_calc_matrix_final(gz, matrix_final); gpuPushMatrix(); gpuMultMatrix(matrix_final); float margin[2]; - gizmo_calc_rect_view_margin(mpr, dims, margin); + gizmo_calc_rect_view_margin(gz, dims, margin); /* Handy for quick testing draw (if it's outside bounds). */ if (false) { @@ -588,18 +588,18 @@ static void gizmo_cage2d_draw_intern( for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) { GPU_select_load_id(select_id | scale_parts[i]); cage2d_draw_box_interaction( - mpr->color, scale_parts[i], size, margin, mpr->line_width, true, draw_options); + gz->color, scale_parts[i], size, margin, gz->line_width, true, draw_options); } } if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { const int transform_part = ED_GIZMO_CAGE2D_PART_TRANSLATE; GPU_select_load_id(select_id | transform_part); cage2d_draw_box_interaction( - mpr->color, transform_part, size, margin, mpr->line_width, true, draw_options); + gz->color, transform_part, size, margin, gz->line_width, true, draw_options); } if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { cage2d_draw_box_interaction( - mpr->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, mpr->line_width, true, draw_options); + gz->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, gz->line_width, true, draw_options); } } else { @@ -611,17 +611,17 @@ static void gizmo_cage2d_draw_intern( }; if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) { /* corner gizmos */ - GPU_line_width(mpr->line_width + 3.0f); + GPU_line_width(gz->line_width + 3.0f); cage2d_draw_box_corners(&r, margin, (const float[3]){0, 0, 0}); /* corner gizmos */ float color[4]; - gizmo_color_get(mpr, highlight, color); - GPU_line_width(mpr->line_width); + gizmo_color_get(gz, highlight, color); + GPU_line_width(gz->line_width); cage2d_draw_box_corners(&r, margin, color); bool show = false; - if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) { + if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) { /* Only show if we're drawing the center handle * otherwise the entire rectangle is the hotspot. */ if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) { @@ -634,24 +634,24 @@ static void gizmo_cage2d_draw_intern( if (show) { cage2d_draw_box_interaction( - mpr->color, mpr->highlight_part, size_real, margin, mpr->line_width, false, draw_options); + gz->color, gz->highlight_part, size_real, margin, gz->line_width, false, draw_options); } if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { cage2d_draw_box_interaction( - mpr->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, mpr->line_width, false, draw_options); + gz->color, ED_GIZMO_CAGE2D_PART_ROTATE, size_real, margin, gz->line_width, false, draw_options); } } else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) { float color[4]; - gizmo_color_get(mpr, highlight, color); + gizmo_color_get(gz, highlight, color); GPU_line_smooth(true); GPU_blend(true); - GPU_line_width(mpr->line_width + 3.0f); + GPU_line_width(gz->line_width + 3.0f); cage2d_draw_circle_wire(&r, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options); - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options); @@ -674,22 +674,22 @@ static void gizmo_cage2d_draw_intern( /** * For when we want to draw 2d cage in 3d views. */ -static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *mpr, int select_id) +static void gizmo_cage2d_draw_select(const bContext *UNUSED(C), wmGizmo *gz, int select_id) { - gizmo_cage2d_draw_intern(mpr, true, false, select_id); + gizmo_cage2d_draw_intern(gz, true, false, select_id); } -static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *mpr) +static void gizmo_cage2d_draw(const bContext *UNUSED(C), wmGizmo *gz) { - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; - gizmo_cage2d_draw_intern(mpr, false, is_highlight, -1); + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + gizmo_cage2d_draw_intern(gz, false, is_highlight, -1); } -static int gizmo_cage2d_get_cursor(wmGizmo *mpr) +static int gizmo_cage2d_get_cursor(wmGizmo *gz) { - int highlight_part = mpr->highlight_part; + int highlight_part = gz->highlight_part; - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { return BC_NSEW_SCROLLCURSOR; } @@ -718,26 +718,26 @@ static int gizmo_cage2d_get_cursor(wmGizmo *mpr) } static int gizmo_cage2d_test_select( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { float point_local[2]; float dims[2]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f}; if (gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) { return -1; } float margin[2]; - gizmo_calc_rect_view_margin(mpr, dims, margin); + gizmo_calc_rect_view_margin(gz, dims, margin); /* expand for hotspot */ const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2}; - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { rctf r; @@ -821,32 +821,32 @@ typedef struct RectTransformInteraction { Dial *dial; } RectTransformInteraction; -static void gizmo_cage2d_setup(wmGizmo *mpr) +static void gizmo_cage2d_setup(wmGizmo *gz) { - mpr->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE; + gz->flag |= WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_NO_SCALE; } static int gizmo_cage2d_invoke( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction"); - copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset); - WM_gizmo_calc_matrix_final_no_offset(mpr, data->orig_matrix_final_no_offset); + copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset); + WM_gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset); if (gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0) + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, data->orig_mouse) == 0) { zero_v2(data->orig_mouse); } - mpr->interaction_data = data; + gz->interaction_data = data; return OPERATOR_RUNNING_MODAL; } static int gizmo_cage2d_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { /* For transform logic to be managable we operate in -0.5..0.5 2D space, @@ -856,40 +856,40 @@ static int gizmo_cage2d_modal( * - The cursor offset are multiplied by 'dims'. * - Matrix translation is also multiplied by 'dims'. */ - RectTransformInteraction *data = mpr->interaction_data; + RectTransformInteraction *data = gz->interaction_data; float point_local[2]; float dims[2]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); { float matrix_back[4][4]; - copy_m4_m4(matrix_back, mpr->matrix_offset); - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(matrix_back, gz->matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); bool ok = gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local); - copy_m4_m4(mpr->matrix_offset, matrix_back); + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, point_local); + copy_m4_m4(gz->matrix_offset, matrix_back); if (!ok) { return OPERATOR_RUNNING_MODAL; } } - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - wmGizmoProperty *mpr_prop; + const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + wmGizmoProperty *gz_prop; - mpr_prop = WM_gizmo_target_property_find(mpr, "matrix"); - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]); + gz_prop = WM_gizmo_target_property_find(gz, "matrix"); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]); } - if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) { + if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_TRANSLATE) { /* do this to prevent clamping from changing size */ - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); - mpr->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]); - mpr->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); + gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]); + gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]); } - else if (mpr->highlight_part == ED_GIZMO_CAGE2D_PART_ROTATE) { + else if (gz->highlight_part == ED_GIZMO_CAGE2D_PART_ROTATE) { #define MUL_V2_V3_M4_FINAL(test_co, mouse_co) \ mul_v3_m4v3(test_co, data->orig_matrix_final_no_offset, ((const float[3]){UNPACK2(mouse_co), 0.0})) @@ -915,28 +915,28 @@ static int gizmo_cage2d_modal( copy_v3_v3(pivot, data->orig_matrix_offset[3]); - invert_m4_m4(matrix_space_inv, mpr->matrix_space); + invert_m4_m4(matrix_space_inv, gz->matrix_space); unit_m4(matrix_rotate); mul_m4_m4m4(matrix_rotate, matrix_rotate, matrix_space_inv); rotate_m4(matrix_rotate, 'Z', -angle); - mul_m4_m4m4(matrix_rotate, matrix_rotate, mpr->matrix_space); + mul_m4_m4m4(matrix_rotate, matrix_rotate, gz->matrix_space); zero_v3(matrix_rotate[3]); transform_pivot_set_m4(matrix_rotate, pivot); - mul_m4_m4m4(mpr->matrix_offset, matrix_rotate, data->orig_matrix_offset); + mul_m4_m4m4(gz->matrix_offset, matrix_rotate, data->orig_matrix_offset); #undef MUL_V2_V3_M4_FINAL } else { /* scale */ - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); float pivot[2]; bool constrain_axis[2] = {false}; if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { - gizmo_rect_pivot_from_scale_part(mpr->highlight_part, pivot, constrain_axis); + gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis); } else { zero_v2(pivot); @@ -991,11 +991,11 @@ static int gizmo_cage2d_modal( mul_v3_fl(matrix_scale[1], scale[1]); transform_pivot_set_m4(matrix_scale, (const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], 0.0f}); - mul_m4_m4m4(mpr->matrix_offset, data->orig_matrix_offset, matrix_scale); + mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale); } - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]); } /* tag the region for redraw */ @@ -1005,11 +1005,11 @@ static int gizmo_cage2d_modal( return OPERATOR_RUNNING_MODAL; } -static void gizmo_cage2d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop) +static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop) { - if (STREQ(mpr_prop->type->idname, "matrix")) { - if (WM_gizmo_target_property_array_length(mpr, mpr_prop) == 16) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]); + if (STREQ(gz_prop->type->idname, "matrix")) { + if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]); } else { BLI_assert(0); @@ -1020,24 +1020,24 @@ static void gizmo_cage2d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop } } -static void gizmo_cage2d_exit(bContext *C, wmGizmo *mpr, const bool cancel) +static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel) { - RectTransformInteraction *data = mpr->interaction_data; + RectTransformInteraction *data = gz->interaction_data; MEM_SAFE_FREE(data->dial); if (!cancel) return; - wmGizmoProperty *mpr_prop; + wmGizmoProperty *gz_prop; /* reset properties */ - mpr_prop = WM_gizmo_target_property_find(mpr, "matrix"); - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]); + gz_prop = WM_gizmo_target_property_find(gz, "matrix"); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]); } - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); } @@ -1046,23 +1046,23 @@ static void gizmo_cage2d_exit(bContext *C, wmGizmo *mpr, const bool cancel) * * \{ */ -static void GIZMO_WT_cage_2d(wmGizmoType *wt) +static void GIZMO_GT_cage_2d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_cage_2d"; + gzt->idname = "GIZMO_GT_cage_2d"; /* api callbacks */ - wt->draw = gizmo_cage2d_draw; - wt->draw_select = gizmo_cage2d_draw_select; - wt->test_select = gizmo_cage2d_test_select; - wt->setup = gizmo_cage2d_setup; - wt->invoke = gizmo_cage2d_invoke; - wt->property_update = gizmo_cage2d_property_update; - wt->modal = gizmo_cage2d_modal; - wt->exit = gizmo_cage2d_exit; - wt->cursor_get = gizmo_cage2d_get_cursor; - - wt->struct_size = sizeof(wmGizmo); + gzt->draw = gizmo_cage2d_draw; + gzt->draw_select = gizmo_cage2d_draw_select; + gzt->test_select = gizmo_cage2d_test_select; + gzt->setup = gizmo_cage2d_setup; + gzt->invoke = gizmo_cage2d_invoke; + gzt->property_update = gizmo_cage2d_property_update; + gzt->modal = gizmo_cage2d_modal; + gzt->exit = gizmo_cage2d_exit; + gzt->cursor_get = gizmo_cage2d_get_cursor; + + gzt->struct_size = sizeof(wmGizmo); /* rna */ static EnumPropertyItem rna_enum_draw_style[] = { @@ -1082,19 +1082,19 @@ static void GIZMO_WT_cage_2d(wmGizmoType *wt) {0, NULL, 0, NULL, NULL} }; static float unit_v2[2] = {1.0f, 1.0f}; - RNA_def_float_vector(wt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); - RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); - RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", ""); + RNA_def_float_vector(gzt->srna, "dimensions", 2, unit_v2, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); + RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); + RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", ""); RNA_def_enum_flag( - wt->srna, "draw_options", rna_enum_draw_options, + gzt->srna, "draw_options", rna_enum_draw_options, ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE, "Draw Options", ""); - WM_gizmotype_target_property_def(wt, "matrix", PROP_FLOAT, 16); + WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16); } void ED_gizmotypes_cage_2d(void) { - WM_gizmotype_append(GIZMO_WT_cage_2d); + WM_gizmotype_append(GIZMO_GT_cage_2d); } /** \} */ diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index e266514855b..c3fb5a08cdb 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -67,7 +67,7 @@ #define GIZMO_MARGIN_OFFSET_SCALE 1.5f static void gizmo_calc_matrix_final_no_offset( - const wmGizmo *mpr, float orig_matrix_final_no_offset[4][4], bool use_space) + const wmGizmo *gz, float orig_matrix_final_no_offset[4][4], bool use_space) { float mat_identity[4][4]; struct WM_GizmoMatrixParams params = {NULL}; @@ -76,11 +76,11 @@ static void gizmo_calc_matrix_final_no_offset( params.matrix_basis = mat_identity; } params.matrix_offset = mat_identity; - WM_gizmo_calc_matrix_final_params(mpr, ¶ms, orig_matrix_final_no_offset); + WM_gizmo_calc_matrix_final_params(gz, ¶ms, orig_matrix_final_no_offset); } static void gizmo_calc_rect_view_scale( - const wmGizmo *mpr, const float dims[3], float scale[3]) + const wmGizmo *gz, const float dims[3], float scale[3]) { UNUSED_VARS(dims); @@ -88,10 +88,10 @@ static void gizmo_calc_rect_view_scale( float matrix_final_no_offset[4][4]; float x_axis[3], y_axis[3], z_axis[3]; - gizmo_calc_matrix_final_no_offset(mpr, matrix_final_no_offset, false); - mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, mpr->matrix_offset[0]); - mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, mpr->matrix_offset[1]); - mul_v3_mat3_m4v3(z_axis, matrix_final_no_offset, mpr->matrix_offset[2]); + gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset, false); + mul_v3_mat3_m4v3(x_axis, matrix_final_no_offset, gz->matrix_offset[0]); + mul_v3_mat3_m4v3(y_axis, matrix_final_no_offset, gz->matrix_offset[1]); + mul_v3_mat3_m4v3(z_axis, matrix_final_no_offset, gz->matrix_offset[2]); scale[0] = 1.0f / len_v3(x_axis); scale[1] = 1.0f / len_v3(y_axis); @@ -99,20 +99,20 @@ static void gizmo_calc_rect_view_scale( } static void gizmo_calc_rect_view_margin( - const wmGizmo *mpr, const float dims[3], float margin[3]) + const wmGizmo *gz, const float dims[3], float margin[3]) { float handle_size; - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { handle_size = 0.15f; } else { handle_size = GIZMO_RESIZER_SIZE; } // XXX, the scale isn't taking offset into account, we need to calculate scale per handle! - // handle_size *= mpr->scale_final; + // handle_size *= gz->scale_final; float scale_xyz[3]; - gizmo_calc_rect_view_scale(mpr, dims, scale_xyz); + gizmo_calc_rect_view_scale(gz, dims, scale_xyz); margin[0] = ((handle_size * scale_xyz[0])); margin[1] = ((handle_size * scale_xyz[1])); margin[2] = ((handle_size * scale_xyz[2])); @@ -281,26 +281,26 @@ static void cage3d_draw_circle_handles( static void gizmo_cage3d_draw_intern( RegionView3D *rv3d, - wmGizmo *mpr, const bool select, const bool highlight, const int select_id) + wmGizmo *gz, const bool select, const bool highlight, const int select_id) { - // const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; + // const bool use_clamp = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; float dims[3]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); float matrix_final[4][4]; - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - const int draw_style = RNA_enum_get(mpr->ptr, "draw_style"); - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); const float size_real[3] = {dims[0] / 2.0f, dims[1] / 2.0f, dims[2] / 2.0f}; - WM_gizmo_calc_matrix_final(mpr, matrix_final); + WM_gizmo_calc_matrix_final(gz, matrix_final); gpuPushMatrix(); gpuMultMatrix(matrix_final); float margin[3]; - gizmo_calc_rect_view_margin(mpr, dims, margin); + gizmo_calc_rect_view_margin(gz, dims, margin); /* Handy for quick testing draw (if it's outside bounds). */ if (false) { @@ -338,14 +338,14 @@ static void gizmo_cage3d_draw_intern( } GPU_select_load_id(select_id | i); cage3d_draw_box_interaction( - mpr->color, i, size, margin); + gz->color, i, size, margin); } } if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { const int transform_part = ED_GIZMO_CAGE3D_PART_TRANSLATE; GPU_select_load_id(select_id | transform_part); cage3d_draw_box_interaction( - mpr->color, transform_part, size, margin); + gz->color, transform_part, size, margin); } } else { @@ -359,17 +359,17 @@ static void gizmo_cage3d_draw_intern( #endif if (draw_style == ED_GIZMO_CAGE2D_STYLE_BOX) { /* corner gizmos */ - GPU_line_width(mpr->line_width + 3.0f); + GPU_line_width(gz->line_width + 3.0f); cage3d_draw_box_corners(size_real, margin, (const float[3]){0, 0, 0}); /* corner gizmos */ float color[4]; - gizmo_color_get(mpr, highlight, color); - GPU_line_width(mpr->line_width); + gizmo_color_get(gz, highlight, color); + GPU_line_width(gz->line_width); cage3d_draw_box_corners(size_real, margin, color); bool show = false; - if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) { + if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) { /* Only show if we're drawing the center handle * otherwise the entire rectangle is the hotspot. */ if (draw_options & ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) { @@ -382,20 +382,20 @@ static void gizmo_cage3d_draw_intern( if (show) { cage3d_draw_box_interaction( - mpr->color, mpr->highlight_part, size_real, margin); + gz->color, gz->highlight_part, size_real, margin); } } else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) { float color[4]; - gizmo_color_get(mpr, highlight, color); + gizmo_color_get(gz, highlight, color); GPU_line_smooth(true); GPU_polygon_smooth(true); GPU_blend(true); - GPU_line_width(mpr->line_width + 3.0f); + GPU_line_width(gz->line_width + 3.0f); cage3d_draw_circle_wire(size_real, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options); - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); cage3d_draw_circle_wire(size_real, margin, color, transform_flag, draw_options); /* corner gizmos */ @@ -418,24 +418,24 @@ static void gizmo_cage3d_draw_intern( /** * For when we want to draw 3d cage in 3d views. */ -static void gizmo_cage3d_draw_select(const bContext *C, wmGizmo *mpr, int select_id) +static void gizmo_cage3d_draw_select(const bContext *C, wmGizmo *gz, int select_id) { ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; - gizmo_cage3d_draw_intern(rv3d, mpr, true, false, select_id); + gizmo_cage3d_draw_intern(rv3d, gz, true, false, select_id); } -static void gizmo_cage3d_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_cage3d_draw(const bContext *C, wmGizmo *gz) { ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; - gizmo_cage3d_draw_intern(rv3d, mpr, false, is_highlight, -1); + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + gizmo_cage3d_draw_intern(rv3d, gz, false, is_highlight, -1); } -static int gizmo_cage3d_get_cursor(wmGizmo *mpr) +static int gizmo_cage3d_get_cursor(wmGizmo *gz) { - if (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { return BC_NSEW_SCROLLCURSOR; } @@ -448,33 +448,33 @@ typedef struct RectTransformInteraction { float orig_matrix_final_no_offset[4][4]; } RectTransformInteraction; -static void gizmo_cage3d_setup(wmGizmo *mpr) +static void gizmo_cage3d_setup(wmGizmo *gz) { - mpr->flag |= /* WM_GIZMO_DRAW_MODAL | */ /* TODO */ + gz->flag |= /* WM_GIZMO_DRAW_MODAL | */ /* TODO */ WM_GIZMO_DRAW_NO_SCALE; } static int gizmo_cage3d_invoke( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { RectTransformInteraction *data = MEM_callocN(sizeof(RectTransformInteraction), "cage_interaction"); - copy_m4_m4(data->orig_matrix_offset, mpr->matrix_offset); - gizmo_calc_matrix_final_no_offset(mpr, data->orig_matrix_final_no_offset, true); + copy_m4_m4(data->orig_matrix_offset, gz->matrix_offset); + gizmo_calc_matrix_final_no_offset(gz, data->orig_matrix_final_no_offset, true); if (gizmo_window_project_3d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, false, data->orig_mouse) == 0) + C, gz, (const float[2]){UNPACK2(event->mval)}, false, data->orig_mouse) == 0) { zero_v3(data->orig_mouse); } - mpr->interaction_data = data; + gz->interaction_data = data; return OPERATOR_RUNNING_MODAL; } static int gizmo_cage3d_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { /* For transform logic to be managable we operate in -0.5..0.5 2D space, @@ -484,51 +484,51 @@ static int gizmo_cage3d_modal( * - The cursor offset are multiplied by 'dims'. * - Matrix translation is also multiplied by 'dims'. */ - RectTransformInteraction *data = mpr->interaction_data; + RectTransformInteraction *data = gz->interaction_data; float point_local[3]; float dims[3]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); { float matrix_back[4][4]; - copy_m4_m4(matrix_back, mpr->matrix_offset); - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(matrix_back, gz->matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); bool ok = gizmo_window_project_3d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, false, point_local); - copy_m4_m4(mpr->matrix_offset, matrix_back); + C, gz, (const float[2]){UNPACK2(event->mval)}, false, point_local); + copy_m4_m4(gz->matrix_offset, matrix_back); if (!ok) { return OPERATOR_RUNNING_MODAL; } } - const int transform_flag = RNA_enum_get(mpr->ptr, "transform"); - wmGizmoProperty *mpr_prop; + const int transform_flag = RNA_enum_get(gz->ptr, "transform"); + wmGizmoProperty *gz_prop; - mpr_prop = WM_gizmo_target_property_find(mpr, "matrix"); - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]); + gz_prop = WM_gizmo_target_property_find(gz, "matrix"); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]); } - if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) { + if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_TRANSLATE) { /* do this to prevent clamping from changing size */ - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); - mpr->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]); - mpr->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]); - mpr->matrix_offset[3][2] = data->orig_matrix_offset[3][2] + (point_local[2] - data->orig_mouse[2]); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); + gz->matrix_offset[3][0] = data->orig_matrix_offset[3][0] + (point_local[0] - data->orig_mouse[0]); + gz->matrix_offset[3][1] = data->orig_matrix_offset[3][1] + (point_local[1] - data->orig_mouse[1]); + gz->matrix_offset[3][2] = data->orig_matrix_offset[3][2] + (point_local[2] - data->orig_mouse[2]); } - else if (mpr->highlight_part == ED_GIZMO_CAGE3D_PART_ROTATE) { + else if (gz->highlight_part == ED_GIZMO_CAGE3D_PART_ROTATE) { /* TODO (if needed) */ } else { /* scale */ - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); float pivot[3]; bool constrain_axis[3] = {false}; if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE) { - gizmo_rect_pivot_from_scale_part(mpr->highlight_part, pivot, constrain_axis); + gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis); } else { zero_v3(pivot); @@ -587,11 +587,11 @@ static int gizmo_cage3d_modal( transform_pivot_set_m4( matrix_scale, (const float[3]){pivot[0] * dims[0], pivot[1] * dims[1], pivot[2] * dims[2]}); - mul_m4_m4m4(mpr->matrix_offset, data->orig_matrix_offset, matrix_scale); + mul_m4_m4m4(gz->matrix_offset, data->orig_matrix_offset, matrix_scale); } - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &mpr->matrix_offset[0][0]); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]); } /* tag the region for redraw */ @@ -601,11 +601,11 @@ static int gizmo_cage3d_modal( return OPERATOR_RUNNING_MODAL; } -static void gizmo_cage3d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop) +static void gizmo_cage3d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop) { - if (STREQ(mpr_prop->type->idname, "matrix")) { - if (WM_gizmo_target_property_array_length(mpr, mpr_prop) == 16) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, &mpr->matrix_offset[0][0]); + if (STREQ(gz_prop->type->idname, "matrix")) { + if (WM_gizmo_target_property_array_length(gz, gz_prop) == 16) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, &gz->matrix_offset[0][0]); } else { BLI_assert(0); @@ -616,22 +616,22 @@ static void gizmo_cage3d_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop } } -static void gizmo_cage3d_exit(bContext *C, wmGizmo *mpr, const bool cancel) +static void gizmo_cage3d_exit(bContext *C, wmGizmo *gz, const bool cancel) { - RectTransformInteraction *data = mpr->interaction_data; + RectTransformInteraction *data = gz->interaction_data; if (!cancel) return; - wmGizmoProperty *mpr_prop; + wmGizmoProperty *gz_prop; /* reset properties */ - mpr_prop = WM_gizmo_target_property_find(mpr, "matrix"); - if (mpr_prop->type != NULL) { - WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, &data->orig_matrix_offset[0][0]); + gz_prop = WM_gizmo_target_property_find(gz, "matrix"); + if (gz_prop->type != NULL) { + WM_gizmo_target_property_value_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]); } - copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset); + copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset); } @@ -640,22 +640,22 @@ static void gizmo_cage3d_exit(bContext *C, wmGizmo *mpr, const bool cancel) * * \{ */ -static void GIZMO_WT_cage_3d(wmGizmoType *wt) +static void GIZMO_GT_cage_3d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_cage_3d"; + gzt->idname = "GIZMO_GT_cage_3d"; /* api callbacks */ - wt->draw = gizmo_cage3d_draw; - wt->draw_select = gizmo_cage3d_draw_select; - wt->setup = gizmo_cage3d_setup; - wt->invoke = gizmo_cage3d_invoke; - wt->property_update = gizmo_cage3d_property_update; - wt->modal = gizmo_cage3d_modal; - wt->exit = gizmo_cage3d_exit; - wt->cursor_get = gizmo_cage3d_get_cursor; + gzt->draw = gizmo_cage3d_draw; + gzt->draw_select = gizmo_cage3d_draw_select; + gzt->setup = gizmo_cage3d_setup; + gzt->invoke = gizmo_cage3d_invoke; + gzt->property_update = gizmo_cage3d_property_update; + gzt->modal = gizmo_cage3d_modal; + gzt->exit = gizmo_cage3d_exit; + gzt->cursor_get = gizmo_cage3d_get_cursor; - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); /* rna */ static EnumPropertyItem rna_enum_draw_style[] = { @@ -674,19 +674,19 @@ static void GIZMO_WT_cage_3d(wmGizmoType *wt) {0, NULL, 0, NULL, NULL} }; static float unit_v3[3] = {1.0f, 1.0f, 1.0f}; - RNA_def_float_vector(wt->srna, "dimensions", 3, unit_v3, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); - RNA_def_enum_flag(wt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); - RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", ""); + RNA_def_float_vector(gzt->srna, "dimensions", 3, unit_v3, 0, FLT_MAX, "Dimensions", "", 0.0f, FLT_MAX); + RNA_def_enum_flag(gzt->srna, "transform", rna_enum_transform, 0, "Transform Options", ""); + RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_CAGE2D_STYLE_CIRCLE, "Draw Style", ""); RNA_def_enum_flag( - wt->srna, "draw_options", rna_enum_draw_options, + gzt->srna, "draw_options", rna_enum_draw_options, ED_GIZMO_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE, "Draw Options", ""); - WM_gizmotype_target_property_def(wt, "matrix", PROP_FLOAT, 16); + WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16); } void ED_gizmotypes_cage_3d(void) { - WM_gizmotype_append(GIZMO_WT_cage_3d); + WM_gizmotype_append(GIZMO_GT_cage_3d); } /** \} */ diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c index b93b87b1efa..b45f3d8a242 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c @@ -71,7 +71,7 @@ // #define USE_GIZMO_CUSTOM_DIAL static int gizmo_dial_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag); typedef struct DialInteraction { @@ -101,30 +101,30 @@ typedef struct DialInteraction { /** * We can't use this for the #wmGizmoType.matrix_basis_get callback, it conflicts with depth picking. */ -static void dial_calc_matrix(const wmGizmo *mpr, float mat[4][4]) +static void dial_calc_matrix(const wmGizmo *gz, float mat[4][4]) { float rot[3][3]; const float up[3] = {0.0f, 0.0f, 1.0f}; - rotation_between_vecs_to_mat3(rot, up, mpr->matrix_basis[2]); + rotation_between_vecs_to_mat3(rot, up, gz->matrix_basis[2]); copy_m4_m3(mat, rot); - copy_v3_v3(mat[3], mpr->matrix_basis[3]); + copy_v3_v3(mat[3], gz->matrix_basis[3]); } /* -------------------------------------------------------------------- */ static void dial_geom_draw( - const wmGizmo *mpr, const float color[4], const bool select, + const wmGizmo *gz, const float color[4], const bool select, float axis_modal_mat[4][4], float clip_plane[4]) { #ifdef USE_GIZMO_CUSTOM_DIAL UNUSED_VARS(dial, col, axis_modal_mat, clip_plane); wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_dial, select); #else - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); const bool filled = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_FILL) != 0; - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); Gwn_VertFormat *format = immVertexFormat(); uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -181,9 +181,9 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[ } static void dial_ghostarc_draw( - const wmGizmo *mpr, const float angle_ofs, const float angle_delta, const float color[4]) + const wmGizmo *gz, const float angle_ofs, const float angle_delta, const float color[4]) { - const float width_inner = DIAL_WIDTH - mpr->line_width * 0.5f / U.gizmo_size; + const float width_inner = DIAL_WIDTH - gz->line_width * 0.5f / U.gizmo_size; Gwn_VertFormat *format = immVertexFormat(); uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -196,24 +196,24 @@ static void dial_ghostarc_draw( static void dial_ghostarc_get_angles( struct Depsgraph *depsgraph, - const wmGizmo *mpr, + const wmGizmo *gz, const wmEvent *event, const ARegion *ar, const View3D *v3d, float mat[4][4], const float co_outer[3], float *r_start, float *r_delta) { - DialInteraction *inter = mpr->interaction_data; + DialInteraction *inter = gz->interaction_data; const RegionView3D *rv3d = ar->regiondata; const float mval[2] = {event->x - ar->winrct.xmin, event->y - ar->winrct.ymin}; /* we might need to invert the direction of the angles */ float view_vec[3], axis_vec[3]; - ED_view3d_global_to_vector(rv3d, mpr->matrix_basis[3], view_vec); - normalize_v3_v3(axis_vec, mpr->matrix_basis[2]); + ED_view3d_global_to_vector(rv3d, gz->matrix_basis[3], view_vec); + normalize_v3_v3(axis_vec, gz->matrix_basis[2]); float proj_outer_rel[3]; mul_v3_project_m4_v3(proj_outer_rel, mat, co_outer); - sub_v3_v3(proj_outer_rel, mpr->matrix_basis[3]); + sub_v3_v3(proj_outer_rel, gz->matrix_basis[3]); float proj_mval_new_rel[3]; float proj_mval_init_rel[3]; @@ -221,7 +221,7 @@ static void dial_ghostarc_get_angles( float ray_co[3], ray_no[3]; float ray_lambda; - plane_from_point_normal_v3(dial_plane, mpr->matrix_basis[3], axis_vec); + plane_from_point_normal_v3(dial_plane, gz->matrix_basis[3], axis_vec); if (!ED_view3d_win_to_ray(depsgraph, ar, v3d, inter->init_mval, ray_co, ray_no, false) || !isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, false)) @@ -229,7 +229,7 @@ static void dial_ghostarc_get_angles( goto fail; } madd_v3_v3v3fl(proj_mval_init_rel, ray_co, ray_no, ray_lambda); - sub_v3_v3(proj_mval_init_rel, mpr->matrix_basis[3]); + sub_v3_v3(proj_mval_init_rel, gz->matrix_basis[3]); if (!ED_view3d_win_to_ray(depsgraph, ar, v3d, mval, ray_co, ray_no, false) || !isect_ray_plane_v3(ray_co, ray_no, dial_plane, &ray_lambda, false)) @@ -237,14 +237,14 @@ static void dial_ghostarc_get_angles( goto fail; } madd_v3_v3v3fl(proj_mval_new_rel, ray_co, ray_no, ray_lambda); - sub_v3_v3(proj_mval_new_rel, mpr->matrix_basis[3]); + sub_v3_v3(proj_mval_new_rel, gz->matrix_basis[3]); - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); /* Start direction from mouse or set by user */ const float *proj_init_rel = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y) ? - mpr->matrix_basis[1] : proj_mval_init_rel; + gz->matrix_basis[1] : proj_mval_init_rel; /* return angles */ const float start = angle_wrap_rad(angle_signed_on_axis_v3v3_v3(proj_outer_rel, proj_init_rel, axis_vec)); @@ -274,7 +274,7 @@ fail: } static void dial_draw_intern( - const bContext *C, wmGizmo *mpr, + const bContext *C, wmGizmo *gz, const bool select, const bool highlight, float clip_plane[4]) { float matrix_basis_adjust[4][4]; @@ -283,12 +283,12 @@ static void dial_draw_intern( BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D); - gizmo_color_get(mpr, highlight, color); + gizmo_color_get(gz, highlight, color); - dial_calc_matrix(mpr, matrix_basis_adjust); + dial_calc_matrix(gz, matrix_basis_adjust); WM_gizmo_calc_matrix_final_params( - mpr, &((struct WM_GizmoMatrixParams) { + gz, &((struct WM_GizmoMatrixParams) { .matrix_basis = (void *)matrix_basis_adjust, }), matrix_final); @@ -296,17 +296,17 @@ static void dial_draw_intern( gpuMultMatrix(matrix_final); /* draw rotation indicator arc first */ - if ((mpr->flag & WM_GIZMO_DRAW_VALUE) && - (mpr->state & WM_GIZMO_STATE_MODAL)) + if ((gz->flag & WM_GIZMO_DRAW_VALUE) && + (gz->state & WM_GIZMO_STATE_MODAL)) { const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */ - DialInteraction *inter = mpr->interaction_data; + DialInteraction *inter = gz->interaction_data; /* XXX, View3D rotation gizmo doesn't call modal. */ - if (!WM_gizmo_target_property_is_valid_any(mpr)) { + if (!WM_gizmo_target_property_is_valid_any(gz)) { wmWindow *win = CTX_wm_window(C); - gizmo_dial_modal((bContext *)C, mpr, win->eventstate, 0); + gizmo_dial_modal((bContext *)C, gz, win->eventstate, 0); } float angle_ofs = inter->output.angle_ofs; @@ -315,14 +315,14 @@ static void dial_draw_intern( /* draw! */ for (int i = 0; i < 2; i++) { GPU_polygon_smooth(false); - dial_ghostarc_draw(mpr, angle_ofs, angle_delta, (const float[4]){0.8f, 0.8f, 0.8f, 0.4f}); + dial_ghostarc_draw(gz, angle_ofs, angle_delta, (const float[4]){0.8f, 0.8f, 0.8f, 0.4f}); GPU_polygon_smooth(true); dial_ghostarc_draw_helpline(angle_ofs, co_outer, color); /* starting position */ dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color); /* starting position + current value */ if (i == 0) { - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); if ((draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) == 0) { break; } @@ -333,15 +333,15 @@ static void dial_draw_intern( } /* draw actual dial gizmo */ - dial_geom_draw(mpr, color, select, matrix_basis_adjust, clip_plane); + dial_geom_draw(gz, color, select, matrix_basis_adjust, clip_plane); gpuPopMatrix(); } -static void gizmo_dial_draw_select(const bContext *C, wmGizmo *mpr, int select_id) +static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id) { float clip_plane_buf[4]; - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); float *clip_plane = (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP) ? clip_plane_buf : NULL; /* enable clipping if needed */ @@ -350,25 +350,25 @@ static void gizmo_dial_draw_select(const bContext *C, wmGizmo *mpr, int select_i RegionView3D *rv3d = ar->regiondata; copy_v3_v3(clip_plane, rv3d->viewinv[2]); - clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], mpr->matrix_basis[3]); - clip_plane[3] += DIAL_CLIP_BIAS * mpr->scale_final; + clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]); + clip_plane[3] += DIAL_CLIP_BIAS * gz->scale_final; glEnable(GL_CLIP_DISTANCE0); } GPU_select_load_id(select_id); - dial_draw_intern(C, mpr, true, false, clip_plane); + dial_draw_intern(C, gz, true, false, clip_plane); if (clip_plane) { glDisable(GL_CLIP_DISTANCE0); } } -static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_dial_draw(const bContext *C, wmGizmo *gz) { - const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL; - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL; + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; float clip_plane_buf[4]; - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); float *clip_plane = (!is_modal && (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_CLIP)) ? clip_plane_buf : NULL; /* enable clipping if needed */ @@ -377,14 +377,14 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr) RegionView3D *rv3d = ar->regiondata; copy_v3_v3(clip_plane, rv3d->viewinv[2]); - clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], mpr->matrix_basis[3]); - clip_plane[3] += DIAL_CLIP_BIAS * mpr->scale_final; + clip_plane[3] = -dot_v3v3(rv3d->viewinv[2], gz->matrix_basis[3]); + clip_plane[3] += DIAL_CLIP_BIAS * gz->scale_final; glEnable(GL_CLIP_DISTANCE0); } GPU_blend(true); - dial_draw_intern(C, mpr, false, is_highlight, clip_plane); + dial_draw_intern(C, gz, false, is_highlight, clip_plane); GPU_blend(false); if (clip_plane) { @@ -393,7 +393,7 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *mpr) } static int gizmo_dial_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; /* coordinate at which the arc drawing will be started */ @@ -401,48 +401,48 @@ static int gizmo_dial_modal( float matrix[4][4]; - dial_calc_matrix(mpr, matrix); + dial_calc_matrix(gz, matrix); dial_ghostarc_get_angles( CTX_data_depsgraph(C), - mpr, event, CTX_wm_region(C), CTX_wm_view3d(C), matrix, co_outer, &angle_ofs, &angle_delta); + gz, event, CTX_wm_region(C), CTX_wm_view3d(C), matrix, co_outer, &angle_ofs, &angle_delta); - DialInteraction *inter = mpr->interaction_data; + DialInteraction *inter = gz->interaction_data; inter->output.angle_delta = angle_delta; inter->output.angle_ofs = angle_ofs; /* set the property for the operator and call its modal function */ - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - WM_gizmo_target_property_value_set(C, mpr, mpr_prop, inter->init_prop_angle + angle_delta); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); + if (WM_gizmo_target_property_is_valid(gz_prop)) { + WM_gizmo_target_property_value_set(C, gz, gz_prop, inter->init_prop_angle + angle_delta); } return OPERATOR_RUNNING_MODAL; } -static void gizmo_dial_setup(wmGizmo *mpr) +static void gizmo_dial_setup(wmGizmo *gz) { const float dir_default[3] = {0.0f, 0.0f, 1.0f}; /* defaults */ - copy_v3_v3(mpr->matrix_basis[2], dir_default); + copy_v3_v3(gz->matrix_basis[2], dir_default); } static int gizmo_dial_invoke( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { DialInteraction *inter = MEM_callocN(sizeof(DialInteraction), __func__); inter->init_mval[0] = event->mval[0]; inter->init_mval[1] = event->mval[1]; - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - inter->init_prop_angle = WM_gizmo_target_property_value_get(mpr, mpr_prop); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); + if (WM_gizmo_target_property_is_valid(gz_prop)) { + inter->init_prop_angle = WM_gizmo_target_property_value_get(gz, gz_prop); } - mpr->interaction_data = inter; + gz->interaction_data = inter; return OPERATOR_RUNNING_MODAL; } @@ -452,19 +452,19 @@ static int gizmo_dial_invoke( * * \{ */ -static void GIZMO_WT_dial_3d(wmGizmoType *wt) +static void GIZMO_GT_dial_3d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_dial_3d"; + gzt->idname = "GIZMO_GT_dial_3d"; /* api callbacks */ - wt->draw = gizmo_dial_draw; - wt->draw_select = gizmo_dial_draw_select; - wt->setup = gizmo_dial_setup; - wt->invoke = gizmo_dial_invoke; - wt->modal = gizmo_dial_modal; + gzt->draw = gizmo_dial_draw; + gzt->draw_select = gizmo_dial_draw_select; + gzt->setup = gizmo_dial_setup; + gzt->invoke = gizmo_dial_invoke; + gzt->modal = gizmo_dial_modal; - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); /* rna */ static EnumPropertyItem rna_enum_draw_options[] = { @@ -474,14 +474,14 @@ static void GIZMO_WT_dial_3d(wmGizmoType *wt) {ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_START_Y, "ANGLE_START_Y", 0, "Angle Start Y", ""}, {0, NULL, 0, NULL, NULL} }; - RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); + RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); - WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 1); + WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 1); } void ED_gizmotypes_dial_3d(void) { - WM_gizmotype_append(GIZMO_WT_dial_3d); + WM_gizmotype_append(GIZMO_GT_dial_3d); } /** \} */ diff --git a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c index 2a89c8cc4ab..c6d11347e9f 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c @@ -68,16 +68,16 @@ typedef struct GrabGizmo3D { float prop_co[3]; } GrabGizmo3D; -static void gizmo_grab_matrix_basis_get(const wmGizmo *mpr, float r_matrix[4][4]) +static void gizmo_grab_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4]) { - GrabGizmo3D *grab = (GrabGizmo3D *)mpr; + GrabGizmo3D *grab = (GrabGizmo3D *)gz; copy_m4_m4(r_matrix, grab->gizmo.matrix_basis); add_v3_v3(r_matrix[3], grab->prop_co); } static int gizmo_grab_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak tweak_flag); typedef struct GrabInteraction { @@ -94,16 +94,16 @@ typedef struct GrabInteraction { /* -------------------------------------------------------------------- */ static void grab_geom_draw( - const wmGizmo *mpr, const float color[4], const bool select, const int draw_options) + const wmGizmo *gz, const float color[4], const bool select, const int draw_options) { #ifdef USE_GIZMO_CUSTOM_DIAL UNUSED_VARS(grab3d, col, axis_modal_mat); wm_gizmo_geometryinfo_draw(&wm_gizmo_geom_data_grab3d, select); #else - const int draw_style = RNA_enum_get(mpr->ptr, "draw_style"); + const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); const bool filled = (draw_options & ED_GIZMO_GRAB_DRAW_FLAG_FILL) != 0; - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); Gwn_VertFormat *format = immVertexFormat(); uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -140,10 +140,10 @@ static void grab_geom_draw( } static void grab3d_get_translate( - const wmGizmo *mpr, const wmEvent *event, const ARegion *ar, + const wmGizmo *gz, const wmEvent *event, const ARegion *ar, float co_delta[3]) { - GrabInteraction *inter = mpr->interaction_data; + GrabInteraction *inter = gz->interaction_data; const float mval_delta[2] = { event->mval[0] - inter->init_mval[0], event->mval[1] - inter->init_mval[1], @@ -151,30 +151,30 @@ static void grab3d_get_translate( RegionView3D *rv3d = ar->regiondata; float co_ref[3]; - mul_v3_mat3_m4v3(co_ref, mpr->matrix_space, inter->init_prop_co); + mul_v3_mat3_m4v3(co_ref, gz->matrix_space, inter->init_prop_co); const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL); ED_view3d_win_to_delta(ar, mval_delta, co_delta, zfac); float matrix_space_inv[3][3]; - copy_m3_m4(matrix_space_inv, mpr->matrix_space); + copy_m3_m4(matrix_space_inv, gz->matrix_space); invert_m3(matrix_space_inv); mul_m3_v3(matrix_space_inv, co_delta); } static void grab3d_draw_intern( - const bContext *C, wmGizmo *mpr, + const bContext *C, wmGizmo *gz, const bool select, const bool highlight) { - GrabInteraction *inter = mpr->interaction_data; - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + GrabInteraction *inter = gz->interaction_data; + const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); const bool align_view = (draw_options & ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW) != 0; float color[4]; float matrix_final[4][4]; float matrix_align[4][4]; - gizmo_color_get(mpr, highlight, color); - WM_gizmo_calc_matrix_final(mpr, matrix_final); + gizmo_color_get(gz, highlight, color); + WM_gizmo_calc_matrix_final(gz, matrix_final); gpuPushMatrix(); gpuMultMatrix(matrix_final); @@ -190,11 +190,11 @@ static void grab3d_draw_intern( } GPU_blend(true); - grab_geom_draw(mpr, color, select, draw_options); + grab_geom_draw(gz, color, select, draw_options); GPU_blend(false); gpuPopMatrix(); - if (mpr->interaction_data) { + if (gz->interaction_data) { gpuPushMatrix(); gpuMultMatrix(inter->init_matrix_final); @@ -203,48 +203,48 @@ static void grab3d_draw_intern( } GPU_blend(true); - grab_geom_draw(mpr, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); + grab_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); GPU_blend(false); gpuPopMatrix(); } } -static void gizmo_grab_draw_select(const bContext *C, wmGizmo *mpr, int select_id) +static void gizmo_grab_draw_select(const bContext *C, wmGizmo *gz, int select_id) { GPU_select_load_id(select_id); - grab3d_draw_intern(C, mpr, true, false); + grab3d_draw_intern(C, gz, true, false); } -static void gizmo_grab_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_grab_draw(const bContext *C, wmGizmo *gz) { - const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL; - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL; + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; (void)is_modal; GPU_blend(true); - grab3d_draw_intern(C, mpr, false, is_highlight); + grab3d_draw_intern(C, gz, false, is_highlight); GPU_blend(false); } static int gizmo_grab_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { - GrabGizmo3D *grab = (GrabGizmo3D *)mpr; - GrabInteraction *inter = mpr->interaction_data; + GrabGizmo3D *grab = (GrabGizmo3D *)gz; + GrabInteraction *inter = gz->interaction_data; ARegion *ar = CTX_wm_region(C); float prop_delta[3]; if (CTX_wm_area(C)->spacetype == SPACE_VIEW3D) { - grab3d_get_translate(mpr, event, ar, prop_delta); + grab3d_get_translate(gz, event, ar, prop_delta); } else { float mval_proj_init[2], mval_proj_curr[2]; if ((gizmo_window_project_2d( - C, mpr, inter->init_mval, 2, false, mval_proj_init) == false) || + C, gz, inter->init_mval, 2, false, mval_proj_init) == false) || (gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false)) + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false)) { return OPERATOR_RUNNING_MODAL; } @@ -254,9 +254,9 @@ static int gizmo_grab_modal( add_v3_v3v3(grab->prop_co, inter->init_prop_co, prop_delta); /* set the property for the operator and call its modal function */ - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - WM_gizmo_target_property_value_set_array(C, mpr, mpr_prop, grab->prop_co); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); + if (WM_gizmo_target_property_is_valid(gz_prop)) { + WM_gizmo_target_property_value_set_array(C, gz, gz_prop, grab->prop_co); } else { zero_v3(grab->prop_co); @@ -268,7 +268,7 @@ static int gizmo_grab_modal( } static int gizmo_grab_invoke( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { GrabInteraction *inter = MEM_callocN(sizeof(GrabInteraction), __func__); @@ -278,32 +278,32 @@ static int gizmo_grab_invoke( #if 0 copy_v3_v3(inter->init_prop_co, grab->prop_co); #else - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_find(mpr, "offset"); - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); + if (WM_gizmo_target_property_is_valid(gz_prop)) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, inter->init_prop_co); } #endif - WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final); + WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final); - mpr->interaction_data = inter; + gz->interaction_data = inter; return OPERATOR_RUNNING_MODAL; } static int gizmo_grab_test_select( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { float point_local[2]; if (gizmo_window_project_2d( - C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) { return -1; } - /* The 'mpr->scale_final' is already applied when projecting. */ + /* The 'gz->scale_final' is already applied when projecting. */ if (len_squared_v2(point_local) < 1.0f) { return 0; } @@ -311,18 +311,18 @@ static int gizmo_grab_test_select( return -1; } -static void gizmo_grab_property_update(wmGizmo *mpr, wmGizmoProperty *mpr_prop) +static void gizmo_grab_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop) { - GrabGizmo3D *grab = (GrabGizmo3D *)mpr; - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, grab->prop_co); + GrabGizmo3D *grab = (GrabGizmo3D *)gz; + if (WM_gizmo_target_property_is_valid(gz_prop)) { + WM_gizmo_target_property_value_get_array(gz, gz_prop, grab->prop_co); } else { zero_v3(grab->prop_co); } } -static int gizmo_grab_cursor_get(wmGizmo *UNUSED(mpr)) +static int gizmo_grab_cursor_get(wmGizmo *UNUSED(gz)) { return BC_NSEW_SCROLLCURSOR; } @@ -332,22 +332,22 @@ static int gizmo_grab_cursor_get(wmGizmo *UNUSED(mpr)) * * \{ */ -static void GIZMO_WT_grab_3d(wmGizmoType *wt) +static void GIZMO_GT_grab_3d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_grab_3d"; + gzt->idname = "GIZMO_GT_grab_3d"; /* api callbacks */ - wt->draw = gizmo_grab_draw; - wt->draw_select = gizmo_grab_draw_select; - wt->test_select = gizmo_grab_test_select; - wt->matrix_basis_get = gizmo_grab_matrix_basis_get; - wt->invoke = gizmo_grab_invoke; - wt->property_update = gizmo_grab_property_update; - wt->modal = gizmo_grab_modal; - wt->cursor_get = gizmo_grab_cursor_get; + gzt->draw = gizmo_grab_draw; + gzt->draw_select = gizmo_grab_draw_select; + gzt->test_select = gizmo_grab_test_select; + gzt->matrix_basis_get = gizmo_grab_matrix_basis_get; + gzt->invoke = gizmo_grab_invoke; + gzt->property_update = gizmo_grab_property_update; + gzt->modal = gizmo_grab_modal; + gzt->cursor_get = gizmo_grab_cursor_get; - wt->struct_size = sizeof(GrabGizmo3D); + gzt->struct_size = sizeof(GrabGizmo3D); /* rna */ static EnumPropertyItem rna_enum_draw_style[] = { @@ -361,15 +361,15 @@ static void GIZMO_WT_grab_3d(wmGizmoType *wt) {0, NULL, 0, NULL, NULL} }; - RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_GRAB_STYLE_RING_2D, "Draw Style", ""); - RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); + RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_GRAB_STYLE_RING_2D, "Draw Style", ""); + RNA_def_enum_flag(gzt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); - WM_gizmotype_target_property_def(wt, "offset", PROP_FLOAT, 3); + WM_gizmotype_target_property_def(gzt, "offset", PROP_FLOAT, 3); } void ED_gizmotypes_grab_3d(void) { - WM_gizmotype_append(GIZMO_WT_grab_3d); + WM_gizmotype_append(GIZMO_GT_grab_3d); } /** \} */ // Grab Gizmo API diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c index ff02517dafa..be2bf7d2c56 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c @@ -86,18 +86,18 @@ static void gizmo_primitive_draw_geom( } static void gizmo_primitive_draw_intern( - wmGizmo *mpr, const bool UNUSED(select), + wmGizmo *gz, const bool UNUSED(select), const bool highlight) { float color_inner[4], color_outer[4]; float matrix_final[4][4]; - const int draw_style = RNA_enum_get(mpr->ptr, "draw_style"); + const int draw_style = RNA_enum_get(gz->ptr, "draw_style"); - gizmo_color_get(mpr, highlight, color_outer); + gizmo_color_get(gz, highlight, color_outer); copy_v4_v4(color_inner, color_outer); color_inner[3] *= 0.5f; - WM_gizmo_calc_matrix_final(mpr, matrix_final); + WM_gizmo_calc_matrix_final(gz, matrix_final); gpuPushMatrix(); gpuMultMatrix(matrix_final); @@ -108,8 +108,8 @@ static void gizmo_primitive_draw_intern( gpuPopMatrix(); - if (mpr->interaction_data) { - GizmoInteraction *inter = mpr->interaction_data; + if (gz->interaction_data) { + GizmoInteraction *inter = gz->interaction_data; copy_v4_fl(color_inner, 0.5f); copy_v3_fl(color_outer, 0.5f); @@ -127,33 +127,33 @@ static void gizmo_primitive_draw_intern( } static void gizmo_primitive_draw_select( - const bContext *UNUSED(C), wmGizmo *mpr, + const bContext *UNUSED(C), wmGizmo *gz, int select_id) { GPU_select_load_id(select_id); - gizmo_primitive_draw_intern(mpr, true, false); + gizmo_primitive_draw_intern(gz, true, false); } -static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *mpr) +static void gizmo_primitive_draw(const bContext *UNUSED(C), wmGizmo *gz) { gizmo_primitive_draw_intern( - mpr, false, - (mpr->state & WM_GIZMO_STATE_HIGHLIGHT)); + gz, false, + (gz->state & WM_GIZMO_STATE_HIGHLIGHT)); } -static void gizmo_primitive_setup(wmGizmo *mpr) +static void gizmo_primitive_setup(wmGizmo *gz) { - mpr->flag |= WM_GIZMO_DRAW_MODAL; + gz->flag |= WM_GIZMO_DRAW_MODAL; } static int gizmo_primitive_invoke( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *UNUSED(event)) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *UNUSED(event)) { GizmoInteraction *inter = MEM_callocN(sizeof(GizmoInteraction), __func__); - WM_gizmo_calc_matrix_final(mpr, inter->init_matrix_final); + WM_gizmo_calc_matrix_final(gz, inter->init_matrix_final); - mpr->interaction_data = inter; + gz->interaction_data = inter; return OPERATOR_RUNNING_MODAL; } @@ -163,29 +163,29 @@ static int gizmo_primitive_invoke( * * \{ */ -static void GIZMO_WT_primitive_3d(wmGizmoType *wt) +static void GIZMO_GT_primitive_3d(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "GIZMO_WT_primitive_3d"; + gzt->idname = "GIZMO_GT_primitive_3d"; /* api callbacks */ - wt->draw = gizmo_primitive_draw; - wt->draw_select = gizmo_primitive_draw_select; - wt->setup = gizmo_primitive_setup; - wt->invoke = gizmo_primitive_invoke; + gzt->draw = gizmo_primitive_draw; + gzt->draw_select = gizmo_primitive_draw_select; + gzt->setup = gizmo_primitive_setup; + gzt->invoke = gizmo_primitive_invoke; - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); static EnumPropertyItem rna_enum_draw_style[] = { {ED_GIZMO_PRIMITIVE_STYLE_PLANE, "PLANE", 0, "Plane", ""}, {0, NULL, 0, NULL, NULL} }; - RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_PRIMITIVE_STYLE_PLANE, "Draw Style", ""); + RNA_def_enum(gzt->srna, "draw_style", rna_enum_draw_style, ED_GIZMO_PRIMITIVE_STYLE_PLANE, "Draw Style", ""); } void ED_gizmotypes_primitive_3d(void) { - WM_gizmotype_append(GIZMO_WT_primitive_3d); + WM_gizmotype_append(GIZMO_GT_primitive_3d); } /** \} */ diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 39a58929b7c..2bf3488a8d3 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -53,13 +53,13 @@ struct wmGizmoGroup; /* gizmo_library_presets.c */ void ED_gizmo_draw_preset_box( - const struct wmGizmo *mpr, float mat[4][4], int select_id); + const struct wmGizmo *gz, float mat[4][4], int select_id); void ED_gizmo_draw_preset_arrow( - const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id); + const struct wmGizmo *gz, float mat[4][4], int axis, int select_id); void ED_gizmo_draw_preset_circle( - const struct wmGizmo *mpr, float mat[4][4], int axis, int select_id); + const struct wmGizmo *gz, float mat[4][4], int axis, int select_id); void ED_gizmo_draw_preset_facemap( - const struct bContext *C, const struct wmGizmo *mpr, struct Scene *scene, + const struct bContext *C, const struct wmGizmo *gz, struct Scene *scene, struct Object *ob, const int facemap, int select_id); @@ -87,8 +87,8 @@ enum { ED_GIZMO_ARROW_DRAW_FLAG_STEM = (1 << 0), }; -void ED_gizmo_arrow3d_set_ui_range(struct wmGizmo *mpr, const float min, const float max); -void ED_gizmo_arrow3d_set_range_fac(struct wmGizmo *mpr, const float range_fac); +void ED_gizmo_arrow3d_set_ui_range(struct wmGizmo *gz, const float min, const float max); +void ED_gizmo_arrow3d_set_range_fac(struct wmGizmo *gz, const float range_fac); /* -------------------------------------------------------------------- */ /* 2D Arrow Gizmo */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 80dea103f8c..cb04ac40acd 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -159,13 +159,13 @@ void Transform_Properties(struct wmOperatorType *ot, int flags); /* transform gizmos */ -void TRANSFORM_WGT_gizmo(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_xform_cage(struct wmGizmoGroupType *wgt); +void TRANSFORM_GGT_gizmo(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_xform_cage(struct wmGizmoGroupType *gzgt); -bool ED_widgetgroup_gizmo2d_poll(const struct bContext *C, struct wmGizmoGroupType *wgt); -void ED_widgetgroup_gizmo2d_setup(const struct bContext *C, struct wmGizmoGroup *mgroup); -void ED_widgetgroup_gizmo2d_refresh(const struct bContext *C, struct wmGizmoGroup *mgroup); -void ED_widgetgroup_gizmo2d_draw_prepare(const struct bContext *C, struct wmGizmoGroup *mgroup); +bool ED_widgetgroup_gizmo2d_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt); +void ED_widgetgroup_gizmo2d_setup(const struct bContext *C, struct wmGizmoGroup *gzgroup); +void ED_widgetgroup_gizmo2d_refresh(const struct bContext *C, struct wmGizmoGroup *gzgroup); +void ED_widgetgroup_gizmo2d_draw_prepare(const struct bContext *C, struct wmGizmoGroup *gzgroup); /* Snapping */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 723dde640e4..07259b91b86 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1265,7 +1265,7 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); /* ui_interface_region_tooltip.c */ struct ARegion *UI_tooltip_create_from_button(struct bContext *C, struct ARegion *butregion, uiBut *but); -struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *mpr); +struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz); void UI_tooltip_free(struct bContext *C, struct bScreen *sc, struct ARegion *ar); /* How long before a tool-tip shows. */ diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index fae547d460c..97f501b7448 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -615,7 +615,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } } -static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr) +static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) { uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); @@ -623,23 +623,23 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr) /* Operator Actions */ { - bool use_drag = mpr->drag_part != -1 && mpr->highlight_part != mpr->drag_part; + bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part; const struct { int part; const char *prefix; } mpop_actions[] = { { - .part = mpr->highlight_part, + .part = gz->highlight_part, .prefix = use_drag ? TIP_("Click") : NULL, }, { - .part = use_drag ? mpr->drag_part : -1, + .part = use_drag ? gz->drag_part : -1, .prefix = use_drag ? TIP_("Drag") : NULL, }, }; for (int i = 0; i < ARRAY_SIZE(mpop_actions); i++) { - wmGizmoOpElem *mpop = (mpop_actions[i].part != -1) ? WM_gizmo_operator_get(mpr, mpop_actions[i].part) : NULL; + wmGizmoOpElem *mpop = (mpop_actions[i].part != -1) ? WM_gizmo_operator_get(gz, mpop_actions[i].part) : NULL; if (mpop != NULL) { /* Description */ const char *info = RNA_struct_ui_description(mpop->type->srna); @@ -691,13 +691,13 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *mpr) } /* Property Actions */ - if (mpr->type->target_property_defs_len) { - wmGizmoProperty *mpr_prop_array = WM_gizmo_target_property_array(mpr); - for (int i = 0; i < mpr->type->target_property_defs_len; i++) { + if (gz->type->target_property_defs_len) { + wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); + for (int i = 0; i < gz->type->target_property_defs_len; i++) { /* TODO(campbell): function callback descriptions. */ - wmGizmoProperty *mpr_prop = &mpr_prop_array[i]; - if (mpr_prop->prop != NULL) { - const char *info = RNA_property_ui_description(mpr_prop->prop); + wmGizmoProperty *gz_prop = &gz_prop_array[i]; + if (gz_prop->prop != NULL) { + const char *info = RNA_property_ui_description(gz_prop->prop); if (info && info[0]) { uiTooltipField *field = text_field_add( data, &(uiTooltipFormat){ @@ -934,13 +934,13 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b return ui_tooltip_create_with_data(C, data, init_position, aspect); } -ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *mpr) +ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) { wmWindow *win = CTX_wm_window(C); const float aspect = 1.0f; float init_position[2]; - uiTooltipData *data = ui_tooltip_data_from_gizmo(C, mpr); + uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz); if (data == NULL) { return NULL; } diff --git a/source/blender/editors/mesh/editmesh_add_gizmo.c b/source/blender/editors/mesh/editmesh_add_gizmo.c index be5c01e08df..6fa0eb33b89 100644 --- a/source/blender/editors/mesh/editmesh_add_gizmo.c +++ b/source/blender/editors/mesh/editmesh_add_gizmo.c @@ -160,14 +160,14 @@ static void gizmo_mesh_placement_update_from_op(GizmoPlacementGroup *man) /* translate callbacks */ static void gizmo_placement_prop_matrix_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoPlacementGroup *man = mpr->parent_mgroup->customdata; + GizmoPlacementGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 16); + UNUSED_VARS_NDEBUG(gz_prop); if (value_p != man->cage->matrix_offset) { mul_m4_m4m4(value_p, man->cage->matrix_basis, man->cage->matrix_offset); @@ -176,14 +176,14 @@ static void gizmo_placement_prop_matrix_get( } static void gizmo_placement_prop_matrix_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value) { - GizmoPlacementGroup *man = mpr->parent_mgroup->customdata; + GizmoPlacementGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; - BLI_assert(mpr_prop->type->array_length == 16); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 16); + UNUSED_VARS_NDEBUG(gz_prop); float mat[4][4]; mul_m4_m4m4(mat, man->cage->matrix_basis, value); @@ -197,38 +197,38 @@ static void gizmo_placement_prop_matrix_set( gizmo_placement_exec(man); } -static bool gizmo_mesh_placement_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool gizmo_mesh_placement_poll(const bContext *C, wmGizmoGroupType *gzgt) { wmOperator *op = WM_operator_last_redo(C); if (op == NULL || !STREQ(op->type->idname, "MESH_OT_primitive_cube_add_gizmo")) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } static void gizmo_mesh_placement_modal_from_setup( - const bContext *C, wmGizmoGroup *mgroup) + const bContext *C, wmGizmoGroup *gzgroup) { - GizmoPlacementGroup *man = mgroup->customdata; + GizmoPlacementGroup *man = gzgroup->customdata; /* Initial size. */ { - wmGizmo *mpr = man->cage; - zero_m4(mpr->matrix_offset); - - /* TODO: support zero scaled matrix in 'GIZMO_WT_cage_3d'. */ - mpr->matrix_offset[0][0] = 0.01; - mpr->matrix_offset[1][1] = 0.01; - mpr->matrix_offset[2][2] = 0.01; - mpr->matrix_offset[3][3] = 1.0f; + wmGizmo *gz = man->cage; + zero_m4(gz->matrix_offset); + + /* TODO: support zero scaled matrix in 'GIZMO_GT_cage_3d'. */ + gz->matrix_offset[0][0] = 0.01; + gz->matrix_offset[1][1] = 0.01; + gz->matrix_offset[2][2] = 0.01; + gz->matrix_offset[3][3] = 1.0f; } /* Start off dragging. */ { wmWindow *win = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); - wmGizmo *mpr = man->cage; + wmGizmo *gz = man->cage; { float mat3[3][3]; @@ -239,19 +239,19 @@ static void gizmo_mesh_placement_modal_from_setup( win->eventstate->y - ar->winrct.ymin, }, location, mat3); - copy_m4_m3(mpr->matrix_basis, mat3); - copy_v3_v3(mpr->matrix_basis[3], location); + copy_m4_m3(gz->matrix_basis, mat3); + copy_v3_v3(gz->matrix_basis[3], location); } if (1) { - wmGizmoMap *mmap = mgroup->parent_mmap; + wmGizmoMap *gzmap = gzgroup->parent_gzmap; WM_gizmo_modal_set_from_setup( - mmap, (bContext *)C, man->cage, ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z, win->eventstate); + gzmap, (bContext *)C, man->cage, ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z, win->eventstate); } } } -static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup) +static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *gzgroup) { wmOperator *op = WM_operator_last_redo(C); @@ -260,11 +260,11 @@ static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup) } struct GizmoPlacementGroup *man = MEM_callocN(sizeof(GizmoPlacementGroup), __func__); - mgroup->customdata = man; + gzgroup->customdata = man; - const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_3d", true); + const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true); - man->cage = WM_gizmo_new_ptr(wt_cage, mgroup, NULL); + man->cage = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL); UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->cage->color); @@ -293,32 +293,32 @@ static void gizmo_mesh_placement_setup(const bContext *C, wmGizmoGroup *mgroup) }); } - gizmo_mesh_placement_modal_from_setup(C, mgroup); + gizmo_mesh_placement_modal_from_setup(C, gzgroup); } static void gizmo_mesh_placement_draw_prepare( - const bContext *UNUSED(C), wmGizmoGroup *mgroup) + const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - GizmoPlacementGroup *man = mgroup->customdata; + GizmoPlacementGroup *man = gzgroup->customdata; if (man->data.op->next) { man->data.op = WM_operator_last_redo((bContext *)man->data.context); } gizmo_mesh_placement_update_from_op(man); } -static void MESH_WGT_add_bounds(struct wmGizmoGroupType *wgt) +static void MESH_GGT_add_bounds(struct wmGizmoGroupType *gzgt) { - wgt->name = "Mesh Add Bounds"; - wgt->idname = "MESH_WGT_add_bounds"; + gzgt->name = "Mesh Add Bounds"; + gzgt->idname = "MESH_GGT_add_bounds"; - wgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = gizmo_mesh_placement_poll; - wgt->setup = gizmo_mesh_placement_setup; - wgt->draw_prepare = gizmo_mesh_placement_draw_prepare; + gzgt->poll = gizmo_mesh_placement_poll; + gzgt->setup = gizmo_mesh_placement_setup; + gzgt->draw_prepare = gizmo_mesh_placement_draw_prepare; } /** \} */ @@ -379,18 +379,18 @@ static int add_primitive_cube_gizmo_invoke(bContext *C, wmOperator *op, const wm int ret = add_primitive_cube_gizmo_exec(C, op); if (ret & OPERATOR_FINISHED) { /* Setup gizmos */ - if (v3d && ((v3d->mpr_flag & V3D_GIZMO_HIDE) == 0)) { + if (v3d && ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) { ARegion *ar = CTX_wm_region(C); - wmGizmoMap *mmap = ar->gizmo_map; - wmGizmoGroupType *wgt = WM_gizmogrouptype_find("MESH_WGT_add_bounds", false); - wmGizmoGroup *mgroup = WM_gizmomap_group_find_ptr(mmap, wgt); - if (mgroup != NULL) { - GizmoPlacementGroup *man = mgroup->customdata; + wmGizmoMap *gzmap = ar->gizmo_map; + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find("MESH_GGT_add_bounds", false); + wmGizmoGroup *gzgroup = WM_gizmomap_group_find_ptr(gzmap, gzgt); + if (gzgroup != NULL) { + GizmoPlacementGroup *man = gzgroup->customdata; man->data.op = op; - gizmo_mesh_placement_modal_from_setup(C, mgroup); + gizmo_mesh_placement_modal_from_setup(C, gzgroup); } else { - WM_gizmo_group_type_ensure_ptr(wgt); + WM_gizmo_group_type_ensure_ptr(gzgt); } } } @@ -420,7 +420,7 @@ void MESH_OT_primitive_cube_add_gizmo(wmOperatorType *ot) PropertyRNA *prop = RNA_def_float_matrix(ot->srna, "matrix", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - WM_gizmogrouptype_append(MESH_WGT_add_bounds); + WM_gizmogrouptype_append(MESH_GGT_add_bounds); } /** \} */ diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index b73ce410626..66e40df2527 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -95,7 +95,7 @@ typedef struct { /* modal only */ float mcenter[2]; void *draw_handle_pixel; - short mpr_flag; + short gizmo_flag; short value_mode; /* Which value does mouse movement and numeric input affect? */ float segments; /* Segments as float so smooth mouse pan works in small increments */ } BevelData; @@ -201,8 +201,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) G.moving = G_TRANSFORM_EDIT; if (v3d) { - opdata->mpr_flag = v3d->mpr_flag; - v3d->mpr_flag = V3D_GIZMO_HIDE; + opdata->gizmo_flag = v3d->gizmo_flag; + v3d->gizmo_flag = V3D_GIZMO_HIDE; } } @@ -284,7 +284,7 @@ static void edbm_bevel_exit(bContext *C, wmOperator *op) } ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel); if (v3d) { - v3d->mpr_flag = opdata->mpr_flag; + v3d->gizmo_flag = opdata->gizmo_flag; } G.moving = 0; } diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index a9e11b7b411..9416d889a3b 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -70,7 +70,7 @@ typedef struct { /* modal only */ BMBackup mesh_backup; bool is_first; - short mpr_flag; + short gizmo_flag; } BisectData; static bool mesh_bisect_interactive_calc( @@ -156,8 +156,8 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* misc other vars */ G.moving = G_TRANSFORM_EDIT; - opdata->mpr_flag = v3d->mpr_flag; - v3d->mpr_flag = V3D_GIZMO_HIDE; + opdata->gizmo_flag = v3d->gizmo_flag; + v3d->gizmo_flag = V3D_GIZMO_HIDE; /* initialize modal callout */ ED_workspace_status_text(C, IFACE_("LMB: Click and drag to draw cut line")); @@ -169,7 +169,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata) { View3D *v3d = CTX_wm_view3d(C); EDBM_redo_state_free(&opdata->mesh_backup, NULL, false); - v3d->mpr_flag = opdata->mpr_flag; + v3d->gizmo_flag = opdata->gizmo_flag; G.moving = 0; } @@ -199,8 +199,8 @@ static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Setup gizmos */ { View3D *v3d = CTX_wm_view3d(C); - if (v3d && (v3d->mpr_flag & V3D_GIZMO_HIDE) == 0) { - WM_gizmo_group_type_ensure("MESH_WGT_bisect"); + if (v3d && (v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { + WM_gizmo_group_type_ensure("MESH_GGT_bisect"); } } #endif @@ -334,7 +334,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op) } #ifdef USE_GIZMO -static void MESH_WGT_bisect(struct wmGizmoGroupType *wgt); +static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt); #endif void MESH_OT_bisect(struct wmOperatorType *ot) @@ -374,7 +374,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot) WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT); #ifdef USE_GIZMO - WM_gizmogrouptype_append(MESH_WGT_bisect); + WM_gizmogrouptype_append(MESH_GGT_bisect); #endif } @@ -459,40 +459,40 @@ static void gizmo_mesh_bisect_update_from_op(GizmoGroup *man) /* depth callbacks */ static void gizmo_bisect_prop_depth_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_co[3], plane_no[3]; RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co); RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no); - value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, mpr->matrix_basis[3]); + value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]); } static void gizmo_bisect_prop_depth_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; const float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_co[3], plane[4]; RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, plane_co); RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane); normalize_v3(plane); - plane[3] = -value[0] - dot_v3v3(plane, mpr->matrix_basis[3]); + plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]); /* Keep our location, may be offset simply to be inside the viewport. */ closest_to_plane_normalized_v3(plane_co, plane, plane_co); @@ -504,27 +504,27 @@ static void gizmo_bisect_prop_depth_set( /* translate callbacks */ static void gizmo_bisect_prop_translate_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; - BLI_assert(mpr_prop->type->array_length == 3); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 3); + UNUSED_VARS_NDEBUG(gz_prop); RNA_property_float_get_array(op->ptr, man->data.prop_plane_co, value_p); } static void gizmo_bisect_prop_translate_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; - BLI_assert(mpr_prop->type->array_length == 3); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 3); + UNUSED_VARS_NDEBUG(gz_prop); RNA_property_float_set_array(op->ptr, man->data.prop_plane_co, value_p); @@ -533,15 +533,15 @@ static void gizmo_bisect_prop_translate_set( /* angle callbacks */ static void gizmo_bisect_prop_angle_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_no[4]; RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no); @@ -560,15 +560,15 @@ static void gizmo_bisect_prop_angle_get( } static void gizmo_bisect_prop_angle_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoGroup *man = mpr->parent_mgroup->customdata; + GizmoGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; const float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_no[4]; RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no); @@ -593,17 +593,17 @@ static void gizmo_bisect_prop_angle_set( } } -static bool gizmo_mesh_bisect_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool gizmo_mesh_bisect_poll(const bContext *C, wmGizmoGroupType *gzgt) { wmOperator *op = WM_operator_last_redo(C); if (op == NULL || !STREQ(op->type->idname, "MESH_OT_bisect")) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } -static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup) +static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *gzgroup) { wmOperator *op = WM_operator_last_redo(C); @@ -612,15 +612,15 @@ static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup) } struct GizmoGroup *man = MEM_callocN(sizeof(GizmoGroup), __func__); - mgroup->customdata = man; + gzgroup->customdata = man; - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true); - const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true); - const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); + const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true); + const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true); - man->translate_z = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - man->translate_c = WM_gizmo_new_ptr(wt_grab, mgroup, NULL); - man->rotate_c = WM_gizmo_new_ptr(wt_dial, mgroup, NULL); + man->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + man->translate_c = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL); + man->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_z->color); UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_c->color); @@ -673,28 +673,28 @@ static void gizmo_mesh_bisect_setup(const bContext *C, wmGizmoGroup *mgroup) } static void gizmo_mesh_bisect_draw_prepare( - const bContext *UNUSED(C), wmGizmoGroup *mgroup) + const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - GizmoGroup *man = mgroup->customdata; + GizmoGroup *man = gzgroup->customdata; if (man->data.op->next) { man->data.op = WM_operator_last_redo((bContext *)man->data.context); } gizmo_mesh_bisect_update_from_op(man); } -static void MESH_WGT_bisect(struct wmGizmoGroupType *wgt) +static void MESH_GGT_bisect(struct wmGizmoGroupType *gzgt) { - wgt->name = "Mesh Bisect"; - wgt->idname = "MESH_WGT_bisect"; + gzgt->name = "Mesh Bisect"; + gzgt->idname = "MESH_GGT_bisect"; - wgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = gizmo_mesh_bisect_poll; - wgt->setup = gizmo_mesh_bisect_setup; - wgt->draw_prepare = gizmo_mesh_bisect_draw_prepare; + gzgt->poll = gizmo_mesh_bisect_poll; + gzgt->setup = gizmo_mesh_bisect_setup; + gzgt->draw_prepare = gizmo_mesh_bisect_draw_prepare; } /** \} */ diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index dd167c1fc15..061cc3ebc32 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -417,31 +417,31 @@ static void gizmo_mesh_extrude_orientation_matrix_set( } } -static bool gizmo_mesh_extrude_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool gizmo_mesh_extrude_poll(const bContext *C, wmGizmoGroupType *gzgt) { ScrArea *sa = CTX_wm_area(C); bToolRef_Runtime *tref_rt = sa->runtime.tool ? sa->runtime.tool->runtime : NULL; if ((tref_rt == NULL) || - !STREQ(wgt->idname, tref_rt->gizmo_group) || + !STREQ(gzgt->idname, tref_rt->gizmo_group) || !ED_operator_editmesh_view3d((bContext *)C)) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } -static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct GizmoExtrudeGroup *man = MEM_callocN(sizeof(GizmoExtrudeGroup), __func__); - mgroup->customdata = man; + gzgroup->customdata = man; - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true); - const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_button_2d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); + const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_button_2d", true); for (int i = 0; i < 4; i++) { - man->adjust_xyz_no[i] = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - man->invoke_xyz_no[i] = WM_gizmo_new_ptr(wt_grab, mgroup, NULL); + man->adjust_xyz_no[i] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + man->invoke_xyz_no[i] = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL); man->invoke_xyz_no[i]->flag |= WM_GIZMO_DRAW_OFFSET_SCALE; } @@ -503,9 +503,9 @@ static void gizmo_mesh_extrude_setup(const bContext *UNUSED(C), wmGizmoGroup *mg } } -static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoExtrudeGroup *man = mgroup->customdata; + GizmoExtrudeGroup *man = gzgroup->customdata; for (int i = 0; i < 4; i++) { WM_gizmo_set_flag(man->invoke_xyz_no[i], WM_GIZMO_HIDDEN, true); @@ -623,9 +623,9 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *mgroup) } } -static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoExtrudeGroup *man = mgroup->customdata; + GizmoExtrudeGroup *man = gzgroup->customdata; switch (man->data.orientation_type) { case V3D_MANIP_VIEW: { @@ -640,38 +640,38 @@ static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *mgr } static void gizmo_mesh_extrude_message_subscribe( - const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus) + const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus) { ARegion *ar = CTX_wm_region(C); /* Subscribe to view properties */ - wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = { + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { .owner = ar, - .user_data = mgroup->parent_mmap, + .user_data = gzgroup->parent_gzmap, .notify = WM_gizmo_do_msg_notify_tag_refresh, }; { - WM_msg_subscribe_rna_anon_prop(mbus, Scene, transform_orientation, &msg_sub_value_mpr_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, Scene, transform_orientation, &msg_sub_value_gz_tag_refresh); } } -static void MESH_WGT_extrude(struct wmGizmoGroupType *wgt) +static void MESH_GGT_extrude(struct wmGizmoGroupType *gzgt) { - wgt->name = "Mesh Extrude"; - wgt->idname = "MESH_WGT_extrude"; + gzgt->name = "Mesh Extrude"; + gzgt->idname = "MESH_GGT_extrude"; - wgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = gizmo_mesh_extrude_poll; - wgt->setup = gizmo_mesh_extrude_setup; - wgt->refresh = gizmo_mesh_extrude_refresh; - wgt->draw_prepare = gizmo_mesh_extrude_draw_prepare; - wgt->message_subscribe = gizmo_mesh_extrude_message_subscribe; + gzgt->poll = gizmo_mesh_extrude_poll; + gzgt->setup = gizmo_mesh_extrude_setup; + gzgt->refresh = gizmo_mesh_extrude_refresh; + gzgt->draw_prepare = gizmo_mesh_extrude_draw_prepare; + gzgt->message_subscribe = gizmo_mesh_extrude_message_subscribe; } #endif /* USE_GIZMO */ @@ -826,7 +826,7 @@ void MESH_OT_extrude_context(wmOperatorType *ot) Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY); #ifdef USE_GIZMO - WM_gizmogrouptype_append(MESH_WGT_extrude); + WM_gizmogrouptype_append(MESH_GGT_extrude); #endif } diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c index 3864bd63036..adb7ee71ee0 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin.c @@ -143,40 +143,40 @@ static void gizmo_mesh_spin_update_from_op(GizmoSpinGroup *man) /* depth callbacks */ static void gizmo_spin_prop_depth_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_co[3], plane_no[3]; RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co); RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no); - value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, mpr->matrix_basis[3]); + value[0] = dot_v3v3(plane_no, plane_co) - dot_v3v3(plane_no, gz->matrix_basis[3]); } static void gizmo_spin_prop_depth_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; const float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_co[3], plane[4]; RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, plane_co); RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane); normalize_v3(plane); - plane[3] = -value[0] - dot_v3v3(plane, mpr->matrix_basis[3]); + plane[3] = -value[0] - dot_v3v3(plane, gz->matrix_basis[3]); /* Keep our location, may be offset simply to be inside the viewport. */ closest_to_plane_normalized_v3(plane_co, plane, plane_co); @@ -188,28 +188,28 @@ static void gizmo_spin_prop_depth_set( /* translate callbacks */ static void gizmo_spin_prop_translate_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 3); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 3); + UNUSED_VARS_NDEBUG(gz_prop); RNA_property_float_get_array(op->ptr, man->data.prop_axis_co, value); } static void gizmo_spin_prop_translate_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; - BLI_assert(mpr_prop->type->array_length == 3); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 3); + UNUSED_VARS_NDEBUG(gz_prop); RNA_property_float_set_array(op->ptr, man->data.prop_axis_co, value); @@ -218,15 +218,15 @@ static void gizmo_spin_prop_translate_set( /* angle callbacks */ static void gizmo_spin_prop_axis_angle_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_no[4]; RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no); @@ -245,15 +245,15 @@ static void gizmo_spin_prop_axis_angle_get( } static void gizmo_spin_prop_axis_angle_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; const float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); float plane_no[4]; RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no); @@ -280,43 +280,43 @@ static void gizmo_spin_prop_axis_angle_set( /* angle callbacks */ static void gizmo_spin_prop_angle_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); value[0] = RNA_property_float_get(op->ptr, man->data.prop_angle); } static void gizmo_spin_prop_angle_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - GizmoSpinGroup *man = mpr->parent_mgroup->customdata; + GizmoSpinGroup *man = gz->parent_gzgroup->customdata; wmOperator *op = man->data.op; - BLI_assert(mpr_prop->type->array_length == 1); - UNUSED_VARS_NDEBUG(mpr_prop); + BLI_assert(gz_prop->type->array_length == 1); + UNUSED_VARS_NDEBUG(gz_prop); const float *value = value_p; RNA_property_float_set(op->ptr, man->data.prop_angle, value[0]); gizmo_spin_exec(man); } -static bool gizmo_mesh_spin_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool gizmo_mesh_spin_poll(const bContext *C, wmGizmoGroupType *gzgt) { wmOperator *op = WM_operator_last_redo(C); if (op == NULL || !STREQ(op->type->idname, "MESH_OT_spin")) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } -static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup) +static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *gzgroup) { wmOperator *op = WM_operator_last_redo(C); @@ -325,16 +325,16 @@ static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup) } struct GizmoSpinGroup *man = MEM_callocN(sizeof(GizmoSpinGroup), __func__); - mgroup->customdata = man; + gzgroup->customdata = man; - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true); - const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true); - const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); + const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true); + const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true); - man->translate_z = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - man->translate_c = WM_gizmo_new_ptr(wt_grab, mgroup, NULL); - man->rotate_c = WM_gizmo_new_ptr(wt_dial, mgroup, NULL); - man->angle_z = WM_gizmo_new_ptr(wt_dial, mgroup, NULL); + man->translate_z = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + man->translate_c = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL); + man->rotate_c = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); + man->angle_z = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_z->color); UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, man->translate_c->color); @@ -403,28 +403,28 @@ static void gizmo_mesh_spin_setup(const bContext *C, wmGizmoGroup *mgroup) } static void gizmo_mesh_spin_draw_prepare( - const bContext *UNUSED(C), wmGizmoGroup *mgroup) + const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - GizmoSpinGroup *man = mgroup->customdata; + GizmoSpinGroup *man = gzgroup->customdata; if (man->data.op->next) { man->data.op = WM_operator_last_redo((bContext *)man->data.context); } gizmo_mesh_spin_update_from_op(man); } -static void MESH_WGT_spin(struct wmGizmoGroupType *wgt) +static void MESH_GGT_spin(struct wmGizmoGroupType *gzgt) { - wgt->name = "Mesh Spin"; - wgt->idname = "MESH_WGT_spin"; + gzgt->name = "Mesh Spin"; + gzgt->idname = "MESH_GGT_spin"; - wgt->flag = WM_GIZMOGROUPTYPE_3D; + gzgt->flag = WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = gizmo_mesh_spin_poll; - wgt->setup = gizmo_mesh_spin_setup; - wgt->draw_prepare = gizmo_mesh_spin_draw_prepare; + gzgt->poll = gizmo_mesh_spin_poll; + gzgt->setup = gizmo_mesh_spin_setup; + gzgt->draw_prepare = gizmo_mesh_spin_draw_prepare; } /** \} */ @@ -511,8 +511,8 @@ static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e #ifdef USE_GIZMO if (ret & OPERATOR_FINISHED) { /* Setup gizmos */ - if (v3d && ((v3d->mpr_flag & V3D_GIZMO_HIDE) == 0)) { - WM_gizmo_group_type_ensure("MESH_WGT_spin"); + if (v3d && ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) { + WM_gizmo_group_type_ensure("MESH_GGT_spin"); } } #endif @@ -549,6 +549,6 @@ void MESH_OT_spin(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -1.0f, 1.0f); #ifdef USE_GIZMO - WM_gizmogrouptype_append(MESH_WGT_spin); + WM_gizmogrouptype_append(MESH_GGT_spin); #endif } diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c index 1be180b852c..486203462a0 100644 --- a/source/blender/editors/mesh/editmesh_inset.c +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -78,7 +78,7 @@ typedef struct { /* modal only */ float mcenter[2]; void *draw_handle_pixel; - short mpr_flag; + short gizmo_flag; } InsetData; @@ -173,8 +173,8 @@ static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal) ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL); G.moving = G_TRANSFORM_EDIT; if (v3d) { - opdata->mpr_flag = v3d->mpr_flag; - v3d->mpr_flag = V3D_GIZMO_HIDE; + opdata->gizmo_flag = v3d->gizmo_flag; + v3d->gizmo_flag = V3D_GIZMO_HIDE; } } @@ -196,7 +196,7 @@ static void edbm_inset_exit(bContext *C, wmOperator *op) } ED_region_draw_cb_exit(ar->type, opdata->draw_handle_pixel); if (v3d) { - v3d->mpr_flag = opdata->mpr_flag; + v3d->gizmo_flag = opdata->gizmo_flag; } G.moving = 0; } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 68b0f42768a..d87bfbe00ce 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -581,25 +581,25 @@ static int image_context(const bContext *C, const char *member, bContextDataResu return 0; } -static void IMAGE_WGT_gizmo2d(wmGizmoGroupType *wgt) +static void IMAGE_GGT_gizmo2d(wmGizmoGroupType *gzgt) { - wgt->name = "UV Transform Gizmo"; - wgt->idname = "IMAGE_WGT_gizmo2d"; + gzgt->name = "UV Transform Gizmo"; + gzgt->idname = "IMAGE_GGT_gizmo2d"; - wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; - wgt->poll = ED_widgetgroup_gizmo2d_poll; - wgt->setup = ED_widgetgroup_gizmo2d_setup; - wgt->refresh = ED_widgetgroup_gizmo2d_refresh; - wgt->draw_prepare = ED_widgetgroup_gizmo2d_draw_prepare; + gzgt->poll = ED_widgetgroup_gizmo2d_poll; + gzgt->setup = ED_widgetgroup_gizmo2d_setup; + gzgt->refresh = ED_widgetgroup_gizmo2d_refresh; + gzgt->draw_prepare = ED_widgetgroup_gizmo2d_draw_prepare; } static void image_widgets(void) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure( + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure( &(const struct wmGizmoMapType_Params){SPACE_IMAGE, RGN_TYPE_WINDOW}); - WM_gizmogrouptype_append_and_link(mmap_type, IMAGE_WGT_gizmo2d); + WM_gizmogrouptype_append_and_link(gzmap_type, IMAGE_GGT_gizmo2d); } /************************** main region ***************************/ diff --git a/source/blender/editors/space_node/node_gizmo.c b/source/blender/editors/space_node/node_gizmo.c index 37ea53aa710..b265d95c06a 100644 --- a/source/blender/editors/space_node/node_gizmo.c +++ b/source/blender/editors/space_node/node_gizmo.c @@ -83,12 +83,12 @@ static void node_gizmo_calc_matrix_space_with_image_dims( * \{ */ static void gizmo_node_backdrop_prop_matrix_get( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - const SpaceNode *snode = mpr_prop->custom_func.user_data; + BLI_assert(gz_prop->type->array_length == 16); + const SpaceNode *snode = gz_prop->custom_func.user_data; matrix[0][0] = snode->zoom; matrix[1][1] = snode->zoom; matrix[3][0] = snode->xof; @@ -96,19 +96,19 @@ static void gizmo_node_backdrop_prop_matrix_get( } static void gizmo_node_backdrop_prop_matrix_set( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { const float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - SpaceNode *snode = mpr_prop->custom_func.user_data; + BLI_assert(gz_prop->type->array_length == 16); + SpaceNode *snode = gz_prop->custom_func.user_data; snode->zoom = matrix[0][0]; snode->zoom = matrix[1][1]; snode->xof = matrix[3][0]; snode->yof = matrix[3][1]; } -static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -127,22 +127,22 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType return false; } -static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL); + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); RNA_enum_set(wwrapper->gizmo->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM); - mgroup->customdata = wwrapper; + gzgroup->customdata = wwrapper; } -static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - wmGizmo *cage = ((wmGizmoWrapper *)mgroup->customdata)->gizmo; + wmGizmo *cage = ((wmGizmoWrapper *)gzgroup->customdata)->gizmo; const ARegion *ar = CTX_wm_region(C); /* center is always at the origin */ const float origin[3] = {ar->winx / 2, ar->winy / 2}; @@ -186,16 +186,16 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup * BKE_image_release_ibuf(ima, ibuf, lock); } -void NODE_WGT_backdrop_transform(wmGizmoGroupType *wgt) +void NODE_GGT_backdrop_transform(wmGizmoGroupType *gzgt) { - wgt->name = "Backdrop Transform Widget"; - wgt->idname = "NODE_WGT_backdrop_transform"; + gzgt->name = "Backdrop Transform Widget"; + gzgt->idname = "NODE_GGT_backdrop_transform"; - wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; - wgt->poll = WIDGETGROUP_node_transform_poll; - wgt->setup = WIDGETGROUP_node_transform_setup; - wgt->refresh = WIDGETGROUP_node_transform_refresh; + gzgt->poll = WIDGETGROUP_node_transform_poll; + gzgt->setup = WIDGETGROUP_node_transform_setup; + gzgt->refresh = WIDGETGROUP_node_transform_refresh; } /** \} */ @@ -258,14 +258,14 @@ static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims /* scale callbacks */ static void gizmo_node_crop_prop_matrix_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + BLI_assert(gz_prop->type->array_length == 16); + struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata; const float *dims = crop_group->state.dims; - const bNode *node = mpr_prop->custom_func.user_data; + const bNode *node = gz_prop->custom_func.user_data; const NodeTwoXYs *nxy = node->storage; bool is_relative = (bool)node->custom2; rctf rct; @@ -277,14 +277,14 @@ static void gizmo_node_crop_prop_matrix_get( } static void gizmo_node_crop_prop_matrix_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { const float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + BLI_assert(gz_prop->type->array_length == 16); + struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata; const float *dims = crop_group->state.dims; - bNode *node = mpr_prop->custom_func.user_data; + bNode *node = gz_prop->custom_func.user_data; NodeTwoXYs *nxy = node->storage; bool is_relative = (bool)node->custom2; rctf rct; @@ -296,7 +296,7 @@ static void gizmo_node_crop_prop_matrix_set( gizmo_node_crop_update(crop_group); } -static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -318,33 +318,33 @@ static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUS return false; } -static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), __func__); - crop_group->border = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL); + crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); RNA_enum_set(crop_group->border->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE); - mgroup->customdata = crop_group; + gzgroup->customdata = crop_group; } -static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *ar = CTX_wm_region(C); - wmGizmo *mpr = mgroup->gizmos.first; + wmGizmo *gz = gzgroup->gizmos.first; SpaceNode *snode = CTX_wm_space_node(C); - node_gizmo_calc_matrix_space(snode, ar, mpr->matrix_space); + node_gizmo_calc_matrix_space(snode, ar, gz->matrix_space); } -static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeCropWidgetGroup *crop_group = mgroup->customdata; - wmGizmo *mpr = crop_group->border; + struct NodeCropWidgetGroup *crop_group = gzgroup->customdata; + wmGizmo *gz = crop_group->border; void *lock; Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); @@ -354,8 +354,8 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; crop_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f; - RNA_float_set_array(mpr->ptr, "dimensions", crop_group->state.dims); - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + RNA_float_set_array(gz->ptr, "dimensions", crop_group->state.dims); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); SpaceNode *snode = CTX_wm_space_node(C); bNode *node = nodeGetActive(snode->edittree); @@ -365,7 +365,7 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative"); WM_gizmo_target_property_def_func( - mpr, "matrix", + gz, "matrix", &(const struct wmGizmoPropertyFnParams) { .value_get_fn = gizmo_node_crop_prop_matrix_get, .value_set_fn = gizmo_node_crop_prop_matrix_set, @@ -374,23 +374,23 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *mgrou }); } else { - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } BKE_image_release_ibuf(ima, ibuf, lock); } -void NODE_WGT_backdrop_crop(wmGizmoGroupType *wgt) +void NODE_GGT_backdrop_crop(wmGizmoGroupType *gzgt) { - wgt->name = "Backdrop Crop Widget"; - wgt->idname = "NODE_WGT_backdrop_crop"; + gzgt->name = "Backdrop Crop Widget"; + gzgt->idname = "NODE_GGT_backdrop_crop"; - wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; - wgt->poll = WIDGETGROUP_node_crop_poll; - wgt->setup = WIDGETGROUP_node_crop_setup; - wgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare; - wgt->refresh = WIDGETGROUP_node_crop_refresh; + gzgt->poll = WIDGETGROUP_node_crop_poll; + gzgt->setup = WIDGETGROUP_node_crop_setup; + gzgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare; + gzgt->refresh = WIDGETGROUP_node_crop_refresh; } /** \} */ @@ -408,7 +408,7 @@ struct NodeSunBeamsWidgetGroup { } state; }; -static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -427,36 +427,36 @@ static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNU return false; } -static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), __func__); - sbeam_group->gizmo = WM_gizmo_new("GIZMO_WT_grab_3d", mgroup, NULL); - wmGizmo *mpr = sbeam_group->gizmo; + sbeam_group->gizmo = WM_gizmo_new("GIZMO_GT_grab_3d", gzgroup, NULL); + wmGizmo *gz = sbeam_group->gizmo; - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D); - mpr->scale_basis = 0.05f; + gz->scale_basis = 0.05f; - mgroup->customdata = sbeam_group; + gzgroup->customdata = sbeam_group; } -static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata; + struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata; ARegion *ar = CTX_wm_region(C); - wmGizmo *mpr = mgroup->gizmos.first; + wmGizmo *gz = gzgroup->gizmos.first; SpaceNode *snode = CTX_wm_space_node(C); - node_gizmo_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, mpr->matrix_space); + node_gizmo_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, gz->matrix_space); } -static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata; - wmGizmo *mpr = sbeam_group->gizmo; + struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata; + wmGizmo *gz = sbeam_group->gizmo; void *lock; Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); @@ -472,28 +472,28 @@ static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *mgro /* need to set property here for undo. TODO would prefer to do this in _init */ PointerRNA nodeptr; RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr); - WM_gizmo_target_property_def_rna(mpr, "offset", &nodeptr, "source", -1); + WM_gizmo_target_property_def_rna(gz, "offset", &nodeptr, "source", -1); - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_MODAL, true); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_MODAL, true); } else { - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } BKE_image_release_ibuf(ima, ibuf, lock); } -void NODE_WGT_backdrop_sun_beams(wmGizmoGroupType *wgt) +void NODE_GGT_backdrop_sun_beams(wmGizmoGroupType *gzgt) { - wgt->name = "Sun Beams Widget"; - wgt->idname = "NODE_WGT_sbeam"; + gzgt->name = "Sun Beams Widget"; + gzgt->idname = "NODE_GGT_sbeam"; - wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; - wgt->poll = WIDGETGROUP_node_sbeam_poll; - wgt->setup = WIDGETGROUP_node_sbeam_setup; - wgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare; - wgt->refresh = WIDGETGROUP_node_sbeam_refresh; + gzgt->poll = WIDGETGROUP_node_sbeam_poll; + gzgt->setup = WIDGETGROUP_node_sbeam_setup; + gzgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare; + gzgt->refresh = WIDGETGROUP_node_sbeam_refresh; } /** \} */ @@ -513,7 +513,7 @@ struct NodeCornerPinWidgetGroup { } state; }; -static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -532,26 +532,26 @@ static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType return false; } -static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN(sizeof(struct NodeCornerPinWidgetGroup), __func__); - const wmGizmoType *wt_grab_3d = WM_gizmotype_find("GIZMO_WT_grab_3d", false); + const wmGizmoType *gzt_grab_3d = WM_gizmotype_find("GIZMO_GT_grab_3d", false); for (int i = 0; i < 4; i++) { - cpin_group->gizmos[i] = WM_gizmo_new_ptr(wt_grab_3d, mgroup, NULL); - wmGizmo *mpr = cpin_group->gizmos[i]; + cpin_group->gizmos[i] = WM_gizmo_new_ptr(gzt_grab_3d, gzgroup, NULL); + wmGizmo *gz = cpin_group->gizmos[i]; - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_CROSS_2D); - mpr->scale_basis = 0.01f; + gz->scale_basis = 0.01f; } - mgroup->customdata = cpin_group; + gzgroup->customdata = cpin_group; } -static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata; + struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata; ARegion *ar = CTX_wm_region(C); SpaceNode *snode = CTX_wm_space_node(C); @@ -560,15 +560,15 @@ static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoG node_gizmo_calc_matrix_space_with_image_dims(snode, ar, cpin_group->state.dims, matrix_space); for (int i = 0; i < 4; i++) { - wmGizmo *mpr = cpin_group->gizmos[i]; - copy_m4_m4(mpr->matrix_space, matrix_space); + wmGizmo *gz = cpin_group->gizmos[i]; + copy_m4_m4(gz->matrix_space, matrix_space); } } -static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata; + struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata; void *lock; Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); @@ -585,37 +585,37 @@ static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup int i = 0; for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) { if (sock->type == SOCK_VECTOR) { - wmGizmo *mpr = cpin_group->gizmos[i++]; + wmGizmo *gz = cpin_group->gizmos[i++]; PointerRNA sockptr; RNA_pointer_create((ID *)snode->edittree, &RNA_NodeSocket, sock, &sockptr); - WM_gizmo_target_property_def_rna(mpr, "offset", &sockptr, "default_value", -1); + WM_gizmo_target_property_def_rna(gz, "offset", &sockptr, "default_value", -1); - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_MODAL, true); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_MODAL, true); } } } else { for (int i = 0; i < 4; i++) { - wmGizmo *mpr = cpin_group->gizmos[i]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + wmGizmo *gz = cpin_group->gizmos[i]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } } BKE_image_release_ibuf(ima, ibuf, lock); } -void NODE_WGT_backdrop_corner_pin(wmGizmoGroupType *wgt) +void NODE_GGT_backdrop_corner_pin(wmGizmoGroupType *gzgt) { - wgt->name = "Corner Pin Widget"; - wgt->idname = "NODE_WGT_backdrop_corner_pin"; + gzgt->name = "Corner Pin Widget"; + gzgt->idname = "NODE_GGT_backdrop_corner_pin"; - wgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; + gzgt->flag |= WM_GIZMOGROUPTYPE_PERSISTENT; - wgt->poll = WIDGETGROUP_node_corner_pin_poll; - wgt->setup = WIDGETGROUP_node_corner_pin_setup; - wgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare; - wgt->refresh = WIDGETGROUP_node_corner_pin_refresh; + gzgt->poll = WIDGETGROUP_node_corner_pin_poll; + gzgt->setup = WIDGETGROUP_node_corner_pin_setup; + gzgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare; + gzgt->refresh = WIDGETGROUP_node_corner_pin_refresh; } /** \} */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 742c3975c8d..1a0f738ab8a 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -224,10 +224,10 @@ void NODE_OT_viewer_border(struct wmOperatorType *ot); void NODE_OT_clear_viewer_border(struct wmOperatorType *ot); /* node_widgets.c */ -void NODE_WGT_backdrop_transform(struct wmGizmoGroupType *wgt); -void NODE_WGT_backdrop_crop(struct wmGizmoGroupType *wgt); -void NODE_WGT_backdrop_sun_beams(struct wmGizmoGroupType *wgt); -void NODE_WGT_backdrop_corner_pin(struct wmGizmoGroupType *wgt); +void NODE_GGT_backdrop_transform(struct wmGizmoGroupType *gzgt); +void NODE_GGT_backdrop_crop(struct wmGizmoGroupType *gzgt); +void NODE_GGT_backdrop_sun_beams(struct wmGizmoGroupType *gzgt); +void NODE_GGT_backdrop_corner_pin(struct wmGizmoGroupType *gzgt); extern const char *node_context_dir[]; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 1149b910947..10f337440d4 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -752,7 +752,7 @@ static void node_region_listener( wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene)) { - wmGizmoMap *mmap = ar->gizmo_map; + wmGizmoMap *gzmap = ar->gizmo_map; /* context changes */ switch (wmn->category) { @@ -762,13 +762,13 @@ static void node_region_listener( ED_region_tag_redraw(ar); break; case ND_SPACE_NODE_VIEW: - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; } break; case NC_SCREEN: if (wmn->data == ND_LAYOUTSET || wmn->action == NA_EDITED) { - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } switch (wmn->data) { case ND_ANIMPLAY: @@ -784,13 +784,13 @@ static void node_region_listener( case NC_SCENE: ED_region_tag_redraw(ar); if (wmn->data == ND_RENDER_RESULT) { - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } break; case NC_NODE: ED_region_tag_redraw(ar); if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) { - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } break; case NC_MATERIAL: @@ -863,12 +863,12 @@ static int node_context(const bContext *C, const char *member, bContextDataResul static void node_widgets(void) { /* create the widgetmap for the area here */ - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure( + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure( &(const struct wmGizmoMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW}); - WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform); - WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop); - WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_sun_beams); - WM_gizmogrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_corner_pin); + WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_transform); + WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_crop); + WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_sun_beams); + WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_corner_pin); } static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 6d4009e9d2b..dca4b3f4f76 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -716,26 +716,26 @@ static void view3d_dropboxes(void) static void view3d_widgets(void) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure( + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure( &(const struct wmGizmoMapType_Params){SPACE_VIEW3D, RGN_TYPE_WINDOW}); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_spot); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_area); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_lamp_target); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_spot); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_area); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_lamp_target); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_force_field); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline); - WM_gizmogrouptype_append(TRANSFORM_WGT_gizmo); - WM_gizmogrouptype_append(VIEW3D_WGT_xform_cage); + WM_gizmogrouptype_append(TRANSFORM_GGT_gizmo); + WM_gizmogrouptype_append(VIEW3D_GGT_xform_cage); - WM_gizmogrouptype_append(VIEW3D_WGT_ruler); - WM_gizmotype_append(VIEW3D_WT_ruler_item); + WM_gizmogrouptype_append(VIEW3D_GGT_ruler); + WM_gizmotype_append(VIEW3D_GT_ruler_item); - WM_gizmogrouptype_append_and_link(mmap_type, VIEW3D_WGT_navigate); - WM_gizmotype_append(VIEW3D_WT_navigate_rotate); + WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_navigate); + WM_gizmotype_append(VIEW3D_GT_navigate_rotate); } @@ -815,13 +815,13 @@ static void view3d_main_region_listener( { View3D *v3d = sa->spacedata.first; RegionView3D *rv3d = ar->regiondata; - wmGizmoMap *mmap = ar->gizmo_map; + wmGizmoMap *gzmap = ar->gizmo_map; /* context changes */ switch (wmn->category) { case NC_WM: if (ELEM(wmn->data, ND_UNDO)) { - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } break; case NC_ANIMATION: @@ -848,14 +848,14 @@ static void view3d_main_region_listener( if (wmn->reference) view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; case ND_LAYER: if (wmn->reference) { BKE_screen_view3d_sync(v3d, wmn->reference); } ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; case ND_OB_ACTIVE: case ND_OB_SELECT: @@ -867,7 +867,7 @@ static void view3d_main_region_listener( case ND_MARKERS: case ND_MODE: ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; case ND_WORLD: /* handled by space_view3d_listener() for v3d access */ @@ -899,7 +899,7 @@ static void view3d_main_region_listener( case ND_POINTCACHE: case ND_LOD: ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; } switch (wmn->action) { @@ -912,7 +912,7 @@ static void view3d_main_region_listener( switch (wmn->data) { case ND_SELECT: { - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); ATTR_FALLTHROUGH; } case ND_DATA: @@ -993,7 +993,7 @@ static void view3d_main_region_listener( break; case ND_LIGHTING_DRAW: ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); break; } break; @@ -1019,7 +1019,7 @@ static void view3d_main_region_listener( rv3d->rflag |= RV3D_GPULIGHT_UPDATE; } ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } break; case NC_ID: @@ -1035,7 +1035,7 @@ static void view3d_main_region_listener( case ND_LAYOUTBROWSE: case ND_LAYOUTDELETE: case ND_LAYOUTSET: - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); ED_region_tag_redraw(ar); break; case ND_LAYER: diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index be79cef182d..89d01727d9b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1207,7 +1207,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int UNUSED(of if ((U.uiflag & USER_SHOW_GIZMO_AXIS) || (v3d->flag2 & V3D_RENDER_OVERRIDE) || /* No need to display gizmo and this info. */ - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) { /* pass */ } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c index c7b12529798..88a95e89bd8 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c @@ -80,14 +80,14 @@ struct BoneSplineWidgetGroup { }; static void gizmo_bbone_offset_get( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { - struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data; + struct BoneSplineHandle *bh = gz_prop->custom_func.user_data; bPoseChannel *pchan = bh->pchan; float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 3); + BLI_assert(gz_prop->type->array_length == 3); if (bh->index == 0) { bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y; @@ -103,15 +103,15 @@ static void gizmo_bbone_offset_get( } static void gizmo_bbone_offset_set( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { - struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data; + struct BoneSplineHandle *bh = gz_prop->custom_func.user_data; bPoseChannel *pchan = bh->pchan; const float *value = value_p; - BLI_assert(mpr_prop->type->array_length == 3); + BLI_assert(gz_prop->type->array_length == 3); copy_v3_v3(bh->co, value); if (bh->index == 0) { @@ -127,7 +127,7 @@ static void gizmo_bbone_offset_set( } -static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); if (ob != NULL) { @@ -136,7 +136,7 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType if (arm->act_bone && arm->act_bone->segments > 1) { View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { /* pass */ } @@ -150,59 +150,59 @@ static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmGizmoGroupType } -static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmGizmoGroup *gzgroup) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bPoseChannel *pchan = BKE_pose_channel_active(ob); - const wmGizmoType *wt_grab = WM_gizmotype_find("GIZMO_WT_grab_3d", true); + const wmGizmoType *gzt_grab = WM_gizmotype_find("GIZMO_GT_grab_3d", true); struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__); - mgroup->customdata = bspline_group; + gzgroup->customdata = bspline_group; /* Handles */ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) { - wmGizmo *mpr; - mpr = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(wt_grab, mgroup, NULL); - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_RING_2D); - RNA_enum_set(mpr->ptr, "draw_options", + wmGizmo *gz; + gz = bspline_group->handles[i].gizmo = WM_gizmo_new_ptr(gzt_grab, gzgroup, NULL); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_GRAB_STYLE_RING_2D); + RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_GRAB_DRAW_FLAG_FILL | ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW); - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_VALUE, true); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_VALUE, true); - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); - mpr->scale_basis = 0.06f; + gz->scale_basis = 0.06f; if (i == 0) { - copy_v3_v3(mpr->matrix_basis[3], pchan->loc); + copy_v3_v3(gz->matrix_basis[3], pchan->loc); } } } -static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); - if (!mgroup->customdata) + if (!gzgroup->customdata) return; - struct BoneSplineWidgetGroup *bspline_group = mgroup->customdata; + struct BoneSplineWidgetGroup *bspline_group = gzgroup->customdata; bPoseChannel *pchan = BKE_pose_channel_active(ob); /* Handles */ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) { - wmGizmo *mpr = bspline_group->handles[i].gizmo; + wmGizmo *gz = bspline_group->handles[i].gizmo; bspline_group->handles[i].pchan = pchan; bspline_group->handles[i].index = i; float mat[4][4]; mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat); - copy_m4_m4(mpr->matrix_space, mat); + copy_m4_m4(gz->matrix_space, mat); /* need to set property here for undo. TODO would prefer to do this in _init */ WM_gizmo_target_property_def_func( - mpr, "offset", + gz, "offset", &(const struct wmGizmoPropertyFnParams) { .value_get_fn = gizmo_bbone_offset_get, .value_set_fn = gizmo_bbone_offset_set, @@ -212,17 +212,17 @@ static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmGizmoGroup } } -void VIEW3D_WGT_armature_spline(wmGizmoGroupType *wgt) +void VIEW3D_GGT_armature_spline(wmGizmoGroupType *gzgt) { - wgt->name = "Armature Spline Widgets"; - wgt->idname = "VIEW3D_WGT_armature_spline"; + gzgt->name = "Armature Spline Widgets"; + gzgt->idname = "VIEW3D_GGT_armature_spline"; - wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D); - wgt->poll = WIDGETGROUP_armature_spline_poll; - wgt->setup = WIDGETGROUP_armature_spline_setup; - wgt->refresh = WIDGETGROUP_armature_spline_refresh; + gzgt->poll = WIDGETGROUP_armature_spline_poll; + gzgt->setup = WIDGETGROUP_armature_spline_setup; + gzgt->refresh = WIDGETGROUP_armature_spline_refresh; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_camera.c b/source/blender/editors/space_view3d/view3d_gizmo_camera.c index b011e6e2e21..87b11f5d7a3 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_camera.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_camera.c @@ -61,11 +61,11 @@ struct CameraWidgetGroup { wmGizmo *ortho_scale; }; -static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { return false; } @@ -81,57 +81,57 @@ static bool WIDGETGROUP_camera_poll(const bContext *C, wmGizmoGroupType *UNUSED( return false; } -static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_camera_setup(const bContext *C, wmGizmoGroup *gzgroup) { Object *ob = CTX_data_active_object(C); float dir[3]; - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); - struct CameraWidgetGroup *camgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); - mgroup->customdata = camgroup; + struct CameraWidgetGroup *cagzgroup = MEM_callocN(sizeof(struct CameraWidgetGroup), __func__); + gzgroup->customdata = cagzgroup; negate_v3_v3(dir, ob->obmat[2]); /* dof distance */ { - wmGizmo *mpr; - mpr = camgroup->dop_dist = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS); - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true); + wmGizmo *gz; + gz = cagzgroup->dop_dist = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CROSS); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true); - UI_GetThemeColor3fv(TH_GIZMO_A, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_A, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); } /* focal length * - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */ { - wmGizmo *mpr; - mpr = camgroup->focal_len = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - mpr->flag |= WM_GIZMO_DRAW_NO_SCALE; - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE); - RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); - - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); - - mpr = camgroup->ortho_scale = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - mpr->flag |= WM_GIZMO_DRAW_NO_SCALE; - RNA_enum_set(mpr->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE); - RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); - - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + wmGizmo *gz; + gz = cagzgroup->focal_len = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + gz->flag |= WM_GIZMO_DRAW_NO_SCALE; + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE); + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); + + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); + + gz = cagzgroup->ortho_scale = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + gz->flag |= WM_GIZMO_DRAW_NO_SCALE; + RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_CONE); + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); + + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); } } -static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - if (!mgroup->customdata) + if (!gzgroup->customdata) return; - struct CameraWidgetGroup *camgroup = mgroup->customdata; + struct CameraWidgetGroup *cagzgroup = gzgroup->customdata; Object *ob = CTX_data_active_object(C); Camera *ca = ob->data; PointerRNA camera_ptr; @@ -149,16 +149,16 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup) negate_v3_v3(dir, ob->obmat[2]); if (ca->flag & CAM_SHOWLIMITS) { - WM_gizmo_set_matrix_location(camgroup->dop_dist, ob->obmat[3]); - WM_gizmo_set_matrix_rotation_from_yz_axis(camgroup->dop_dist, ob->obmat[1], dir); - WM_gizmo_set_scale(camgroup->dop_dist, ca->drawsize); - WM_gizmo_set_flag(camgroup->dop_dist, WM_GIZMO_HIDDEN, false); + WM_gizmo_set_matrix_location(cagzgroup->dop_dist, ob->obmat[3]); + WM_gizmo_set_matrix_rotation_from_yz_axis(cagzgroup->dop_dist, ob->obmat[1], dir); + WM_gizmo_set_scale(cagzgroup->dop_dist, ca->drawsize); + WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, false); /* need to set property here for undo. TODO would prefer to do this in _init */ - WM_gizmo_target_property_def_rna(camgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); + WM_gizmo_target_property_def_rna(cagzgroup->dop_dist, "offset", &camera_ptr, "dof_distance", -1); } else { - WM_gizmo_set_flag(camgroup->dop_dist, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(cagzgroup->dop_dist, WM_GIZMO_HIDDEN, true); } /* TODO - make focal length/ortho ob_scale_inv widget optional */ @@ -167,14 +167,14 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup) const float aspy = (float)scene->r.ysch * scene->r.yasp; const bool is_ortho = (ca->type == CAM_ORTHO); const int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, aspx, aspy); - wmGizmo *widget = is_ortho ? camgroup->ortho_scale : camgroup->focal_len; + wmGizmo *widget = is_ortho ? cagzgroup->ortho_scale : cagzgroup->focal_len; float scale_matrix; if (true) { float offset[3]; float aspect[2]; WM_gizmo_set_flag(widget, WM_GIZMO_HIDDEN, false); - WM_gizmo_set_flag(is_ortho ? camgroup->focal_len : camgroup->ortho_scale, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(is_ortho ? cagzgroup->focal_len : cagzgroup->ortho_scale, WM_GIZMO_HIDDEN, true); /* account for lens shifting */ @@ -208,9 +208,9 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup) { const char *propname = is_ortho ? "ortho_scale" : "lens"; PropertyRNA *prop = RNA_struct_find_property(&camera_ptr, propname); - const wmGizmoPropertyType *mpr_prop_type = WM_gizmotype_target_property_find(widget->type, "offset"); + const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(widget->type, "offset"); - WM_gizmo_target_property_clear_rna_ptr(widget, mpr_prop_type); + WM_gizmo_target_property_clear_rna_ptr(widget, gz_prop_type); float min, max, range; float step, precision; @@ -226,21 +226,21 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmGizmoGroup *mgroup) /* Half sensor, intentionally use sensor from camera and not calculated above. */ (0.5f * ((ca->sensor_fit == CAMERA_SENSOR_FIT_HOR) ? ca->sensor_x : ca->sensor_x)))); - WM_gizmo_target_property_def_rna_ptr(widget, mpr_prop_type, &camera_ptr, prop, -1); + WM_gizmo_target_property_def_rna_ptr(widget, gz_prop_type, &camera_ptr, prop, -1); } } static void WIDGETGROUP_camera_message_subscribe( - const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus) + const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus) { ARegion *ar = CTX_wm_region(C); Object *ob = CTX_data_active_object(C); Camera *ca = ob->data; - wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = { + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { .owner = ar, - .user_data = mgroup->parent_mmap, + .user_data = gzgroup->parent_gzmap, .notify = WM_gizmo_do_msg_notify_tag_refresh, }; @@ -270,32 +270,32 @@ static void WIDGETGROUP_camera_message_subscribe( RNA_id_pointer_create(&ca->id, &idptr); for (int i = 0; i < ARRAY_SIZE(props); i++) { - WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__); + WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); } } /* Subscribe to render settings */ { - WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_mpr_tag_refresh); - WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_mpr_tag_refresh); - WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_mpr_tag_refresh); - WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_mpr_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_x, &msg_sub_value_gz_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, resolution_y, &msg_sub_value_gz_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_x, &msg_sub_value_gz_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, RenderSettings, pixel_aspect_y, &msg_sub_value_gz_tag_refresh); } } -void VIEW3D_WGT_camera(wmGizmoGroupType *wgt) +void VIEW3D_GGT_camera(wmGizmoGroupType *gzgt) { - wgt->name = "Camera Widgets"; - wgt->idname = "VIEW3D_WGT_camera"; + gzgt->name = "Camera Widgets"; + gzgt->idname = "VIEW3D_GGT_camera"; - wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D); - wgt->poll = WIDGETGROUP_camera_poll; - wgt->setup = WIDGETGROUP_camera_setup; - wgt->refresh = WIDGETGROUP_camera_refresh; - wgt->message_subscribe = WIDGETGROUP_camera_message_subscribe; + gzgt->poll = WIDGETGROUP_camera_poll; + gzgt->setup = WIDGETGROUP_camera_setup; + gzgt->refresh = WIDGETGROUP_camera_refresh; + gzgt->message_subscribe = WIDGETGROUP_camera_message_subscribe; } /** \} */ @@ -316,12 +316,12 @@ struct CameraViewWidgetGroup { /* scale callbacks */ static void gizmo_render_border_prop_matrix_get( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + BLI_assert(gz_prop->type->array_length == 16); + struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data; const rctf *border = viewgroup->state.edit_border; unit_m4(matrix); @@ -332,20 +332,20 @@ static void gizmo_render_border_prop_matrix_get( } static void gizmo_render_border_prop_matrix_set( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { const float (*matrix)[4] = value_p; - struct CameraViewWidgetGroup *viewgroup = mpr_prop->custom_func.user_data; + struct CameraViewWidgetGroup *viewgroup = gz_prop->custom_func.user_data; rctf *border = viewgroup->state.edit_border; - BLI_assert(mpr_prop->type->array_length == 16); + BLI_assert(gz_prop->type->array_length == 16); BLI_rctf_resize(border, len_v3(matrix[0]), len_v3(matrix[1])); BLI_rctf_recenter(border, matrix[3][0], matrix[3][1]); BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, border, border); } -static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { Scene *scene = CTX_data_scene(C); @@ -361,7 +361,7 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UN View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { return false; } @@ -382,11 +382,11 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmGizmoGroupType *UN return false; } -static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct CameraViewWidgetGroup *viewgroup = MEM_mallocN(sizeof(struct CameraViewWidgetGroup), __func__); - viewgroup->border = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL); + viewgroup->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); RNA_enum_set(viewgroup->border->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE); @@ -394,12 +394,12 @@ static void WIDGETGROUP_camera_view_setup(const bContext *UNUSED(C), wmGizmoGrou RNA_enum_set(viewgroup->border->ptr, "draw_style", ED_GIZMO_CAGE2D_STYLE_BOX); - mgroup->customdata = viewgroup; + gzgroup->customdata = viewgroup; } -static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct CameraViewWidgetGroup *viewgroup = mgroup->customdata; + struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata; ARegion *ar = CTX_wm_region(C); struct Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -413,17 +413,17 @@ static void WIDGETGROUP_camera_view_draw_prepare(const bContext *C, wmGizmoGroup viewgroup->state.view_border = (rctf){.xmin = 0, .ymin = 0, .xmax = ar->winx, .ymax = ar->winy}; } - wmGizmo *mpr = viewgroup->border; - unit_m4(mpr->matrix_space); - mul_v3_fl(mpr->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border)); - mul_v3_fl(mpr->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border)); - mpr->matrix_space[3][0] = viewgroup->state.view_border.xmin; - mpr->matrix_space[3][1] = viewgroup->state.view_border.ymin; + wmGizmo *gz = viewgroup->border; + unit_m4(gz->matrix_space); + mul_v3_fl(gz->matrix_space[0], BLI_rctf_size_x(&viewgroup->state.view_border)); + mul_v3_fl(gz->matrix_space[1], BLI_rctf_size_y(&viewgroup->state.view_border)); + gz->matrix_space[3][0] = viewgroup->state.view_border.xmin; + gz->matrix_space[3][1] = viewgroup->state.view_border.ymin; } -static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - struct CameraViewWidgetGroup *viewgroup = mgroup->customdata; + struct CameraViewWidgetGroup *viewgroup = gzgroup->customdata; View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); @@ -431,8 +431,8 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr Scene *scene = CTX_data_scene(C); { - wmGizmo *mpr = viewgroup->border; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + wmGizmo *gz = viewgroup->border; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); RNA_enum_set(viewgroup->border->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE); @@ -445,7 +445,7 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr } WM_gizmo_target_property_def_func( - mpr, "matrix", + gz, "matrix", &(const struct wmGizmoPropertyFnParams) { .value_get_fn = gizmo_render_border_prop_matrix_get, .value_set_fn = gizmo_render_border_prop_matrix_set, @@ -456,18 +456,18 @@ static void WIDGETGROUP_camera_view_refresh(const bContext *C, wmGizmoGroup *mgr } -void VIEW3D_WGT_camera_view(wmGizmoGroupType *wgt) +void VIEW3D_GGT_camera_view(wmGizmoGroupType *gzgt) { - wgt->name = "Camera View Widgets"; - wgt->idname = "VIEW3D_WGT_camera_view"; + gzgt->name = "Camera View Widgets"; + gzgt->idname = "VIEW3D_GGT_camera_view"; - wgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag = (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_SCALE); - wgt->poll = WIDGETGROUP_camera_view_poll; - wgt->setup = WIDGETGROUP_camera_view_setup; - wgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare; - wgt->refresh = WIDGETGROUP_camera_view_refresh; + gzgt->poll = WIDGETGROUP_camera_view_poll; + gzgt->setup = WIDGETGROUP_camera_view_setup; + gzgt->draw_prepare = WIDGETGROUP_camera_view_draw_prepare; + gzgt->refresh = WIDGETGROUP_camera_view_refresh; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_empty.c b/source/blender/editors/space_view3d/view3d_gizmo_empty.c index 3b51af5ca15..2913ba245e7 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_empty.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_empty.c @@ -63,20 +63,20 @@ struct EmptyImageWidgetGroup { /* translate callbacks */ static void gizmo_empty_image_prop_matrix_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data; - const Object *ob = imgroup->state.ob; + BLI_assert(gz_prop->type->array_length == 16); + struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data; + const Object *ob = igzgroup->state.ob; unit_m4(matrix); matrix[0][0] = ob->empty_drawsize; matrix[1][1] = ob->empty_drawsize; float dims[2] = {0.0f, 0.0f}; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); dims[0] *= ob->empty_drawsize; dims[1] *= ob->empty_drawsize; @@ -85,18 +85,18 @@ static void gizmo_empty_image_prop_matrix_get( } static void gizmo_empty_image_prop_matrix_set( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { const float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data; - Object *ob = imgroup->state.ob; + BLI_assert(gz_prop->type->array_length == 16); + struct EmptyImageWidgetGroup *igzgroup = gz_prop->custom_func.user_data; + Object *ob = igzgroup->state.ob; ob->empty_drawsize = matrix[0][0]; float dims[2]; - RNA_float_get_array(mpr->ptr, "dimensions", dims); + RNA_float_get_array(gz->ptr, "dimensions", dims); dims[0] *= ob->empty_drawsize; dims[1] *= ob->empty_drawsize; @@ -104,12 +104,12 @@ static void gizmo_empty_image_prop_matrix_set( ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1]; } -static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { return false; } @@ -122,36 +122,36 @@ static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UN return false; } -static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - struct EmptyImageWidgetGroup *imgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__); - imgroup->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL); - wmGizmo *mpr = imgroup->gizmo; - RNA_enum_set(mpr->ptr, "transform", + struct EmptyImageWidgetGroup *igzgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__); + igzgroup->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + wmGizmo *gz = igzgroup->gizmo; + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE); - mgroup->customdata = imgroup; + gzgroup->customdata = igzgroup; - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true); - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); } -static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - struct EmptyImageWidgetGroup *imgroup = mgroup->customdata; + struct EmptyImageWidgetGroup *igzgroup = gzgroup->customdata; Object *ob = CTX_data_active_object(C); - wmGizmo *mpr = imgroup->gizmo; + wmGizmo *gz = igzgroup->gizmo; - copy_m4_m4(mpr->matrix_basis, ob->obmat); + copy_m4_m4(gz->matrix_basis, ob->obmat); - RNA_enum_set(mpr->ptr, "transform", + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM); - imgroup->state.ob = ob; + igzgroup->state.ob = ob; /* Use dimensions for aspect. */ if (ob->data != NULL) { @@ -169,36 +169,36 @@ static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmGizmoGroup *mgr } const float dims_max = max_ff(size[0], size[1]); - imgroup->state.dims[0] = size[0] / dims_max; - imgroup->state.dims[1] = size[1] / dims_max; + igzgroup->state.dims[0] = size[0] / dims_max; + igzgroup->state.dims[1] = size[1] / dims_max; } else { - copy_v2_fl(imgroup->state.dims, 1.0f); + copy_v2_fl(igzgroup->state.dims, 1.0f); } - RNA_float_set_array(mpr->ptr, "dimensions", imgroup->state.dims); + RNA_float_set_array(gz->ptr, "dimensions", igzgroup->state.dims); WM_gizmo_target_property_def_func( - mpr, "matrix", + gz, "matrix", &(const struct wmGizmoPropertyFnParams) { .value_get_fn = gizmo_empty_image_prop_matrix_get, .value_set_fn = gizmo_empty_image_prop_matrix_set, .range_get_fn = NULL, - .user_data = imgroup, + .user_data = igzgroup, }); } -void VIEW3D_WGT_empty_image(wmGizmoGroupType *wgt) +void VIEW3D_GGT_empty_image(wmGizmoGroupType *gzgt) { - wgt->name = "Area Light Widgets"; - wgt->idname = "VIEW3D_WGT_empty_image"; + gzgt->name = "Area Light Widgets"; + gzgt->idname = "VIEW3D_GGT_empty_image"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D); - wgt->poll = WIDGETGROUP_empty_image_poll; - wgt->setup = WIDGETGROUP_empty_image_setup; - wgt->refresh = WIDGETGROUP_empty_image_refresh; + gzgt->poll = WIDGETGROUP_empty_image_poll; + gzgt->setup = WIDGETGROUP_empty_image_setup; + gzgt->refresh = WIDGETGROUP_empty_image_refresh; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c index d4605bb0c7d..e2a8d2802e7 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_forcefield.c @@ -52,12 +52,12 @@ /** \name Force Field Gizmos * \{ */ -static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { return false; } @@ -67,26 +67,26 @@ static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmGizmoGroupType *UNU return (ob && ob->pd && ob->pd->forcefield); } -static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { /* only wind effector for now */ wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - mgroup->customdata = wwrapper; + gzgroup->customdata = wwrapper; - wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_arrow_3d", mgroup, NULL); - wmGizmo *mpr = wwrapper->gizmo; - RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); - ED_gizmo_arrow3d_set_ui_range(mpr, -200.0f, 200.0f); - ED_gizmo_arrow3d_set_range_fac(mpr, 6.0f); + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL); + wmGizmo *gz = wwrapper->gizmo; + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_CONSTRAINED); + ED_gizmo_arrow3d_set_ui_range(gz, -200.0f, 200.0f); + ED_gizmo_arrow3d_set_range_fac(gz, 6.0f); - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); } -static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = mgroup->customdata; - wmGizmo *mpr = wwrapper->gizmo; + wmGizmoWrapper *wwrapper = gzgroup->customdata; + wmGizmo *gz = wwrapper->gizmo; Object *ob = CTX_data_active_object(C); PartDeflect *pd = ob->pd; @@ -96,30 +96,30 @@ static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmGizmoGroup *mgro PointerRNA field_ptr; RNA_pointer_create(&ob->id, &RNA_FieldSettings, pd, &field_ptr); - WM_gizmo_set_matrix_location(mpr, ob->obmat[3]); - WM_gizmo_set_matrix_rotation_from_z_axis(mpr, ob->obmat[2]); - WM_gizmo_set_matrix_offset_location(mpr, ofs); - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); - WM_gizmo_target_property_def_rna(mpr, "offset", &field_ptr, "strength", -1); + WM_gizmo_set_matrix_location(gz, ob->obmat[3]); + WM_gizmo_set_matrix_rotation_from_z_axis(gz, ob->obmat[2]); + WM_gizmo_set_matrix_offset_location(gz, ofs); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); + WM_gizmo_target_property_def_rna(gz, "offset", &field_ptr, "strength", -1); } else { - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } } -void VIEW3D_WGT_force_field(wmGizmoGroupType *wgt) +void VIEW3D_GGT_force_field(wmGizmoGroupType *gzgt) { - wgt->name = "Force Field Widgets"; - wgt->idname = "VIEW3D_WGT_force_field"; + gzgt->name = "Force Field Widgets"; + gzgt->idname = "VIEW3D_GGT_force_field"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DEPTH_3D); - wgt->poll = WIDGETGROUP_forcefield_poll; - wgt->setup = WIDGETGROUP_forcefield_setup; - wgt->refresh = WIDGETGROUP_forcefield_refresh; + gzgt->poll = WIDGETGROUP_forcefield_poll; + gzgt->setup = WIDGETGROUP_forcefield_setup; + gzgt->refresh = WIDGETGROUP_forcefield_refresh; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_lamp.c b/source/blender/editors/space_view3d/view3d_gizmo_lamp.c index a872cc96172..057c085b69d 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_lamp.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_lamp.c @@ -52,11 +52,11 @@ /** \name Spot Lamp Gizmos * \{ */ -static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT))) { return false; } @@ -70,53 +70,53 @@ static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmGizmoGroupType *UNUS return false; } -static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_arrow_3d", mgroup, NULL); - wmGizmo *mpr = wwrapper->gizmo; - RNA_enum_set(mpr->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED); + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_arrow_3d", gzgroup, NULL); + wmGizmo *gz = wwrapper->gizmo; + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_ARROW_XFORM_FLAG_INVERTED); - mgroup->customdata = wwrapper; + gzgroup->customdata = wwrapper; - ED_gizmo_arrow3d_set_range_fac(mpr, 4.0f); + ED_gizmo_arrow3d_set_range_fac(gz, 4.0f); - UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, mpr->color); + UI_GetThemeColor3fv(TH_GIZMO_SECONDARY, gz->color); } -static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = mgroup->customdata; - wmGizmo *mpr = wwrapper->gizmo; + wmGizmoWrapper *wwrapper = gzgroup->customdata; + wmGizmo *gz = wwrapper->gizmo; Object *ob = CTX_data_active_object(C); Lamp *la = ob->data; float dir[3]; negate_v3_v3(dir, ob->obmat[2]); - WM_gizmo_set_matrix_rotation_from_z_axis(mpr, dir); - WM_gizmo_set_matrix_location(mpr, ob->obmat[3]); + WM_gizmo_set_matrix_rotation_from_z_axis(gz, dir); + WM_gizmo_set_matrix_location(gz, ob->obmat[3]); /* need to set property here for undo. TODO would prefer to do this in _init */ PointerRNA lamp_ptr; const char *propname = "spot_size"; RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr); - WM_gizmo_target_property_def_rna(mpr, "offset", &lamp_ptr, propname, -1); + WM_gizmo_target_property_def_rna(gz, "offset", &lamp_ptr, propname, -1); } -void VIEW3D_WGT_lamp_spot(wmGizmoGroupType *wgt) +void VIEW3D_GGT_lamp_spot(wmGizmoGroupType *gzgt) { - wgt->name = "Spot Light Widgets"; - wgt->idname = "VIEW3D_WGT_lamp_spot"; + gzgt->name = "Spot Light Widgets"; + gzgt->idname = "VIEW3D_GGT_lamp_spot"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D); - wgt->poll = WIDGETGROUP_lamp_spot_poll; - wgt->setup = WIDGETGROUP_lamp_spot_setup; - wgt->refresh = WIDGETGROUP_lamp_spot_refresh; + gzgt->poll = WIDGETGROUP_lamp_spot_poll; + gzgt->setup = WIDGETGROUP_lamp_spot_setup; + gzgt->refresh = WIDGETGROUP_lamp_spot_refresh; } /** \} */ @@ -128,24 +128,24 @@ void VIEW3D_WGT_lamp_spot(wmGizmoGroupType *wgt) /* scale callbacks */ static void gizmo_area_lamp_prop_matrix_get( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { - BLI_assert(mpr_prop->type->array_length == 16); + BLI_assert(gz_prop->type->array_length == 16); float (*matrix)[4] = value_p; - const Lamp *la = mpr_prop->custom_func.user_data; + const Lamp *la = gz_prop->custom_func.user_data; matrix[0][0] = la->area_size; matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey : la->area_size; } static void gizmo_area_lamp_prop_matrix_set( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { const float (*matrix)[4] = value_p; - BLI_assert(mpr_prop->type->array_length == 16); - Lamp *la = mpr_prop->custom_func.user_data; + BLI_assert(gz_prop->type->array_length == 16); + Lamp *la = gz_prop->custom_func.user_data; if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) { la->area_size = len_v3(matrix[0]); @@ -156,7 +156,7 @@ static void gizmo_area_lamp_prop_matrix_set( } } -static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if (v3d->flag2 & V3D_RENDER_OVERRIDE) { @@ -171,40 +171,40 @@ static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmGizmoGroupType *UNUS return false; } -static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_cage_2d", mgroup, NULL); - wmGizmo *mpr = wwrapper->gizmo; - RNA_enum_set(mpr->ptr, "transform", + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + wmGizmo *gz = wwrapper->gizmo; + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE); - mgroup->customdata = wwrapper; + gzgroup->customdata = wwrapper; - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_HOVER, true); + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_HOVER, true); - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); } -static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = mgroup->customdata; + wmGizmoWrapper *wwrapper = gzgroup->customdata; Object *ob = CTX_data_active_object(C); Lamp *la = ob->data; - wmGizmo *mpr = wwrapper->gizmo; + wmGizmo *gz = wwrapper->gizmo; - copy_m4_m4(mpr->matrix_basis, ob->obmat); + copy_m4_m4(gz->matrix_basis, ob->obmat); int flag = ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE; if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) { flag |= ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE_UNIFORM; } - RNA_enum_set(mpr->ptr, "transform", flag); + RNA_enum_set(gz->ptr, "transform", flag); /* need to set property here for undo. TODO would prefer to do this in _init */ WM_gizmo_target_property_def_func( - mpr, "matrix", + gz, "matrix", &(const struct wmGizmoPropertyFnParams) { .value_get_fn = gizmo_area_lamp_prop_matrix_get, .value_set_fn = gizmo_area_lamp_prop_matrix_set, @@ -213,18 +213,18 @@ static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmGizmoGroup *mgrou }); } -void VIEW3D_WGT_lamp_area(wmGizmoGroupType *wgt) +void VIEW3D_GGT_lamp_area(wmGizmoGroupType *gzgt) { - wgt->name = "Area Light Widgets"; - wgt->idname = "VIEW3D_WGT_lamp_area"; + gzgt->name = "Area Light Widgets"; + gzgt->idname = "VIEW3D_GGT_lamp_area"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DEPTH_3D); - wgt->poll = WIDGETGROUP_lamp_area_poll; - wgt->setup = WIDGETGROUP_lamp_area_setup; - wgt->refresh = WIDGETGROUP_lamp_area_refresh; + gzgt->poll = WIDGETGROUP_lamp_area_poll; + gzgt->setup = WIDGETGROUP_lamp_area_setup; + gzgt->refresh = WIDGETGROUP_lamp_area_refresh; } /** \} */ @@ -235,7 +235,7 @@ void VIEW3D_WGT_lamp_area(wmGizmoGroupType *wgt) /** \name Lamp Target Gizmo * \{ */ -static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if (v3d->flag2 & V3D_RENDER_OVERRIDE) { @@ -258,50 +258,50 @@ static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmGizmoGroupType *UN return false; } -static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_WT_grab_3d", mgroup, NULL); - wmGizmo *mpr = wwrapper->gizmo; + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_grab_3d", gzgroup, NULL); + wmGizmo *gz = wwrapper->gizmo; - mgroup->customdata = wwrapper; + gzgroup->customdata = wwrapper; - UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, mpr->color); - UI_GetThemeColor3fv(TH_GIZMO_HI, mpr->color_hi); + UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, gz->color); + UI_GetThemeColor3fv(TH_GIZMO_HI, gz->color_hi); - mpr->scale_basis = 0.06f; + gz->scale_basis = 0.06f; wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true); - RNA_enum_set(mpr->ptr, "draw_options", + RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_GRAB_DRAW_FLAG_FILL | ED_GIZMO_GRAB_DRAW_FLAG_ALIGN_VIEW); - WM_gizmo_operator_set(mpr, 0, ot, NULL); + WM_gizmo_operator_set(gz, 0, ot, NULL); } -static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = mgroup->customdata; + wmGizmoWrapper *wwrapper = gzgroup->customdata; Object *ob = CTX_data_active_object(C); - wmGizmo *mpr = wwrapper->gizmo; + wmGizmo *gz = wwrapper->gizmo; - copy_m4_m4(mpr->matrix_basis, ob->obmat); - unit_m4(mpr->matrix_offset); - mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis; - WM_gizmo_set_flag(mpr, WM_GIZMO_DRAW_OFFSET_SCALE, true); + copy_m4_m4(gz->matrix_basis, ob->obmat); + unit_m4(gz->matrix_offset); + gz->matrix_offset[3][2] = -2.4f / gz->scale_basis; + WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true); } -void VIEW3D_WGT_lamp_target(wmGizmoGroupType *wgt) +void VIEW3D_GGT_lamp_target(wmGizmoGroupType *gzgt) { - wgt->name = "Target Light Widgets"; - wgt->idname = "VIEW3D_WGT_lamp_target"; + gzgt->name = "Target Light Widgets"; + gzgt->idname = "VIEW3D_GGT_lamp_target"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_3D); - wgt->poll = WIDGETGROUP_lamp_target_poll; - wgt->setup = WIDGETGROUP_lamp_target_setup; - wgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare; + gzgt->poll = WIDGETGROUP_lamp_target_poll; + gzgt->setup = WIDGETGROUP_lamp_target_setup; + gzgt->draw_prepare = WIDGETGROUP_lamp_target_draw_prepare; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c index f4a8bad7e30..388d9a29eff 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c @@ -134,28 +134,28 @@ struct NavigateGizmoInfo { struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = { { .opname = "VIEW3D_OT_move", - .gizmo = "GIZMO_WT_button_2d", + .gizmo = "GIZMO_GT_button_2d", .SHAPE_VARS(shape_pan), }, { .opname = "VIEW3D_OT_rotate", - .gizmo = "VIEW3D_WT_navigate_rotate", + .gizmo = "VIEW3D_GT_navigate_rotate", .shape = NULL, .shape_size = 0, }, { .opname = "VIEW3D_OT_zoom", - .gizmo = "GIZMO_WT_button_2d", + .gizmo = "GIZMO_GT_button_2d", .SHAPE_VARS(shape_zoom), }, { .opname = "VIEW3D_OT_view_persportho", - .gizmo = "GIZMO_WT_button_2d", + .gizmo = "GIZMO_GT_button_2d", .SHAPE_VARS(shape_persp), }, { .opname = "VIEW3D_OT_view_persportho", - .gizmo = "GIZMO_WT_button_2d", + .gizmo = "GIZMO_GT_button_2d", .SHAPE_VARS(shape_ortho), }, { .opname = "VIEW3D_OT_view_camera", - .gizmo = "GIZMO_WT_button_2d", + .gizmo = "GIZMO_GT_button_2d", .SHAPE_VARS(shape_camera), }, }; @@ -163,7 +163,7 @@ struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = { #undef SHAPE_VARS struct NavigateWidgetGroup { - wmGizmo *mpr_array[MPR_TOTAL]; + wmGizmo *gz_array[MPR_TOTAL]; /* Store the view state to check for changes. */ struct { rcti rect_visible; @@ -176,12 +176,12 @@ struct NavigateWidgetGroup { int region_size[2]; }; -static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { View3D *v3d = CTX_wm_view3d(C); if (((U.uiflag & USER_SHOW_GIZMO_AXIS) == 0) || (v3d->flag2 & V3D_RENDER_OVERRIDE) || - (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) + (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_NAVIGATE))) { return false; } @@ -189,7 +189,7 @@ static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSE } -static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__); @@ -201,53 +201,53 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup * for (int i = 0; i < MPR_TOTAL; i++) { const struct NavigateGizmoInfo *info = &g_navigate_params[i]; - navgroup->mpr_array[i] = WM_gizmo_new(info->gizmo, mgroup, NULL); - wmGizmo *mpr = navgroup->mpr_array[i]; - mpr->flag |= WM_GIZMO_GRAB_CURSOR | WM_GIZMO_DRAW_MODAL; - mpr->color[3] = 0.2f; - mpr->color_hi[3] = 0.4f; + navgroup->gz_array[i] = WM_gizmo_new(info->gizmo, gzgroup, NULL); + wmGizmo *gz = navgroup->gz_array[i]; + gz->flag |= WM_GIZMO_GRAB_CURSOR | WM_GIZMO_DRAW_MODAL; + gz->color[3] = 0.2f; + gz->color_hi[3] = 0.4f; /* may be overwritten later */ - mpr->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2; + gz->scale_basis = (GIZMO_SIZE * GIZMO_MINI_FAC) / 2; if (info->shape != NULL) { - PropertyRNA *prop = RNA_struct_find_property(mpr->ptr, "shape"); + PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "shape"); RNA_property_string_set_bytes( - mpr->ptr, prop, + gz->ptr, prop, (const char *)info->shape, info->shape_size); - RNA_enum_set(mpr->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE); + RNA_enum_set(gz->ptr, "draw_options", ED_GIZMO_BUTTON_SHOW_OUTLINE); } wmOperatorType *ot = WM_operatortype_find(info->opname, true); - WM_gizmo_operator_set(mpr, 0, ot, NULL); + WM_gizmo_operator_set(gz, 0, ot, NULL); } { - wmGizmo *mpr = navgroup->mpr_array[MPR_CAMERA]; - WM_gizmo_operator_set(mpr, 0, ot_view_camera, NULL); + wmGizmo *gz = navgroup->gz_array[MPR_CAMERA]; + WM_gizmo_operator_set(gz, 0, ot_view_camera, NULL); } /* Click only buttons (not modal). */ { - int mpr_ids[] = {MPR_PERSP, MPR_ORTHO, MPR_CAMERA}; - for (int i = 0; i < ARRAY_SIZE(mpr_ids); i++) { - wmGizmo *mpr = navgroup->mpr_array[mpr_ids[i]]; - RNA_boolean_set(mpr->ptr, "show_drag", false); + int gz_ids[] = {MPR_PERSP, MPR_ORTHO, MPR_CAMERA}; + for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) { + wmGizmo *gz = navgroup->gz_array[gz_ids[i]]; + RNA_boolean_set(gz->ptr, "show_drag", false); } } /* Modal operators, don't use initial mouse location since we're clicking on a button. */ { - int mpr_ids[] = {MPR_MOVE, MPR_ROTATE, MPR_ZOOM}; - for (int i = 0; i < ARRAY_SIZE(mpr_ids); i++) { - wmGizmo *mpr = navgroup->mpr_array[mpr_ids[i]]; - wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, 0); + int gz_ids[] = {MPR_MOVE, MPR_ROTATE, MPR_ZOOM}; + for (int i = 0; i < ARRAY_SIZE(gz_ids); i++) { + wmGizmo *gz = navgroup->gz_array[gz_ids[i]]; + wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, 0); RNA_boolean_set(&mpop->ptr, "use_mouse_init", false); } } { - wmGizmo *mpr = navgroup->mpr_array[MPR_ROTATE]; - mpr->scale_basis = GIZMO_SIZE / 2; + wmGizmo *gz = navgroup->gz_array[MPR_ROTATE]; + gz->scale_basis = GIZMO_SIZE / 2; char mapping[6] = { RV3D_VIEW_LEFT, RV3D_VIEW_RIGHT, @@ -258,25 +258,25 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup * }; for (int part_index = 0; part_index < 6; part_index += 1) { - PointerRNA *ptr = WM_gizmo_operator_set(mpr, part_index + 1, ot_view_axis, NULL); + PointerRNA *ptr = WM_gizmo_operator_set(gz, part_index + 1, ot_view_axis, NULL); RNA_enum_set(ptr, "type", mapping[part_index]); } /* When dragging an axis, use this instead. */ - mpr->drag_part = 0; + gz->drag_part = 0; } - mgroup->customdata = navgroup; + gzgroup->customdata = navgroup; } -static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct NavigateWidgetGroup *navgroup = mgroup->customdata; + struct NavigateWidgetGroup *navgroup = gzgroup->customdata; ARegion *ar = CTX_wm_region(C); const RegionView3D *rv3d = ar->regiondata; for (int i = 0; i < 3; i++) { - copy_v3_v3(navgroup->mpr_array[MPR_ROTATE]->matrix_offset[i], rv3d->viewmat[i]); + copy_v3_v3(navgroup->gz_array[MPR_ROTATE]->matrix_offset[i], rv3d->viewmat[i]); } rcti rect_visible; @@ -312,60 +312,60 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *m rect_visible.ymax - icon_offset_mini * 0.75f, }; - wmGizmo *mpr; + wmGizmo *gz; - for (uint i = 0; i < ARRAY_SIZE(navgroup->mpr_array); i++) { - mpr = navgroup->mpr_array[i]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + for (uint i = 0; i < ARRAY_SIZE(navgroup->gz_array); i++) { + gz = navgroup->gz_array[i]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } /* RV3D_LOCKED or Camera: only show supported buttons. */ if (show_rotate) { - mpr = navgroup->mpr_array[MPR_ROTATE]; - mpr->matrix_basis[3][0] = co_rotate[0]; - mpr->matrix_basis[3][1] = co_rotate[1]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + gz = navgroup->gz_array[MPR_ROTATE]; + gz->matrix_basis[3][0] = co_rotate[0]; + gz->matrix_basis[3][1] = co_rotate[1]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); } int icon_mini_slot = 0; - mpr = navgroup->mpr_array[MPR_ZOOM]; - mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); - mpr->matrix_basis[3][1] = co[1]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + gz = navgroup->gz_array[MPR_ZOOM]; + gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); + gz->matrix_basis[3][1] = co[1]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); - mpr = navgroup->mpr_array[MPR_MOVE]; - mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); - mpr->matrix_basis[3][1] = co[1]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + gz = navgroup->gz_array[MPR_MOVE]; + gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); + gz->matrix_basis[3][1] = co[1]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); if ((rv3d->viewlock & RV3D_LOCKED) == 0) { - mpr = navgroup->mpr_array[MPR_CAMERA]; - mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); - mpr->matrix_basis[3][1] = co[1]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + gz = navgroup->gz_array[MPR_CAMERA]; + gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); + gz->matrix_basis[3][1] = co[1]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); if (navgroup->state.rv3d.is_camera == false) { - mpr = navgroup->mpr_array[rv3d->is_persp ? MPR_PERSP : MPR_ORTHO]; - mpr->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); - mpr->matrix_basis[3][1] = co[1]; - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); + gz = navgroup->gz_array[rv3d->is_persp ? MPR_PERSP : MPR_ORTHO]; + gz->matrix_basis[3][0] = co[0] - (icon_offset_mini * icon_mini_slot++); + gz->matrix_basis[3][1] = co[1]; + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); } } } -void VIEW3D_WGT_navigate(wmGizmoGroupType *wgt) +void VIEW3D_GGT_navigate(wmGizmoGroupType *gzgt) { - wgt->name = "View3D Navigate"; - wgt->idname = "VIEW3D_WGT_navigate"; + gzgt->name = "View3D Navigate"; + gzgt->idname = "VIEW3D_GGT_navigate"; - wgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | + gzgt->flag |= (WM_GIZMOGROUPTYPE_PERSISTENT | WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL); - wgt->poll = WIDGETGROUP_navigate_poll; - wgt->setup = WIDGETGROUP_navigate_setup; - wgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare; + gzgt->poll = WIDGETGROUP_navigate_poll; + gzgt->setup = WIDGETGROUP_navigate_setup; + gzgt->draw_prepare = WIDGETGROUP_navigate_draw_prepare; } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 041fe343526..f296c2ee874 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -168,9 +168,9 @@ static void draw_xyz_wire( immEnd(); } -static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool UNUSED(select)) +static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool UNUSED(select)) { - GPU_line_width(mpr->line_width); + GPU_line_width(gz->line_width); Gwn_VertFormat *format = immVertexFormat(); const uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); @@ -182,12 +182,12 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool char axis; char is_pos; } axis_order[6] = { - {-mpr->matrix_offset[0][2], 0, 0, false}, - {+mpr->matrix_offset[0][2], 1, 0, true}, - {-mpr->matrix_offset[1][2], 2, 1, false}, - {+mpr->matrix_offset[1][2], 3, 1, true}, - {-mpr->matrix_offset[2][2], 4, 2, false}, - {+mpr->matrix_offset[2][2], 5, 2, true}, + {-gz->matrix_offset[0][2], 0, 0, false}, + {+gz->matrix_offset[0][2], 1, 0, true}, + {-gz->matrix_offset[1][2], 2, 1, false}, + {+gz->matrix_offset[1][2], 3, 1, true}, + {-gz->matrix_offset[2][2], 4, 2, false}, + {+gz->matrix_offset[2][2], 5, 2, true}, }; qsort(&axis_order, ARRAY_SIZE(axis_order), sizeof(axis_order[0]), BLI_sortutil_cmp_float); @@ -196,13 +196,13 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool static const float axis_black[4] = {0, 0, 0, 1}; static float axis_color[3][4]; gpuPushMatrix(); - gpuMultMatrix(mpr->matrix_offset); + gpuMultMatrix(gz->matrix_offset); bool draw_center_done = false; int axis_align = -1; for (int axis = 0; axis < 3; axis++) { - if (len_squared_v2(mpr->matrix_offset[axis]) < 1e-6f) { + if (len_squared_v2(gz->matrix_offset[axis]) < 1e-6f) { axis_align = axis; break; } @@ -212,7 +212,7 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool const int index = axis_order[axis_index].index; const int axis = axis_order[axis_index].axis; const bool is_pos = axis_order[axis_index].is_pos; - const bool is_highlight = index + 1 == mpr->highlight_part; + const bool is_highlight = index + 1 == gz->highlight_part; /* Draw slightly before, so axis aligned arrows draw ontop. */ if ((draw_center_done == false) && (axis_order[axis_index].depth > -0.01f)) { @@ -223,7 +223,7 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool immUniformColor4fv(color); imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION); gpuPushMatrix(); - gpuMultMatrix(mpr->matrix_offset); + gpuMultMatrix(gz->matrix_offset); } draw_center_done = true; } @@ -237,7 +237,7 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool bool ok = true; /* skip view align axis */ - if ((axis_align == axis) && (mpr->matrix_offset[axis][2] > 0.0f) == is_pos) { + if ((axis_align == axis) && (gz->matrix_offset[axis][2] > 0.0f) == is_pos) { ok = false; } if (ok) { @@ -291,7 +291,7 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool if (is_pos) { GPU_line_width(1.0f); float m3[3][3]; - copy_m3_m4(m3, mpr->matrix_offset); + copy_m3_m4(m3, gz->matrix_offset); immUniformColor4fv(is_highlight ? axis_black : axis_highlight); draw_xyz_wire(pos_id, m3, v_final, 1.0, axis); } @@ -303,17 +303,17 @@ static void axis_geom_draw(const wmGizmo *mpr, const float color[4], const bool } static void axis3d_draw_intern( - const bContext *UNUSED(C), wmGizmo *mpr, + const bContext *UNUSED(C), wmGizmo *gz, const bool select, const bool highlight) { - const float *color = highlight ? mpr->color_hi : mpr->color; + const float *color = highlight ? gz->color_hi : gz->color; float matrix_final[4][4]; float matrix_unit[4][4]; unit_m4(matrix_unit); WM_gizmo_calc_matrix_final_params( - mpr, + gz, &((struct WM_GizmoMatrixParams) { .matrix_offset = matrix_unit, }), matrix_final); @@ -322,29 +322,29 @@ static void axis3d_draw_intern( gpuMultMatrix(matrix_final); GPU_blend(true); - axis_geom_draw(mpr, color, select); + axis_geom_draw(gz, color, select); GPU_blend(false); gpuPopMatrix(); } -static void gizmo_axis_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) { - const bool is_modal = mpr->state & WM_GIZMO_STATE_MODAL; - const bool is_highlight = (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; + const bool is_modal = gz->state & WM_GIZMO_STATE_MODAL; + const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; (void)is_modal; GPU_blend(true); - axis3d_draw_intern(C, mpr, false, is_highlight); + axis3d_draw_intern(C, gz, false, is_highlight); GPU_blend(false); } static int gizmo_axis_test_select( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { float point_local[2] = {UNPACK2(event->mval)}; - sub_v2_v2(point_local, mpr->matrix_basis[3]); - mul_v2_fl(point_local, 1.0f / (mpr->scale_basis * UI_DPI_FAC)); + sub_v2_v2(point_local, gz->matrix_basis[3]); + mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC)); const float len_sq = len_squared_v2(point_local); if (len_sq > 1.0) { @@ -358,14 +358,14 @@ static int gizmo_axis_test_select( for (int i = 0; i < 3; i++) { for (int is_pos = 0; is_pos < 2; is_pos++) { float co[2] = { - mpr->matrix_offset[i][0] * (is_pos ? 1 : -1), - mpr->matrix_offset[i][1] * (is_pos ? 1 : -1), + gz->matrix_offset[i][0] * (is_pos ? 1 : -1), + gz->matrix_offset[i][1] * (is_pos ? 1 : -1), }; bool ok = true; /* Check if we're viewing on an axis, there is no point to clicking on the current axis so show the reverse. */ - if (len_squared_v2(co) < 1e-6f && (mpr->matrix_offset[i][2] > 0.0f) == is_pos) { + if (len_squared_v2(co) < 1e-6f && (gz->matrix_offset[i][2] > 0.0f) == is_pos) { ok = false; } @@ -384,7 +384,7 @@ static int gizmo_axis_test_select( return part_best; } - /* The 'mpr->scale_final' is already applied when projecting. */ + /* The 'gz->scale_final' is already applied when projecting. */ if (len_sq < 1.0f) { return 0; } @@ -392,23 +392,23 @@ static int gizmo_axis_test_select( return -1; } -static int gizmo_axis_cursor_get(wmGizmo *mpr) +static int gizmo_axis_cursor_get(wmGizmo *gz) { - if (mpr->highlight_part > 0) { + if (gz->highlight_part > 0) { return CURSOR_EDIT; } return BC_NSEW_SCROLLCURSOR; } -void VIEW3D_WT_navigate_rotate(wmGizmoType *wt) +void VIEW3D_GT_navigate_rotate(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "VIEW3D_WT_navigate_rotate"; + gzt->idname = "VIEW3D_GT_navigate_rotate"; /* api callbacks */ - wt->draw = gizmo_axis_draw; - wt->test_select = gizmo_axis_test_select; - wt->cursor_get = gizmo_axis_cursor_get; + gzt->draw = gizmo_axis_draw; + gzt->test_select = gizmo_axis_test_select; + gzt->cursor_get = gizmo_axis_cursor_get; - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index ac6a984bea5..db7ba040b3b 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -68,7 +68,7 @@ #include "BLF_api.h" -static const char *view3d_wgt_ruler_id = "VIEW3D_WGT_ruler"; +static const char *view3d_gzgt_ruler_id = "VIEW3D_GGT_ruler"; #define MVAL_MAX_PX_DIST 12.0f @@ -123,7 +123,7 @@ typedef struct RulerInfo { /* Ruler Item (two or three points) */ typedef struct RulerItem { - wmGizmo mpr; + wmGizmo gz; /* worldspace coords, middle being optional */ float co[3][3]; @@ -143,18 +143,18 @@ typedef struct RulerInteraction { /** \name Internal Ruler Utilities * \{ */ -static RulerItem *ruler_item_add(wmGizmoGroup *mgroup) +static RulerItem *ruler_item_add(wmGizmoGroup *gzgroup) { /* could pass this as an arg */ - const wmGizmoType *wt_ruler = WM_gizmotype_find("VIEW3D_WT_ruler_item", true); - RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(wt_ruler, mgroup, NULL); - WM_gizmo_set_flag(&ruler_item->mpr, WM_GIZMO_DRAW_MODAL, true); + const wmGizmoType *gzt_ruler = WM_gizmotype_find("VIEW3D_GT_ruler_item", true); + RulerItem *ruler_item = (RulerItem *)WM_gizmo_new_ptr(gzt_ruler, gzgroup, NULL); + WM_gizmo_set_flag(&ruler_item->gz, WM_GIZMO_DRAW_MODAL, true); return ruler_item; } -static void ruler_item_remove(bContext *C, wmGizmoGroup *mgroup, RulerItem *ruler_item) +static void ruler_item_remove(bContext *C, wmGizmoGroup *gzgroup, RulerItem *ruler_item) { - WM_gizmo_unlink(&mgroup->gizmos, mgroup->parent_mmap, &ruler_item->mpr, C); + WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, &ruler_item->gz, C); } static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, @@ -192,10 +192,10 @@ static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit, } static bool view3d_ruler_pick( - wmGizmoGroup *mgroup, RulerItem *ruler_item, const float mval[2], + wmGizmoGroup *gzgroup, RulerItem *ruler_item, const float mval[2], int *r_co_index) { - RulerInfo *ruler_info = mgroup->customdata; + RulerInfo *ruler_info = gzgroup->customdata; ARegion *ar = ruler_info->ar; bool found = false; @@ -304,7 +304,7 @@ static bool view3d_ruler_item_mousemove( RulerInfo *ruler_info, RulerItem *ruler_item, const int mval[2], const bool do_thickness, const bool do_snap) { - RulerInteraction *inter = ruler_item->mpr.interaction_data; + RulerInteraction *inter = ruler_item->gz.interaction_data; const float eps_bias = 0.0002f; float dist_px = MVAL_MAX_PX_DIST * U.pixelsize; /* snap dist */ @@ -380,9 +380,9 @@ static bool view3d_ruler_item_mousemove( * \{ */ #define RULER_ID "RulerData3D" -static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup) +static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) { - // RulerInfo *ruler_info = mgroup->customdata; + // RulerInfo *ruler_info = gzgroup->customdata; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); bGPDlayer *gpl; @@ -419,7 +419,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup) gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); BKE_gpencil_free_strokes(gpf); - for (ruler_item = mgroup->gizmos.first; ruler_item; ruler_item = (RulerItem *)ruler_item->mpr.next) { + for (ruler_item = gzgroup->gizmos.first; ruler_item; ruler_item = (RulerItem *)ruler_item->gz.next) { bGPDspoint *pt; int j; @@ -457,7 +457,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *mgroup) return changed; } -static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup) +static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *gzgroup) { Scene *scene = CTX_data_scene(C); bool changed = false; @@ -476,7 +476,7 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup) int j; RulerItem *ruler_item = NULL; if (gps->totpoints == 3) { - ruler_item = ruler_item_add(mgroup); + ruler_item = ruler_item_add(gzgroup); for (j = 0; j < 3; j++) { copy_v3_v3(ruler_item->co[j], &pt->x); pt++; @@ -485,7 +485,7 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup) changed = true; } else if (gps->totpoints == 2) { - ruler_item = ruler_item_add(mgroup); + ruler_item = ruler_item_add(gzgroup); for (j = 0; j < 3; j += 2) { copy_v3_v3(ruler_item->co[j], &pt->x); pt++; @@ -506,12 +506,12 @@ static bool view3d_ruler_from_gpencil(const bContext *C, wmGizmoGroup *mgroup) /** \name Ruler Item Gizmo Type * \{ */ -static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr) +static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) { Scene *scene = CTX_data_scene(C); UnitSettings *unit = &scene->unit; - RulerInfo *ruler_info = mpr->parent_mgroup->customdata; - RulerItem *ruler_item = (RulerItem *)mpr; + RulerInfo *ruler_info = gz->parent_gzgroup->customdata; + RulerItem *ruler_item = (RulerItem *)gz; ARegion *ar = ruler_info->ar; RegionView3D *rv3d = ar->regiondata; const float cap_size = 4.0f; @@ -536,7 +536,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr) UI_GetThemeColor3ubv(TH_TEXT, color_text); UI_GetThemeColor3ubv(TH_WIRE, color_wire); - const bool is_act = (mpr->flag & WM_GIZMO_DRAW_HOVER); + const bool is_act = (gz->flag & WM_GIZMO_DRAW_HOVER); float dir_ruler[2]; float co_ss[3][2]; int j; @@ -785,9 +785,9 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr) /* draw snap */ if ((ruler_info->snap_flag & RULER_SNAP_OK) && (ruler_info->state == RULER_STATE_DRAG) && - (ruler_item->mpr.interaction_data != NULL)) + (ruler_item->gz.interaction_data != NULL)) { - RulerInteraction *inter = ruler_item->mpr.interaction_data; + RulerInteraction *inter = ruler_item->gz.interaction_data; /* size from drawSnapping */ const float size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); float co_ss_snap[3]; @@ -805,14 +805,14 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *mpr) } static int gizmo_ruler_test_select( - bContext *UNUSED(C), wmGizmo *mpr, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) { - RulerItem *ruler_item_pick = (RulerItem *)mpr; + RulerItem *ruler_item_pick = (RulerItem *)gz; float mval_fl[2] = {UNPACK2(event->mval)}; int co_index; /* select and drag */ - if (view3d_ruler_pick(mpr->parent_mgroup, ruler_item_pick, mval_fl, &co_index)) { + if (view3d_ruler_pick(gz->parent_gzgroup, ruler_item_pick, mval_fl, &co_index)) { if (co_index == -1) { if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { return PART_LINE; @@ -826,14 +826,14 @@ static int gizmo_ruler_test_select( } static int gizmo_ruler_modal( - bContext *C, wmGizmo *mpr, const wmEvent *event, + bContext *C, wmGizmo *gz, const wmEvent *event, eWM_GizmoFlagTweak UNUSED(tweak_flag)) { bool do_draw = false; int exit_code = OPERATOR_RUNNING_MODAL; - RulerInfo *ruler_info = mpr->parent_mgroup->customdata; - RulerItem *ruler_item = (RulerItem *)mpr; - RulerInteraction *inter = ruler_item->mpr.interaction_data; + RulerInfo *ruler_info = gz->parent_gzgroup->customdata; + RulerItem *ruler_item = (RulerItem *)gz; + RulerInteraction *inter = ruler_item->gz.interaction_data; ARegion *ar = CTX_wm_region(C); ruler_info->ar = ar; @@ -860,20 +860,20 @@ static int gizmo_ruler_modal( } static int gizmo_ruler_invoke( - bContext *C, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmo *gz, const wmEvent *event) { - wmGizmoGroup *mgroup = mpr->parent_mgroup; - RulerInfo *ruler_info = mgroup->customdata; - RulerItem *ruler_item_pick = (RulerItem *)mpr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + RulerInfo *ruler_info = gzgroup->customdata; + RulerItem *ruler_item_pick = (RulerItem *)gz; RulerInteraction *inter = MEM_callocN(sizeof(RulerInteraction), __func__); - mpr->interaction_data = inter; + gz->interaction_data = inter; ARegion *ar = ruler_info->ar; const float mval_fl[2] = {UNPACK2(event->mval)}; /* select and drag */ - if (mpr->highlight_part == PART_LINE) { + if (gz->highlight_part == PART_LINE) { if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) { /* Add Center Point */ ruler_item_pick->flag |= RULERITEM_USE_ANGLE; @@ -903,7 +903,7 @@ static int gizmo_ruler_invoke( } } else { - inter->co_index = mpr->highlight_part; + inter->co_index = gz->highlight_part; ruler_state_set(C, ruler_info, RULER_STATE_DRAG); /* store the initial depth */ @@ -913,15 +913,15 @@ static int gizmo_ruler_invoke( return OPERATOR_RUNNING_MODAL; } -static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel) +static void gizmo_ruler_exit(bContext *C, wmGizmo *gz, const bool cancel) { - wmGizmoGroup *mgroup = mpr->parent_mgroup; - RulerInfo *ruler_info = mgroup->customdata; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + RulerInfo *ruler_info = gzgroup->customdata; if (!cancel) { if (ruler_info->state == RULER_STATE_DRAG) { - RulerItem *ruler_item = (RulerItem *)mpr; - RulerInteraction *inter = mpr->interaction_data; + RulerItem *ruler_item = (RulerItem *)gz; + RulerInteraction *inter = gz->interaction_data; /* rubber-band angle removal */ if (!inter->inside_region) { if ((inter->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) { @@ -930,9 +930,9 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel) else { /* Not ideal, since the ruler isn't a mode and we don't want to override delete key * use dragging out of the view for removal. */ - ruler_item_remove(C, mgroup, ruler_item); + ruler_item_remove(C, gzgroup, ruler_item); ruler_item = NULL; - mpr = NULL; + gz = NULL; inter = NULL; } } @@ -942,38 +942,38 @@ static void gizmo_ruler_exit(bContext *C, wmGizmo *mpr, const bool cancel) ruler_state_set(C, ruler_info, RULER_STATE_NORMAL); } /* We could convert only the current gizmo, for now just re-generate. */ - view3d_ruler_to_gpencil(C, mgroup); + view3d_ruler_to_gpencil(C, gzgroup); } - if (mpr) { - MEM_SAFE_FREE(mpr->interaction_data); + if (gz) { + MEM_SAFE_FREE(gz->interaction_data); } ruler_state_set(C, ruler_info, RULER_STATE_NORMAL); } -static int gizmo_ruler_cursor_get(wmGizmo *mpr) +static int gizmo_ruler_cursor_get(wmGizmo *gz) { - if (mpr->highlight_part == PART_LINE) { + if (gz->highlight_part == PART_LINE) { return BC_CROSSCURSOR; } return BC_NSEW_SCROLLCURSOR; } -void VIEW3D_WT_ruler_item(wmGizmoType *wt) +void VIEW3D_GT_ruler_item(wmGizmoType *gzt) { /* identifiers */ - wt->idname = "VIEW3D_WT_ruler_item"; + gzt->idname = "VIEW3D_GT_ruler_item"; /* api callbacks */ - wt->draw = gizmo_ruler_draw; - wt->test_select = gizmo_ruler_test_select; - wt->modal = gizmo_ruler_modal; - wt->invoke = gizmo_ruler_invoke; - wt->exit = gizmo_ruler_exit; - wt->cursor_get = gizmo_ruler_cursor_get; - - wt->struct_size = sizeof(RulerItem); + gzt->draw = gizmo_ruler_draw; + gzt->test_select = gizmo_ruler_test_select; + gzt->modal = gizmo_ruler_modal; + gzt->invoke = gizmo_ruler_invoke; + gzt->exit = gizmo_ruler_exit; + gzt->cursor_get = gizmo_ruler_cursor_get; + + gzt->struct_size = sizeof(RulerItem); } /** \} */ @@ -982,23 +982,23 @@ void VIEW3D_WT_ruler_item(wmGizmoType *wt) /** \name Ruler Gizmo Group * \{ */ -static bool WIDGETGROUP_ruler_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool WIDGETGROUP_ruler_poll(const bContext *C, wmGizmoGroupType *gzgt) { bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C); if ((tref_rt == NULL) || - !STREQ(wgt->idname, tref_rt->gizmo_group)) + !STREQ(gzgt->idname, tref_rt->gizmo_group)) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } -static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *gzgroup) { RulerInfo *ruler_info = MEM_callocN(sizeof(RulerInfo), __func__); - if (view3d_ruler_from_gpencil(C, mgroup)) { + if (view3d_ruler_from_gpencil(C, gzgroup)) { /* nop */ } @@ -1009,21 +1009,21 @@ static void WIDGETGROUP_ruler_setup(const bContext *C, wmGizmoGroup *mgroup) ruler_info->sa = sa; ruler_info->ar = ar; - mgroup->customdata = ruler_info; + gzgroup->customdata = ruler_info; } -void VIEW3D_WGT_ruler(wmGizmoGroupType *wgt) +void VIEW3D_GGT_ruler(wmGizmoGroupType *gzgt) { - wgt->name = "Ruler Widgets"; - wgt->idname = view3d_wgt_ruler_id; + gzgt->name = "Ruler Widgets"; + gzgt->idname = view3d_gzgt_ruler_id; - wgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL; + gzgt->flag |= WM_GIZMOGROUPTYPE_SCALE | WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = WIDGETGROUP_ruler_poll; - wgt->setup = WIDGETGROUP_ruler_setup; + gzgt->poll = WIDGETGROUP_ruler_poll; + gzgt->setup = WIDGETGROUP_ruler_setup; } /** \} */ @@ -1036,7 +1036,7 @@ static bool view3d_ruler_poll(bContext *C) { bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C); if ((tref_rt == NULL) || - !STREQ(view3d_wgt_ruler_id, tref_rt->gizmo_group) || + !STREQ(view3d_gzgt_ruler_id, tref_rt->gizmo_group) || CTX_wm_region_view3d(C) == NULL) { return false; @@ -1050,22 +1050,22 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wm View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ar->regiondata; - wmGizmoMap *mmap = ar->gizmo_map; - wmGizmoGroup *mgroup = WM_gizmomap_group_find(mmap, view3d_wgt_ruler_id); + wmGizmoMap *gzmap = ar->gizmo_map; + wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id); const bool use_depth = (v3d->drawtype >= OB_SOLID); /* Create new line */ RulerItem *ruler_item; - ruler_item = ruler_item_add(mgroup); + ruler_item = ruler_item_add(gzgroup); /* This is a little weak, but there is no real good way to tweak directly. */ - WM_gizmo_highlight_set(mmap, &ruler_item->mpr); + WM_gizmo_highlight_set(gzmap, &ruler_item->gz); if (WM_operator_name_call( C, "GIZMOGROUP_OT_gizmo_tweak", WM_OP_INVOKE_REGION_WIN, NULL) == OPERATOR_RUNNING_MODAL) { - RulerInfo *ruler_info = mgroup->customdata; - RulerInteraction *inter = ruler_item->mpr.interaction_data; + RulerInfo *ruler_info = gzgroup->customdata; + RulerInteraction *inter = ruler_item->gz.interaction_data; if (use_depth) { /* snap the first point added, not essential but handy */ inter->co_index = 0; @@ -1079,7 +1079,7 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wm } copy_v3_v3(ruler_item->co[2], ruler_item->co[0]); - ruler_item->mpr.highlight_part = inter->co_index = 2; + ruler_item->gz.highlight_part = inter->co_index = 2; } return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 89dd254c130..5796014571a 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -254,21 +254,21 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* view3d_widgets.c */ -void VIEW3D_WGT_lamp_spot(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_lamp_area(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_lamp_target(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_camera(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_camera_view(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_force_field(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_empty_image(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_armature_spline(struct wmGizmoGroupType *wgt); -void VIEW3D_WGT_navigate(struct wmGizmoGroupType *wgt); - -void VIEW3D_WGT_ruler(struct wmGizmoGroupType *wgt); -void VIEW3D_WT_ruler_item(struct wmGizmoType *wt); +void VIEW3D_GGT_lamp_spot(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_lamp_area(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_lamp_target(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_camera(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_camera_view(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_force_field(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_empty_image(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_armature_spline(struct wmGizmoGroupType *gzgt); +void VIEW3D_GGT_navigate(struct wmGizmoGroupType *gzgt); + +void VIEW3D_GGT_ruler(struct wmGizmoGroupType *gzgt); +void VIEW3D_GT_ruler_item(struct wmGizmoType *gzt); void VIEW3D_OT_ruler_add(struct wmOperatorType *ot); -void VIEW3D_WT_navigate_rotate(struct wmGizmoType *wt); +void VIEW3D_GT_navigate_rotate(struct wmGizmoType *gzt); /* draw_volume.c */ void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2006bd830b4..ded2a49a33f 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -505,7 +505,7 @@ typedef struct TransInfo { short current_orientation; TransformOrientation *custom_orientation; /* this gets used when current_orientation is V3D_MANIP_CUSTOM */ - short mpr_flag; /* backup from view3d, to restore on end */ + short gizmo_flag; /* backup from view3d, to restore on end */ short prop_mode; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index e32bef72cf6..e54b154ee0d 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1350,8 +1350,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve /* turn gizmo off during transform */ if (t->flag & T_MODAL) { - t->mpr_flag = v3d->mpr_flag; - v3d->mpr_flag = V3D_GIZMO_HIDE; + t->gizmo_flag = v3d->gizmo_flag; + v3d->gizmo_flag = V3D_GIZMO_HIDE; } if (t->scene->toolsettings->transform_flag & SCE_XFORM_AXIS_ALIGN) { @@ -1690,7 +1690,7 @@ void postTrans(bContext *C, TransInfo *t) View3D *v3d = t->sa->spacedata.first; /* restore gizmo */ if (t->flag & T_MODAL) { - v3d->mpr_flag = t->mpr_flag; + v3d->gizmo_flag = t->gizmo_flag; } } diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index 995faae8333..ff69c2859fc 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -128,16 +128,16 @@ static void gizmo2d_get_axis_color(const int axis_idx, float *r_col, float *r_co r_col_hi[3] *= alpha_hi; } -static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *mgroup) +static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup) { - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_2d", true); - const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_2d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_2d", true); + const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_2d", true); GizmoGroup2D *man = MEM_callocN(sizeof(GizmoGroup2D), __func__); - man->translate_x = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - man->translate_y = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); - man->cage = WM_gizmo_new_ptr(wt_cage, mgroup, NULL); + man->translate_x = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + man->translate_y = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); + man->cage = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL); RNA_enum_set(man->cage->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE | @@ -197,11 +197,11 @@ static int gizmo2d_modal( return OPERATOR_RUNNING_MODAL; } -void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { wmOperatorType *ot_translate = WM_operatortype_find("TRANSFORM_OT_translate", true); - GizmoGroup2D *man = gizmogroup2d_init(mgroup); - mgroup->customdata = man; + GizmoGroup2D *man = gizmogroup2d_init(gzgroup); + gzgroup->customdata = man; MAN2D_ITER_AXES_BEGIN(axis, axis_idx) { @@ -271,9 +271,9 @@ void ED_widgetgroup_gizmo2d_setup(const bContext *UNUSED(C), wmGizmoGroup *mgrou } } -void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *mgroup) +void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoGroup2D *man = mgroup->customdata; + GizmoGroup2D *man = gzgroup->customdata; float origin[3]; gizmo2d_calc_bounds(C, origin, man->min, man->max); copy_v2_v2(man->origin, origin); @@ -321,10 +321,10 @@ void ED_widgetgroup_gizmo2d_refresh(const bContext *C, wmGizmoGroup *mgroup) } } -void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *ar = CTX_wm_region(C); - GizmoGroup2D *man = mgroup->customdata; + GizmoGroup2D *man = gzgroup->customdata; float origin[3] = {UNPACK2(man->origin), 0.0f}; float origin_aa[3] = {UNPACK2(man->origin), 0.0f}; @@ -346,7 +346,7 @@ void ED_widgetgroup_gizmo2d_draw_prepare(const bContext *C, wmGizmoGroup *mgroup * - Called on every redraw, better to do a more simple poll and check for selection in _refresh * - UV editing only, could be expanded for other things. */ -bool ED_widgetgroup_gizmo2d_poll(const bContext *C, wmGizmoGroupType *UNUSED(wgt)) +bool ED_widgetgroup_gizmo2d_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt)) { if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) { return false; diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 7d608c433c3..cbc2b312512 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1137,13 +1137,13 @@ static void gizmo_line_range(const int twtype, const short axis_type, float *r_s } static void gizmo_xform_message_subscribe( - wmGizmoGroup *mgroup, struct wmMsgBus *mbus, + wmGizmoGroup *gzgroup, struct wmMsgBus *mbus, Scene *scene, bScreen *UNUSED(screen), ScrArea *UNUSED(sa), ARegion *ar, const void *type_fn) { /* Subscribe to view properties */ - wmMsgSubscribeValue msg_sub_value_mpr_tag_refresh = { + wmMsgSubscribeValue msg_sub_value_gz_tag_refresh = { .owner = ar, - .user_data = mgroup->parent_mmap, + .user_data = gzgroup->parent_gzmap, .notify = WM_gizmo_do_msg_notify_tag_refresh, }; @@ -1159,7 +1159,7 @@ static void gizmo_xform_message_subscribe( }; for (int i = 0; i < ARRAY_SIZE(props); i++) { if (props[i]) { - WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__); + WM_msg_subscribe_rna(mbus, &scene_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); } } } @@ -1167,7 +1167,7 @@ static void gizmo_xform_message_subscribe( PointerRNA toolsettings_ptr; RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &toolsettings_ptr); - if (type_fn == TRANSFORM_WGT_gizmo) { + if (type_fn == TRANSFORM_GGT_gizmo) { extern PropertyRNA rna_ToolSettings_transform_pivot_point; extern PropertyRNA rna_ToolSettings_use_gizmo_mode; const PropertyRNA *props[] = { @@ -1175,17 +1175,17 @@ static void gizmo_xform_message_subscribe( &rna_ToolSettings_use_gizmo_mode, }; for (int i = 0; i < ARRAY_SIZE(props); i++) { - WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_mpr_tag_refresh, __func__); + WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); } } - else if (type_fn == VIEW3D_WGT_xform_cage) { + else if (type_fn == VIEW3D_GGT_xform_cage) { /* pass */ } else { BLI_assert(0); } - WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_mpr_tag_refresh); + WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_gz_tag_refresh); } /** \} */ @@ -1195,26 +1195,26 @@ static void gizmo_xform_message_subscribe( /** \name Transform Gizmo * \{ */ -static GizmoGroup *gizmogroup_init(wmGizmoGroup *mgroup) +static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup) { GizmoGroup *man; man = MEM_callocN(sizeof(GizmoGroup), "gizmo_data"); - const wmGizmoType *wt_arrow = WM_gizmotype_find("GIZMO_WT_arrow_3d", true); - const wmGizmoType *wt_dial = WM_gizmotype_find("GIZMO_WT_dial_3d", true); - const wmGizmoType *wt_prim = WM_gizmotype_find("GIZMO_WT_primitive_3d", true); + const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true); + const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true); + const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true); #define GIZMO_NEW_ARROW(v, draw_style) { \ - man->gizmos[v] = WM_gizmo_new_ptr(wt_arrow, mgroup, NULL); \ + man->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \ RNA_enum_set(man->gizmos[v]->ptr, "draw_style", draw_style); \ } ((void)0) #define GIZMO_NEW_DIAL(v, draw_options) { \ - man->gizmos[v] = WM_gizmo_new_ptr(wt_dial, mgroup, NULL); \ + man->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \ RNA_enum_set(man->gizmos[v]->ptr, "draw_options", draw_options); \ } ((void)0) #define GIZMO_NEW_PRIM(v, draw_style) { \ - man->gizmos[v] = WM_gizmo_new_ptr(wt_prim, mgroup, NULL); \ + man->gizmos[v] = WM_gizmo_new_ptr(gzt_prim, gzgroup, NULL); \ RNA_enum_set(man->gizmos[v]->ptr, "draw_style", draw_style); \ } ((void)0) @@ -1286,12 +1286,12 @@ static int gizmo_modal( return OPERATOR_RUNNING_MODAL; } -static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *mgroup) +static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup) { struct { wmOperatorType *translate, *rotate, *trackball, *resize; } ot_store = {NULL}; - GizmoGroup *man = mgroup->customdata; + GizmoGroup *man = gzgroup->customdata; MAN_ITER_AXES_BEGIN(axis, axis_idx) { const short axis_type = gizmo_get_axis_type(axis_idx); @@ -1406,11 +1406,11 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *mgroup) MAN_ITER_AXES_END; } -static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoGroup *man = gizmogroup_init(mgroup); + GizmoGroup *man = gizmogroup_init(gzgroup); - mgroup->customdata = man; + gzgroup->customdata = man; { man->twtype = 0; @@ -1436,12 +1436,12 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *mgroup) } /* *** set properties for axes *** */ - gizmogroup_init_properties_from_twtype(mgroup); + gizmogroup_init_properties_from_twtype(gzgroup); } -static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoGroup *man = mgroup->customdata; + GizmoGroup *man = gzgroup->customdata; ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); View3D *v3d = sa->spacedata.first; @@ -1453,7 +1453,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup) man->twtype = scene->toolsettings->gizmo_flag & man->twtype_init; if (man->twtype != man->twtype_prev) { man->twtype_prev = man->twtype; - gizmogroup_init_properties_from_twtype(mgroup); + gizmogroup_init_properties_from_twtype(gzgroup); } } @@ -1527,18 +1527,18 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *mgroup) } static void WIDGETGROUP_gizmo_message_subscribe( - const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus) + const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); - gizmo_xform_message_subscribe(mgroup, mbus, scene, screen, sa, ar, TRANSFORM_WGT_gizmo); + gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, TRANSFORM_GGT_gizmo); } -static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - GizmoGroup *man = mgroup->customdata; + GizmoGroup *man = gzgroup->customdata; // ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); // View3D *v3d = sa->spacedata.first; @@ -1588,39 +1588,39 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *mgro MAN_ITER_AXES_END; } -static bool WIDGETGROUP_gizmo_poll(const struct bContext *C, struct wmGizmoGroupType *wgt) +static bool WIDGETGROUP_gizmo_poll(const struct bContext *C, struct wmGizmoGroupType *gzgt) { /* it's a given we only use this in 3D view */ bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C); if ((tref_rt == NULL) || - !STREQ(wgt->idname, tref_rt->gizmo_group)) + !STREQ(gzgt->idname, tref_rt->gizmo_group)) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } View3D *v3d = CTX_wm_view3d(C); - if (v3d->mpr_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) { + if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) { return false; } return true; } -void TRANSFORM_WGT_gizmo(wmGizmoGroupType *wgt) +void TRANSFORM_GGT_gizmo(wmGizmoGroupType *gzgt) { - wgt->name = "Transform Gizmo"; - wgt->idname = "TRANSFORM_WGT_gizmo"; + gzgt->name = "Transform Gizmo"; + gzgt->idname = "TRANSFORM_GGT_gizmo"; - wgt->flag |= WM_GIZMOGROUPTYPE_3D; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = WIDGETGROUP_gizmo_poll; - wgt->setup = WIDGETGROUP_gizmo_setup; - wgt->refresh = WIDGETGROUP_gizmo_refresh; - wgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe; - wgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare; + gzgt->poll = WIDGETGROUP_gizmo_poll; + gzgt->setup = WIDGETGROUP_gizmo_setup; + gzgt->refresh = WIDGETGROUP_gizmo_refresh; + gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe; + gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare; } /** \} */ @@ -1634,31 +1634,31 @@ struct XFormCageWidgetGroup { wmGizmo *gizmo; }; -static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *wgt) +static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt) { bToolRef_Runtime *tref_rt = WM_toolsystem_runtime_from_context((bContext *)C); - if (!STREQ(wgt->idname, tref_rt->gizmo_group)) { - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + if (!STREQ(gzgt->idname, tref_rt->gizmo_group)) { + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); return false; } return true; } -static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *mgroup) +static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - struct XFormCageWidgetGroup *xmgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__); - const wmGizmoType *wt_cage = WM_gizmotype_find("GIZMO_WT_cage_3d", true); - xmgroup->gizmo = WM_gizmo_new_ptr(wt_cage, mgroup, NULL); - wmGizmo *mpr = xmgroup->gizmo; + struct XFormCageWidgetGroup *xgzgroup = MEM_mallocN(sizeof(struct XFormCageWidgetGroup), __func__); + const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true); + xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, NULL); + wmGizmo *gz = xgzgroup->gizmo; - RNA_enum_set(mpr->ptr, "transform", + RNA_enum_set(gz->ptr, "transform", ED_GIZMO_CAGE2D_XFORM_FLAG_SCALE | ED_GIZMO_CAGE2D_XFORM_FLAG_TRANSLATE); - mpr->color[0] = 1; - mpr->color_hi[0] = 1; + gz->color[0] = 1; + gz->color_hi[0] = 1; - mgroup->customdata = xmgroup; + gzgroup->customdata = xgzgroup; { wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true); @@ -1673,7 +1673,7 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup for (int y = 0; y < 3; y++) { for (int z = 0; z < 3; z++) { bool constraint[3] = {x != 1, y != 1, z != 1}; - ptr = WM_gizmo_operator_set(mpr, i, ot_resize, NULL); + ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL); if (prop_release_confirm == NULL) { prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm"); prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis"); @@ -1687,15 +1687,15 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup } } -static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup) { ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ar->regiondata; - struct XFormCageWidgetGroup *xmgroup = mgroup->customdata; - wmGizmo *mpr = xmgroup->gizmo; + struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata; + wmGizmo *gz = xgzgroup->gizmo; struct TransformBounds tbounds; @@ -1705,22 +1705,22 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro }, &tbounds) == 0) || equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) { - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, true); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); } else { gizmo_prepare_mat(C, v3d, rv3d, &tbounds); - WM_gizmo_set_flag(mpr, WM_GIZMO_HIDDEN, false); - WM_gizmo_set_flag(mpr, WM_GIZMO_GRAB_CURSOR, true); + WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false); + WM_gizmo_set_flag(gz, WM_GIZMO_GRAB_CURSOR, true); float dims[3]; sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min); - RNA_float_set_array(mpr->ptr, "dimensions", dims); + RNA_float_set_array(gz->ptr, "dimensions", dims); mul_v3_fl(dims, 0.5f); - copy_m4_m3(mpr->matrix_offset, rv3d->tw_axis_matrix); - mid_v3_v3v3(mpr->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min); - mul_m3_v3(rv3d->tw_axis_matrix, mpr->matrix_offset[3]); + copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix); + mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min); + mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]); PropertyRNA *prop_center_override = NULL; float center[3]; @@ -1732,11 +1732,11 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro center[1] = (float)(1 - y) * dims[1]; for (int z = 0; z < 3; z++) { center[2] = (float)(1 - z) * dims[2]; - struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, i); + struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, i); if (prop_center_override == NULL) { prop_center_override = RNA_struct_find_property(&mpop->ptr, "center_override"); } - mul_v3_m4v3(center_global, mpr->matrix_offset, center); + mul_v3_m4v3(center_global, gz->matrix_offset, center); RNA_property_float_set_array(&mpop->ptr, prop_center_override, center_global); i++; } @@ -1746,45 +1746,45 @@ static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *mgro } static void WIDGETGROUP_xform_cage_message_subscribe( - const bContext *C, wmGizmoGroup *mgroup, struct wmMsgBus *mbus) + const bContext *C, wmGizmoGroup *gzgroup, struct wmMsgBus *mbus) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); - gizmo_xform_message_subscribe(mgroup, mbus, scene, screen, sa, ar, VIEW3D_WGT_xform_cage); + gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, sa, ar, VIEW3D_GGT_xform_cage); } -static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *mgroup) +static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct XFormCageWidgetGroup *xmgroup = mgroup->customdata; - wmGizmo *mpr = xmgroup->gizmo; + struct XFormCageWidgetGroup *xgzgroup = gzgroup->customdata; + wmGizmo *gz = xgzgroup->gizmo; ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); if (ob && ob->mode & OB_MODE_EDIT) { - copy_m4_m4(mpr->matrix_space, ob->obmat); + copy_m4_m4(gz->matrix_space, ob->obmat); } else { - unit_m4(mpr->matrix_space); + unit_m4(gz->matrix_space); } } -void VIEW3D_WGT_xform_cage(wmGizmoGroupType *wgt) +void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt) { - wgt->name = "Transform Cage"; - wgt->idname = "VIEW3D_WGT_xform_cage"; + gzgt->name = "Transform Cage"; + gzgt->idname = "VIEW3D_GGT_xform_cage"; - wgt->flag |= WM_GIZMOGROUPTYPE_3D; + gzgt->flag |= WM_GIZMOGROUPTYPE_3D; - wgt->mmap_params.spaceid = SPACE_VIEW3D; - wgt->mmap_params.regionid = RGN_TYPE_WINDOW; + gzgt->gzmap_params.spaceid = SPACE_VIEW3D; + gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW; - wgt->poll = WIDGETGROUP_xform_cage_poll; - wgt->setup = WIDGETGROUP_xform_cage_setup; - wgt->refresh = WIDGETGROUP_xform_cage_refresh; - wgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe; - wgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare; + gzgt->poll = WIDGETGROUP_xform_cage_poll; + gzgt->setup = WIDGETGROUP_xform_cage_setup; + gzgt->refresh = WIDGETGROUP_xform_cage_refresh; + gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe; + gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare; } /** \} */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 40551701627..8abec3474f9 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -237,7 +237,7 @@ typedef struct View3D { char gridflag; /* transform gizmo info */ - char _pad5[2], mpr_flag; + char _pad5[2], gizmo_flag; short flag3; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5c30cdb2b07..df838264cb7 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2940,22 +2940,22 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_gizmo", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mpr_flag", V3D_GIZMO_HIDE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gizmo_flag", V3D_GIZMO_HIDE); RNA_def_property_ui_text(prop, "Show Gizmo", "Show gizmos of all types"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_gizmo_navigate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mpr_flag", V3D_GIZMO_HIDE_NAVIGATE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gizmo_flag", V3D_GIZMO_HIDE_NAVIGATE); RNA_def_property_ui_text(prop, "Navigate Gizmo", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_gizmo_context", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mpr_flag", V3D_GIZMO_HIDE_CONTEXT); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gizmo_flag", V3D_GIZMO_HIDE_CONTEXT); RNA_def_property_ui_text(prop, "Context Gizmo", "Context sensitive gizmos for the active item"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_gizmo_tool", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "mpr_flag", V3D_GIZMO_HIDE_TOOL); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gizmo_flag", V3D_GIZMO_HIDE_TOOL); RNA_def_property_ui_text(prop, "Tool Gizmo", "Active tool gizmo"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 7abcf0f0667..a1780b45aed 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -120,31 +120,31 @@ static void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer) static wmGizmoGroupType *wm_gizmogrouptype_find_for_add_remove(ReportList *reports, const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, true); - if (wgt == NULL) { + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, true); + if (gzgt == NULL) { BKE_reportf(reports, RPT_ERROR, "Gizmo group type '%s' not found!", idname); return NULL; } - if (wgt->flag & WM_GIZMOGROUPTYPE_PERSISTENT) { + if (gzgt->flag & WM_GIZMOGROUPTYPE_PERSISTENT) { BKE_reportf(reports, RPT_ERROR, "Gizmo group '%s' has 'PERSISTENT' option set!", idname); return NULL; } - return wgt; + return gzgt; } static void rna_gizmo_group_type_add(ReportList *reports, const char *idname) { - wmGizmoGroupType *wgt = wm_gizmogrouptype_find_for_add_remove(reports, idname); - if (wgt != NULL) { - WM_gizmo_group_type_add_ptr(wgt); + wmGizmoGroupType *gzgt = wm_gizmogrouptype_find_for_add_remove(reports, idname); + if (gzgt != NULL) { + WM_gizmo_group_type_add_ptr(gzgt); } } static void rna_gizmo_group_type_remove(Main *bmain, ReportList *reports, const char *idname) { - wmGizmoGroupType *wgt = wm_gizmogrouptype_find_for_add_remove(reports, idname); - if (wgt != NULL) { - WM_gizmo_group_type_remove_ptr(bmain, wgt); + wmGizmoGroupType *gzgt = wm_gizmogrouptype_find_for_add_remove(reports, idname); + if (gzgt != NULL) { + WM_gizmo_group_type_remove_ptr(bmain, gzgt); } } diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c index 754ef4575a4..7a2460a7694 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo.c @@ -76,55 +76,55 @@ #ifdef WITH_PYTHON static void rna_gizmo_draw_cb( - const struct bContext *C, struct wmGizmo *mpr) + const struct bContext *C, struct wmGizmo *gz) { extern FunctionRNA rna_Gizmo_draw_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "draw"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "draw"); */ func = &rna_Gizmo_draw_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); RNA_parameter_list_free(&list); } static void rna_gizmo_draw_select_cb( - const struct bContext *C, struct wmGizmo *mpr, int select_id) + const struct bContext *C, struct wmGizmo *gz, int select_id) { extern FunctionRNA rna_Gizmo_draw_select_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "draw_select"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "draw_select"); */ func = &rna_Gizmo_draw_select_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "select_id", &select_id); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); RNA_parameter_list_free(&list); } static int rna_gizmo_test_select_cb( - struct bContext *C, struct wmGizmo *mpr, const struct wmEvent *event) + struct bContext *C, struct wmGizmo *gz, const struct wmEvent *event) { extern FunctionRNA rna_Gizmo_test_select_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "test_select"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "test_select"); */ func = &rna_Gizmo_test_select_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "event", &event); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); void *ret; RNA_parameter_get_lookup(&list, "intersect_id", &ret); @@ -135,23 +135,23 @@ static int rna_gizmo_test_select_cb( } static int rna_gizmo_modal_cb( - struct bContext *C, struct wmGizmo *mpr, const struct wmEvent *event, + struct bContext *C, struct wmGizmo *gz, const struct wmEvent *event, eWM_GizmoFlagTweak tweak_flag) { extern FunctionRNA rna_Gizmo_modal_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; const int tweak_flag_int = tweak_flag; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "modal"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "modal"); */ func = &rna_Gizmo_modal_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "event", &event); RNA_parameter_set_lookup(&list, "tweak", &tweak_flag_int); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); void *ret; RNA_parameter_get_lookup(&list, "result", &ret); @@ -162,37 +162,37 @@ static int rna_gizmo_modal_cb( } static void rna_gizmo_setup_cb( - struct wmGizmo *mpr) + struct wmGizmo *gz) { extern FunctionRNA rna_Gizmo_setup_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "setup"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "setup"); */ func = &rna_Gizmo_setup_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); - mgroup->type->ext.call((bContext *)NULL, &mpr_ptr, func, &list); + RNA_parameter_list_create(&list, &gz_ptr, func); + gzgroup->type->ext.call((bContext *)NULL, &gz_ptr, func, &list); RNA_parameter_list_free(&list); } static int rna_gizmo_invoke_cb( - struct bContext *C, struct wmGizmo *mpr, const struct wmEvent *event) + struct bContext *C, struct wmGizmo *gz, const struct wmEvent *event) { extern FunctionRNA rna_Gizmo_invoke_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "invoke"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "invoke"); */ func = &rna_Gizmo_invoke_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); RNA_parameter_set_lookup(&list, "event", &event); - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); void *ret; RNA_parameter_get_lookup(&list, "result", &ret); @@ -203,39 +203,39 @@ static int rna_gizmo_invoke_cb( } static void rna_gizmo_exit_cb( - struct bContext *C, struct wmGizmo *mpr, bool cancel) + struct bContext *C, struct wmGizmo *gz, bool cancel) { extern FunctionRNA rna_Gizmo_exit_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "exit"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "exit"); */ func = &rna_Gizmo_exit_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); + RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); { int cancel_i = cancel; RNA_parameter_set_lookup(&list, "cancel", &cancel_i); } - mgroup->type->ext.call((bContext *)C, &mpr_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); RNA_parameter_list_free(&list); } static void rna_gizmo_select_refresh_cb( - struct wmGizmo *mpr) + struct wmGizmo *gz) { extern FunctionRNA rna_Gizmo_select_refresh_func; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - PointerRNA mpr_ptr; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + PointerRNA gz_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mpr->type->ext.srna, mpr, &mpr_ptr); - /* RNA_struct_find_function(&mpr_ptr, "select_refresh"); */ + RNA_pointer_create(NULL, gz->type->ext.srna, gz, &gz_ptr); + /* RNA_struct_find_function(&gz_ptr, "select_refresh"); */ func = &rna_Gizmo_select_refresh_func; - RNA_parameter_list_create(&list, &mpr_ptr, func); - mgroup->type->ext.call((bContext *)NULL, &mpr_ptr, func, &list); + RNA_parameter_list_create(&list, &gz_ptr, func); + gzgroup->type->ext.call((bContext *)NULL, &gz_ptr, func, &list); RNA_parameter_list_free(&list); } @@ -266,14 +266,14 @@ static wmGizmo *rna_GizmoProperties_find_operator(PointerRNA *ptr) for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->gizmo_map) { - wmGizmoMap *mmap = ar->gizmo_map; - for (wmGizmoGroup *mgroup = WM_gizmomap_group_list(mmap)->first; - mgroup; - mgroup = mgroup->next) + wmGizmoMap *gzmap = ar->gizmo_map; + for (wmGizmoGroup *gzgroup = WM_gizmomap_group_list(gzmap)->first; + gzgroup; + gzgroup = gzgroup->next) { - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if (mpr->properties == properties) { - return mpr; + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if (gz->properties == properties) { + return gz; } } } @@ -286,10 +286,10 @@ static wmGizmo *rna_GizmoProperties_find_operator(PointerRNA *ptr) static StructRNA *rna_GizmoProperties_refine(PointerRNA *ptr) { - wmGizmo *mpr = rna_GizmoProperties_find_operator(ptr); + wmGizmo *gz = rna_GizmoProperties_find_operator(ptr); - if (mpr) - return mpr->type->srna; + if (gz) + return gz->type->srna; else return ptr->type; } @@ -306,77 +306,77 @@ static IDProperty *rna_GizmoProperties_idprops(PointerRNA *ptr, bool create) static PointerRNA rna_Gizmo_properties_get(PointerRNA *ptr) { - wmGizmo *mpr = ptr->data; - return rna_pointer_inherit_refine(ptr, mpr->type->srna, mpr->properties); + wmGizmo *gz = ptr->data; + return rna_pointer_inherit_refine(ptr, gz->type->srna, gz->properties); } /* wmGizmo.float */ #define RNA_GIZMO_GENERIC_FLOAT_RW_DEF(func_id, member_id) \ static float rna_Gizmo_##func_id##_get(PointerRNA *ptr) \ { \ - wmGizmo *mpr = ptr->data; \ - return mpr->member_id; \ + wmGizmo *gz = ptr->data; \ + return gz->member_id; \ } \ static void rna_Gizmo_##func_id##_set(PointerRNA *ptr, float value) \ { \ - wmGizmo *mpr = ptr->data; \ - mpr->member_id = value; \ + wmGizmo *gz = ptr->data; \ + gz->member_id = value; \ } #define RNA_GIZMO_GENERIC_FLOAT_ARRAY_INDEX_RW_DEF(func_id, member_id, index) \ static float rna_Gizmo_##func_id##_get(PointerRNA *ptr) \ { \ - wmGizmo *mpr = ptr->data; \ - return mpr->member_id[index]; \ + wmGizmo *gz = ptr->data; \ + return gz->member_id[index]; \ } \ static void rna_Gizmo_##func_id##_set(PointerRNA *ptr, float value) \ { \ - wmGizmo *mpr = ptr->data; \ - mpr->member_id[index] = value; \ + wmGizmo *gz = ptr->data; \ + gz->member_id[index] = value; \ } /* wmGizmo.float[len] */ #define RNA_GIZMO_GENERIC_FLOAT_ARRAY_RW_DEF(func_id, member_id, len) \ static void rna_Gizmo_##func_id##_get(PointerRNA *ptr, float value[len]) \ { \ - wmGizmo *mpr = ptr->data; \ - memcpy(value, mpr->member_id, sizeof(float[len])); \ + wmGizmo *gz = ptr->data; \ + memcpy(value, gz->member_id, sizeof(float[len])); \ } \ static void rna_Gizmo_##func_id##_set(PointerRNA *ptr, const float value[len]) \ { \ - wmGizmo *mpr = ptr->data; \ - memcpy(mpr->member_id, value, sizeof(float[len])); \ + wmGizmo *gz = ptr->data; \ + memcpy(gz->member_id, value, sizeof(float[len])); \ } /* wmGizmo.flag */ #define RNA_GIZMO_GENERIC_FLAG_RW_DEF(func_id, member_id, flag_value) \ static bool rna_Gizmo_##func_id##_get(PointerRNA *ptr) \ { \ - wmGizmo *mpr = ptr->data; \ - return (mpr->member_id & flag_value) != 0; \ + wmGizmo *gz = ptr->data; \ + return (gz->member_id & flag_value) != 0; \ } \ static void rna_Gizmo_##func_id##_set(PointerRNA *ptr, bool value) \ { \ - wmGizmo *mpr = ptr->data; \ - SET_FLAG_FROM_TEST(mpr->member_id, value, flag_value); \ + wmGizmo *gz = ptr->data; \ + SET_FLAG_FROM_TEST(gz->member_id, value, flag_value); \ } /* wmGizmo.flag (negative) */ #define RNA_GIZMO_GENERIC_FLAG_NEG_RW_DEF(func_id, member_id, flag_value) \ static bool rna_Gizmo_##func_id##_get(PointerRNA *ptr) \ { \ - wmGizmo *mpr = ptr->data; \ - return (mpr->member_id & flag_value) == 0; \ + wmGizmo *gz = ptr->data; \ + return (gz->member_id & flag_value) == 0; \ } \ static void rna_Gizmo_##func_id##_set(PointerRNA *ptr, bool value) \ { \ - wmGizmo *mpr = ptr->data; \ - SET_FLAG_FROM_TEST(mpr->member_id, !value, flag_value); \ + wmGizmo *gz = ptr->data; \ + SET_FLAG_FROM_TEST(gz->member_id, !value, flag_value); \ } #define RNA_GIZMO_FLAG_RO_DEF(func_id, member_id, flag_value) \ static int rna_Gizmo_##func_id##_get(PointerRNA *ptr) \ { \ - wmGizmo *mpr = ptr->data; \ - return (mpr->member_id & flag_value) != 0; \ + wmGizmo *gz = ptr->data; \ + return (gz->member_id & flag_value) != 0; \ } RNA_GIZMO_GENERIC_FLOAT_ARRAY_RW_DEF(color, color, 3); @@ -391,8 +391,8 @@ RNA_GIZMO_GENERIC_FLOAT_ARRAY_RW_DEF(matrix_offset, matrix_offset, 16); static void rna_Gizmo_matrix_world_get(PointerRNA *ptr, float value[16]) { - wmGizmo *mpr = ptr->data; - WM_gizmo_calc_matrix_final(mpr, (float (*)[4])value); + wmGizmo *gz = ptr->data; + WM_gizmo_calc_matrix_final(gz, (float (*)[4])value); } RNA_GIZMO_GENERIC_FLOAT_RW_DEF(scale_basis, scale_basis); @@ -414,21 +414,21 @@ RNA_GIZMO_FLAG_RO_DEF(state_select, state, WM_GIZMO_STATE_SELECT); static void rna_Gizmo_state_select_set(struct PointerRNA *ptr, bool value) { - wmGizmo *mpr = ptr->data; - wmGizmoGroup *mgroup = mpr->parent_mgroup; - WM_gizmo_select_set(mgroup->parent_mmap, mpr, value); + wmGizmo *gz = ptr->data; + wmGizmoGroup *gzgroup = gz->parent_gzgroup; + WM_gizmo_select_set(gzgroup->parent_gzmap, gz, value); } static PointerRNA rna_Gizmo_group_get(PointerRNA *ptr) { - wmGizmo *mpr = ptr->data; - return rna_pointer_inherit_refine(ptr, &RNA_GizmoGroup, mpr->parent_mgroup); + wmGizmo *gz = ptr->data; + return rna_pointer_inherit_refine(ptr, &RNA_GizmoGroup, gz->parent_gzgroup); } #ifdef WITH_PYTHON static void rna_Gizmo_unregister(struct Main *bmain, StructRNA *type); -void BPY_RNA_gizmo_wrapper(wmGizmoType *wgt, void *userdata); +void BPY_RNA_gizmo_wrapper(wmGizmoType *gzgt, void *userdata); static StructRNA *rna_Gizmo_register( Main *bmain, ReportList *reports, void *data, const char *identifier, @@ -438,7 +438,7 @@ static StructRNA *rna_Gizmo_register( char idname[MAX_NAME]; } temp_buffers; - wmGizmoType dummywt = {NULL}; + wmGizmoType dummygt = {NULL}; wmGizmo dummymnp = {NULL}; PointerRNA mnp_ptr; @@ -446,8 +446,8 @@ static StructRNA *rna_Gizmo_register( int have_function[8]; /* setup dummy gizmo & gizmo type to store static properties in */ - dummymnp.type = &dummywt; - dummywt.idname = temp_buffers.idname; + dummymnp.type = &dummygt; + dummygt.idname = temp_buffers.idname; RNA_pointer_create(NULL, &RNA_Gizmo, &dummymnp, &mnp_ptr); /* Clear so we can detect if it's left unset. */ @@ -465,71 +465,72 @@ static StructRNA *rna_Gizmo_register( /* check if we have registered this gizmo type before, and remove it */ { - const wmGizmoType *wt = WM_gizmotype_find(dummywt.idname, true); - if (wt && wt->ext.srna) { - rna_Gizmo_unregister(bmain, wt->ext.srna); + const wmGizmoType *gzt = WM_gizmotype_find(dummygt.idname, true); + if (gzt && gzt->ext.srna) { + rna_Gizmo_unregister(bmain, gzt->ext.srna); } } - if (!RNA_struct_available_or_report(reports, dummywt.idname)) { + if (!RNA_struct_available_or_report(reports, dummygt.idname)) { return NULL; } { /* allocate the idname */ /* For multiple strings see GizmoGroup. */ - dummywt.idname = BLI_strdup(temp_buffers.idname); + dummygt.idname = BLI_strdup(temp_buffers.idname); } /* create a new gizmo type */ - dummywt.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummywt.idname, &RNA_Gizmo); + dummygt.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummygt.idname, &RNA_Gizmo); /* gizmo properties are registered separately */ - RNA_def_struct_flag(dummywt.ext.srna, STRUCT_NO_IDPROPERTIES); - dummywt.ext.data = data; - dummywt.ext.call = call; - dummywt.ext.free = free; + RNA_def_struct_flag(dummygt.ext.srna, STRUCT_NO_IDPROPERTIES); + dummygt.ext.data = data; + dummygt.ext.call = call; + dummygt.ext.free = free; { int i = 0; - dummywt.draw = (have_function[i++]) ? rna_gizmo_draw_cb : NULL; - dummywt.draw_select = (have_function[i++]) ? rna_gizmo_draw_select_cb : NULL; - dummywt.test_select = (have_function[i++]) ? rna_gizmo_test_select_cb : NULL; - dummywt.modal = (have_function[i++]) ? rna_gizmo_modal_cb : NULL; -// dummywt.property_update = (have_function[i++]) ? rna_gizmo_property_update : NULL; -// dummywt.position_get = (have_function[i++]) ? rna_gizmo_position_get : NULL; - dummywt.setup = (have_function[i++]) ? rna_gizmo_setup_cb : NULL; - dummywt.invoke = (have_function[i++]) ? rna_gizmo_invoke_cb : NULL; - dummywt.exit = (have_function[i++]) ? rna_gizmo_exit_cb : NULL; - dummywt.select_refresh = (have_function[i++]) ? rna_gizmo_select_refresh_cb : NULL; + dummygt.draw = (have_function[i++]) ? rna_gizmo_draw_cb : NULL; + dummygt.draw_select = (have_function[i++]) ? rna_gizmo_draw_select_cb : NULL; + dummygt.test_select = (have_function[i++]) ? rna_gizmo_test_select_cb : NULL; + dummygt.modal = (have_function[i++]) ? rna_gizmo_modal_cb : NULL; +// dummygt.property_update = (have_function[i++]) ? rna_gizmo_property_update : NULL; +// dummygt.position_get = (have_function[i++]) ? rna_gizmo_position_get : NULL; + dummygt.setup = (have_function[i++]) ? rna_gizmo_setup_cb : NULL; + dummygt.invoke = (have_function[i++]) ? rna_gizmo_invoke_cb : NULL; + dummygt.exit = (have_function[i++]) ? rna_gizmo_exit_cb : NULL; + dummygt.select_refresh = (have_function[i++]) ? rna_gizmo_select_refresh_cb : NULL; BLI_assert(i == ARRAY_SIZE(have_function)); } - WM_gizmotype_append_ptr(BPY_RNA_gizmo_wrapper, (void *)&dummywt); + WM_gizmotype_append_ptr(BPY_RNA_gizmo_wrapper, (void *)&dummygt); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); - return dummywt.ext.srna; + return dummygt.ext.srna; } static void rna_Gizmo_unregister(struct Main *bmain, StructRNA *type) { - wmGizmoType *wt = RNA_struct_blender_type_get(type); + wmGizmoType *gzt = RNA_struct_blender_type_get(type); - if (!wt) + if (!gzt) { return; + } - RNA_struct_free_extension(type, &wt->ext); + RNA_struct_free_extension(type, &gzt->ext); RNA_struct_free(&BLENDER_RNA, type); WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); - WM_gizmotype_remove_ptr(NULL, bmain, wt); + WM_gizmotype_remove_ptr(NULL, bmain, gzt); } static void **rna_Gizmo_instance(PointerRNA *ptr) { - wmGizmo *mpr = ptr->data; - return &mpr->py_instance; + wmGizmo *gz = ptr->data; + return &gz->py_instance; } #endif /* WITH_PYTHON */ @@ -537,8 +538,8 @@ static void **rna_Gizmo_instance(PointerRNA *ptr) static StructRNA *rna_Gizmo_refine(PointerRNA *mnp_ptr) { - wmGizmo *mpr = mnp_ptr->data; - return (mpr->type && mpr->type->ext.srna) ? mpr->type->ext.srna : &RNA_Gizmo; + wmGizmo *gz = mnp_ptr->data; + return (gz->type && gz->type->ext.srna) ? gz->type->ext.srna : &RNA_Gizmo; } /** \} */ @@ -547,41 +548,41 @@ static StructRNA *rna_Gizmo_refine(PointerRNA *mnp_ptr) * \{ */ static wmGizmo *rna_GizmoGroup_gizmo_new( - wmGizmoGroup *mgroup, ReportList *reports, const char *idname) + wmGizmoGroup *gzgroup, ReportList *reports, const char *idname) { - const wmGizmoType *wt = WM_gizmotype_find(idname, true); - if (wt == NULL) { + const wmGizmoType *gzt = WM_gizmotype_find(idname, true); + if (gzt == NULL) { BKE_reportf(reports, RPT_ERROR, "GizmoType '%s' not known", idname); return NULL; } - wmGizmo *mpr = WM_gizmo_new_ptr(wt, mgroup, NULL); - return mpr; + wmGizmo *gz = WM_gizmo_new_ptr(gzt, gzgroup, NULL); + return gz; } static void rna_GizmoGroup_gizmo_remove( - wmGizmoGroup *mgroup, bContext *C, wmGizmo *mpr) + wmGizmoGroup *gzgroup, bContext *C, wmGizmo *gz) { - WM_gizmo_unlink(&mgroup->gizmos, mgroup->parent_mmap, mpr, C); + WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, gz, C); } static void rna_GizmoGroup_gizmo_clear( - wmGizmoGroup *mgroup, bContext *C) + wmGizmoGroup *gzgroup, bContext *C) { - while (mgroup->gizmos.first) { - WM_gizmo_unlink(&mgroup->gizmos, mgroup->parent_mmap, mgroup->gizmos.first, C); + while (gzgroup->gizmos.first) { + WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, gzgroup->gizmos.first, C); } } static void rna_GizmoGroup_name_get(PointerRNA *ptr, char *value) { - wmGizmoGroup *mgroup = ptr->data; - strcpy(value, mgroup->type->name); + wmGizmoGroup *gzgroup = ptr->data; + strcpy(value, gzgroup->type->name); } static int rna_GizmoGroup_name_length(PointerRNA *ptr) { - wmGizmoGroup *mgroup = ptr->data; - return strlen(mgroup->type->name); + wmGizmoGroup *gzgroup = ptr->data; + return strlen(gzgroup->type->name); } /* just to work around 'const char *' warning and to ensure this is a python op */ @@ -607,13 +608,13 @@ static void rna_GizmoGroup_bl_label_set(PointerRNA *ptr, const char *value) static bool rna_GizmoGroup_has_reports_get(PointerRNA *ptr) { - wmGizmoGroup *mgroup = ptr->data; - return (mgroup->reports && mgroup->reports->list.first); + wmGizmoGroup *gzgroup = ptr->data; + return (gzgroup->reports && gzgroup->reports->list.first); } #ifdef WITH_PYTHON -static bool rna_gizmogroup_poll_cb(const bContext *C, wmGizmoGroupType *wgt) +static bool rna_gizmogroup_poll_cb(const bContext *C, wmGizmoGroupType *gzgt) { extern FunctionRNA rna_GizmoGroup_poll_func; @@ -624,12 +625,12 @@ static bool rna_gizmogroup_poll_cb(const bContext *C, wmGizmoGroupType *wgt) void *ret; int visible; - RNA_pointer_create(NULL, wgt->ext.srna, NULL, &ptr); /* dummy */ + RNA_pointer_create(NULL, gzgt->ext.srna, NULL, &ptr); /* dummy */ func = &rna_GizmoGroup_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */ RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - wgt->ext.call((bContext *)C, &ptr, func, &list); + gzgt->ext.call((bContext *)C, &ptr, func, &list); RNA_parameter_get_lookup(&list, "visible", &ret); visible = *(int *)ret; @@ -639,25 +640,25 @@ static bool rna_gizmogroup_poll_cb(const bContext *C, wmGizmoGroupType *wgt) return visible; } -static void rna_gizmogroup_setup_cb(const bContext *C, wmGizmoGroup *mgroup) +static void rna_gizmogroup_setup_cb(const bContext *C, wmGizmoGroup *gzgroup) { extern FunctionRNA rna_GizmoGroup_setup_func; - PointerRNA mgroup_ptr; + PointerRNA gzgroup_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr); + RNA_pointer_create(NULL, gzgroup->type->ext.srna, gzgroup, &gzgroup_ptr); func = &rna_GizmoGroup_setup_func; /* RNA_struct_find_function(&wgroupr, "setup"); */ - RNA_parameter_list_create(&list, &mgroup_ptr, func); + RNA_parameter_list_create(&list, &gzgroup_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gzgroup_ptr, func, &list); RNA_parameter_list_free(&list); } -static wmKeyMap *rna_gizmogroup_setup_keymap_cb(const wmGizmoGroupType *wgt, wmKeyConfig *config) +static wmKeyMap *rna_gizmogroup_setup_keymap_cb(const wmGizmoGroupType *gzgt, wmKeyConfig *config) { extern FunctionRNA rna_GizmoGroup_setup_keymap_func; void *ret; @@ -666,12 +667,12 @@ static wmKeyMap *rna_gizmogroup_setup_keymap_cb(const wmGizmoGroupType *wgt, wmK ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, wgt->ext.srna, NULL, &ptr); /* dummy */ + RNA_pointer_create(NULL, gzgt->ext.srna, NULL, &ptr); /* dummy */ func = &rna_GizmoGroup_setup_keymap_func; /* RNA_struct_find_function(&wgroupr, "setup_keymap"); */ RNA_parameter_list_create(&list, &ptr, func); RNA_parameter_set_lookup(&list, "keyconfig", &config); - wgt->ext.call(NULL, &ptr, func, &list); + gzgt->ext.call(NULL, &ptr, func, &list); RNA_parameter_get_lookup(&list, "keymap", &ret); wmKeyMap *keymap = *(wmKeyMap **)ret; @@ -681,43 +682,43 @@ static wmKeyMap *rna_gizmogroup_setup_keymap_cb(const wmGizmoGroupType *wgt, wmK return keymap; } -static void rna_gizmogroup_refresh_cb(const bContext *C, wmGizmoGroup *mgroup) +static void rna_gizmogroup_refresh_cb(const bContext *C, wmGizmoGroup *gzgroup) { extern FunctionRNA rna_GizmoGroup_refresh_func; - PointerRNA mgroup_ptr; + PointerRNA gzgroup_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr); + RNA_pointer_create(NULL, gzgroup->type->ext.srna, gzgroup, &gzgroup_ptr); func = &rna_GizmoGroup_refresh_func; /* RNA_struct_find_function(&wgroupr, "refresh"); */ - RNA_parameter_list_create(&list, &mgroup_ptr, func); + RNA_parameter_list_create(&list, &gzgroup_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gzgroup_ptr, func, &list); RNA_parameter_list_free(&list); } -static void rna_gizmogroup_draw_prepare_cb(const bContext *C, wmGizmoGroup *mgroup) +static void rna_gizmogroup_draw_prepare_cb(const bContext *C, wmGizmoGroup *gzgroup) { extern FunctionRNA rna_GizmoGroup_draw_prepare_func; - PointerRNA mgroup_ptr; + PointerRNA gzgroup_ptr; ParameterList list; FunctionRNA *func; - RNA_pointer_create(NULL, mgroup->type->ext.srna, mgroup, &mgroup_ptr); + RNA_pointer_create(NULL, gzgroup->type->ext.srna, gzgroup, &gzgroup_ptr); func = &rna_GizmoGroup_draw_prepare_func; /* RNA_struct_find_function(&wgroupr, "draw_prepare"); */ - RNA_parameter_list_create(&list, &mgroup_ptr, func); + RNA_parameter_list_create(&list, &gzgroup_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - mgroup->type->ext.call((bContext *)C, &mgroup_ptr, func, &list); + gzgroup->type->ext.call((bContext *)C, &gzgroup_ptr, func, &list); RNA_parameter_list_free(&list); } -void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *wgt, void *userdata); +void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *gzgt, void *userdata); static void rna_GizmoGroup_unregister(struct Main *bmain, StructRNA *type); static StructRNA *rna_GizmoGroup_register( @@ -758,21 +759,21 @@ static StructRNA *rna_GizmoGroup_register( /* check if the area supports widgets */ const struct wmGizmoMapType_Params wmap_params = { - .spaceid = dummywgt.mmap_params.spaceid, - .regionid = dummywgt.mmap_params.regionid, + .spaceid = dummywgt.gzmap_params.spaceid, + .regionid = dummywgt.gzmap_params.regionid, }; - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wmap_params); - if (mmap_type == NULL) { + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&wmap_params); + if (gzmap_type == NULL) { BKE_reportf(reports, RPT_ERROR, "Area type does not support gizmos"); return NULL; } /* check if we have registered this gizmogroup type before, and remove it */ { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(dummywgt.idname, true); - if (wgt && wgt->ext.srna) { - rna_GizmoGroup_unregister(bmain, wgt->ext.srna); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(dummywgt.idname, true); + if (gzgt && gzgt->ext.srna) { + rna_GizmoGroup_unregister(bmain, gzgt->ext.srna); } } if (!RNA_struct_available_or_report(reports, dummywgt.idname)) { @@ -807,18 +808,18 @@ static StructRNA *rna_GizmoGroup_register( dummywgt.refresh = (have_function[3]) ? rna_gizmogroup_refresh_cb : NULL; dummywgt.draw_prepare = (have_function[4]) ? rna_gizmogroup_draw_prepare_cb : NULL; - wmGizmoGroupType *wgt = WM_gizmogrouptype_append_ptr( + wmGizmoGroupType *gzgt = WM_gizmogrouptype_append_ptr( BPY_RNA_gizmogroup_wrapper, (void *)&dummywgt); { const char *owner_id = RNA_struct_state_owner_get(); if (owner_id) { - BLI_strncpy(wgt->owner_id, owner_id, sizeof(wgt->owner_id)); + BLI_strncpy(gzgt->owner_id, owner_id, sizeof(gzgt->owner_id)); } } - if (wgt->flag & WM_GIZMOGROUPTYPE_PERSISTENT) { - WM_gizmo_group_type_add_ptr_ex(wgt, mmap_type); + if (gzgt->flag & WM_GIZMOGROUPTYPE_PERSISTENT) { + WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type); /* update while blender is running */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); @@ -829,37 +830,37 @@ static StructRNA *rna_GizmoGroup_register( static void rna_GizmoGroup_unregister(struct Main *bmain, StructRNA *type) { - wmGizmoGroupType *wgt = RNA_struct_blender_type_get(type); + wmGizmoGroupType *gzgt = RNA_struct_blender_type_get(type); - if (!wgt) + if (!gzgt) return; - RNA_struct_free_extension(type, &wgt->ext); + RNA_struct_free_extension(type, &gzgt->ext); RNA_struct_free(&BLENDER_RNA, type); WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); - WM_gizmo_group_type_remove_ptr(bmain, wgt); + WM_gizmo_group_type_remove_ptr(bmain, gzgt); } static void **rna_GizmoGroup_instance(PointerRNA *ptr) { - wmGizmoGroup *mgroup = ptr->data; - return &mgroup->py_instance; + wmGizmoGroup *gzgroup = ptr->data; + return &gzgroup->py_instance; } #endif /* WITH_PYTHON */ -static StructRNA *rna_GizmoGroup_refine(PointerRNA *mgroup_ptr) +static StructRNA *rna_GizmoGroup_refine(PointerRNA *gzgroup_ptr) { - wmGizmoGroup *mgroup = mgroup_ptr->data; - return (mgroup->type && mgroup->type->ext.srna) ? mgroup->type->ext.srna : &RNA_GizmoGroup; + wmGizmoGroup *gzgroup = gzgroup_ptr->data; + return (gzgroup->type && gzgroup->type->ext.srna) ? gzgroup->type->ext.srna : &RNA_GizmoGroup; } -static void rna_GizmoGroup_gizmos_begin(CollectionPropertyIterator *iter, PointerRNA *mgroup_ptr) +static void rna_GizmoGroup_gizmos_begin(CollectionPropertyIterator *iter, PointerRNA *gzgroup_ptr) { - wmGizmoGroup *mgroup = mgroup_ptr->data; - rna_iterator_listbase_begin(iter, &mgroup->gizmos, NULL); + wmGizmoGroup *gzgroup = gzgroup_ptr->data; + rna_iterator_listbase_begin(iter, &gzgroup->gizmos, NULL); } /** \} */ @@ -1210,13 +1211,13 @@ static void rna_def_gizmogroup(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_REGISTER); prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type->mmap_params.spaceid"); + RNA_def_property_enum_sdna(prop, NULL, "type->gzmap_params.spaceid"); RNA_def_property_enum_items(prop, rna_enum_space_type_items); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in"); prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type->mmap_params.regionid"); + RNA_def_property_enum_sdna(prop, NULL, "type->gzmap_params.regionid"); RNA_def_property_enum_items(prop, rna_enum_region_type_items); RNA_def_property_flag(prop, PROP_REGISTER); RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in"); diff --git a/source/blender/makesrna/intern/rna_wm_gizmo_api.c b/source/blender/makesrna/intern/rna_wm_gizmo_api.c index 04c02889fa3..e8a9e585165 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo_api.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo_api.c @@ -47,28 +47,28 @@ #include "ED_gizmo_library.h" static void rna_gizmo_draw_preset_box( - wmGizmo *mpr, float matrix[16], int select_id) + wmGizmo *gz, float matrix[16], int select_id) { - ED_gizmo_draw_preset_box(mpr, (float (*)[4])matrix, select_id); + ED_gizmo_draw_preset_box(gz, (float (*)[4])matrix, select_id); } static void rna_gizmo_draw_preset_arrow( - wmGizmo *mpr, float matrix[16], int axis, int select_id) + wmGizmo *gz, float matrix[16], int axis, int select_id) { - ED_gizmo_draw_preset_arrow(mpr, (float (*)[4])matrix, axis, select_id); + ED_gizmo_draw_preset_arrow(gz, (float (*)[4])matrix, axis, select_id); } static void rna_gizmo_draw_preset_circle( - wmGizmo *mpr, float matrix[16], int axis, int select_id) + wmGizmo *gz, float matrix[16], int axis, int select_id) { - ED_gizmo_draw_preset_circle(mpr, (float (*)[4])matrix, axis, select_id); + ED_gizmo_draw_preset_circle(gz, (float (*)[4])matrix, axis, select_id); } static void rna_gizmo_draw_preset_facemap( - wmGizmo *mpr, struct bContext *C, struct Object *ob, int facemap, int select_id) + wmGizmo *gz, struct bContext *C, struct Object *ob, int facemap, int select_id) { struct Scene *scene = CTX_data_scene(C); - ED_gizmo_draw_preset_facemap(C, mpr, scene, ob, facemap, select_id); + ED_gizmo_draw_preset_facemap(C, gz, scene, ob, facemap, select_id); } /* -------------------------------------------------------------------- */ @@ -76,14 +76,14 @@ static void rna_gizmo_draw_preset_facemap( * \{ */ static void rna_gizmo_target_set_prop( - wmGizmo *mpr, ReportList *reports, const char *target_propname, + wmGizmo *gz, ReportList *reports, const char *target_propname, PointerRNA *ptr, const char *propname, int index) { - const wmGizmoPropertyType *mpr_prop_type = - WM_gizmotype_target_property_find(mpr->type, target_propname); - if (mpr_prop_type == NULL) { + const wmGizmoPropertyType *gz_prop_type = + WM_gizmotype_target_property_find(gz->type, target_propname); + if (gz_prop_type == NULL) { BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' not found", - mpr->type->idname, target_propname); + gz->type->idname, target_propname); return; } @@ -94,13 +94,13 @@ static void rna_gizmo_target_set_prop( return; } - if (mpr_prop_type->data_type != RNA_property_type(prop)) { - const int gizmo_type_index = RNA_enum_from_value(rna_enum_property_type_items, mpr_prop_type->data_type); + if (gz_prop_type->data_type != RNA_property_type(prop)) { + const int gizmo_type_index = RNA_enum_from_value(rna_enum_property_type_items, gz_prop_type->data_type); const int prop_type_index = RNA_enum_from_value(rna_enum_property_type_items, RNA_property_type(prop)); BLI_assert((gizmo_type_index != -1) && (prop_type_index == -1)); BKE_reportf(reports, RPT_ERROR, "Gizmo target '%s.%s' expects '%s', '%s.%s' is '%s'", - mpr->type->idname, target_propname, + gz->type->idname, target_propname, rna_enum_property_type_items[gizmo_type_index].identifier, RNA_struct_identifier(ptr->type), propname, rna_enum_property_type_items[prop_type_index].identifier); @@ -110,37 +110,37 @@ static void rna_gizmo_target_set_prop( if (RNA_property_array_check(prop)) { if (index == -1) { const int prop_array_length = RNA_property_array_length(ptr, prop); - if (mpr_prop_type->array_length != prop_array_length) { + if (gz_prop_type->array_length != prop_array_length) { BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' expects an array of length %d, found %d", - mpr->type->idname, target_propname, - mpr_prop_type->array_length, + gz->type->idname, target_propname, + gz_prop_type->array_length, prop_array_length); return; } } } else { - if (mpr_prop_type->array_length != 1) { + if (gz_prop_type->array_length != 1) { BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' expects an array of length %d", - mpr->type->idname, target_propname, - mpr_prop_type->array_length); + gz->type->idname, target_propname, + gz_prop_type->array_length); return; } } - if (index >= mpr_prop_type->array_length) { + if (index >= gz_prop_type->array_length) { BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s', index %d must be below %d", - mpr->type->idname, target_propname, index, mpr_prop_type->array_length); + gz->type->idname, target_propname, index, gz_prop_type->array_length); return; } - WM_gizmo_target_property_def_rna_ptr(mpr, mpr_prop_type, ptr, prop, index); + WM_gizmo_target_property_def_rna_ptr(gz, gz_prop_type, ptr, prop, index); } static PointerRNA rna_gizmo_target_set_operator( - wmGizmo *mpr, ReportList *reports, const char *opname, int part_index) + wmGizmo *gz, ReportList *reports, const char *opname, int part_index) { wmOperatorType *ot; @@ -157,7 +157,7 @@ static PointerRNA rna_gizmo_target_set_operator( properties = IDP_New(IDP_GROUP, &val, "wmGizmoProperties"); } - return *WM_gizmo_operator_set(mpr, part_index, ot, properties); + return *WM_gizmo_operator_set(gz, part_index, ot, properties); } /** \} */ @@ -167,16 +167,16 @@ static PointerRNA rna_gizmo_target_set_operator( * \{ */ static bool rna_gizmo_target_is_valid( - wmGizmo *mpr, ReportList *reports, const char *target_propname) + wmGizmo *gz, ReportList *reports, const char *target_propname) { - wmGizmoProperty *mpr_prop = - WM_gizmo_target_property_find(mpr, target_propname); - if (mpr_prop == NULL) { + wmGizmoProperty *gz_prop = + WM_gizmo_target_property_find(gz, target_propname); + if (gz_prop == NULL) { BKE_reportf(reports, RPT_ERROR, "Gizmo target property '%s.%s' not found", - mpr->type->idname, target_propname); + gz->type->idname, target_propname); return false; } - return WM_gizmo_target_property_is_valid(mpr_prop); + return WM_gizmo_target_property_is_valid(gz_prop); } /** \} */ diff --git a/source/blender/python/intern/bpy_gizmo_wrap.c b/source/blender/python/intern/bpy_gizmo_wrap.c index 4b71ea92010..2a932cb6a99 100644 --- a/source/blender/python/intern/bpy_gizmo_wrap.c +++ b/source/blender/python/intern/bpy_gizmo_wrap.c @@ -54,7 +54,7 @@ static bool bpy_gizmotype_target_property_def( - wmGizmoType *wt, PyObject *item) + wmGizmoType *gzt, PyObject *item) { /* Note: names based on 'rna_rna.c' */ PyObject *empty_tuple = PyTuple_New(0); @@ -102,7 +102,7 @@ static bool bpy_gizmotype_target_property_def( goto fail; } - WM_gizmotype_target_property_def(wt, params.id, params.type, params.array_length); + WM_gizmotype_target_property_def(gzt, params.id, params.type, params.array_length); Py_DECREF(empty_tuple); return true; @@ -111,17 +111,17 @@ fail: return false; } -static void gizmo_properties_init(wmGizmoType *wt) +static void gizmo_properties_init(wmGizmoType *gzt) { - PyTypeObject *py_class = wt->ext.data; - RNA_struct_blender_type_set(wt->ext.srna, wt); + PyTypeObject *py_class = gzt->ext.data; + RNA_struct_blender_type_set(gzt->ext.srna, gzt); /* only call this so pyrna_deferred_register_class gives a useful error * WM_operatortype_append_ptr will call RNA_def_struct_identifier * later */ - RNA_def_struct_identifier_no_struct_map(wt->srna, wt->idname); + RNA_def_struct_identifier_no_struct_map(gzt->srna, gzt->idname); - if (pyrna_deferred_register_class(wt->srna, py_class) != 0) { + if (pyrna_deferred_register_class(gzt->srna, py_class) != 0) { PyErr_Print(); /* failed to register operator props */ PyErr_Clear(); } @@ -149,7 +149,7 @@ static void gizmo_properties_init(wmGizmoType *wt) PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast); for (uint i = 0; i < items_len; i++) { - if (!bpy_gizmotype_target_property_def(wt, items[i])) { + if (!bpy_gizmotype_target_property_def(gzt, items[i])) { PyErr_Print(); PyErr_Clear(); break; @@ -161,25 +161,25 @@ static void gizmo_properties_init(wmGizmoType *wt) } } -void BPY_RNA_gizmo_wrapper(wmGizmoType *wt, void *userdata) +void BPY_RNA_gizmo_wrapper(wmGizmoType *gzt, void *userdata) { /* take care not to overwrite anything set in * WM_gizmomaptype_group_link_ptr before opfunc() is called */ - StructRNA *srna = wt->srna; - *wt = *((wmGizmoType *)userdata); - wt->srna = srna; /* restore */ + StructRNA *srna = gzt->srna; + *gzt = *((wmGizmoType *)userdata); + gzt->srna = srna; /* restore */ /* don't do translations here yet */ #if 0 /* Use i18n context from ext.srna if possible (py gizmogroups). */ - if (wt->ext.srna) { - RNA_def_struct_translation_context(wt->srna, RNA_struct_translation_context(wt->ext.srna)); + if (gt->ext.srna) { + RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->ext.srna)); } #endif - wt->struct_size = sizeof(wmGizmo); + gzt->struct_size = sizeof(wmGizmo); - gizmo_properties_init(wt); + gizmo_properties_init(gzt); } /** \} */ @@ -190,46 +190,46 @@ void BPY_RNA_gizmo_wrapper(wmGizmoType *wt, void *userdata) /** \name Gizmo Group * \{ */ -static void gizmogroup_properties_init(wmGizmoGroupType *wgt) +static void gizmogroup_properties_init(wmGizmoGroupType *gzgt) { #ifdef USE_SRNA - PyTypeObject *py_class = wgt->ext.data; + PyTypeObject *py_class = gzgt->ext.data; #endif - RNA_struct_blender_type_set(wgt->ext.srna, wgt); + RNA_struct_blender_type_set(gzgt->ext.srna, gzgt); #ifdef USE_SRNA /* only call this so pyrna_deferred_register_class gives a useful error * WM_operatortype_append_ptr will call RNA_def_struct_identifier * later */ - RNA_def_struct_identifier(wgt->srna, wgt->idname); + RNA_def_struct_identifier(gzgt->srna, gzgt->idname); - if (pyrna_deferred_register_class(wgt->srna, py_class) != 0) { + if (pyrna_deferred_register_class(gzgt->srna, py_class) != 0) { PyErr_Print(); /* failed to register operator props */ PyErr_Clear(); } #endif } -void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *wgt, void *userdata) +void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *gzgt, void *userdata) { /* take care not to overwrite anything set in * WM_gizmomaptype_group_link_ptr before opfunc() is called */ #ifdef USE_SRNA - StructRNA *srna = wgt->srna; + StructRNA *srna = gzgt->srna; #endif - *wgt = *((wmGizmoGroupType *)userdata); + *gzgt = *((wmGizmoGroupType *)userdata); #ifdef USE_SRNA - wgt->srna = srna; /* restore */ + gzgt->srna = srna; /* restore */ #endif #ifdef USE_SRNA /* Use i18n context from ext.srna if possible (py gizmogroups). */ - if (wgt->ext.srna) { - RNA_def_struct_translation_context(wgt->srna, RNA_struct_translation_context(wgt->ext.srna)); + if (gzgt->ext.srna) { + RNA_def_struct_translation_context(gzgt->srna, RNA_struct_translation_context(gzgt->ext.srna)); } #endif - gizmogroup_properties_init(wgt); + gizmogroup_properties_init(gzgt); } /** \} */ diff --git a/source/blender/python/intern/bpy_gizmo_wrap.h b/source/blender/python/intern/bpy_gizmo_wrap.h index 4d6639d977f..96f15312a4e 100644 --- a/source/blender/python/intern/bpy_gizmo_wrap.h +++ b/source/blender/python/intern/bpy_gizmo_wrap.h @@ -29,7 +29,7 @@ struct wmGizmoType; struct wmGizmoGroupType; /* exposed to rna/wm api */ -void BPY_RNA_gizmo_wrapper(struct wmGizmoType *wt, void *userdata); -void BPY_RNA_gizmogroup_wrapper(struct wmGizmoGroupType *wgt, void *userdata); +void BPY_RNA_gizmo_wrapper(struct wmGizmoType *gzt, void *userdata); +void BPY_RNA_gizmogroup_wrapper(struct wmGizmoGroupType *gzgt, void *userdata); #endif /* __BPY_GIZMO_WRAP_H__ */ diff --git a/source/blender/python/intern/bpy_rna_gizmo.c b/source/blender/python/intern/bpy_rna_gizmo.c index e834595114a..ded26f777a5 100644 --- a/source/blender/python/intern/bpy_rna_gizmo.c +++ b/source/blender/python/intern/bpy_rna_gizmo.c @@ -67,26 +67,26 @@ struct BPyGizmoHandlerUserData { }; static void py_rna_gizmo_handler_get_cb( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { PyGILState_STATE gilstate = PyGILState_Ensure(); - struct BPyGizmoHandlerUserData *data = mpr_prop->custom_func.user_data; + struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_GIZMO_FN_SLOT_GET], NULL); if (ret == NULL) { goto fail; } - if (mpr_prop->type->data_type == PROP_FLOAT) { + if (gz_prop->type->data_type == PROP_FLOAT) { float *value = value_p; - if (mpr_prop->type->array_length == 1) { + if (gz_prop->type->array_length == 1) { if ((*value = PyFloat_AsDouble(ret)) == -1.0f && PyErr_Occurred()) { goto fail; } } else { - if (PyC_AsArray(value, ret, mpr_prop->type->array_length, &PyFloat_Type, false, + if (PyC_AsArray(value, ret, gz_prop->type->array_length, &PyFloat_Type, false, "Gizmo get callback: ") == -1) { goto fail; @@ -111,23 +111,23 @@ fail: } static void py_rna_gizmo_handler_set_cb( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { PyGILState_STATE gilstate = PyGILState_Ensure(); - struct BPyGizmoHandlerUserData *data = mpr_prop->custom_func.user_data; + struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; PyObject *args = PyTuple_New(1); - if (mpr_prop->type->data_type == PROP_FLOAT) { + if (gz_prop->type->data_type == PROP_FLOAT) { const float *value = value_p; PyObject *py_value; - if (mpr_prop->type->array_length == 1) { + if (gz_prop->type->array_length == 1) { py_value = PyFloat_FromDouble(*value); } else { - py_value = PyC_Tuple_PackArray_F32(value, mpr_prop->type->array_length); + py_value = PyC_Tuple_PackArray_F32(value, gz_prop->type->array_length); } if (py_value == NULL) { goto fail; @@ -158,10 +158,10 @@ fail: } static void py_rna_gizmo_handler_range_get_cb( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop, + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { - struct BPyGizmoHandlerUserData *data = mpr_prop->custom_func.user_data; + struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -184,7 +184,7 @@ static void py_rna_gizmo_handler_range_get_cb( goto fail; } - if (mpr_prop->type->data_type == PROP_FLOAT) { + if (gz_prop->type->data_type == PROP_FLOAT) { float range[2]; for (int i = 0; i < 2; i++) { if (((range[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(ret, i))) == -1.0f && PyErr_Occurred()) == 0) { @@ -215,9 +215,9 @@ fail: } static void py_rna_gizmo_handler_free_cb( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop) + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop) { - struct BPyGizmoHandlerUserData *data = mpr_prop->custom_func.user_data; + struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; PyGILState_STATE gilstate = PyGILState_Ensure(); for (int i = 0; i < BPY_GIZMO_FN_SLOT_LEN; i++) { @@ -271,14 +271,14 @@ static PyObject *bpy_gizmo_target_set_handler(PyObject *UNUSED(self), PyObject * goto fail; } - wmGizmo *mpr = ((BPy_StructRNA *)params.self)->ptr.data; + wmGizmo *gz = ((BPy_StructRNA *)params.self)->ptr.data; - const wmGizmoPropertyType *mpr_prop_type = - WM_gizmotype_target_property_find(mpr->type, params.target); - if (mpr_prop_type == NULL) { + const wmGizmoPropertyType *gz_prop_type = + WM_gizmotype_target_property_find(gz->type, params.target); + if (gz_prop_type == NULL) { PyErr_Format(PyExc_ValueError, "Gizmo target property '%s.%s' not found", - mpr->type->idname, params.target); + gz->type->idname, params.target); goto fail; } @@ -307,7 +307,7 @@ static PyObject *bpy_gizmo_target_set_handler(PyObject *UNUSED(self), PyObject * } WM_gizmo_target_property_def_func_ptr( - mpr, mpr_prop_type, + gz, gz_prop_type, &(const struct wmGizmoPropertyFnParams) { .value_get_fn = py_rna_gizmo_handler_get_cb, .value_set_fn = py_rna_gizmo_handler_set_cb, @@ -361,28 +361,28 @@ static PyObject *bpy_gizmo_target_get_value(PyObject *UNUSED(self), PyObject *ar goto fail; } - wmGizmo *mpr = ((BPy_StructRNA *)params.self)->ptr.data; + wmGizmo *gz = ((BPy_StructRNA *)params.self)->ptr.data; - wmGizmoProperty *mpr_prop = - WM_gizmo_target_property_find(mpr, params.target); - if (mpr_prop == NULL) { + wmGizmoProperty *gz_prop = + WM_gizmo_target_property_find(gz, params.target); + if (gz_prop == NULL) { PyErr_Format(PyExc_ValueError, "Gizmo target property '%s.%s' not found", - mpr->type->idname, params.target); + gz->type->idname, params.target); goto fail; } - const int array_len = WM_gizmo_target_property_array_length(mpr, mpr_prop); - switch (mpr_prop->type->data_type) { + const int array_len = WM_gizmo_target_property_array_length(gz, gz_prop); + switch (gz_prop->type->data_type) { case PROP_FLOAT: { if (array_len != 0) { float *value = BLI_array_alloca(value, array_len); - WM_gizmo_target_property_value_get_array(mpr, mpr_prop, value); + WM_gizmo_target_property_value_get_array(gz, gz_prop, value); return PyC_Tuple_PackArray_F32(value, array_len); } else { - float value = WM_gizmo_target_property_value_get(mpr, mpr_prop); + float value = WM_gizmo_target_property_value_get(gz, gz_prop); return PyFloat_FromDouble(value); } break; @@ -429,36 +429,36 @@ static PyObject *bpy_gizmo_target_set_value(PyObject *UNUSED(self), PyObject *ar goto fail; } - wmGizmo *mpr = ((BPy_StructRNA *)params.self)->ptr.data; + wmGizmo *gz = ((BPy_StructRNA *)params.self)->ptr.data; - wmGizmoProperty *mpr_prop = - WM_gizmo_target_property_find(mpr, params.target); - if (mpr_prop == NULL) { + wmGizmoProperty *gz_prop = + WM_gizmo_target_property_find(gz, params.target); + if (gz_prop == NULL) { PyErr_Format(PyExc_ValueError, "Gizmo target property '%s.%s' not found", - mpr->type->idname, params.target); + gz->type->idname, params.target); goto fail; } - const int array_len = WM_gizmo_target_property_array_length(mpr, mpr_prop); - switch (mpr_prop->type->data_type) { + const int array_len = WM_gizmo_target_property_array_length(gz, gz_prop); + switch (gz_prop->type->data_type) { case PROP_FLOAT: { if (array_len != 0) { float *value = BLI_array_alloca(value, array_len); - if (PyC_AsArray(value, params.value, mpr_prop->type->array_length, &PyFloat_Type, false, + if (PyC_AsArray(value, params.value, gz_prop->type->array_length, &PyFloat_Type, false, "Gizmo target property array") == -1) { goto fail; } - WM_gizmo_target_property_value_set_array(BPy_GetContext(), mpr, mpr_prop, value); + WM_gizmo_target_property_value_set_array(BPy_GetContext(), gz, gz_prop, value); } else { float value; if ((value = PyFloat_AsDouble(params.value)) == -1.0f && PyErr_Occurred()) { goto fail; } - WM_gizmo_target_property_value_set(BPy_GetContext(), mpr, mpr_prop, value); + WM_gizmo_target_property_value_set(BPy_GetContext(), gz, gz_prop, value); } Py_RETURN_NONE; } @@ -504,22 +504,22 @@ static PyObject *bpy_gizmo_target_get_range(PyObject *UNUSED(self), PyObject *ar goto fail; } - wmGizmo *mpr = ((BPy_StructRNA *)params.self)->ptr.data; + wmGizmo *gz = ((BPy_StructRNA *)params.self)->ptr.data; - wmGizmoProperty *mpr_prop = - WM_gizmo_target_property_find(mpr, params.target); - if (mpr_prop == NULL) { + wmGizmoProperty *gz_prop = + WM_gizmo_target_property_find(gz, params.target); + if (gz_prop == NULL) { PyErr_Format(PyExc_ValueError, "Gizmo target property '%s.%s' not found", - mpr->type->idname, params.target); + gz->type->idname, params.target); goto fail; } - switch (mpr_prop->type->data_type) { + switch (gz_prop->type->data_type) { case PROP_FLOAT: { float range[2]; - WM_gizmo_target_property_range_get(mpr, mpr_prop, range); + WM_gizmo_target_property_range_get(gz, gz_prop, range); return PyC_Tuple_PackArray_F32(range, 2); } default: diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h index a93597d4f64..9b8cecfb4bc 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h @@ -60,57 +60,57 @@ struct wmMsgSubscribeValue; /* wmGizmo */ struct wmGizmo *WM_gizmo_new_ptr( - const struct wmGizmoType *wt, struct wmGizmoGroup *mgroup, + const struct wmGizmoType *gzt, struct wmGizmoGroup *gzgroup, struct PointerRNA *properties); struct wmGizmo *WM_gizmo_new( - const char *idname, struct wmGizmoGroup *mgroup, + const char *idname, struct wmGizmoGroup *gzgroup, struct PointerRNA *properties); -void WM_gizmo_free(struct wmGizmo *mpr); +void WM_gizmo_free(struct wmGizmo *gz); void WM_gizmo_unlink( - ListBase *gizmolist, struct wmGizmoMap *mmap, struct wmGizmo *mpr, + ListBase *gizmolist, struct wmGizmoMap *gzmap, struct wmGizmo *gz, struct bContext *C); -void WM_gizmo_name_set(struct wmGizmoGroup *mgroup, struct wmGizmo *mpr, const char *name); +void WM_gizmo_name_set(struct wmGizmoGroup *gzgroup, struct wmGizmo *gz, const char *name); -bool WM_gizmo_select_unlink(struct wmGizmoMap *mmap, struct wmGizmo *mpr); -bool WM_gizmo_select_set(struct wmGizmoMap *mmap, struct wmGizmo *mpr, bool select); -void WM_gizmo_highlight_set(struct wmGizmoMap *mmap, struct wmGizmo *mpr); +bool WM_gizmo_select_unlink(struct wmGizmoMap *gzmap, struct wmGizmo *gz); +bool WM_gizmo_select_set(struct wmGizmoMap *gzmap, struct wmGizmo *gz, bool select); +void WM_gizmo_highlight_set(struct wmGizmoMap *gzmap, struct wmGizmo *gz); void WM_gizmo_modal_set_from_setup( - struct wmGizmoMap *mmap, struct bContext *C, - struct wmGizmo *mpr, int part_index, const struct wmEvent *event); + struct wmGizmoMap *gzmap, struct bContext *C, + struct wmGizmo *gz, int part_index, const struct wmEvent *event); struct wmGizmoOpElem *WM_gizmo_operator_get( - struct wmGizmo *mpr, int part_index); + struct wmGizmo *gz, int part_index); struct PointerRNA *WM_gizmo_operator_set( - struct wmGizmo *mpr, int part_index, + struct wmGizmo *gz, int part_index, struct wmOperatorType *ot, struct IDProperty *properties); /* callbacks */ -void WM_gizmo_set_fn_custom_modal(struct wmGizmo *mpr, wmGizmoFnModal fn); +void WM_gizmo_set_fn_custom_modal(struct wmGizmo *gz, wmGizmoFnModal fn); void WM_gizmo_set_matrix_location( - struct wmGizmo *mpr, const float origin[3]); + struct wmGizmo *gz, const float origin[3]); void WM_gizmo_set_matrix_rotation_from_z_axis( - struct wmGizmo *mpr, const float z_axis[3]); + struct wmGizmo *gz, const float z_axis[3]); void WM_gizmo_set_matrix_rotation_from_yz_axis( - struct wmGizmo *mpr, const float y_axis[3], const float z_axis[3]); + struct wmGizmo *gz, const float y_axis[3], const float z_axis[3]); void WM_gizmo_set_matrix_offset_location( - struct wmGizmo *mpr, const float origin[3]); + struct wmGizmo *gz, const float origin[3]); void WM_gizmo_set_matrix_offset_rotation_from_z_axis( - struct wmGizmo *mpr, const float z_axis[3]); + struct wmGizmo *gz, const float z_axis[3]); void WM_gizmo_set_matrix_offset_rotation_from_yz_axis( - struct wmGizmo *mpr, const float y_axis[3], const float z_axis[3]); + struct wmGizmo *gz, const float y_axis[3], const float z_axis[3]); -void WM_gizmo_set_flag(struct wmGizmo *mpr, const int flag, const bool enable); -void WM_gizmo_set_scale(struct wmGizmo *mpr, float scale); -void WM_gizmo_set_line_width(struct wmGizmo *mpr, const float line_width); +void WM_gizmo_set_flag(struct wmGizmo *gz, const int flag, const bool enable); +void WM_gizmo_set_scale(struct wmGizmo *gz, float scale); +void WM_gizmo_set_line_width(struct wmGizmo *gz, const float line_width); -void WM_gizmo_get_color(const struct wmGizmo *mpr, float color[4]); -void WM_gizmo_set_color(struct wmGizmo *mpr, const float color[4]); -void WM_gizmo_get_color_highlight(const struct wmGizmo *mpr, float color_hi[4]); -void WM_gizmo_set_color_highlight(struct wmGizmo *mpr, const float color[4]); +void WM_gizmo_get_color(const struct wmGizmo *gz, float color[4]); +void WM_gizmo_set_color(struct wmGizmo *gz, const float color[4]); +void WM_gizmo_get_color_highlight(const struct wmGizmo *gz, float color_hi[4]); +void WM_gizmo_set_color_highlight(struct wmGizmo *gz, const float color[4]); /** * Leaving values NULL use values from #wmGizmo. @@ -123,16 +123,16 @@ struct WM_GizmoMatrixParams { }; void WM_gizmo_calc_matrix_final_params( - const struct wmGizmo *mpr, const struct WM_GizmoMatrixParams *params, + const struct wmGizmo *gz, const struct WM_GizmoMatrixParams *params, float r_mat[4][4]); void WM_gizmo_calc_matrix_final_no_offset( - const struct wmGizmo *mpr, float r_mat[4][4]); + const struct wmGizmo *gz, float r_mat[4][4]); void WM_gizmo_calc_matrix_final( - const struct wmGizmo *mpr, float r_mat[4][4]); + const struct wmGizmo *gz, float r_mat[4][4]); /* properties */ -void WM_gizmo_properties_create_ptr(struct PointerRNA *ptr, struct wmGizmoType *wt); +void WM_gizmo_properties_create_ptr(struct PointerRNA *ptr, struct wmGizmoType *gzt); void WM_gizmo_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_gizmo_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *wtstring); void WM_gizmo_properties_sanitize(struct PointerRNA *ptr, const bool no_context); @@ -147,7 +147,7 @@ const struct wmGizmoType *WM_gizmotype_find(const char *idname, bool quiet); void WM_gizmotype_append(void (*wtfunc)(struct wmGizmoType *)); void WM_gizmotype_append_ptr(void (*mnpfunc)(struct wmGizmoType *, void *), void *userdata); bool WM_gizmotype_remove(struct bContext *C, struct Main *bmain, const char *idname); -void WM_gizmotype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmGizmoType *wt); +void WM_gizmotype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmGizmoType *gzt); void WM_gizmotype_iter(struct GHashIterator *ghi); /* wm_gizmo_group_type.c */ @@ -159,111 +159,111 @@ void WM_gizmogrouptype_free_ptr(struct wmGizmoGroupType *wt); void WM_gizmogrouptype_iter(struct GHashIterator *ghi); struct wmGizmoGroupTypeRef *WM_gizmogrouptype_append_and_link( - struct wmGizmoMapType *mmap_type, + struct wmGizmoMapType *gzmap_type, void (*wtfunc)(struct wmGizmoGroupType *)); /* wm_gizmo_map.c */ /* Dynamic Updates (for RNA runtime registration) */ -void WM_gizmoconfig_update_tag_init(struct wmGizmoMapType *mmap_type, struct wmGizmoGroupType *wgt); -void WM_gizmoconfig_update_tag_remove(struct wmGizmoMapType *mmap_type, struct wmGizmoGroupType *wgt); +void WM_gizmoconfig_update_tag_init(struct wmGizmoMapType *gzmap_type, struct wmGizmoGroupType *gzgt); +void WM_gizmoconfig_update_tag_remove(struct wmGizmoMapType *gzmap_type, struct wmGizmoGroupType *gzgt); void WM_gizmoconfig_update(struct Main *bmain); /* wm_maniulator_target_props.c */ -struct wmGizmoProperty *WM_gizmo_target_property_array(struct wmGizmo *mpr); +struct wmGizmoProperty *WM_gizmo_target_property_array(struct wmGizmo *gz); struct wmGizmoProperty *WM_gizmo_target_property_at_index( - struct wmGizmo *mpr, int index); + struct wmGizmo *gz, int index); struct wmGizmoProperty *WM_gizmo_target_property_find( - struct wmGizmo *mpr, const char *idname); + struct wmGizmo *gz, const char *idname); void WM_gizmo_target_property_def_rna_ptr( - struct wmGizmo *mpr, const struct wmGizmoPropertyType *mpr_prop_type, + struct wmGizmo *gz, const struct wmGizmoPropertyType *gz_prop_type, struct PointerRNA *ptr, struct PropertyRNA *prop, int index); void WM_gizmo_target_property_def_rna( - struct wmGizmo *mpr, const char *idname, + struct wmGizmo *gz, const char *idname, struct PointerRNA *ptr, const char *propname, int index); void WM_gizmo_target_property_def_func_ptr( - struct wmGizmo *mpr, const struct wmGizmoPropertyType *mpr_prop_type, + struct wmGizmo *gz, const struct wmGizmoPropertyType *gz_prop_type, const struct wmGizmoPropertyFnParams *params); void WM_gizmo_target_property_def_func( - struct wmGizmo *mpr, const char *idname, + struct wmGizmo *gz, const char *idname, const struct wmGizmoPropertyFnParams *params); void WM_gizmo_target_property_clear_rna_ptr( - struct wmGizmo *mpr, const struct wmGizmoPropertyType *mpr_prop_type); + struct wmGizmo *gz, const struct wmGizmoPropertyType *gz_prop_type); void WM_gizmo_target_property_clear_rna( - struct wmGizmo *mpr, const char *idname); + struct wmGizmo *gz, const char *idname); -bool WM_gizmo_target_property_is_valid_any(struct wmGizmo *mpr); +bool WM_gizmo_target_property_is_valid_any(struct wmGizmo *gz); bool WM_gizmo_target_property_is_valid( - const struct wmGizmoProperty *mpr_prop); + const struct wmGizmoProperty *gz_prop); float WM_gizmo_target_property_value_get( - const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop); + const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop); void WM_gizmo_target_property_value_set( - struct bContext *C, const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop, + struct bContext *C, const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop, const float value); void WM_gizmo_target_property_value_get_array( - const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop, + const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop, float *value); void WM_gizmo_target_property_value_set_array( - struct bContext *C, const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop, + struct bContext *C, const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop, const float *value); bool WM_gizmo_target_property_range_get( - const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop, + const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop, float range[2]); int WM_gizmo_target_property_array_length( - const struct wmGizmo *mpr, struct wmGizmoProperty *mpr_prop); + const struct wmGizmo *gz, struct wmGizmoProperty *gz_prop); /* definitions */ const struct wmGizmoPropertyType *WM_gizmotype_target_property_find( - const struct wmGizmoType *wt, const char *idname); + const struct wmGizmoType *gzt, const char *idname); void WM_gizmotype_target_property_def( - struct wmGizmoType *wt, const char *idname, int data_type, int array_length); + struct wmGizmoType *gzt, const char *idname, int data_type, int array_length); /* utilities */ void WM_gizmo_do_msg_notify_tag_refresh( struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val); void WM_gizmo_target_property_subscribe_all( - struct wmGizmo *mpr, struct wmMsgBus *mbus, struct ARegion *ar); + struct wmGizmo *gz, struct wmMsgBus *mbus, struct ARegion *ar); /* -------------------------------------------------------------------- */ /* wmGizmoGroup */ /* Callbacks for 'wmGizmoGroupType.setup_keymap' */ struct wmKeyMap *WM_gizmogroup_keymap_common( - const struct wmGizmoGroupType *wgt, struct wmKeyConfig *config); + const struct wmGizmoGroupType *gzgt, struct wmKeyConfig *config); struct wmKeyMap *WM_gizmogroup_keymap_common_select( - const struct wmGizmoGroupType *wgt, struct wmKeyConfig *config); + const struct wmGizmoGroupType *gzgt, struct wmKeyConfig *config); /* -------------------------------------------------------------------- */ /* wmGizmoMap */ struct wmGizmoMap *WM_gizmomap_new_from_type( - const struct wmGizmoMapType_Params *mmap_params); -const struct ListBase *WM_gizmomap_group_list(struct wmGizmoMap *mmap); + const struct wmGizmoMapType_Params *gzmap_params); +const struct ListBase *WM_gizmomap_group_list(struct wmGizmoMap *gzmap); struct wmGizmoGroup *WM_gizmomap_group_find( - struct wmGizmoMap *mmap, + struct wmGizmoMap *gzmap, const char *idname); struct wmGizmoGroup *WM_gizmomap_group_find_ptr( - struct wmGizmoMap *mmap, - const struct wmGizmoGroupType *wgt); -void WM_gizmomap_tag_refresh(struct wmGizmoMap *mmap); + struct wmGizmoMap *gzmap, + const struct wmGizmoGroupType *gzgt); +void WM_gizmomap_tag_refresh(struct wmGizmoMap *gzmap); void WM_gizmomap_draw( - struct wmGizmoMap *mmap, const struct bContext *C, const eWM_GizmoFlagMapDrawStep drawstep); -void WM_gizmomap_add_handlers(struct ARegion *ar, struct wmGizmoMap *mmap); -bool WM_gizmomap_select_all(struct bContext *C, struct wmGizmoMap *mmap, const int action); -bool WM_gizmomap_cursor_set(const struct wmGizmoMap *mmap, struct wmWindow *win); + struct wmGizmoMap *gzmap, const struct bContext *C, const eWM_GizmoFlagMapDrawStep drawstep); +void WM_gizmomap_add_handlers(struct ARegion *ar, struct wmGizmoMap *gzmap); +bool WM_gizmomap_select_all(struct bContext *C, struct wmGizmoMap *gzmap, const int action); +bool WM_gizmomap_cursor_set(const struct wmGizmoMap *gzmap, struct wmWindow *win); void WM_gizmomap_message_subscribe( - struct bContext *C, struct wmGizmoMap *mmap, struct ARegion *ar, struct wmMsgBus *mbus); -bool WM_gizmomap_is_any_selected(const struct wmGizmoMap *mmap); + struct bContext *C, struct wmGizmoMap *gzmap, struct ARegion *ar, struct wmMsgBus *mbus); +bool WM_gizmomap_is_any_selected(const struct wmGizmoMap *gzmap); bool WM_gizmomap_minmax( - const struct wmGizmoMap *mmap, bool use_hidden, bool use_select, + const struct wmGizmoMap *gzmap, bool use_hidden, bool use_select, float r_min[3], float r_max[3]); struct ARegion *WM_gizmomap_tooltip_init( @@ -273,34 +273,34 @@ struct ARegion *WM_gizmomap_tooltip_init( /* wmGizmoMapType */ struct wmGizmoMapType *WM_gizmomaptype_find( - const struct wmGizmoMapType_Params *mmap_params); + const struct wmGizmoMapType_Params *gzmap_params); struct wmGizmoMapType *WM_gizmomaptype_ensure( - const struct wmGizmoMapType_Params *mmap_params); + const struct wmGizmoMapType_Params *gzmap_params); struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_find( - struct wmGizmoMapType *mmap_type, + struct wmGizmoMapType *gzmap_type, const char *idname); struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_find_ptr( - struct wmGizmoMapType *mmap_type, - const struct wmGizmoGroupType *wgt); + struct wmGizmoMapType *gzmap_type, + const struct wmGizmoGroupType *gzgt); struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_link( - struct wmGizmoMapType *mmap_type, + struct wmGizmoMapType *gzmap_type, const char *idname); struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_link_ptr( - struct wmGizmoMapType *mmap_type, - struct wmGizmoGroupType *wgt); + struct wmGizmoMapType *gzmap_type, + struct wmGizmoGroupType *gzgt); void WM_gizmomaptype_group_init_runtime_keymap( const struct Main *bmain, - struct wmGizmoGroupType *wgt); + struct wmGizmoGroupType *gzgt); void WM_gizmomaptype_group_init_runtime( - const struct Main *bmain, struct wmGizmoMapType *mmap_type, - struct wmGizmoGroupType *wgt); + const struct Main *bmain, struct wmGizmoMapType *gzmap_type, + struct wmGizmoGroupType *gzgt); void WM_gizmomaptype_group_unlink( - struct bContext *C, struct Main *bmain, struct wmGizmoMapType *mmap_type, - const struct wmGizmoGroupType *wgt); + struct bContext *C, struct Main *bmain, struct wmGizmoMapType *gzmap_type, + const struct wmGizmoGroupType *gzgt); -void WM_gizmomaptype_group_free(struct wmGizmoGroupTypeRef *wgt); +void WM_gizmomaptype_group_free(struct wmGizmoGroupTypeRef *gzgt); /* -------------------------------------------------------------------- */ /* GizmoGroup */ @@ -308,36 +308,36 @@ void WM_gizmomaptype_group_free(struct wmGizmoGroupTypeRef *wgt); /* Add/Ensure/Remove (High level API) */ void WM_gizmo_group_type_add_ptr_ex( - struct wmGizmoGroupType *wgt, - struct wmGizmoMapType *mmap_type); + struct wmGizmoGroupType *gzgt, + struct wmGizmoMapType *gzmap_type); void WM_gizmo_group_type_add_ptr( - struct wmGizmoGroupType *wgt); + struct wmGizmoGroupType *gzgt); void WM_gizmo_group_type_add(const char *idname); void WM_gizmo_group_type_ensure_ptr_ex( - struct wmGizmoGroupType *wgt, - struct wmGizmoMapType *mmap_type); + struct wmGizmoGroupType *gzgt, + struct wmGizmoMapType *gzmap_type); void WM_gizmo_group_type_ensure_ptr( - struct wmGizmoGroupType *wgt); + struct wmGizmoGroupType *gzgt); void WM_gizmo_group_type_ensure(const char *idname); void WM_gizmo_group_type_remove_ptr_ex( - struct Main *bmain, struct wmGizmoGroupType *wgt, - struct wmGizmoMapType *mmap_type); + struct Main *bmain, struct wmGizmoGroupType *gzgt, + struct wmGizmoMapType *gzmap_type); void WM_gizmo_group_type_remove_ptr( - struct Main *bmain, struct wmGizmoGroupType *wgt); + struct Main *bmain, struct wmGizmoGroupType *gzgt); void WM_gizmo_group_type_remove(struct Main *bmain, const char *idname); void WM_gizmo_group_type_unlink_delayed_ptr_ex( - struct wmGizmoGroupType *wgt, - struct wmGizmoMapType *mmap_type); + struct wmGizmoGroupType *gzgt, + struct wmGizmoMapType *gzmap_type); void WM_gizmo_group_type_unlink_delayed_ptr( - struct wmGizmoGroupType *wgt); + struct wmGizmoGroupType *gzgt); void WM_gizmo_group_type_unlink_delayed(const char *idname); /* Utilities */ bool WM_gizmo_context_check_drawstep(const struct bContext *C, eWM_GizmoFlagMapDrawStep step); -bool WM_gizmo_group_type_poll(const struct bContext *C, const struct wmGizmoGroupType *wgt); +bool WM_gizmo_group_type_poll(const struct bContext *C, const struct wmGizmoGroupType *gzgt); #endif /* __WM_GIZMO_API_H__ */ diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h index ecdda256306..2339523db5e 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h @@ -171,7 +171,7 @@ struct wmGizmo { wmGizmoFnModal custom_modal; /* pointer back to group this gizmo is in (just for quick access) */ - struct wmGizmoGroup *parent_mgroup; + struct wmGizmoGroup *parent_gzgroup; void *py_instance; @@ -385,7 +385,7 @@ typedef struct wmGizmoGroupType { eWM_GizmoFlagMapTypeUpdateFlag type_update_flag; /* same as gizmo-maps, so registering/unregistering goes to the correct region */ - struct wmGizmoMapType_Params mmap_params; + struct wmGizmoMapType_Params gzmap_params; } wmGizmoGroupType; @@ -395,7 +395,7 @@ typedef struct wmGizmoGroup { struct wmGizmoGroupType *type; ListBase gizmos; - struct wmGizmoMap *parent_mmap; + struct wmGizmoMap *parent_gzmap; void *py_instance; /* python stores the class instance here */ struct ReportList *reports; /* errors and warnings storage */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c index da8b301b536..14deb0be725 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c @@ -67,98 +67,98 @@ #include "wm_gizmo_intern.h" static void wm_gizmo_register( - wmGizmoGroup *mgroup, wmGizmo *mpr); + wmGizmoGroup *gzgroup, wmGizmo *gz); /** * \note Follow #wm_operator_create convention. */ static wmGizmo *wm_gizmo_create( - const wmGizmoType *wt, + const wmGizmoType *gzt, PointerRNA *properties) { - BLI_assert(wt != NULL); - BLI_assert(wt->struct_size >= sizeof(wmGizmo)); + BLI_assert(gzt != NULL); + BLI_assert(gzt->struct_size >= sizeof(wmGizmo)); - wmGizmo *mpr = MEM_callocN( - wt->struct_size + (sizeof(wmGizmoProperty) * wt->target_property_defs_len), __func__); - mpr->type = wt; + wmGizmo *gz = MEM_callocN( + gzt->struct_size + (sizeof(wmGizmoProperty) * gzt->target_property_defs_len), __func__); + gz->type = gzt; /* initialize properties, either copy or create */ - mpr->ptr = MEM_callocN(sizeof(PointerRNA), "wmGizmoPtrRNA"); + gz->ptr = MEM_callocN(sizeof(PointerRNA), "wmGizmoPtrRNA"); if (properties && properties->data) { - mpr->properties = IDP_CopyProperty(properties->data); + gz->properties = IDP_CopyProperty(properties->data); } else { IDPropertyTemplate val = {0}; - mpr->properties = IDP_New(IDP_GROUP, &val, "wmGizmoProperties"); + gz->properties = IDP_New(IDP_GROUP, &val, "wmGizmoProperties"); } - RNA_pointer_create(G_MAIN->wm.first, wt->srna, mpr->properties, mpr->ptr); + RNA_pointer_create(G_MAIN->wm.first, gzt->srna, gz->properties, gz->ptr); - WM_gizmo_properties_sanitize(mpr->ptr, 0); + WM_gizmo_properties_sanitize(gz->ptr, 0); - unit_m4(mpr->matrix_space); - unit_m4(mpr->matrix_basis); - unit_m4(mpr->matrix_offset); + unit_m4(gz->matrix_space); + unit_m4(gz->matrix_basis); + unit_m4(gz->matrix_offset); - mpr->drag_part = -1; + gz->drag_part = -1; - return mpr; + return gz; } wmGizmo *WM_gizmo_new_ptr( - const wmGizmoType *wt, wmGizmoGroup *mgroup, + const wmGizmoType *gzt, wmGizmoGroup *gzgroup, PointerRNA *properties) { - wmGizmo *mpr = wm_gizmo_create(wt, properties); + wmGizmo *gz = wm_gizmo_create(gzt, properties); - wm_gizmo_register(mgroup, mpr); + wm_gizmo_register(gzgroup, gz); - if (mpr->type->setup != NULL) { - mpr->type->setup(mpr); + if (gz->type->setup != NULL) { + gz->type->setup(gz); } - return mpr; + return gz; } /** - * \param wt: Must be valid, + * \param gt: Must be valid, * if you need to check it exists use #WM_gizmo_new_ptr * because callers of this function don't NULL check the return value. */ wmGizmo *WM_gizmo_new( - const char *idname, wmGizmoGroup *mgroup, + const char *idname, wmGizmoGroup *gzgroup, PointerRNA *properties) { - const wmGizmoType *wt = WM_gizmotype_find(idname, false); - return WM_gizmo_new_ptr(wt, mgroup, properties); + const wmGizmoType *gzt = WM_gizmotype_find(idname, false); + return WM_gizmo_new_ptr(gzt, gzgroup, properties); } /** * Initialize default values and allocate needed memory for members. */ -static void gizmo_init(wmGizmo *mpr) +static void gizmo_init(wmGizmo *gz) { const float color_default[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - mpr->scale_basis = 1.0f; - mpr->line_width = 1.0f; + gz->scale_basis = 1.0f; + gz->line_width = 1.0f; /* defaults */ - copy_v4_v4(mpr->color, color_default); - copy_v4_v4(mpr->color_hi, color_default); + copy_v4_v4(gz->color, color_default); + copy_v4_v4(gz->color_hi, color_default); } /** * Register \a gizmo. * - * \param name: name used to create a unique idname for \a gizmo in \a mgroup + * \param name: name used to create a unique idname for \a gizmo in \a gzgroup * * \note Not to be confused with type registration from RNA. */ -static void wm_gizmo_register(wmGizmoGroup *mgroup, wmGizmo *mpr) +static void wm_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz) { - gizmo_init(mpr); - wm_gizmogroup_gizmo_register(mgroup, mpr); + gizmo_init(gz); + wm_gizmogroup_gizmo_register(gzgroup, gz); } /** @@ -166,70 +166,70 @@ static void wm_gizmo_register(wmGizmoGroup *mgroup, wmGizmo *mpr) * Typical use is when freeing the windowing data, * where caller can manage clearing selection, highlight... etc. */ -void WM_gizmo_free(wmGizmo *mpr) +void WM_gizmo_free(wmGizmo *gz) { - if (mpr->type->free != NULL) { - mpr->type->free(mpr); + if (gz->type->free != NULL) { + gz->type->free(gz); } #ifdef WITH_PYTHON - if (mpr->py_instance) { + if (gz->py_instance) { /* do this first in case there are any __del__ functions or * similar that use properties */ - BPY_DECREF_RNA_INVALIDATE(mpr->py_instance); + BPY_DECREF_RNA_INVALIDATE(gz->py_instance); } #endif - if (mpr->op_data) { - for (int i = 0; i < mpr->op_data_len; i++) { - WM_operator_properties_free(&mpr->op_data[i].ptr); + if (gz->op_data) { + for (int i = 0; i < gz->op_data_len; i++) { + WM_operator_properties_free(&gz->op_data[i].ptr); } - MEM_freeN(mpr->op_data); + MEM_freeN(gz->op_data); } - if (mpr->ptr != NULL) { - WM_gizmo_properties_free(mpr->ptr); - MEM_freeN(mpr->ptr); + if (gz->ptr != NULL) { + WM_gizmo_properties_free(gz->ptr); + MEM_freeN(gz->ptr); } - if (mpr->type->target_property_defs_len != 0) { - wmGizmoProperty *mpr_prop_array = WM_gizmo_target_property_array(mpr); - for (int i = 0; i < mpr->type->target_property_defs_len; i++) { - wmGizmoProperty *mpr_prop = &mpr_prop_array[i]; - if (mpr_prop->custom_func.free_fn) { - mpr_prop->custom_func.free_fn(mpr, mpr_prop); + if (gz->type->target_property_defs_len != 0) { + wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); + for (int i = 0; i < gz->type->target_property_defs_len; i++) { + wmGizmoProperty *gz_prop = &gz_prop_array[i]; + if (gz_prop->custom_func.free_fn) { + gz_prop->custom_func.free_fn(gz, gz_prop); } } } - MEM_freeN(mpr); + MEM_freeN(gz); } /** * Free \a gizmo and unlink from \a gizmolist. * \a gizmolist is allowed to be NULL. */ -void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *mmap, wmGizmo *mpr, bContext *C) +void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C) { - if (mpr->state & WM_GIZMO_STATE_HIGHLIGHT) { - wm_gizmomap_highlight_set(mmap, C, NULL, 0); + if (gz->state & WM_GIZMO_STATE_HIGHLIGHT) { + wm_gizmomap_highlight_set(gzmap, C, NULL, 0); } - if (mpr->state & WM_GIZMO_STATE_MODAL) { - wm_gizmomap_modal_set(mmap, C, mpr, NULL, false); + if (gz->state & WM_GIZMO_STATE_MODAL) { + wm_gizmomap_modal_set(gzmap, C, gz, NULL, false); } /* Unlink instead of setting so we don't run callbacks. */ - if (mpr->state & WM_GIZMO_STATE_SELECT) { - WM_gizmo_select_unlink(mmap, mpr); + if (gz->state & WM_GIZMO_STATE_SELECT) { + WM_gizmo_select_unlink(gzmap, gz); } if (gizmolist) { - BLI_remlink(gizmolist, mpr); + BLI_remlink(gizmolist, gz); } - BLI_assert(mmap->mmap_context.highlight != mpr); - BLI_assert(mmap->mmap_context.modal != mpr); + BLI_assert(gzmap->gzmap_context.highlight != gz); + BLI_assert(gzmap->gzmap_context.modal != gz); - WM_gizmo_free(mpr); + WM_gizmo_free(gz); } /* -------------------------------------------------------------------- */ @@ -240,25 +240,25 @@ void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *mmap, wmGizmo *mpr, bConte * \{ */ struct wmGizmoOpElem *WM_gizmo_operator_get( - wmGizmo *mpr, int part_index) + wmGizmo *gz, int part_index) { - if (mpr->op_data && ((part_index >= 0) && (part_index < mpr->op_data_len))) { - return &mpr->op_data[part_index]; + if (gz->op_data && ((part_index >= 0) && (part_index < gz->op_data_len))) { + return &gz->op_data[part_index]; } return NULL; } PointerRNA *WM_gizmo_operator_set( - wmGizmo *mpr, int part_index, + wmGizmo *gz, int part_index, wmOperatorType *ot, IDProperty *properties) { BLI_assert(part_index < 255); /* We could pre-allocate these but using multiple is such a rare thing. */ - if (part_index >= mpr->op_data_len) { - mpr->op_data_len = part_index + 1; - mpr->op_data = MEM_recallocN(mpr->op_data, sizeof(*mpr->op_data) * mpr->op_data_len); + if (part_index >= gz->op_data_len) { + gz->op_data_len = part_index + 1; + gz->op_data = MEM_recallocN(gz->op_data, sizeof(*gz->op_data) * gz->op_data_len); } - wmGizmoOpElem *mpop = &mpr->op_data[part_index]; + wmGizmoOpElem *mpop = &gz->op_data[part_index]; mpop->type = ot; if (mpop->ptr.data) { @@ -305,56 +305,56 @@ static void wm_gizmo_set_matrix_rotation_from_yz_axis__internal( * wmGizmo.matrix utils. */ void WM_gizmo_set_matrix_rotation_from_z_axis( - wmGizmo *mpr, const float z_axis[3]) + wmGizmo *gz, const float z_axis[3]) { - wm_gizmo_set_matrix_rotation_from_z_axis__internal(mpr->matrix_basis, z_axis); + wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_basis, z_axis); } void WM_gizmo_set_matrix_rotation_from_yz_axis( - wmGizmo *mpr, const float y_axis[3], const float z_axis[3]) + wmGizmo *gz, const float y_axis[3], const float z_axis[3]) { - wm_gizmo_set_matrix_rotation_from_yz_axis__internal(mpr->matrix_basis, y_axis, z_axis); + wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_basis, y_axis, z_axis); } -void WM_gizmo_set_matrix_location(wmGizmo *mpr, const float origin[3]) +void WM_gizmo_set_matrix_location(wmGizmo *gz, const float origin[3]) { - copy_v3_v3(mpr->matrix_basis[3], origin); + copy_v3_v3(gz->matrix_basis[3], origin); } /** * wmGizmo.matrix_offset utils. */ void WM_gizmo_set_matrix_offset_rotation_from_z_axis( - wmGizmo *mpr, const float z_axis[3]) + wmGizmo *gz, const float z_axis[3]) { - wm_gizmo_set_matrix_rotation_from_z_axis__internal(mpr->matrix_offset, z_axis); + wm_gizmo_set_matrix_rotation_from_z_axis__internal(gz->matrix_offset, z_axis); } void WM_gizmo_set_matrix_offset_rotation_from_yz_axis( - wmGizmo *mpr, const float y_axis[3], const float z_axis[3]) + wmGizmo *gz, const float y_axis[3], const float z_axis[3]) { - wm_gizmo_set_matrix_rotation_from_yz_axis__internal(mpr->matrix_offset, y_axis, z_axis); + wm_gizmo_set_matrix_rotation_from_yz_axis__internal(gz->matrix_offset, y_axis, z_axis); } -void WM_gizmo_set_matrix_offset_location(wmGizmo *mpr, const float offset[3]) +void WM_gizmo_set_matrix_offset_location(wmGizmo *gz, const float offset[3]) { - copy_v3_v3(mpr->matrix_offset[3], offset); + copy_v3_v3(gz->matrix_offset[3], offset); } -void WM_gizmo_set_flag(wmGizmo *mpr, const int flag, const bool enable) +void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable) { if (enable) { - mpr->flag |= flag; + gz->flag |= flag; } else { - mpr->flag &= ~flag; + gz->flag &= ~flag; } } -void WM_gizmo_set_scale(wmGizmo *mpr, const float scale) +void WM_gizmo_set_scale(wmGizmo *gz, const float scale) { - mpr->scale_basis = scale; + gz->scale_basis = scale; } -void WM_gizmo_set_line_width(wmGizmo *mpr, const float line_width) +void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width) { - mpr->line_width = line_width; + gz->line_width = line_width; } /** @@ -363,22 +363,22 @@ void WM_gizmo_set_line_width(wmGizmo *mpr, const float line_width) * \param col Normal state color. * \param col_hi Highlighted state color. */ -void WM_gizmo_get_color(const wmGizmo *mpr, float color[4]) +void WM_gizmo_get_color(const wmGizmo *gz, float color[4]) { - copy_v4_v4(color, mpr->color); + copy_v4_v4(color, gz->color); } -void WM_gizmo_set_color(wmGizmo *mpr, const float color[4]) +void WM_gizmo_set_color(wmGizmo *gz, const float color[4]) { - copy_v4_v4(mpr->color, color); + copy_v4_v4(gz->color, color); } -void WM_gizmo_get_color_highlight(const wmGizmo *mpr, float color_hi[4]) +void WM_gizmo_get_color_highlight(const wmGizmo *gz, float color_hi[4]) { - copy_v4_v4(color_hi, mpr->color_hi); + copy_v4_v4(color_hi, gz->color_hi); } -void WM_gizmo_set_color_highlight(wmGizmo *mpr, const float color_hi[4]) +void WM_gizmo_set_color_highlight(wmGizmo *gz, const float color_hi[4]) { - copy_v4_v4(mpr->color_hi, color_hi); + copy_v4_v4(gz->color_hi, color_hi); } @@ -390,9 +390,9 @@ void WM_gizmo_set_color_highlight(wmGizmo *mpr, const float color_hi[4]) * * \{ */ -void WM_gizmo_set_fn_custom_modal(struct wmGizmo *mpr, wmGizmoFnModal fn) +void WM_gizmo_set_fn_custom_modal(struct wmGizmo *gz, wmGizmoFnModal fn) { - mpr->custom_modal = fn; + gz->custom_modal = fn; } /** \} */ @@ -407,26 +407,26 @@ void WM_gizmo_set_fn_custom_modal(struct wmGizmo *mpr, wmGizmoFnModal fn) * \return if the selection has changed. */ bool wm_gizmo_select_set_ex( - wmGizmoMap *mmap, wmGizmo *mpr, bool select, + wmGizmoMap *gzmap, wmGizmo *gz, bool select, bool use_array, bool use_callback) { bool changed = false; if (select) { - if ((mpr->state & WM_GIZMO_STATE_SELECT) == 0) { + if ((gz->state & WM_GIZMO_STATE_SELECT) == 0) { if (use_array) { - wm_gizmomap_select_array_push_back(mmap, mpr); + wm_gizmomap_select_array_push_back(gzmap, gz); } - mpr->state |= WM_GIZMO_STATE_SELECT; + gz->state |= WM_GIZMO_STATE_SELECT; changed = true; } } else { - if (mpr->state & WM_GIZMO_STATE_SELECT) { + if (gz->state & WM_GIZMO_STATE_SELECT) { if (use_array) { - wm_gizmomap_select_array_remove(mmap, mpr); + wm_gizmomap_select_array_remove(gzmap, gz); } - mpr->state &= ~WM_GIZMO_STATE_SELECT; + gz->state &= ~WM_GIZMO_STATE_SELECT; changed = true; } } @@ -434,8 +434,8 @@ bool wm_gizmo_select_set_ex( /* In the case of unlinking we only want to remove from the array * and not write to the external state */ if (use_callback && changed) { - if (mpr->type->select_refresh) { - mpr->type->select_refresh(mpr); + if (gz->type->select_refresh) { + gz->type->select_refresh(gz); } } @@ -443,25 +443,25 @@ bool wm_gizmo_select_set_ex( } /* Remove from selection array without running callbacks. */ -bool WM_gizmo_select_unlink(wmGizmoMap *mmap, wmGizmo *mpr) +bool WM_gizmo_select_unlink(wmGizmoMap *gzmap, wmGizmo *gz) { - return wm_gizmo_select_set_ex(mmap, mpr, false, true, false); + return wm_gizmo_select_set_ex(gzmap, gz, false, true, false); } -bool WM_gizmo_select_set(wmGizmoMap *mmap, wmGizmo *mpr, bool select) +bool WM_gizmo_select_set(wmGizmoMap *gzmap, wmGizmo *gz, bool select) { - return wm_gizmo_select_set_ex(mmap, mpr, select, true, true); + return wm_gizmo_select_set_ex(gzmap, gz, select, true, true); } -void WM_gizmo_highlight_set(wmGizmoMap *mmap, wmGizmo *mpr) +void WM_gizmo_highlight_set(wmGizmoMap *gzmap, wmGizmo *gz) { - wm_gizmomap_highlight_set(mmap, NULL, mpr, mpr ? mpr->highlight_part : 0); + wm_gizmomap_highlight_set(gzmap, NULL, gz, gz ? gz->highlight_part : 0); } -bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *mmap, wmGizmo *mpr) +bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz) { - if (WM_gizmo_select_set(mmap, mpr, true)) { - wm_gizmomap_highlight_set(mmap, C, mpr, mpr->highlight_part); + if (WM_gizmo_select_set(gzmap, gz, true)) { + wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part); return true; } else { @@ -475,13 +475,13 @@ bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *mmap, wmGizmo *mpr) * We could do this when linking them, but this complicates things since the window update code needs to run first. */ void WM_gizmo_modal_set_from_setup( - struct wmGizmoMap *mmap, struct bContext *C, - struct wmGizmo *mpr, int part_index, const wmEvent *event) + struct wmGizmoMap *gzmap, struct bContext *C, + struct wmGizmo *gz, int part_index, const wmEvent *event) { - mpr->highlight_part = part_index; - WM_gizmo_highlight_set(mmap, mpr); + gz->highlight_part = part_index; + WM_gizmo_highlight_set(gzmap, gz); if (false) { - wm_gizmomap_modal_set(mmap, C, mpr, event, true); + wm_gizmomap_modal_set(gzmap, C, gz, event, true); } else { /* WEAK: but it works. */ @@ -489,23 +489,23 @@ void WM_gizmo_modal_set_from_setup( } } -void wm_gizmo_calculate_scale(wmGizmo *mpr, const bContext *C) +void wm_gizmo_calculate_scale(wmGizmo *gz, const bContext *C) { const RegionView3D *rv3d = CTX_wm_region_view3d(C); float scale = UI_DPI_FAC; - if ((mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_SCALE) == 0) { + if ((gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_SCALE) == 0) { scale *= U.gizmo_size; if (rv3d) { /* 'ED_view3d_pixel_size' includes 'U.pixelsize', remove it. */ float matrix_world[4][4]; - if (mpr->type->matrix_basis_get) { + if (gz->type->matrix_basis_get) { float matrix_basis[4][4]; - mpr->type->matrix_basis_get(mpr, matrix_basis); - mul_m4_m4m4(matrix_world, mpr->matrix_space, matrix_basis); + gz->type->matrix_basis_get(gz, matrix_basis); + mul_m4_m4m4(matrix_world, gz->matrix_space, matrix_basis); } else { - mul_m4_m4m4(matrix_world, mpr->matrix_space, mpr->matrix_basis); + mul_m4_m4m4(matrix_world, gz->matrix_space, gz->matrix_basis); } /* Exclude matrix_offset from scale. */ @@ -516,45 +516,45 @@ void wm_gizmo_calculate_scale(wmGizmo *mpr, const bContext *C) } } - mpr->scale_final = mpr->scale_basis * scale; + gz->scale_final = gz->scale_basis * scale; } -static void gizmo_update_prop_data(wmGizmo *mpr) +static void gizmo_update_prop_data(wmGizmo *gz) { /* gizmo property might have been changed, so update gizmo */ - if (mpr->type->property_update) { - wmGizmoProperty *mpr_prop_array = WM_gizmo_target_property_array(mpr); - for (int i = 0; i < mpr->type->target_property_defs_len; i++) { - wmGizmoProperty *mpr_prop = &mpr_prop_array[i]; - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - mpr->type->property_update(mpr, mpr_prop); + if (gz->type->property_update) { + wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); + for (int i = 0; i < gz->type->target_property_defs_len; i++) { + wmGizmoProperty *gz_prop = &gz_prop_array[i]; + if (WM_gizmo_target_property_is_valid(gz_prop)) { + gz->type->property_update(gz, gz_prop); } } } } -void wm_gizmo_update(wmGizmo *mpr, const bContext *C, const bool refresh_map) +void wm_gizmo_update(wmGizmo *gz, const bContext *C, const bool refresh_map) { if (refresh_map) { - gizmo_update_prop_data(mpr); + gizmo_update_prop_data(gz); } - wm_gizmo_calculate_scale(mpr, C); + wm_gizmo_calculate_scale(gz, C); } -int wm_gizmo_is_visible(wmGizmo *mpr) +int wm_gizmo_is_visible(wmGizmo *gz) { - if (mpr->flag & WM_GIZMO_HIDDEN) { + if (gz->flag & WM_GIZMO_HIDDEN) { return 0; } - if ((mpr->state & WM_GIZMO_STATE_MODAL) && - !(mpr->flag & (WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_VALUE))) + if ((gz->state & WM_GIZMO_STATE_MODAL) && + !(gz->flag & (WM_GIZMO_DRAW_MODAL | WM_GIZMO_DRAW_VALUE))) { /* don't draw while modal (dragging) */ return 0; } - if ((mpr->flag & WM_GIZMO_DRAW_HOVER) && - !(mpr->state & WM_GIZMO_STATE_HIGHLIGHT) && - !(mpr->state & WM_GIZMO_STATE_SELECT)) /* still draw selected gizmos */ + if ((gz->flag & WM_GIZMO_DRAW_HOVER) && + !(gz->state & WM_GIZMO_STATE_HIGHLIGHT) && + !(gz->state & WM_GIZMO_STATE_SELECT)) /* still draw selected gizmos */ { /* update but don't draw */ return WM_GIZMO_IS_VISIBLE_UPDATE; @@ -564,28 +564,28 @@ int wm_gizmo_is_visible(wmGizmo *mpr) } void WM_gizmo_calc_matrix_final_params( - const wmGizmo *mpr, + const wmGizmo *gz, const struct WM_GizmoMatrixParams *params, float r_mat[4][4]) { - const float (* const matrix_space)[4] = params->matrix_space ? params->matrix_space : mpr->matrix_space; - const float (* const matrix_basis)[4] = params->matrix_basis ? params->matrix_basis : mpr->matrix_basis; - const float (* const matrix_offset)[4] = params->matrix_offset ? params->matrix_offset : mpr->matrix_offset; - const float *scale_final = params->scale_final ? params->scale_final : &mpr->scale_final; + const float (* const matrix_space)[4] = params->matrix_space ? params->matrix_space : gz->matrix_space; + const float (* const matrix_basis)[4] = params->matrix_basis ? params->matrix_basis : gz->matrix_basis; + const float (* const matrix_offset)[4] = params->matrix_offset ? params->matrix_offset : gz->matrix_offset; + const float *scale_final = params->scale_final ? params->scale_final : &gz->scale_final; float final_matrix[4][4]; - if (params->matrix_basis == NULL && mpr->type->matrix_basis_get) { - mpr->type->matrix_basis_get(mpr, final_matrix); + if (params->matrix_basis == NULL && gz->type->matrix_basis_get) { + gz->type->matrix_basis_get(gz, final_matrix); } else { copy_m4_m4(final_matrix, matrix_basis); } - if (mpr->flag & WM_GIZMO_DRAW_NO_SCALE) { + if (gz->flag & WM_GIZMO_DRAW_NO_SCALE) { mul_m4_m4m4(final_matrix, final_matrix, matrix_offset); } else { - if (mpr->flag & WM_GIZMO_DRAW_OFFSET_SCALE) { + if (gz->flag & WM_GIZMO_DRAW_OFFSET_SCALE) { mul_mat3_m4_fl(final_matrix, *scale_final); mul_m4_m4m4(final_matrix, final_matrix, matrix_offset); } @@ -598,13 +598,13 @@ void WM_gizmo_calc_matrix_final_params( mul_m4_m4m4(r_mat, matrix_space, final_matrix); } -void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *mpr, float r_mat[4][4]) +void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *gz, float r_mat[4][4]) { float mat_identity[4][4]; unit_m4(mat_identity); WM_gizmo_calc_matrix_final_params( - mpr, + gz, &((struct WM_GizmoMatrixParams) { .matrix_space = NULL, .matrix_basis = NULL, @@ -614,10 +614,10 @@ void WM_gizmo_calc_matrix_final_no_offset(const wmGizmo *mpr, float r_mat[4][4]) ); } -void WM_gizmo_calc_matrix_final(const wmGizmo *mpr, float r_mat[4][4]) +void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4]) { WM_gizmo_calc_matrix_final_params( - mpr, + gz, &((struct WM_GizmoMatrixParams) { .matrix_space = NULL, .matrix_basis = NULL, @@ -634,24 +634,24 @@ void WM_gizmo_calc_matrix_final(const wmGizmo *mpr, float r_mat[4][4]) * \{ */ -void WM_gizmo_properties_create_ptr(PointerRNA *ptr, wmGizmoType *wt) +void WM_gizmo_properties_create_ptr(PointerRNA *ptr, wmGizmoType *gzt) { - RNA_pointer_create(NULL, wt->srna, NULL, ptr); + RNA_pointer_create(NULL, gzt->srna, NULL, ptr); } -void WM_gizmo_properties_create(PointerRNA *ptr, const char *wtstring) +void WM_gizmo_properties_create(PointerRNA *ptr, const char *gtstring) { - const wmGizmoType *wt = WM_gizmotype_find(wtstring, false); + const wmGizmoType *gzt = WM_gizmotype_find(gtstring, false); - if (wt) - WM_gizmo_properties_create_ptr(ptr, (wmGizmoType *)wt); + if (gzt) + WM_gizmo_properties_create_ptr(ptr, (wmGizmoType *)gzt); else RNA_pointer_create(NULL, &RNA_GizmoProperties, NULL, ptr); } /* similar to the function above except its uses ID properties * used for keymaps and macros */ -void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *wtstring) +void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *gtstring) { if (*properties == NULL) { IDPropertyTemplate val = {0}; @@ -660,7 +660,7 @@ void WM_gizmo_properties_alloc(PointerRNA **ptr, IDProperty **properties, const if (*ptr == NULL) { *ptr = MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr"); - WM_gizmo_properties_create(*ptr, wtstring); + WM_gizmo_properties_create(*ptr, gtstring); } (*ptr)->data = *properties; @@ -733,19 +733,19 @@ bool WM_gizmo_properties_default(PointerRNA *ptr, const bool do_update) } /* remove all props without PROP_SKIP_SAVE */ -void WM_gizmo_properties_reset(wmGizmo *mpr) +void WM_gizmo_properties_reset(wmGizmo *gz) { - if (mpr->ptr->data) { + if (gz->ptr->data) { PropertyRNA *iterprop; - iterprop = RNA_struct_iterator_property(mpr->type->srna); + iterprop = RNA_struct_iterator_property(gz->type->srna); - RNA_PROP_BEGIN (mpr->ptr, itemptr, iterprop) + RNA_PROP_BEGIN (gz->ptr, itemptr, iterprop) { PropertyRNA *prop = itemptr.data; if ((RNA_property_flag(prop) & PROP_SKIP_SAVE) == 0) { const char *identifier = RNA_property_identifier(prop); - RNA_struct_idprops_unset(mpr->ptr, identifier); + RNA_struct_idprops_unset(gz->ptr, identifier); } } RNA_PROP_END; diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index f30744859aa..9cc096e1cdd 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -74,87 +74,87 @@ * \{ */ /** - * Create a new gizmo-group from \a wgt. + * Create a new gizmo-group from \a gzgt. */ wmGizmoGroup *wm_gizmogroup_new_from_type( - wmGizmoMap *mmap, wmGizmoGroupType *wgt) + wmGizmoMap *gzmap, wmGizmoGroupType *gzgt) { - wmGizmoGroup *mgroup = MEM_callocN(sizeof(*mgroup), "gizmo-group"); - mgroup->type = wgt; + wmGizmoGroup *gzgroup = MEM_callocN(sizeof(*gzgroup), "gizmo-group"); + gzgroup->type = gzgt; /* keep back-link */ - mgroup->parent_mmap = mmap; + gzgroup->parent_gzmap = gzmap; - BLI_addtail(&mmap->groups, mgroup); + BLI_addtail(&gzmap->groups, gzgroup); - return mgroup; + return gzgroup; } -void wm_gizmogroup_free(bContext *C, wmGizmoGroup *mgroup) +void wm_gizmogroup_free(bContext *C, wmGizmoGroup *gzgroup) { - wmGizmoMap *mmap = mgroup->parent_mmap; + wmGizmoMap *gzmap = gzgroup->parent_gzmap; - /* Similar to WM_gizmo_unlink, but only to keep mmap state correct, + /* Similar to WM_gizmo_unlink, but only to keep gzmap state correct, * we don't want to run callbacks. */ - if (mmap->mmap_context.highlight && mmap->mmap_context.highlight->parent_mgroup == mgroup) { - wm_gizmomap_highlight_set(mmap, C, NULL, 0); + if (gzmap->gzmap_context.highlight && gzmap->gzmap_context.highlight->parent_gzgroup == gzgroup) { + wm_gizmomap_highlight_set(gzmap, C, NULL, 0); } - if (mmap->mmap_context.modal && mmap->mmap_context.modal->parent_mgroup == mgroup) { - wm_gizmomap_modal_set(mmap, C, mmap->mmap_context.modal, NULL, false); + if (gzmap->gzmap_context.modal && gzmap->gzmap_context.modal->parent_gzgroup == gzgroup) { + wm_gizmomap_modal_set(gzmap, C, gzmap->gzmap_context.modal, NULL, false); } - for (wmGizmo *mpr = mgroup->gizmos.first, *mpr_next; mpr; mpr = mpr_next) { - mpr_next = mpr->next; - if (mmap->mmap_context.select.len) { - WM_gizmo_select_unlink(mmap, mpr); + for (wmGizmo *gz = gzgroup->gizmos.first, *gz_next; gz; gz = gz_next) { + gz_next = gz->next; + if (gzmap->gzmap_context.select.len) { + WM_gizmo_select_unlink(gzmap, gz); } - WM_gizmo_free(mpr); + WM_gizmo_free(gz); } - BLI_listbase_clear(&mgroup->gizmos); + BLI_listbase_clear(&gzgroup->gizmos); #ifdef WITH_PYTHON - if (mgroup->py_instance) { + if (gzgroup->py_instance) { /* do this first in case there are any __del__ functions or * similar that use properties */ - BPY_DECREF_RNA_INVALIDATE(mgroup->py_instance); + BPY_DECREF_RNA_INVALIDATE(gzgroup->py_instance); } #endif - if (mgroup->reports && (mgroup->reports->flag & RPT_FREE)) { - BKE_reports_clear(mgroup->reports); - MEM_freeN(mgroup->reports); + if (gzgroup->reports && (gzgroup->reports->flag & RPT_FREE)) { + BKE_reports_clear(gzgroup->reports); + MEM_freeN(gzgroup->reports); } - if (mgroup->customdata_free) { - mgroup->customdata_free(mgroup->customdata); + if (gzgroup->customdata_free) { + gzgroup->customdata_free(gzgroup->customdata); } else { - MEM_SAFE_FREE(mgroup->customdata); + MEM_SAFE_FREE(gzgroup->customdata); } - BLI_remlink(&mmap->groups, mgroup); + BLI_remlink(&gzmap->groups, gzgroup); - MEM_freeN(mgroup); + MEM_freeN(gzgroup); } /** - * Add \a gizmo to \a mgroup and make sure its name is unique within the group. + * Add \a gizmo to \a gzgroup and make sure its name is unique within the group. */ -void wm_gizmogroup_gizmo_register(wmGizmoGroup *mgroup, wmGizmo *mpr) +void wm_gizmogroup_gizmo_register(wmGizmoGroup *gzgroup, wmGizmo *gz) { - BLI_assert(BLI_findindex(&mgroup->gizmos, mpr) == -1); - BLI_addtail(&mgroup->gizmos, mpr); - mpr->parent_mgroup = mgroup; + BLI_assert(BLI_findindex(&gzgroup->gizmos, gz) == -1); + BLI_addtail(&gzgroup->gizmos, gz); + gz->parent_gzgroup = gzgroup; } wmGizmo *wm_gizmogroup_find_intersected_gizmo( - const wmGizmoGroup *mgroup, bContext *C, const wmEvent *event, + const wmGizmoGroup *gzgroup, bContext *C, const wmEvent *event, int *r_part) { - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if (mpr->type->test_select && (mpr->flag & WM_GIZMO_HIDDEN) == 0) { - if ((*r_part = mpr->type->test_select(C, mpr, event)) != -1) { - return mpr; + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if (gz->type->test_select && (gz->flag & WM_GIZMO_HIDDEN) == 0) { + if ((*r_part = gz->type->test_select(C, gz, event)) != -1) { + return gz; } } } @@ -163,78 +163,78 @@ wmGizmo *wm_gizmogroup_find_intersected_gizmo( } /** - * Adds all gizmos of \a mgroup that can be selected to the head of \a listbase. Added items need freeing! + * Adds all gizmos of \a gzgroup that can be selected to the head of \a listbase. Added items need freeing! */ -void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *mgroup, ListBase *listbase) +void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, ListBase *listbase) { - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if ((mpr->flag & WM_GIZMO_HIDDEN) == 0) { - if (((mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && mpr->type->draw_select) || - ((mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && mpr->type->test_select)) + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if ((gz->flag & WM_GIZMO_HIDDEN) == 0) { + if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && gz->type->draw_select) || + ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select)) { - BLI_addhead(listbase, BLI_genericNodeN(mpr)); + BLI_addhead(listbase, BLI_genericNodeN(gz)); } } } } -void wm_gizmogroup_ensure_initialized(wmGizmoGroup *mgroup, const bContext *C) +void wm_gizmogroup_ensure_initialized(wmGizmoGroup *gzgroup, const bContext *C) { /* prepare for first draw */ - if (UNLIKELY((mgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0)) { - mgroup->type->setup(C, mgroup); + if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0)) { + gzgroup->type->setup(C, gzgroup); /* Not ideal, initialize keymap here, needed for RNA runtime generated gizmos. */ - wmGizmoGroupType *wgt = mgroup->type; - if (wgt->keymap == NULL) { + wmGizmoGroupType *gzgt = gzgroup->type; + if (gzgt->keymap == NULL) { wmWindowManager *wm = CTX_wm_manager(C); - wm_gizmogrouptype_setup_keymap(wgt, wm->defaultconf); - BLI_assert(wgt->keymap != NULL); + wm_gizmogrouptype_setup_keymap(gzgt, wm->defaultconf); + BLI_assert(gzgt->keymap != NULL); } - mgroup->init_flag |= WM_GIZMOGROUP_INIT_SETUP; + gzgroup->init_flag |= WM_GIZMOGROUP_INIT_SETUP; } /* refresh may be called multiple times, this just ensures its called at least once before we draw. */ - if (UNLIKELY((mgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0)) { - if (mgroup->type->refresh) { - mgroup->type->refresh(C, mgroup); + if (UNLIKELY((gzgroup->init_flag & WM_GIZMOGROUP_INIT_REFRESH) == 0)) { + if (gzgroup->type->refresh) { + gzgroup->type->refresh(C, gzgroup); } - mgroup->init_flag |= WM_GIZMOGROUP_INIT_REFRESH; + gzgroup->init_flag |= WM_GIZMOGROUP_INIT_REFRESH; } } -bool WM_gizmo_group_type_poll(const bContext *C, const struct wmGizmoGroupType *wgt) +bool WM_gizmo_group_type_poll(const bContext *C, const struct wmGizmoGroupType *gzgt) { /* If we're tagged, only use compatible. */ - if (wgt->owner_id[0] != '\0') { + if (gzgt->owner_id[0] != '\0') { const WorkSpace *workspace = CTX_wm_workspace(C); - if (BKE_workspace_owner_id_check(workspace, wgt->owner_id) == false) { + if (BKE_workspace_owner_id_check(workspace, gzgt->owner_id) == false) { return false; } } /* Check for poll function, if gizmo-group belongs to an operator, also check if the operator is running. */ - return (!wgt->poll || wgt->poll(C, (wmGizmoGroupType *)wgt)); + return (!gzgt->poll || gzgt->poll(C, (wmGizmoGroupType *)gzgt)); } bool wm_gizmogroup_is_visible_in_drawstep( - const wmGizmoGroup *mgroup, const eWM_GizmoFlagMapDrawStep drawstep) + const wmGizmoGroup *gzgroup, const eWM_GizmoFlagMapDrawStep drawstep) { switch (drawstep) { case WM_GIZMOMAP_DRAWSTEP_2D: - return (mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; + return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0; case WM_GIZMOMAP_DRAWSTEP_3D: - return (mgroup->type->flag & WM_GIZMOGROUPTYPE_3D); + return (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D); default: BLI_assert(0); return false; } } -bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *mgroup) +bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *gzgroup) { - if (mgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT) { - for (const wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if (mpr->state & WM_GIZMO_STATE_SELECT) { + if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT) { + for (const wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if (gz->state & WM_GIZMO_STATE_SELECT) { return true; } } @@ -253,9 +253,9 @@ bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *mgroup) static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { ARegion *ar = CTX_wm_region(C); - wmGizmoMap *mmap = ar->gizmo_map; - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; - wmGizmo *highlight = mmap->mmap_context.highlight; + wmGizmoMap *gzmap = ar->gizmo_map; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; + wmGizmo *highlight = gzmap->gzmap_context.highlight; bool extend = RNA_boolean_get(op->ptr, "extend"); bool deselect = RNA_boolean_get(op->ptr, "deselect"); @@ -263,7 +263,7 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE /* deselect all first */ if (extend == false && deselect == false && toggle == false) { - wm_gizmomap_deselect_all(mmap); + wm_gizmomap_deselect_all(gzmap); BLI_assert(msel->items == NULL && msel->len == 0); UNUSED_VARS_NDEBUG(msel); } @@ -278,11 +278,11 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE } if (deselect) { - if (is_selected && WM_gizmo_select_set(mmap, highlight, false)) { + if (is_selected && WM_gizmo_select_set(gzmap, highlight, false)) { redraw = true; } } - else if (wm_gizmo_select_and_highlight(C, mmap, highlight)) { + else if (wm_gizmo_select_and_highlight(C, gzmap, highlight)) { redraw = true; } @@ -316,9 +316,9 @@ void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot) } typedef struct GizmoTweakData { - wmGizmoMap *mmap; - wmGizmoGroup *mgroup; - wmGizmo *mpr_modal; + wmGizmoMap *gzmap; + wmGizmoGroup *gzgroup; + wmGizmo *gz_modal; int init_event; /* initial event type */ int flag; /* tweak flags */ @@ -342,18 +342,18 @@ typedef struct GizmoTweakData { } GizmoTweakData; static bool gizmo_tweak_start( - bContext *C, wmGizmoMap *mmap, wmGizmo *mpr, const wmEvent *event) + bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event) { /* activate highlighted gizmo */ - wm_gizmomap_modal_set(mmap, C, mpr, event, true); + wm_gizmomap_modal_set(gzmap, C, gz, event, true); - return (mpr->state & WM_GIZMO_STATE_MODAL); + return (gz->state & WM_GIZMO_STATE_MODAL); } static bool gizmo_tweak_start_and_finish( - bContext *C, wmGizmoMap *mmap, wmGizmo *mpr, const wmEvent *event, bool *r_is_modal) + bContext *C, wmGizmoMap *gzmap, wmGizmo *gz, const wmEvent *event, bool *r_is_modal) { - wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, mpr->highlight_part); + wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, gz->highlight_part); if (r_is_modal) { *r_is_modal = false; } @@ -377,7 +377,7 @@ static bool gizmo_tweak_start_and_finish( * conflicting with modal operator attached to gizmo */ if (mpop->type->modal) { /* activate highlighted gizmo */ - wm_gizmomap_modal_set(mmap, C, mpr, event, true); + wm_gizmomap_modal_set(gzmap, C, gz, event, true); if (r_is_modal) { *r_is_modal = true; } @@ -396,15 +396,15 @@ static bool gizmo_tweak_start_and_finish( static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal) { GizmoTweakData *mtweak = op->customdata; - if (mtweak->mpr_modal->type->exit) { - mtweak->mpr_modal->type->exit(C, mtweak->mpr_modal, cancel); + if (mtweak->gz_modal->type->exit) { + mtweak->gz_modal->type->exit(C, mtweak->gz_modal, cancel); } if (clear_modal) { /* The gizmo may have been removed. */ - if ((BLI_findindex(&mtweak->mmap->groups, mtweak->mgroup) != -1) && - (BLI_findindex(&mtweak->mgroup->gizmos, mtweak->mpr_modal) != -1)) + if ((BLI_findindex(&mtweak->gzmap->groups, mtweak->gzgroup) != -1) && + (BLI_findindex(&mtweak->gzgroup->gizmos, mtweak->gz_modal) != -1)) { - wm_gizmomap_modal_set(mtweak->mmap, C, mtweak->mpr_modal, NULL, false); + wm_gizmomap_modal_set(mtweak->gzmap, C, mtweak->gz_modal, NULL, false); } } MEM_freeN(mtweak); @@ -413,22 +413,22 @@ static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, b static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) { GizmoTweakData *mtweak = op->customdata; - wmGizmo *mpr = mtweak->mpr_modal; + wmGizmo *gz = mtweak->gz_modal; int retval = OPERATOR_PASS_THROUGH; bool clear_modal = true; - if (mpr == NULL) { + if (gz == NULL) { BLI_assert(0); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } #ifdef USE_DRAG_DETECT - wmGizmoMap *mmap = mtweak->mmap; + wmGizmoMap *gzmap = mtweak->gzmap; if (mtweak->drag_state == DRAG_DETECT) { if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { - if (len_manhattan_v2v2_int(&event->x, mmap->mmap_context.event_xy) > 2) { + if (len_manhattan_v2v2_int(&event->x, gzmap->gzmap_context.event_xy) > 2) { mtweak->drag_state = DRAG_IDLE; - mpr->highlight_part = mpr->drag_part; + gz->highlight_part = gz->drag_part; } } else if (event->type == mtweak->init_event && event->val == KM_RELEASE) { @@ -439,20 +439,20 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) if (mtweak->drag_state != DRAG_DETECT) { /* Follow logic in 'gizmo_tweak_invoke' */ bool is_modal = false; - if (gizmo_tweak_start_and_finish(C, mmap, mpr, event, &is_modal)) { + if (gizmo_tweak_start_and_finish(C, gzmap, gz, event, &is_modal)) { if (is_modal) { clear_modal = false; } } else { - if (!gizmo_tweak_start(C, mmap, mpr, event)) { + if (!gizmo_tweak_start(C, gzmap, gz, event)) { retval = OPERATOR_FINISHED; } } } } if (mtweak->drag_state == DRAG_IDLE) { - if (mmap->mmap_context.modal != NULL) { + if (gzmap->gzmap_context.modal != NULL) { return OPERATOR_PASS_THROUGH; } else { @@ -498,9 +498,9 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* handle gizmo */ - wmGizmoFnModal modal_fn = mpr->custom_modal ? mpr->custom_modal : mpr->type->modal; + wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal; if (modal_fn) { - int modal_retval = modal_fn(C, mpr, event, mtweak->flag); + int modal_retval = modal_fn(C, gz, event, mtweak->flag); if ((modal_retval & OPERATOR_RUNNING_MODAL) == 0) { gizmo_tweak_finish(C, op, (modal_retval & OPERATOR_CANCELLED) != 0, true); @@ -520,13 +520,13 @@ static int gizmo_tweak_modal(bContext *C, wmOperator *op, const wmEvent *event) static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ARegion *ar = CTX_wm_region(C); - wmGizmoMap *mmap = ar->gizmo_map; - wmGizmo *mpr = mmap->mmap_context.highlight; + wmGizmoMap *gzmap = ar->gizmo_map; + wmGizmo *gz = gzmap->gzmap_context.highlight; /* Needed for single click actions which don't enter modal state. */ WM_tooltip_clear(C, CTX_wm_window(C)); - if (!mpr) { + if (!gz) { /* wm_handlers_do_intern shouldn't let this happen */ BLI_assert(0); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); @@ -535,11 +535,11 @@ static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) bool use_drag_fallback = false; #ifdef USE_DRAG_DETECT - use_drag_fallback = !ELEM(mpr->drag_part, -1, mpr->highlight_part); + use_drag_fallback = !ELEM(gz->drag_part, -1, gz->highlight_part); #endif if (use_drag_fallback == false) { - if (gizmo_tweak_start_and_finish(C, mmap, mpr, event, NULL)) { + if (gizmo_tweak_start_and_finish(C, gzmap, gz, event, NULL)) { return OPERATOR_FINISHED; } } @@ -547,7 +547,7 @@ static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) bool use_drag_detect = false; #ifdef USE_DRAG_DETECT if (use_drag_fallback) { - wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, mpr->highlight_part); + wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, gz->highlight_part); if (mpop && mpop->type) { if (mpop->type->modal == NULL) { use_drag_detect = true; @@ -557,7 +557,7 @@ static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) #endif if (use_drag_detect == false) { - if (!gizmo_tweak_start(C, mmap, mpr, event)) { + if (!gizmo_tweak_start(C, gzmap, gz, event)) { /* failed to start */ return OPERATOR_PASS_THROUGH; } @@ -566,9 +566,9 @@ static int gizmo_tweak_invoke(bContext *C, wmOperator *op, const wmEvent *event) GizmoTweakData *mtweak = MEM_mallocN(sizeof(GizmoTweakData), __func__); mtweak->init_event = WM_userdef_event_type_from_keymap_type(event->type); - mtweak->mpr_modal = mmap->mmap_context.highlight; - mtweak->mgroup = mtweak->mpr_modal->parent_mgroup; - mtweak->mmap = mmap; + mtweak->gz_modal = gzmap->gzmap_context.highlight; + mtweak->gzgroup = mtweak->gz_modal->parent_gzgroup; + mtweak->gzmap = gzmap; mtweak->flag = 0; #ifdef USE_DRAG_DETECT @@ -603,7 +603,7 @@ void GIZMOGROUP_OT_gizmo_tweak(wmOperatorType *ot) /** \} */ -static wmKeyMap *gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf, const char *mgroupname) +static wmKeyMap *gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf, const char *gzgroupname) { wmKeyMap *keymap; char name[KMAP_MAX_NAME]; @@ -619,7 +619,7 @@ static wmKeyMap *gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf, const char }; - BLI_snprintf(name, sizeof(name), "%s Tweak Modal Map", mgroupname); + BLI_snprintf(name, sizeof(name), "%s Tweak Modal Map", gzgroupname); keymap = WM_modalkeymap_get(keyconf, name); /* this function is called for each spacetype, only needs to add map once */ @@ -655,13 +655,13 @@ static wmKeyMap *gizmogroup_tweak_modal_keymap(wmKeyConfig *keyconf, const char * Common default keymap for gizmo groups */ wmKeyMap *WM_gizmogroup_keymap_common( - const wmGizmoGroupType *wgt, wmKeyConfig *config) + const wmGizmoGroupType *gzgt, wmKeyConfig *config) { /* Use area and region id since we might have multiple gizmos with the same name in different areas/regions */ - wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->mmap_params.spaceid, wgt->mmap_params.regionid); + wmKeyMap *km = WM_keymap_find(config, gzgt->name, gzgt->gzmap_params.spaceid, gzgt->gzmap_params.regionid); WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", LEFTMOUSE, KM_PRESS, KM_ANY, 0); - gizmogroup_tweak_modal_keymap(config, wgt->name); + gizmogroup_tweak_modal_keymap(config, gzgt->name); return km; } @@ -670,14 +670,14 @@ wmKeyMap *WM_gizmogroup_keymap_common( * Variation of #WM_gizmogroup_keymap_common but with keymap items for selection */ wmKeyMap *WM_gizmogroup_keymap_common_select( - const wmGizmoGroupType *wgt, wmKeyConfig *config) + const wmGizmoGroupType *gzgt, wmKeyConfig *config) { /* Use area and region id since we might have multiple gizmos with the same name in different areas/regions */ - wmKeyMap *km = WM_keymap_find(config, wgt->name, wgt->mmap_params.spaceid, wgt->mmap_params.regionid); + wmKeyMap *km = WM_keymap_find(config, gzgt->name, gzgt->gzmap_params.spaceid, gzgt->gzmap_params.regionid); WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", ACTIONMOUSE, KM_PRESS, KM_ANY, 0); WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_tweak", EVT_TWEAK_S, KM_ANY, 0, 0); - gizmogroup_tweak_modal_keymap(config, wgt->name); + gizmogroup_tweak_modal_keymap(config, gzgt->name); wmKeyMapItem *kmi = WM_keymap_add_item(km, "GIZMOGROUP_OT_gizmo_select", SELECTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "extend", false); @@ -699,32 +699,32 @@ wmKeyMap *WM_gizmogroup_keymap_common_select( * \{ */ struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_find_ptr( - struct wmGizmoMapType *mmap_type, - const wmGizmoGroupType *wgt) + struct wmGizmoMapType *gzmap_type, + const wmGizmoGroupType *gzgt) { /* could use hash lookups as operator types do, for now simple search. */ - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; - wgt_ref; - wgt_ref = wgt_ref->next) + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first; + gzgt_ref; + gzgt_ref = gzgt_ref->next) { - if (wgt_ref->type == wgt) { - return wgt_ref; + if (gzgt_ref->type == gzgt) { + return gzgt_ref; } } return NULL; } struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_find( - struct wmGizmoMapType *mmap_type, + struct wmGizmoMapType *gzmap_type, const char *idname) { /* could use hash lookups as operator types do, for now simple search. */ - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; - wgt_ref; - wgt_ref = wgt_ref->next) + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first; + gzgt_ref; + gzgt_ref = gzgt_ref->next) { - if (STREQ(idname, wgt_ref->type->idname)) { - return wgt_ref; + if (STREQ(idname, gzgt_ref->type->idname)) { + return gzgt_ref; } } return NULL; @@ -734,33 +734,33 @@ struct wmGizmoGroupTypeRef *WM_gizmomaptype_group_find( * Use this for registering gizmos on startup. For runtime, use #WM_gizmomaptype_group_link_runtime. */ wmGizmoGroupTypeRef *WM_gizmomaptype_group_link( - wmGizmoMapType *mmap_type, const char *idname) + wmGizmoMapType *gzmap_type, const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - BLI_assert(wgt != NULL); - return WM_gizmomaptype_group_link_ptr(mmap_type, wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + BLI_assert(gzgt != NULL); + return WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt); } wmGizmoGroupTypeRef *WM_gizmomaptype_group_link_ptr( - wmGizmoMapType *mmap_type, wmGizmoGroupType *wgt) + wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt) { - wmGizmoGroupTypeRef *wgt_ref = MEM_callocN(sizeof(wmGizmoGroupTypeRef), "gizmo-group-ref"); - wgt_ref->type = wgt; - BLI_addtail(&mmap_type->grouptype_refs, wgt_ref); - return wgt_ref; + wmGizmoGroupTypeRef *gzgt_ref = MEM_callocN(sizeof(wmGizmoGroupTypeRef), "gizmo-group-ref"); + gzgt_ref->type = gzgt; + BLI_addtail(&gzmap_type->grouptype_refs, gzgt_ref); + return gzgt_ref; } void WM_gizmomaptype_group_init_runtime_keymap( const Main *bmain, - wmGizmoGroupType *wgt) + wmGizmoGroupType *gzgt) { /* init keymap - on startup there's an extra call to init keymaps for 'permanent' gizmo-groups */ - wm_gizmogrouptype_setup_keymap(wgt, ((wmWindowManager *)bmain->wm.first)->defaultconf); + wm_gizmogrouptype_setup_keymap(gzgt, ((wmWindowManager *)bmain->wm.first)->defaultconf); } void WM_gizmomaptype_group_init_runtime( - const Main *bmain, wmGizmoMapType *mmap_type, - wmGizmoGroupType *wgt) + const Main *bmain, wmGizmoMapType *gzmap_type, + wmGizmoGroupType *gzgt) { /* now create a gizmo for all existing areas */ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { @@ -768,12 +768,12 @@ void WM_gizmomaptype_group_init_runtime( for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; for (ARegion *ar = lb->first; ar; ar = ar->next) { - wmGizmoMap *mmap = ar->gizmo_map; - if (mmap && mmap->type == mmap_type) { - wm_gizmogroup_new_from_type(mmap, wgt); + wmGizmoMap *gzmap = ar->gizmo_map; + if (gzmap && gzmap->type == gzmap_type) { + wm_gizmogroup_new_from_type(gzmap, gzgt); /* just add here, drawing will occur on next update */ - wm_gizmomap_highlight_set(mmap, NULL, NULL, 0); + wm_gizmomap_highlight_set(gzmap, NULL, NULL, 0); ED_region_tag_redraw(ar); } } @@ -786,14 +786,14 @@ void WM_gizmomaptype_group_init_runtime( /** * Unlike #WM_gizmomaptype_group_unlink this doesn't maintain correct state, simply free. */ -void WM_gizmomaptype_group_free(wmGizmoGroupTypeRef *wgt_ref) +void WM_gizmomaptype_group_free(wmGizmoGroupTypeRef *gzgt_ref) { - MEM_freeN(wgt_ref); + MEM_freeN(gzgt_ref); } void WM_gizmomaptype_group_unlink( - bContext *C, Main *bmain, wmGizmoMapType *mmap_type, - const wmGizmoGroupType *wgt) + bContext *C, Main *bmain, wmGizmoMapType *gzmap_type, + const wmGizmoGroupType *gzgt) { /* Free instances. */ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { @@ -801,14 +801,14 @@ void WM_gizmomaptype_group_unlink( for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; for (ARegion *ar = lb->first; ar; ar = ar->next) { - wmGizmoMap *mmap = ar->gizmo_map; - if (mmap && mmap->type == mmap_type) { - wmGizmoGroup *mgroup, *mgroup_next; - for (mgroup = mmap->groups.first; mgroup; mgroup = mgroup_next) { - mgroup_next = mgroup->next; - if (mgroup->type == wgt) { - BLI_assert(mgroup->parent_mmap == mmap); - wm_gizmogroup_free(C, mgroup); + wmGizmoMap *gzmap = ar->gizmo_map; + if (gzmap && gzmap->type == gzmap_type) { + wmGizmoGroup *gzgroup, *gzgroup_next; + for (gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup_next) { + gzgroup_next = gzgroup->next; + if (gzgroup->type == gzgt) { + BLI_assert(gzgroup->parent_gzmap == gzmap); + wm_gizmogroup_free(C, gzgroup); ED_region_tag_redraw(ar); } } @@ -819,27 +819,27 @@ void WM_gizmomaptype_group_unlink( } /* Free types. */ - wmGizmoGroupTypeRef *wgt_ref = WM_gizmomaptype_group_find_ptr(mmap_type, wgt); - if (wgt_ref) { - BLI_remlink(&mmap_type->grouptype_refs, wgt_ref); - WM_gizmomaptype_group_free(wgt_ref); + wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt); + if (gzgt_ref) { + BLI_remlink(&gzmap_type->grouptype_refs, gzgt_ref); + WM_gizmomaptype_group_free(gzgt_ref); } /* Note, we may want to keep this keymap for editing */ - WM_keymap_remove(wgt->keyconf, wgt->keymap); + WM_keymap_remove(gzgt->keyconf, gzgt->keymap); - BLI_assert(WM_gizmomaptype_group_find_ptr(mmap_type, wgt) == NULL); + BLI_assert(WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt) == NULL); } void wm_gizmogrouptype_setup_keymap( - wmGizmoGroupType *wgt, wmKeyConfig *keyconf) + wmGizmoGroupType *gzgt, wmKeyConfig *keyconf) { /* Use flag since setup_keymap may return NULL, * in that case we better not keep calling it. */ - if (wgt->type_update_flag & WM_GIZMOMAPTYPE_KEYMAP_INIT) { - wgt->keymap = wgt->setup_keymap(wgt, keyconf); - wgt->keyconf = keyconf; - wgt->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT; + if (gzgt->type_update_flag & WM_GIZMOMAPTYPE_KEYMAP_INIT) { + gzgt->keymap = gzgt->setup_keymap(gzgt, keyconf); + gzgt->keyconf = keyconf; + gzgt->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT; } } @@ -861,89 +861,89 @@ void wm_gizmogrouptype_setup_keymap( * \{ */ void WM_gizmo_group_type_add_ptr_ex( - wmGizmoGroupType *wgt, - wmGizmoMapType *mmap_type) + wmGizmoGroupType *gzgt, + wmGizmoMapType *gzmap_type) { - WM_gizmomaptype_group_link_ptr(mmap_type, wgt); + WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt); - WM_gizmoconfig_update_tag_init(mmap_type, wgt); + WM_gizmoconfig_update_tag_init(gzmap_type, gzgt); } void WM_gizmo_group_type_add_ptr( - wmGizmoGroupType *wgt) + wmGizmoGroupType *gzgt) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wgt->mmap_params); - WM_gizmo_group_type_add_ptr_ex(wgt, mmap_type); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&gzgt->gzmap_params); + WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type); } void WM_gizmo_group_type_add(const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - BLI_assert(wgt != NULL); - WM_gizmo_group_type_add_ptr(wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + BLI_assert(gzgt != NULL); + WM_gizmo_group_type_add_ptr(gzgt); } void WM_gizmo_group_type_ensure_ptr_ex( - wmGizmoGroupType *wgt, - wmGizmoMapType *mmap_type) + wmGizmoGroupType *gzgt, + wmGizmoMapType *gzmap_type) { - wmGizmoGroupTypeRef *wgt_ref = WM_gizmomaptype_group_find_ptr(mmap_type, wgt); - if (wgt_ref == NULL) { - WM_gizmo_group_type_add_ptr_ex(wgt, mmap_type); + wmGizmoGroupTypeRef *gzgt_ref = WM_gizmomaptype_group_find_ptr(gzmap_type, gzgt); + if (gzgt_ref == NULL) { + WM_gizmo_group_type_add_ptr_ex(gzgt, gzmap_type); } } void WM_gizmo_group_type_ensure_ptr( - wmGizmoGroupType *wgt) + wmGizmoGroupType *gzgt) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wgt->mmap_params); - WM_gizmo_group_type_ensure_ptr_ex(wgt, mmap_type); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&gzgt->gzmap_params); + WM_gizmo_group_type_ensure_ptr_ex(gzgt, gzmap_type); } void WM_gizmo_group_type_ensure(const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - BLI_assert(wgt != NULL); - WM_gizmo_group_type_ensure_ptr(wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + BLI_assert(gzgt != NULL); + WM_gizmo_group_type_ensure_ptr(gzgt); } void WM_gizmo_group_type_remove_ptr_ex( - struct Main *bmain, wmGizmoGroupType *wgt, - wmGizmoMapType *mmap_type) + struct Main *bmain, wmGizmoGroupType *gzgt, + wmGizmoMapType *gzmap_type) { - WM_gizmomaptype_group_unlink(NULL, bmain, mmap_type, wgt); - WM_gizmogrouptype_free_ptr(wgt); + WM_gizmomaptype_group_unlink(NULL, bmain, gzmap_type, gzgt); + WM_gizmogrouptype_free_ptr(gzgt); } void WM_gizmo_group_type_remove_ptr( - struct Main *bmain, wmGizmoGroupType *wgt) + struct Main *bmain, wmGizmoGroupType *gzgt) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wgt->mmap_params); - WM_gizmo_group_type_remove_ptr_ex(bmain, wgt, mmap_type); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&gzgt->gzmap_params); + WM_gizmo_group_type_remove_ptr_ex(bmain, gzgt, gzmap_type); } void WM_gizmo_group_type_remove(struct Main *bmain, const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - BLI_assert(wgt != NULL); - WM_gizmo_group_type_remove_ptr(bmain, wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + BLI_assert(gzgt != NULL); + WM_gizmo_group_type_remove_ptr(bmain, gzgt); } /* delayed versions */ void WM_gizmo_group_type_unlink_delayed_ptr_ex( - wmGizmoGroupType *wgt, - wmGizmoMapType *mmap_type) + wmGizmoGroupType *gzgt, + wmGizmoMapType *gzmap_type) { - WM_gizmoconfig_update_tag_remove(mmap_type, wgt); + WM_gizmoconfig_update_tag_remove(gzmap_type, gzgt); } void WM_gizmo_group_type_unlink_delayed_ptr( - wmGizmoGroupType *wgt) + wmGizmoGroupType *gzgt) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wgt->mmap_params); - WM_gizmo_group_type_unlink_delayed_ptr_ex(wgt, mmap_type); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&gzgt->gzmap_params); + WM_gizmo_group_type_unlink_delayed_ptr_ex(gzgt, gzmap_type); } void WM_gizmo_group_type_unlink_delayed(const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - BLI_assert(wgt != NULL); - WM_gizmo_group_type_unlink_delayed_ptr(wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + BLI_assert(gzgt != NULL); + WM_gizmo_group_type_unlink_delayed_ptr(gzgt); } /** \} */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c index 44f5fac4cd4..a44005a7d28 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c @@ -54,11 +54,11 @@ static GHash *global_gizmogrouptype_hash = NULL; wmGizmoGroupType *WM_gizmogrouptype_find(const char *idname, bool quiet) { if (idname[0]) { - wmGizmoGroupType *wgt; + wmGizmoGroupType *gzgt; - wgt = BLI_ghash_lookup(global_gizmogrouptype_hash, idname); - if (wgt) { - return wgt; + gzgt = BLI_ghash_lookup(global_gizmogrouptype_hash, idname); + if (gzgt) { + return gzgt; } if (!quiet) { @@ -82,46 +82,46 @@ void WM_gizmogrouptype_iter(GHashIterator *ghi) static wmGizmoGroupType *wm_gizmogrouptype_append__begin(void) { - wmGizmoGroupType *wgt = MEM_callocN(sizeof(wmGizmoGroupType), "gizmogrouptype"); + wmGizmoGroupType *gzgt = MEM_callocN(sizeof(wmGizmoGroupType), "gizmogrouptype"); - return wgt; + return gzgt; } -static void wm_gizmogrouptype_append__end(wmGizmoGroupType *wgt) +static void wm_gizmogrouptype_append__end(wmGizmoGroupType *gzgt) { - BLI_assert(wgt->name != NULL); - BLI_assert(wgt->idname != NULL); + BLI_assert(gzgt->name != NULL); + BLI_assert(gzgt->idname != NULL); - wgt->type_update_flag |= WM_GIZMOMAPTYPE_KEYMAP_INIT; + gzgt->type_update_flag |= WM_GIZMOMAPTYPE_KEYMAP_INIT; /* if not set, use default */ - if (wgt->setup_keymap == NULL) { - if (wgt->flag & WM_GIZMOGROUPTYPE_SELECT) { - wgt->setup_keymap = WM_gizmogroup_keymap_common_select; + if (gzgt->setup_keymap == NULL) { + if (gzgt->flag & WM_GIZMOGROUPTYPE_SELECT) { + gzgt->setup_keymap = WM_gizmogroup_keymap_common_select; } else { - wgt->setup_keymap = WM_gizmogroup_keymap_common; + gzgt->setup_keymap = WM_gizmogroup_keymap_common; } } - BLI_ghash_insert(global_gizmogrouptype_hash, (void *)wgt->idname, wgt); + BLI_ghash_insert(global_gizmogrouptype_hash, (void *)gzgt->idname, gzgt); } wmGizmoGroupType *WM_gizmogrouptype_append( void (*wtfunc)(struct wmGizmoGroupType *)) { - wmGizmoGroupType *wgt = wm_gizmogrouptype_append__begin(); - wtfunc(wgt); - wm_gizmogrouptype_append__end(wgt); - return wgt; + wmGizmoGroupType *gzgt = wm_gizmogrouptype_append__begin(); + wtfunc(gzgt); + wm_gizmogrouptype_append__end(gzgt); + return gzgt; } wmGizmoGroupType *WM_gizmogrouptype_append_ptr( void (*wtfunc)(struct wmGizmoGroupType *, void *), void *userdata) { - wmGizmoGroupType *wgt = wm_gizmogrouptype_append__begin(); - wtfunc(wgt, userdata); - wm_gizmogrouptype_append__end(wgt); - return wgt; + wmGizmoGroupType *gzgt = wm_gizmogrouptype_append__begin(); + wtfunc(gzgt, userdata); + wm_gizmogrouptype_append__end(gzgt); + return gzgt; } /** @@ -129,56 +129,56 @@ wmGizmoGroupType *WM_gizmogrouptype_append_ptr( * This is most common for C gizmos which are enabled by default. */ wmGizmoGroupTypeRef *WM_gizmogrouptype_append_and_link( - wmGizmoMapType *mmap_type, + wmGizmoMapType *gzmap_type, void (*wtfunc)(struct wmGizmoGroupType *)) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_append(wtfunc); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_append(wtfunc); - wgt->mmap_params.spaceid = mmap_type->spaceid; - wgt->mmap_params.regionid = mmap_type->regionid; + gzgt->gzmap_params.spaceid = gzmap_type->spaceid; + gzgt->gzmap_params.regionid = gzmap_type->regionid; - return WM_gizmomaptype_group_link_ptr(mmap_type, wgt); + return WM_gizmomaptype_group_link_ptr(gzmap_type, gzgt); } /** * Free but don't remove from ghash. */ -static void gizmogrouptype_free(wmGizmoGroupType *wgt) +static void gizmogrouptype_free(wmGizmoGroupType *gzgt) { - if (wgt->ext.srna) { /* python gizmo group, allocs own string */ - MEM_freeN((void *)wgt->idname); + if (gzgt->ext.srna) { /* python gizmo group, allocs own string */ + MEM_freeN((void *)gzgt->idname); } - MEM_freeN(wgt); + MEM_freeN(gzgt); } -void WM_gizmogrouptype_free_ptr(wmGizmoGroupType *wgt) +void WM_gizmogrouptype_free_ptr(wmGizmoGroupType *gzgt) { - BLI_assert(wgt == WM_gizmogrouptype_find(wgt->idname, false)); + BLI_assert(gzgt == WM_gizmogrouptype_find(gzgt->idname, false)); - BLI_ghash_remove(global_gizmogrouptype_hash, wgt->idname, NULL, NULL); + BLI_ghash_remove(global_gizmogrouptype_hash, gzgt->idname, NULL, NULL); - gizmogrouptype_free(wgt); + gizmogrouptype_free(gzgt); /* XXX, TODO, update the world! */ } bool WM_gizmogrouptype_free(const char *idname) { - wmGizmoGroupType *wgt = BLI_ghash_lookup(global_gizmogrouptype_hash, idname); + wmGizmoGroupType *gzgt = BLI_ghash_lookup(global_gizmogrouptype_hash, idname); - if (wgt == NULL) { + if (gzgt == NULL) { return false; } - WM_gizmogrouptype_free_ptr(wgt); + WM_gizmogrouptype_free_ptr(gzgt); return true; } -static void wm_gizmogrouptype_ghash_free_cb(wmGizmoGroupType *wgt) +static void wm_gizmogrouptype_ghash_free_cb(wmGizmoGroupType *gzgt) { - gizmogrouptype_free(wgt); + gizmogrouptype_free(gzgt); } void wm_gizmogrouptype_free(void) diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h index 5eed4f2bda2..d4a9dc4f54c 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h @@ -40,14 +40,14 @@ struct GHashIterator; bool wm_gizmo_select_set_ex( - struct wmGizmoMap *mmap, struct wmGizmo *mpr, bool select, + struct wmGizmoMap *gzmap, struct wmGizmo *gz, bool select, bool use_array, bool use_callback); -bool wm_gizmo_select_and_highlight(bContext *C, struct wmGizmoMap *mmap, struct wmGizmo *mpr); +bool wm_gizmo_select_and_highlight(bContext *C, struct wmGizmoMap *gzmap, struct wmGizmo *gz); -void wm_gizmo_calculate_scale(struct wmGizmo *mpr, const bContext *C); -void wm_gizmo_update(struct wmGizmo *mpr, const bContext *C, const bool refresh_map); +void wm_gizmo_calculate_scale(struct wmGizmo *gz, const bContext *C); +void wm_gizmo_update(struct wmGizmo *gz, const bContext *C, const bool refresh_map); -int wm_gizmo_is_visible(struct wmGizmo *mpr); +int wm_gizmo_is_visible(struct wmGizmo *gz); enum { WM_GIZMO_IS_VISIBLE_UPDATE = (1 << 0), WM_GIZMO_IS_VISIBLE_DRAW = (1 << 1), @@ -66,20 +66,20 @@ enum { }; struct wmGizmoGroup *wm_gizmogroup_new_from_type( - struct wmGizmoMap *mmap, struct wmGizmoGroupType *wgt); -void wm_gizmogroup_free(bContext *C, struct wmGizmoGroup *mgroup); -void wm_gizmogroup_gizmo_register(struct wmGizmoGroup *mgroup, struct wmGizmo *mpr); + struct wmGizmoMap *gzmap, struct wmGizmoGroupType *gzgt); +void wm_gizmogroup_free(bContext *C, struct wmGizmoGroup *gzgroup); +void wm_gizmogroup_gizmo_register(struct wmGizmoGroup *gzgroup, struct wmGizmo *gz); struct wmGizmo *wm_gizmogroup_find_intersected_gizmo( - const struct wmGizmoGroup *mgroup, struct bContext *C, const struct wmEvent *event, + const struct wmGizmoGroup *gzgroup, struct bContext *C, const struct wmEvent *event, int *r_part); void wm_gizmogroup_intersectable_gizmos_to_list( - const struct wmGizmoGroup *mgroup, struct ListBase *listbase); -void wm_gizmogroup_ensure_initialized(struct wmGizmoGroup *mgroup, const struct bContext *C); + const struct wmGizmoGroup *gzgroup, struct ListBase *listbase); +void wm_gizmogroup_ensure_initialized(struct wmGizmoGroup *gzgroup, const struct bContext *C); bool wm_gizmogroup_is_visible_in_drawstep( - const struct wmGizmoGroup *mgroup, const eWM_GizmoFlagMapDrawStep drawstep); + const struct wmGizmoGroup *gzgroup, const eWM_GizmoFlagMapDrawStep drawstep); void wm_gizmogrouptype_setup_keymap( - struct wmGizmoGroupType *wgt, struct wmKeyConfig *keyconf); + struct wmGizmoGroupType *gzgt, struct wmKeyConfig *keyconf); /* -------------------------------------------------------------------- */ @@ -116,7 +116,7 @@ struct wmGizmoMap { short event_grabcursor; /* until we have nice cursor push/pop API. */ int last_cursor; - } mmap_context; + } gzmap_context; }; /** @@ -135,10 +135,10 @@ struct wmGizmoMapType { eWM_GizmoFlagMapTypeUpdateFlag type_update_flag; }; -void wm_gizmomap_select_array_clear(struct wmGizmoMap *mmap); -bool wm_gizmomap_deselect_all(struct wmGizmoMap *mmap); -void wm_gizmomap_select_array_shrink(struct wmGizmoMap *mmap, int len_subtract); -void wm_gizmomap_select_array_push_back(struct wmGizmoMap *mmap, wmGizmo *mpr); -void wm_gizmomap_select_array_remove(struct wmGizmoMap *mmap, wmGizmo *mpr); +void wm_gizmomap_select_array_clear(struct wmGizmoMap *gzmap); +bool wm_gizmomap_deselect_all(struct wmGizmoMap *gzmap); +void wm_gizmomap_select_array_shrink(struct wmGizmoMap *gzmap, int len_subtract); +void wm_gizmomap_select_array_push_back(struct wmGizmoMap *gzmap, wmGizmo *gz); +void wm_gizmomap_select_array_remove(struct wmGizmoMap *gzmap, wmGizmo *gz); #endif diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 9da1591d535..9321ec674a9 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -75,7 +75,7 @@ typedef enum eWM_GizmoFlagGroupTypeGlobalFlag { WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE = (1 << 1), } eWM_GizmoFlagGroupTypeGlobalFlag; -static eWM_GizmoFlagGroupTypeGlobalFlag wm_mmap_type_update_flag = 0; +static eWM_GizmoFlagGroupTypeGlobalFlag wm_gzmap_type_update_flag = 0; /** * Gizmo-map update tagging. @@ -94,9 +94,9 @@ enum { * * \{ */ -static void wm_gizmomap_select_array_ensure_len_alloc(wmGizmoMap *mmap, int len) +static void wm_gizmomap_select_array_ensure_len_alloc(wmGizmoMap *gzmap, int len) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; if (len <= msel->len_alloc) { return; } @@ -104,20 +104,20 @@ static void wm_gizmomap_select_array_ensure_len_alloc(wmGizmoMap *mmap, int len) msel->len_alloc = len; } -void wm_gizmomap_select_array_clear(wmGizmoMap *mmap) +void wm_gizmomap_select_array_clear(wmGizmoMap *gzmap) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; MEM_SAFE_FREE(msel->items); msel->len = 0; msel->len_alloc = 0; } -void wm_gizmomap_select_array_shrink(wmGizmoMap *mmap, int len_subtract) +void wm_gizmomap_select_array_shrink(wmGizmoMap *gzmap, int len_subtract) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; msel->len -= len_subtract; if (msel->len <= 0) { - wm_gizmomap_select_array_clear(mmap); + wm_gizmomap_select_array_clear(gzmap); } else { if (msel->len < msel->len_alloc / 2) { @@ -127,27 +127,27 @@ void wm_gizmomap_select_array_shrink(wmGizmoMap *mmap, int len_subtract) } } -void wm_gizmomap_select_array_push_back(wmGizmoMap *mmap, wmGizmo *mpr) +void wm_gizmomap_select_array_push_back(wmGizmoMap *gzmap, wmGizmo *gz) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; BLI_assert(msel->len <= msel->len_alloc); if (msel->len == msel->len_alloc) { msel->len_alloc = (msel->len + 1) * 2; msel->items = MEM_reallocN(msel->items, sizeof(*msel->items) * msel->len_alloc); } - msel->items[msel->len++] = mpr; + msel->items[msel->len++] = gz; } -void wm_gizmomap_select_array_remove(wmGizmoMap *mmap, wmGizmo *mpr) +void wm_gizmomap_select_array_remove(wmGizmoMap *gzmap, wmGizmo *gz) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; /* remove gizmo from selected_gizmos array */ for (int i = 0; i < msel->len; i++) { - if (msel->items[i] == mpr) { + if (msel->items[i] == gz) { for (int j = i; j < (msel->len - 1); j++) { msel->items[j] = msel->items[j + 1]; } - wm_gizmomap_select_array_shrink(mmap, 1); + wm_gizmomap_select_array_shrink(gzmap, 1); break; } } @@ -166,84 +166,84 @@ void wm_gizmomap_select_array_remove(wmGizmoMap *mmap, wmGizmo *mpr) * Creates a gizmo-map with all registered gizmos for that type */ wmGizmoMap *WM_gizmomap_new_from_type( - const struct wmGizmoMapType_Params *mmap_params) + const struct wmGizmoMapType_Params *gzmap_params) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(mmap_params); - wmGizmoMap *mmap; + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(gzmap_params); + wmGizmoMap *gzmap; - mmap = MEM_callocN(sizeof(wmGizmoMap), "GizmoMap"); - mmap->type = mmap_type; - WM_gizmomap_tag_refresh(mmap); + gzmap = MEM_callocN(sizeof(wmGizmoMap), "GizmoMap"); + gzmap->type = gzmap_type; + WM_gizmomap_tag_refresh(gzmap); /* create all gizmo-groups for this gizmo-map. We may create an empty one * too in anticipation of gizmos from operators etc */ - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; wgt_ref; wgt_ref = wgt_ref->next) { - wm_gizmogroup_new_from_type(mmap, wgt_ref->type); + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first; gzgt_ref; gzgt_ref = gzgt_ref->next) { + wm_gizmogroup_new_from_type(gzmap, gzgt_ref->type); } - return mmap; + return gzmap; } -void wm_gizmomap_remove(wmGizmoMap *mmap) +void wm_gizmomap_remove(wmGizmoMap *gzmap) { /* Clear first so further calls don't waste time trying to maintain correct array state. */ - wm_gizmomap_select_array_clear(mmap); + wm_gizmomap_select_array_clear(gzmap); - for (wmGizmoGroup *mgroup = mmap->groups.first, *mgroup_next; mgroup; mgroup = mgroup_next) { - mgroup_next = mgroup->next; - BLI_assert(mgroup->parent_mmap == mmap); - wm_gizmogroup_free(NULL, mgroup); + for (wmGizmoGroup *gzgroup = gzmap->groups.first, *gzgroup_next; gzgroup; gzgroup = gzgroup_next) { + gzgroup_next = gzgroup->next; + BLI_assert(gzgroup->parent_gzmap == gzmap); + wm_gizmogroup_free(NULL, gzgroup); } - BLI_assert(BLI_listbase_is_empty(&mmap->groups)); + BLI_assert(BLI_listbase_is_empty(&gzmap->groups)); - MEM_freeN(mmap); + MEM_freeN(gzmap); } wmGizmoGroup *WM_gizmomap_group_find( - struct wmGizmoMap *mmap, + struct wmGizmoMap *gzmap, const char *idname) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - if (wgt) { - return WM_gizmomap_group_find_ptr(mmap, wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + if (gzgt) { + return WM_gizmomap_group_find_ptr(gzmap, gzgt); } return NULL; } wmGizmoGroup *WM_gizmomap_group_find_ptr( - struct wmGizmoMap *mmap, - const struct wmGizmoGroupType *wgt) + struct wmGizmoMap *gzmap, + const struct wmGizmoGroupType *gzgt) { - for (wmGizmoGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { - if (mgroup->type == wgt) { - return mgroup; + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { + if (gzgroup->type == gzgt) { + return gzgroup; } } return NULL; } -const ListBase *WM_gizmomap_group_list(wmGizmoMap *mmap) +const ListBase *WM_gizmomap_group_list(wmGizmoMap *gzmap) { - return &mmap->groups; + return &gzmap->groups; } -bool WM_gizmomap_is_any_selected(const wmGizmoMap *mmap) +bool WM_gizmomap_is_any_selected(const wmGizmoMap *gzmap) { - return mmap->mmap_context.select.len != 0; + return gzmap->gzmap_context.select.len != 0; } /** * \note We could use a callback to define bounds, for now just use matrix location. */ bool WM_gizmomap_minmax( - const wmGizmoMap *mmap, bool UNUSED(use_hidden), bool use_select, + const wmGizmoMap *gzmap, bool UNUSED(use_hidden), bool use_select, float r_min[3], float r_max[3]) { if (use_select) { int i; - for (i = 0; i < mmap->mmap_context.select.len; i++) { - minmax_v3v3_v3(r_min, r_max, mmap->mmap_context.select.items[i]->matrix_basis[3]); + for (i = 0; i < gzmap->gzmap_context.select.len; i++) { + minmax_v3v3_v3(r_min, r_max, gzmap->gzmap_context.select.items[i]->matrix_basis[3]); } return i != 0; } @@ -255,7 +255,7 @@ bool WM_gizmomap_minmax( } /** - * Creates and returns idname hash table for (visible) gizmos in \a mmap + * Creates and returns idname hash table for (visible) gizmos in \a gzmap * * \param poll Polling function for excluding gizmos. * \param data Custom data passed to \a poll @@ -264,20 +264,20 @@ bool WM_gizmomap_minmax( * best we use an iterator function instead of a hash. */ static GHash *WM_gizmomap_gizmo_hash_new( - const bContext *C, wmGizmoMap *mmap, + const bContext *C, wmGizmoMap *gzmap, bool (*poll)(const wmGizmo *, void *), void *data, const bool include_hidden) { GHash *hash = BLI_ghash_ptr_new(__func__); /* collect gizmos */ - for (wmGizmoGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { - if (WM_gizmo_group_type_poll(C, mgroup->type)) { - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if ((include_hidden || (mpr->flag & WM_GIZMO_HIDDEN) == 0) && - (!poll || poll(mpr, data))) + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { + if (WM_gizmo_group_type_poll(C, gzgroup->type)) { + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if ((include_hidden || (gz->flag & WM_GIZMO_HIDDEN) == 0) && + (!poll || poll(gz, data))) { - BLI_ghash_insert(hash, mpr, mpr); + BLI_ghash_insert(hash, gz, gz); } } } @@ -286,12 +286,12 @@ static GHash *WM_gizmomap_gizmo_hash_new( return hash; } -void WM_gizmomap_tag_refresh(wmGizmoMap *mmap) +void WM_gizmomap_tag_refresh(wmGizmoMap *gzmap) { - if (mmap) { + if (gzmap) { /* We might want only to refresh some, for tag all steps. */ for (int i = 0; i < WM_GIZMOMAP_DRAWSTEP_MAX; i++) { - mmap->update_flag[i] |= ( + gzmap->update_flag[i] |= ( GIZMOMAP_IS_PREPARE_DRAW | GIZMOMAP_IS_REFRESH_CALLBACK); } @@ -299,11 +299,11 @@ void WM_gizmomap_tag_refresh(wmGizmoMap *mmap) } static bool gizmo_prepare_drawing( - wmGizmoMap *mmap, wmGizmo *mpr, + wmGizmoMap *gzmap, wmGizmo *gz, const bContext *C, ListBase *draw_gizmos, const eWM_GizmoFlagMapDrawStep drawstep) { - int do_draw = wm_gizmo_is_visible(mpr); + int do_draw = wm_gizmo_is_visible(gz); if (do_draw == 0) { /* skip */ } @@ -311,10 +311,10 @@ static bool gizmo_prepare_drawing( /* Ensure we get RNA updates */ if (do_draw & WM_GIZMO_IS_VISIBLE_UPDATE) { /* hover gizmos need updating, even if we don't draw them */ - wm_gizmo_update(mpr, C, (mmap->update_flag[drawstep] & GIZMOMAP_IS_PREPARE_DRAW) != 0); + wm_gizmo_update(gz, C, (gzmap->update_flag[drawstep] & GIZMOMAP_IS_PREPARE_DRAW) != 0); } if (do_draw & WM_GIZMO_IS_VISIBLE_DRAW) { - BLI_addhead(draw_gizmos, BLI_genericNodeN(mpr)); + BLI_addhead(draw_gizmos, BLI_genericNodeN(gz)); } return true; } @@ -323,23 +323,23 @@ static bool gizmo_prepare_drawing( } /** - * Update gizmos of \a mmap to prepare for drawing. Adds all gizmos that + * Update gizmos of \a gzmap to prepare for drawing. Adds all gizmos that * should be drawn to list \a draw_gizmos, note that added items need freeing. */ static void gizmomap_prepare_drawing( - wmGizmoMap *mmap, const bContext *C, ListBase *draw_gizmos, + wmGizmoMap *gzmap, const bContext *C, ListBase *draw_gizmos, const eWM_GizmoFlagMapDrawStep drawstep) { - if (!mmap || BLI_listbase_is_empty(&mmap->groups)) + if (!gzmap || BLI_listbase_is_empty(&gzmap->groups)) return; - wmGizmo *mpr_modal = mmap->mmap_context.modal; + wmGizmo *gz_modal = gzmap->gzmap_context.modal; /* only active gizmo needs updating */ - if (mpr_modal) { - if ((mpr_modal->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL) == 0) { - if (wm_gizmogroup_is_visible_in_drawstep(mpr_modal->parent_mgroup, drawstep)) { - if (gizmo_prepare_drawing(mmap, mpr_modal, C, draw_gizmos, drawstep)) { - mmap->update_flag[drawstep] &= ~GIZMOMAP_IS_PREPARE_DRAW; + if (gz_modal) { + if ((gz_modal->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DRAW_MODAL_ALL) == 0) { + if (wm_gizmogroup_is_visible_in_drawstep(gz_modal->parent_gzgroup, drawstep)) { + if (gizmo_prepare_drawing(gzmap, gz_modal, C, draw_gizmos, drawstep)) { + gzmap->update_flag[drawstep] &= ~GIZMOMAP_IS_PREPARE_DRAW; } } /* don't draw any other gizmos */ @@ -347,46 +347,46 @@ static void gizmomap_prepare_drawing( } } - for (wmGizmoGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { /* check group visibility - drawstep first to avoid unnecessary call of group poll callback */ - if (!wm_gizmogroup_is_visible_in_drawstep(mgroup, drawstep) || - !WM_gizmo_group_type_poll(C, mgroup->type)) + if (!wm_gizmogroup_is_visible_in_drawstep(gzgroup, drawstep) || + !WM_gizmo_group_type_poll(C, gzgroup->type)) { continue; } /* needs to be initialized on first draw */ /* XXX weak: Gizmo-group may skip refreshing if it's invisible (map gets untagged nevertheless) */ - if (mmap->update_flag[drawstep] & GIZMOMAP_IS_REFRESH_CALLBACK) { + if (gzmap->update_flag[drawstep] & GIZMOMAP_IS_REFRESH_CALLBACK) { /* force refresh again. */ - mgroup->init_flag &= ~WM_GIZMOGROUP_INIT_REFRESH; + gzgroup->init_flag &= ~WM_GIZMOGROUP_INIT_REFRESH; } /* Calls `setup`, `setup_keymap` and `refresh` if they're defined. */ - wm_gizmogroup_ensure_initialized(mgroup, C); + wm_gizmogroup_ensure_initialized(gzgroup, C); /* prepare drawing */ - if (mgroup->type->draw_prepare) { - mgroup->type->draw_prepare(C, mgroup); + if (gzgroup->type->draw_prepare) { + gzgroup->type->draw_prepare(C, gzgroup); } - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - gizmo_prepare_drawing(mmap, mpr, C, draw_gizmos, drawstep); + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + gizmo_prepare_drawing(gzmap, gz, C, draw_gizmos, drawstep); } } - mmap->update_flag[drawstep] &= + gzmap->update_flag[drawstep] &= ~(GIZMOMAP_IS_REFRESH_CALLBACK | GIZMOMAP_IS_PREPARE_DRAW); } /** - * Draw all visible gizmos in \a mmap. + * Draw all visible gizmos in \a gzmap. * Uses global draw_gizmos listbase. */ -static void gizmos_draw_list(const wmGizmoMap *mmap, const bContext *C, ListBase *draw_gizmos) +static void gizmos_draw_list(const wmGizmoMap *gzmap, const bContext *C, ListBase *draw_gizmos) { /* Can be empty if we're dynamically added and removed. */ - if ((mmap == NULL) || BLI_listbase_is_empty(&mmap->groups)) { + if ((gzmap == NULL) || BLI_listbase_is_empty(&gzmap->groups)) { return; } @@ -397,13 +397,13 @@ static void gizmos_draw_list(const wmGizmoMap *mmap, const bContext *C, ListBase /* draw_gizmos contains all visible gizmos - draw them */ for (LinkData *link = draw_gizmos->first, *link_next; link; link = link_next) { - wmGizmo *mpr = link->data; + wmGizmo *gz = link->data; link_next = link->next; - bool is_depth = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0; + bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0; /* Weak! since we don't 100% support depth yet (select ignores depth) always show highlighted */ - if (is_depth && (mpr->state & WM_GIZMO_STATE_HIGHLIGHT)) { + if (is_depth && (gz->state & WM_GIZMO_STATE_HIGHLIGHT)) { is_depth = false; } @@ -424,7 +424,7 @@ static void gizmos_draw_list(const wmGizmoMap *mmap, const bContext *C, ListBase glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); - mpr->type->draw(C, mpr); + gz->type->draw(C, gz); glDisable(GL_LINE_SMOOTH); glDisable(GL_POLYGON_SMOOTH); @@ -439,7 +439,7 @@ static void gizmos_draw_list(const wmGizmoMap *mmap, const bContext *C, ListBase } void WM_gizmomap_draw( - wmGizmoMap *mmap, const bContext *C, + wmGizmoMap *gzmap, const bContext *C, const eWM_GizmoFlagMapDrawStep drawstep) { if (!WM_gizmo_context_check_drawstep(C, drawstep)) { @@ -448,24 +448,24 @@ void WM_gizmomap_draw( ListBase draw_gizmos = {NULL}; - gizmomap_prepare_drawing(mmap, C, &draw_gizmos, drawstep); - gizmos_draw_list(mmap, C, &draw_gizmos); + gizmomap_prepare_drawing(gzmap, C, &draw_gizmos, drawstep); + gizmos_draw_list(gzmap, C, &draw_gizmos); BLI_assert(BLI_listbase_is_empty(&draw_gizmos)); } static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmos) { int select_id = 0; - wmGizmo *mpr; + wmGizmo *gz; /* TODO(campbell): this depends on depth buffer being written to, currently broken for the 3D view. */ bool is_depth_prev = false; bool is_depth_skip_prev = false; for (LinkData *link = visible_gizmos->first; link; link = link->next) { - mpr = link->data; + gz = link->data; - bool is_depth = (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0; + bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0; if (is_depth == is_depth_prev) { /* pass */ } @@ -478,7 +478,7 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo } is_depth_prev = is_depth; } - bool is_depth_skip = (mpr->flag & WM_GIZMO_SELECT_BACKGROUND) != 0; + bool is_depth_skip = (gz->flag & WM_GIZMO_SELECT_BACKGROUND) != 0; if (is_depth_skip == is_depth_skip_prev) { /* pass */ } @@ -489,7 +489,7 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo /* pass the selection id shifted by 8 bits. Last 8 bits are used for selected gizmo part id */ - mpr->type->draw_select(C, mpr, select_id << 8); + gz->type->draw_select(C, gz, select_id << 8); select_id++; @@ -593,10 +593,10 @@ static wmGizmo *gizmo_find_intersected_3d( * 3D ones (could check for smallest screen-space distance but not needed right now). */ wmGizmo *wm_gizmomap_highlight_find( - wmGizmoMap *mmap, bContext *C, const wmEvent *event, + wmGizmoMap *gzmap, bContext *C, const wmEvent *event, int *r_part) { - wmGizmo *mpr = NULL; + wmGizmo *gz = NULL; ListBase visible_3d_gizmos = {NULL}; bool do_step[WM_GIZMOMAP_DRAWSTEP_MAX]; @@ -604,18 +604,18 @@ wmGizmo *wm_gizmomap_highlight_find( do_step[i] = WM_gizmo_context_check_drawstep(C, i); } - for (wmGizmoGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { /* If it were important we could initialize here, * but this only happens when events are handled before drawing, * just skip to keep code-path for initializing gizmos simple. */ - if ((mgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0) { + if ((gzgroup->init_flag & WM_GIZMOGROUP_INIT_SETUP) == 0) { continue; } - if (WM_gizmo_group_type_poll(C, mgroup->type)) { + if (WM_gizmo_group_type_poll(C, gzgroup->type)) { eWM_GizmoFlagMapDrawStep step; - if (mgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { + if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) { step = WM_GIZMOMAP_DRAWSTEP_3D; } else { @@ -623,17 +623,17 @@ wmGizmo *wm_gizmomap_highlight_find( } if (do_step[step]) { - if ((mmap->update_flag[step] & GIZMOMAP_IS_REFRESH_CALLBACK) && - (mgroup->type->refresh != NULL)) + if ((gzmap->update_flag[step] & GIZMOMAP_IS_REFRESH_CALLBACK) && + (gzgroup->type->refresh != NULL)) { - mgroup->type->refresh(C, mgroup); + gzgroup->type->refresh(C, gzgroup); /* cleared below */ } if (step == WM_GIZMOMAP_DRAWSTEP_3D) { - wm_gizmogroup_intersectable_gizmos_to_list(mgroup, &visible_3d_gizmos); + wm_gizmogroup_intersectable_gizmos_to_list(gzgroup, &visible_3d_gizmos); } else if (step == WM_GIZMOMAP_DRAWSTEP_2D) { - if ((mpr = wm_gizmogroup_find_intersected_gizmo(mgroup, C, event, r_part))) { + if ((gz = wm_gizmogroup_find_intersected_gizmo(gzgroup, C, event, r_part))) { break; } } @@ -643,32 +643,32 @@ wmGizmo *wm_gizmomap_highlight_find( if (!BLI_listbase_is_empty(&visible_3d_gizmos)) { /* 2D gizmos get priority. */ - if (mpr == NULL) { - mpr = gizmo_find_intersected_3d(C, event->mval, &visible_3d_gizmos, r_part); + if (gz == NULL) { + gz = gizmo_find_intersected_3d(C, event->mval, &visible_3d_gizmos, r_part); } BLI_freelistN(&visible_3d_gizmos); } - mmap->update_flag[WM_GIZMOMAP_DRAWSTEP_3D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK; - mmap->update_flag[WM_GIZMOMAP_DRAWSTEP_2D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK; + gzmap->update_flag[WM_GIZMOMAP_DRAWSTEP_3D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK; + gzmap->update_flag[WM_GIZMOMAP_DRAWSTEP_2D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK; - return mpr; + return gz; } -void WM_gizmomap_add_handlers(ARegion *ar, wmGizmoMap *mmap) +void WM_gizmomap_add_handlers(ARegion *ar, wmGizmoMap *gzmap) { wmEventHandler *handler; for (handler = ar->handlers.first; handler; handler = handler->next) { - if (handler->gizmo_map == mmap) { + if (handler->gizmo_map == gzmap) { return; } } handler = MEM_callocN(sizeof(wmEventHandler), "gizmo handler"); - BLI_assert(mmap == ar->gizmo_map); - handler->gizmo_map = mmap; + BLI_assert(gzmap == ar->gizmo_map); + handler->gizmo_map = gzmap; BLI_addtail(&ar->handlers, handler); } @@ -682,8 +682,8 @@ void wm_gizmomaps_handled_modal_update( return; } - wmGizmoMap *mmap = handler->op_region->gizmo_map; - wmGizmo *mpr = wm_gizmomap_modal_get(mmap); + wmGizmoMap *gzmap = handler->op_region->gizmo_map; + wmGizmo *gz = wm_gizmomap_modal_get(gzmap); ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -691,11 +691,11 @@ void wm_gizmomaps_handled_modal_update( /* regular update for running operator */ if (modal_running) { - wmGizmoOpElem *mpop = mpr ? WM_gizmo_operator_get(mpr, mpr->highlight_part) : NULL; - if (mpr && mpop && (mpop->type != NULL) && (mpop->type == handler->op->type)) { - wmGizmoFnModal modal_fn = mpr->custom_modal ? mpr->custom_modal : mpr->type->modal; + wmGizmoOpElem *mpop = gz ? WM_gizmo_operator_get(gz, gz->highlight_part) : NULL; + if (gz && mpop && (mpop->type != NULL) && (mpop->type == handler->op->type)) { + wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal; if (modal_fn != NULL) { - int retval = modal_fn(C, mpr, event, 0); + int retval = modal_fn(C, gz, event, 0); /* The gizmo is tried to the operator, we can't choose when to exit. */ BLI_assert(retval & OPERATOR_RUNNING_MODAL); UNUSED_VARS_NDEBUG(retval); @@ -704,14 +704,14 @@ void wm_gizmomaps_handled_modal_update( } /* operator not running anymore */ else { - wm_gizmomap_highlight_set(mmap, C, NULL, 0); - if (mpr) { + wm_gizmomap_highlight_set(gzmap, C, NULL, 0); + if (gz) { /* This isn't defined if it ends because of success of cancel, we may want to change. */ bool cancel = true; - if (mpr->type->exit) { - mpr->type->exit(C, mpr, cancel); + if (gz->type->exit) { + gz->type->exit(C, gz, cancel); } - wm_gizmomap_modal_set(mmap, C, mpr, NULL, false); + wm_gizmomap_modal_set(gzmap, C, gz, NULL, false); } } @@ -721,58 +721,58 @@ void wm_gizmomaps_handled_modal_update( } /** - * Deselect all selected gizmos in \a mmap. + * Deselect all selected gizmos in \a gzmap. * \return if selection has changed. */ -bool wm_gizmomap_deselect_all(wmGizmoMap *mmap) +bool wm_gizmomap_deselect_all(wmGizmoMap *gzmap) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; if (msel->items == NULL || msel->len == 0) { return false; } for (int i = 0; i < msel->len; i++) { - wm_gizmo_select_set_ex(mmap, msel->items[i], false, false, true); + wm_gizmo_select_set_ex(gzmap, msel->items[i], false, false, true); } - wm_gizmomap_select_array_clear(mmap); + wm_gizmomap_select_array_clear(gzmap); /* always return true, we already checked * if there's anything to deselect */ return true; } -BLI_INLINE bool gizmo_selectable_poll(const wmGizmo *mpr, void *UNUSED(data)) +BLI_INLINE bool gizmo_selectable_poll(const wmGizmo *gz, void *UNUSED(data)) { - return (mpr->parent_mgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT); + return (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_SELECT); } /** - * Select all selectable gizmos in \a mmap. + * Select all selectable gizmos in \a gzmap. * \return if selection has changed. */ static bool wm_gizmomap_select_all_intern( - bContext *C, wmGizmoMap *mmap) + bContext *C, wmGizmoMap *gzmap) { - wmGizmoMapSelectState *msel = &mmap->mmap_context.select; + wmGizmoMapSelectState *msel = &gzmap->gzmap_context.select; /* GHash is used here to avoid having to loop over all gizmos twice (once to * get tot_sel for allocating, once for actually selecting). Instead we collect * selectable gizmos in hash table and use this to get tot_sel and do selection */ - GHash *hash = WM_gizmomap_gizmo_hash_new(C, mmap, gizmo_selectable_poll, NULL, true); + GHash *hash = WM_gizmomap_gizmo_hash_new(C, gzmap, gizmo_selectable_poll, NULL, true); GHashIterator gh_iter; int i; bool changed = false; - wm_gizmomap_select_array_ensure_len_alloc(mmap, BLI_ghash_len(hash)); + wm_gizmomap_select_array_ensure_len_alloc(gzmap, BLI_ghash_len(hash)); GHASH_ITER_INDEX (gh_iter, hash, i) { - wmGizmo *mpr_iter = BLI_ghashIterator_getValue(&gh_iter); - WM_gizmo_select_set(mmap, mpr_iter, true); + wmGizmo *gz_iter = BLI_ghashIterator_getValue(&gh_iter); + WM_gizmo_select_set(gzmap, gz_iter, true); } /* highlight first gizmo */ - wm_gizmomap_highlight_set(mmap, C, msel->items[0], msel->items[0]->highlight_part); + wm_gizmomap_highlight_set(gzmap, C, msel->items[0], msel->items[0]->highlight_part); BLI_assert(BLI_ghash_len(hash) == msel->len); @@ -781,21 +781,21 @@ static bool wm_gizmomap_select_all_intern( } /** - * Select/Deselect all selectable gizmos in \a mmap. + * Select/Deselect all selectable gizmos in \a gzmap. * \return if selection has changed. * * TODO select all by type */ -bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *mmap, const int action) +bool WM_gizmomap_select_all(bContext *C, wmGizmoMap *gzmap, const int action) { bool changed = false; switch (action) { case SEL_SELECT: - changed = wm_gizmomap_select_all_intern(C, mmap); + changed = wm_gizmomap_select_all_intern(C, gzmap); break; case SEL_DESELECT: - changed = wm_gizmomap_deselect_all(mmap); + changed = wm_gizmomap_deselect_all(gzmap); break; default: BLI_assert(0); @@ -846,11 +846,11 @@ void wm_gizmomap_handler_context(bContext *C, wmEventHandler *handler) } } -bool WM_gizmomap_cursor_set(const wmGizmoMap *mmap, wmWindow *win) +bool WM_gizmomap_cursor_set(const wmGizmoMap *gzmap, wmWindow *win) { - wmGizmo *mpr = mmap->mmap_context.highlight; - if (mpr && mpr->type->cursor_get) { - WM_cursor_set(win, mpr->type->cursor_get(mpr)); + wmGizmo *gz = gzmap->gzmap_context.highlight; + if (gz && gz->type->cursor_get) { + WM_cursor_set(win, gz->type->cursor_get(gz)); return true; } @@ -858,33 +858,33 @@ bool WM_gizmomap_cursor_set(const wmGizmoMap *mmap, wmWindow *win) } bool wm_gizmomap_highlight_set( - wmGizmoMap *mmap, const bContext *C, wmGizmo *mpr, int part) + wmGizmoMap *gzmap, const bContext *C, wmGizmo *gz, int part) { - if ((mpr != mmap->mmap_context.highlight) || - (mpr && part != mpr->highlight_part)) + if ((gz != gzmap->gzmap_context.highlight) || + (gz && part != gz->highlight_part)) { - if (mmap->mmap_context.highlight) { - mmap->mmap_context.highlight->state &= ~WM_GIZMO_STATE_HIGHLIGHT; - mmap->mmap_context.highlight->highlight_part = -1; + if (gzmap->gzmap_context.highlight) { + gzmap->gzmap_context.highlight->state &= ~WM_GIZMO_STATE_HIGHLIGHT; + gzmap->gzmap_context.highlight->highlight_part = -1; } - mmap->mmap_context.highlight = mpr; + gzmap->gzmap_context.highlight = gz; - if (mpr) { - mpr->state |= WM_GIZMO_STATE_HIGHLIGHT; - mpr->highlight_part = part; - mmap->mmap_context.last_cursor = -1; + if (gz) { + gz->state |= WM_GIZMO_STATE_HIGHLIGHT; + gz->highlight_part = part; + gzmap->gzmap_context.last_cursor = -1; - if (C && mpr->type->cursor_get) { + if (C && gz->type->cursor_get) { wmWindow *win = CTX_wm_window(C); - mmap->mmap_context.last_cursor = win->cursor; - WM_cursor_set(win, mpr->type->cursor_get(mpr)); + gzmap->gzmap_context.last_cursor = win->cursor; + WM_cursor_set(win, gz->type->cursor_get(gz)); } } else { - if (C && mmap->mmap_context.last_cursor != -1) { + if (C && gzmap->gzmap_context.last_cursor != -1) { wmWindow *win = CTX_wm_window(C); - WM_cursor_set(win, mmap->mmap_context.last_cursor); + WM_cursor_set(win, gzmap->gzmap_context.last_cursor); } } @@ -900,123 +900,123 @@ bool wm_gizmomap_highlight_set( return false; } -wmGizmo *wm_gizmomap_highlight_get(wmGizmoMap *mmap) +wmGizmo *wm_gizmomap_highlight_get(wmGizmoMap *gzmap) { - return mmap->mmap_context.highlight; + return gzmap->gzmap_context.highlight; } /** * Caller should call exit when (enable == False). */ void wm_gizmomap_modal_set( - wmGizmoMap *mmap, bContext *C, wmGizmo *mpr, const wmEvent *event, bool enable) + wmGizmoMap *gzmap, bContext *C, wmGizmo *gz, const wmEvent *event, bool enable) { if (enable) { - BLI_assert(mmap->mmap_context.modal == NULL); + BLI_assert(gzmap->gzmap_context.modal == NULL); wmWindow *win = CTX_wm_window(C); WM_tooltip_clear(C, win); - if (mpr->type->invoke && - (mpr->type->modal || mpr->custom_modal)) + if (gz->type->invoke && + (gz->type->modal || gz->custom_modal)) { - const int retval = mpr->type->invoke(C, mpr, event); + const int retval = gz->type->invoke(C, gz, event); if ((retval & OPERATOR_RUNNING_MODAL) == 0) { return; } } - mpr->state |= WM_GIZMO_STATE_MODAL; - mmap->mmap_context.modal = mpr; + gz->state |= WM_GIZMO_STATE_MODAL; + gzmap->gzmap_context.modal = gz; - if ((mpr->flag & WM_GIZMO_GRAB_CURSOR) && + if ((gz->flag & WM_GIZMO_GRAB_CURSOR) && (event->is_motion_absolute == false)) { WM_cursor_grab_enable(win, true, true, NULL); - copy_v2_v2_int(mmap->mmap_context.event_xy, &event->x); - mmap->mmap_context.event_grabcursor = win->grabcursor; + copy_v2_v2_int(gzmap->gzmap_context.event_xy, &event->x); + gzmap->gzmap_context.event_grabcursor = win->grabcursor; } else { - mmap->mmap_context.event_xy[0] = INT_MAX; + gzmap->gzmap_context.event_xy[0] = INT_MAX; } - struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(mpr, mpr->highlight_part); + struct wmGizmoOpElem *mpop = WM_gizmo_operator_get(gz, gz->highlight_part); if (mpop && mpop->type) { const int retval = WM_operator_name_call_ptr(C, mpop->type, WM_OP_INVOKE_DEFAULT, &mpop->ptr); if ((retval & OPERATOR_RUNNING_MODAL) == 0) { - wm_gizmomap_modal_set(mmap, C, mpr, event, false); + wm_gizmomap_modal_set(gzmap, C, gz, event, false); } /* we failed to hook the gizmo to the operator handler or operator was cancelled, return */ - if (!mmap->mmap_context.modal) { - mpr->state &= ~WM_GIZMO_STATE_MODAL; - MEM_SAFE_FREE(mpr->interaction_data); + if (!gzmap->gzmap_context.modal) { + gz->state &= ~WM_GIZMO_STATE_MODAL; + MEM_SAFE_FREE(gz->interaction_data); } return; } } else { - BLI_assert(ELEM(mmap->mmap_context.modal, NULL, mpr)); + BLI_assert(ELEM(gzmap->gzmap_context.modal, NULL, gz)); /* deactivate, gizmo but first take care of some stuff */ - if (mpr) { - mpr->state &= ~WM_GIZMO_STATE_MODAL; - MEM_SAFE_FREE(mpr->interaction_data); + if (gz) { + gz->state &= ~WM_GIZMO_STATE_MODAL; + MEM_SAFE_FREE(gz->interaction_data); } - mmap->mmap_context.modal = NULL; + gzmap->gzmap_context.modal = NULL; if (C) { wmWindow *win = CTX_wm_window(C); - if (mmap->mmap_context.event_xy[0] != INT_MAX) { + if (gzmap->gzmap_context.event_xy[0] != INT_MAX) { /* Check if some other part of Blender (typically operators) * have adjusted the grab mode since it was set. * If so: warp, so we have a predictable outcome. */ - if (mmap->mmap_context.event_grabcursor == win->grabcursor) { - WM_cursor_grab_disable(win, mmap->mmap_context.event_xy); + if (gzmap->gzmap_context.event_grabcursor == win->grabcursor) { + WM_cursor_grab_disable(win, gzmap->gzmap_context.event_xy); } else { - WM_cursor_warp(win, UNPACK2(mmap->mmap_context.event_xy)); + WM_cursor_warp(win, UNPACK2(gzmap->gzmap_context.event_xy)); } } ED_region_tag_redraw(CTX_wm_region(C)); WM_event_add_mousemove(C); } - mmap->mmap_context.event_xy[0] = INT_MAX; + gzmap->gzmap_context.event_xy[0] = INT_MAX; } } -wmGizmo *wm_gizmomap_modal_get(wmGizmoMap *mmap) +wmGizmo *wm_gizmomap_modal_get(wmGizmoMap *gzmap) { - return mmap->mmap_context.modal; + return gzmap->gzmap_context.modal; } -wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *mmap, int *r_selected_len) +wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *gzmap, int *r_selected_len) { - *r_selected_len = mmap->mmap_context.select.len; - return mmap->mmap_context.select.items; + *r_selected_len = gzmap->gzmap_context.select.len; + return gzmap->gzmap_context.select.items; } -ListBase *wm_gizmomap_groups_get(wmGizmoMap *mmap) +ListBase *wm_gizmomap_groups_get(wmGizmoMap *gzmap) { - return &mmap->groups; + return &gzmap->groups; } void WM_gizmomap_message_subscribe( - bContext *C, wmGizmoMap *mmap, ARegion *ar, struct wmMsgBus *mbus) + bContext *C, wmGizmoMap *gzmap, ARegion *ar, struct wmMsgBus *mbus) { - for (wmGizmoGroup *mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { - if (!WM_gizmo_group_type_poll(C, mgroup->type)) { + for (wmGizmoGroup *gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { + if (!WM_gizmo_group_type_poll(C, gzgroup->type)) { continue; } - for (wmGizmo *mpr = mgroup->gizmos.first; mpr; mpr = mpr->next) { - if (mpr->flag & WM_GIZMO_HIDDEN) { + for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { + if (gz->flag & WM_GIZMO_HIDDEN) { continue; } - WM_gizmo_target_property_subscribe_all(mpr, mbus, ar); + WM_gizmo_target_property_subscribe_all(gz, mbus, ar); } - if (mgroup->type->message_subscribe != NULL) { - mgroup->type->message_subscribe(C, mgroup, mbus); + if (gzgroup->type->message_subscribe != NULL) { + gzgroup->type->message_subscribe(C, gzgroup, mbus); } } } @@ -1032,12 +1032,12 @@ void WM_gizmomap_message_subscribe( struct ARegion *WM_gizmomap_tooltip_init( struct bContext *C, struct ARegion *ar, bool *r_exit_on_event) { - wmGizmoMap *mmap = ar->gizmo_map; + wmGizmoMap *gzmap = ar->gizmo_map; *r_exit_on_event = true; - if (mmap) { - wmGizmo *mpr = mmap->mmap_context.highlight; - if (mpr) { - return UI_tooltip_create_from_gizmo(C, mpr); + if (gzmap) { + wmGizmo *gz = gzmap->gzmap_context.highlight; + if (gz) { + return UI_tooltip_create_from_gizmo(C, gz); } } return NULL; @@ -1051,13 +1051,13 @@ struct ARegion *WM_gizmomap_tooltip_init( * \{ */ wmGizmoMapType *WM_gizmomaptype_find( - const struct wmGizmoMapType_Params *mmap_params) + const struct wmGizmoMapType_Params *gzmap_params) { - for (wmGizmoMapType *mmap_type = gizmomaptypes.first; mmap_type; mmap_type = mmap_type->next) { - if (mmap_type->spaceid == mmap_params->spaceid && - mmap_type->regionid == mmap_params->regionid) + for (wmGizmoMapType *gzmap_type = gizmomaptypes.first; gzmap_type; gzmap_type = gzmap_type->next) { + if (gzmap_type->spaceid == gzmap_params->spaceid && + gzmap_type->regionid == gzmap_params->regionid) { - return mmap_type; + return gzmap_type; } } @@ -1065,37 +1065,37 @@ wmGizmoMapType *WM_gizmomaptype_find( } wmGizmoMapType *WM_gizmomaptype_ensure( - const struct wmGizmoMapType_Params *mmap_params) + const struct wmGizmoMapType_Params *gzmap_params) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_find(mmap_params); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_find(gzmap_params); - if (mmap_type) { - return mmap_type; + if (gzmap_type) { + return gzmap_type; } - mmap_type = MEM_callocN(sizeof(wmGizmoMapType), "gizmotype list"); - mmap_type->spaceid = mmap_params->spaceid; - mmap_type->regionid = mmap_params->regionid; - BLI_addhead(&gizmomaptypes, mmap_type); + gzmap_type = MEM_callocN(sizeof(wmGizmoMapType), "gizmotype list"); + gzmap_type->spaceid = gzmap_params->spaceid; + gzmap_type->regionid = gzmap_params->regionid; + BLI_addhead(&gizmomaptypes, gzmap_type); - return mmap_type; + return gzmap_type; } void wm_gizmomaptypes_free(void) { - for (wmGizmoMapType *mmap_type = gizmomaptypes.first, *mmap_type_next; - mmap_type; - mmap_type = mmap_type_next) + for (wmGizmoMapType *gzmap_type = gizmomaptypes.first, *gzmap_type_next; + gzmap_type; + gzmap_type = gzmap_type_next) { - mmap_type_next = mmap_type->next; - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first, *wgt_next; - wgt_ref; - wgt_ref = wgt_next) + gzmap_type_next = gzmap_type->next; + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first, *gzgt_next; + gzgt_ref; + gzgt_ref = gzgt_next) { - wgt_next = wgt_ref->next; - WM_gizmomaptype_group_free(wgt_ref); + gzgt_next = gzgt_ref->next; + WM_gizmomaptype_group_free(gzgt_ref); } - MEM_freeN(mmap_type); + MEM_freeN(gzmap_type); } } @@ -1107,9 +1107,9 @@ void wm_gizmos_keymap(wmKeyConfig *keyconf) /* we add this item-less keymap once and use it to group gizmo-group keymaps into it */ WM_keymap_find(keyconf, "Gizmos", 0, 0); - for (wmGizmoMapType *mmap_type = gizmomaptypes.first; mmap_type; mmap_type = mmap_type->next) { - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; wgt_ref; wgt_ref = wgt_ref->next) { - wm_gizmogrouptype_setup_keymap(wgt_ref->type, keyconf); + for (wmGizmoMapType *gzmap_type = gizmomaptypes.first; gzmap_type; gzmap_type = gzmap_type->next) { + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first; gzgt_ref; gzgt_ref = gzgt_ref->next) { + wm_gizmogrouptype_setup_keymap(gzgt_ref->type, keyconf); } } } @@ -1123,23 +1123,23 @@ void wm_gizmos_keymap(wmKeyConfig *keyconf) void WM_gizmoconfig_update_tag_init( - wmGizmoMapType *mmap_type, wmGizmoGroupType *wgt) + wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt) { /* tag for update on next use */ - mmap_type->type_update_flag |= (WM_GIZMOMAPTYPE_UPDATE_INIT | WM_GIZMOMAPTYPE_KEYMAP_INIT); - wgt->type_update_flag |= (WM_GIZMOMAPTYPE_UPDATE_INIT | WM_GIZMOMAPTYPE_KEYMAP_INIT); + gzmap_type->type_update_flag |= (WM_GIZMOMAPTYPE_UPDATE_INIT | WM_GIZMOMAPTYPE_KEYMAP_INIT); + gzgt->type_update_flag |= (WM_GIZMOMAPTYPE_UPDATE_INIT | WM_GIZMOMAPTYPE_KEYMAP_INIT); - wm_mmap_type_update_flag |= WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT; + wm_gzmap_type_update_flag |= WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT; } void WM_gizmoconfig_update_tag_remove( - wmGizmoMapType *mmap_type, wmGizmoGroupType *wgt) + wmGizmoMapType *gzmap_type, wmGizmoGroupType *gzgt) { /* tag for update on next use */ - mmap_type->type_update_flag |= WM_GIZMOMAPTYPE_UPDATE_REMOVE; - wgt->type_update_flag |= WM_GIZMOMAPTYPE_UPDATE_REMOVE; + gzmap_type->type_update_flag |= WM_GIZMOMAPTYPE_UPDATE_REMOVE; + gzgt->type_update_flag |= WM_GIZMOMAPTYPE_UPDATE_REMOVE; - wm_mmap_type_update_flag |= WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE; + wm_gzmap_type_update_flag |= WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE; } /** @@ -1151,58 +1151,58 @@ void WM_gizmoconfig_update(struct Main *bmain) if (G.background) return; - if (wm_mmap_type_update_flag == 0) + if (wm_gzmap_type_update_flag == 0) return; - if (wm_mmap_type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE) { - for (wmGizmoMapType *mmap_type = gizmomaptypes.first; - mmap_type; - mmap_type = mmap_type->next) + if (wm_gzmap_type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE) { + for (wmGizmoMapType *gzmap_type = gizmomaptypes.first; + gzmap_type; + gzmap_type = gzmap_type->next) { - if (mmap_type->type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE) { - mmap_type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE; - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first, *wgt_ref_next; - wgt_ref; - wgt_ref = wgt_ref_next) + if (gzmap_type->type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE) { + gzmap_type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE; + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first, *gzgt_ref_next; + gzgt_ref; + gzgt_ref = gzgt_ref_next) { - wgt_ref_next = wgt_ref->next; - if (wgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_REMOVE) { - wgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE; - WM_gizmomaptype_group_unlink(NULL, bmain, mmap_type, wgt_ref->type); + gzgt_ref_next = gzgt_ref->next; + if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_REMOVE) { + gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_REMOVE; + WM_gizmomaptype_group_unlink(NULL, bmain, gzmap_type, gzgt_ref->type); } } } } - wm_mmap_type_update_flag &= ~WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE; + wm_gzmap_type_update_flag &= ~WM_GIZMOMAPTYPE_GLOBAL_UPDATE_REMOVE; } - if (wm_mmap_type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT) { - for (wmGizmoMapType *mmap_type = gizmomaptypes.first; - mmap_type; - mmap_type = mmap_type->next) + if (wm_gzmap_type_update_flag & WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT) { + for (wmGizmoMapType *gzmap_type = gizmomaptypes.first; + gzmap_type; + gzmap_type = gzmap_type->next) { const uchar type_update_all = WM_GIZMOMAPTYPE_UPDATE_INIT | WM_GIZMOMAPTYPE_KEYMAP_INIT; - if (mmap_type->type_update_flag & type_update_all) { - mmap_type->type_update_flag &= ~type_update_all; - for (wmGizmoGroupTypeRef *wgt_ref = mmap_type->grouptype_refs.first; - wgt_ref; - wgt_ref = wgt_ref->next) + if (gzmap_type->type_update_flag & type_update_all) { + gzmap_type->type_update_flag &= ~type_update_all; + for (wmGizmoGroupTypeRef *gzgt_ref = gzmap_type->grouptype_refs.first; + gzgt_ref; + gzgt_ref = gzgt_ref->next) { - if (wgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_KEYMAP_INIT) { - WM_gizmomaptype_group_init_runtime_keymap(bmain, wgt_ref->type); - wgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT; + if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_KEYMAP_INIT) { + WM_gizmomaptype_group_init_runtime_keymap(bmain, gzgt_ref->type); + gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_KEYMAP_INIT; } - if (wgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_INIT) { - WM_gizmomaptype_group_init_runtime(bmain, mmap_type, wgt_ref->type); - wgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_INIT; + if (gzgt_ref->type->type_update_flag & WM_GIZMOMAPTYPE_UPDATE_INIT) { + WM_gizmomaptype_group_init_runtime(bmain, gzmap_type, gzgt_ref->type); + gzgt_ref->type->type_update_flag &= ~WM_GIZMOMAPTYPE_UPDATE_INIT; } } } } - wm_mmap_type_update_flag &= ~WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT; + wm_gzmap_type_update_flag &= ~WM_GIZMOMAPTYPE_GLOBAL_UPDATE_INIT; } } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c index f3df001af55..601c54b8be5 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c @@ -51,30 +51,30 @@ /** \name Property Definition * \{ */ -BLI_INLINE wmGizmoProperty *wm_gizmo_target_property_array(wmGizmo *mpr) +BLI_INLINE wmGizmoProperty *wm_gizmo_target_property_array(wmGizmo *gz) { - return (wmGizmoProperty *)(POINTER_OFFSET(mpr, mpr->type->struct_size)); + return (wmGizmoProperty *)(POINTER_OFFSET(gz, gz->type->struct_size)); } -wmGizmoProperty *WM_gizmo_target_property_array(wmGizmo *mpr) +wmGizmoProperty *WM_gizmo_target_property_array(wmGizmo *gz) { - return wm_gizmo_target_property_array(mpr); + return wm_gizmo_target_property_array(gz); } -wmGizmoProperty *WM_gizmo_target_property_at_index(wmGizmo *mpr, int index) +wmGizmoProperty *WM_gizmo_target_property_at_index(wmGizmo *gz, int index) { - BLI_assert(index < mpr->type->target_property_defs_len); + BLI_assert(index < gz->type->target_property_defs_len); BLI_assert(index != -1); - wmGizmoProperty *mpr_prop_array = wm_gizmo_target_property_array(mpr); - return &mpr_prop_array[index]; + wmGizmoProperty *gz_prop_array = wm_gizmo_target_property_array(gz); + return &gz_prop_array[index]; } -wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *mpr, const char *idname) +wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname) { int index = BLI_findstringindex( - &mpr->type->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname)); + &gz->type->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname)); if (index != -1) { - return WM_gizmo_target_property_at_index(mpr, index); + return WM_gizmo_target_property_at_index(gz, index); } else { return NULL; @@ -82,84 +82,84 @@ wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *mpr, const char *idname) } void WM_gizmo_target_property_def_rna_ptr( - wmGizmo *mpr, const wmGizmoPropertyType *mpr_prop_type, + wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type, PointerRNA *ptr, PropertyRNA *prop, int index) { - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_at_index(mpr, mpr_prop_type->index_in_type); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_at_index(gz, gz_prop_type->index_in_type); /* if gizmo evokes an operator we cannot use it for property manipulation */ - BLI_assert(mpr->op_data == NULL); + BLI_assert(gz->op_data == NULL); - mpr_prop->type = mpr_prop_type; + gz_prop->type = gz_prop_type; - mpr_prop->ptr = *ptr; - mpr_prop->prop = prop; - mpr_prop->index = index; + gz_prop->ptr = *ptr; + gz_prop->prop = prop; + gz_prop->index = index; - if (mpr->type->property_update) { - mpr->type->property_update(mpr, mpr_prop); + if (gz->type->property_update) { + gz->type->property_update(gz, gz_prop); } } void WM_gizmo_target_property_def_rna( - wmGizmo *mpr, const char *idname, + wmGizmo *gz, const char *idname, PointerRNA *ptr, const char *propname, int index) { - const wmGizmoPropertyType *mpr_prop_type = WM_gizmotype_target_property_find(mpr->type, idname); + const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname); PropertyRNA *prop = RNA_struct_find_property(ptr, propname); - WM_gizmo_target_property_def_rna_ptr(mpr, mpr_prop_type, ptr, prop, index); + WM_gizmo_target_property_def_rna_ptr(gz, gz_prop_type, ptr, prop, index); } void WM_gizmo_target_property_def_func_ptr( - wmGizmo *mpr, const wmGizmoPropertyType *mpr_prop_type, + wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type, const wmGizmoPropertyFnParams *params) { - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_at_index(mpr, mpr_prop_type->index_in_type); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_at_index(gz, gz_prop_type->index_in_type); /* if gizmo evokes an operator we cannot use it for property manipulation */ - BLI_assert(mpr->op_data == NULL); + BLI_assert(gz->op_data == NULL); - mpr_prop->type = mpr_prop_type; + gz_prop->type = gz_prop_type; - mpr_prop->custom_func.value_get_fn = params->value_get_fn; - mpr_prop->custom_func.value_set_fn = params->value_set_fn; - mpr_prop->custom_func.range_get_fn = params->range_get_fn; - mpr_prop->custom_func.free_fn = params->free_fn; - mpr_prop->custom_func.user_data = params->user_data; + gz_prop->custom_func.value_get_fn = params->value_get_fn; + gz_prop->custom_func.value_set_fn = params->value_set_fn; + gz_prop->custom_func.range_get_fn = params->range_get_fn; + gz_prop->custom_func.free_fn = params->free_fn; + gz_prop->custom_func.user_data = params->user_data; - if (mpr->type->property_update) { - mpr->type->property_update(mpr, mpr_prop); + if (gz->type->property_update) { + gz->type->property_update(gz, gz_prop); } } void WM_gizmo_target_property_def_func( - wmGizmo *mpr, const char *idname, + wmGizmo *gz, const char *idname, const wmGizmoPropertyFnParams *params) { - const wmGizmoPropertyType *mpr_prop_type = WM_gizmotype_target_property_find(mpr->type, idname); - WM_gizmo_target_property_def_func_ptr(mpr, mpr_prop_type, params); + const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname); + WM_gizmo_target_property_def_func_ptr(gz, gz_prop_type, params); } void WM_gizmo_target_property_clear_rna_ptr( - wmGizmo *mpr, const wmGizmoPropertyType *mpr_prop_type) + wmGizmo *gz, const wmGizmoPropertyType *gz_prop_type) { - wmGizmoProperty *mpr_prop = WM_gizmo_target_property_at_index(mpr, mpr_prop_type->index_in_type); + wmGizmoProperty *gz_prop = WM_gizmo_target_property_at_index(gz, gz_prop_type->index_in_type); /* if gizmo evokes an operator we cannot use it for property manipulation */ - BLI_assert(mpr->op_data == NULL); + BLI_assert(gz->op_data == NULL); - mpr_prop->type = NULL; + gz_prop->type = NULL; - mpr_prop->ptr = PointerRNA_NULL; - mpr_prop->prop = NULL; - mpr_prop->index = -1; + gz_prop->ptr = PointerRNA_NULL; + gz_prop->prop = NULL; + gz_prop->index = -1; } void WM_gizmo_target_property_clear_rna( - wmGizmo *mpr, const char *idname) + wmGizmo *gz, const char *idname) { - const wmGizmoPropertyType *mpr_prop_type = WM_gizmotype_target_property_find(mpr->type, idname); - WM_gizmo_target_property_clear_rna_ptr(mpr, mpr_prop_type); + const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, idname); + WM_gizmo_target_property_clear_rna_ptr(gz, gz_prop_type); } @@ -171,93 +171,93 @@ void WM_gizmo_target_property_clear_rna( /** \name Property Access * \{ */ -bool WM_gizmo_target_property_is_valid_any(wmGizmo *mpr) +bool WM_gizmo_target_property_is_valid_any(wmGizmo *gz) { - wmGizmoProperty *mpr_prop_array = wm_gizmo_target_property_array(mpr); - for (int i = 0; i < mpr->type->target_property_defs_len; i++) { - wmGizmoProperty *mpr_prop = &mpr_prop_array[i]; - if (WM_gizmo_target_property_is_valid(mpr_prop)) { + wmGizmoProperty *gz_prop_array = wm_gizmo_target_property_array(gz); + for (int i = 0; i < gz->type->target_property_defs_len; i++) { + wmGizmoProperty *gz_prop = &gz_prop_array[i]; + if (WM_gizmo_target_property_is_valid(gz_prop)) { return true; } } return false; } -bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *mpr_prop) +bool WM_gizmo_target_property_is_valid(const wmGizmoProperty *gz_prop) { - return ((mpr_prop->prop != NULL) || - (mpr_prop->custom_func.value_get_fn && mpr_prop->custom_func.value_set_fn)); + return ((gz_prop->prop != NULL) || + (gz_prop->custom_func.value_get_fn && gz_prop->custom_func.value_set_fn)); } float WM_gizmo_target_property_value_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop) + const wmGizmo *gz, wmGizmoProperty *gz_prop) { - if (mpr_prop->custom_func.value_get_fn) { + if (gz_prop->custom_func.value_get_fn) { float value = 0.0f; - BLI_assert(mpr_prop->type->array_length == 1); - mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, &value); + BLI_assert(gz_prop->type->array_length == 1); + gz_prop->custom_func.value_get_fn(gz, gz_prop, &value); return value; } - if (mpr_prop->index == -1) { - return RNA_property_float_get(&mpr_prop->ptr, mpr_prop->prop); + if (gz_prop->index == -1) { + return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop); } else { - return RNA_property_float_get_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index); + return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index); } } void WM_gizmo_target_property_value_set( - bContext *C, const wmGizmo *mpr, - wmGizmoProperty *mpr_prop, const float value) + bContext *C, const wmGizmo *gz, + wmGizmoProperty *gz_prop, const float value) { - if (mpr_prop->custom_func.value_set_fn) { - BLI_assert(mpr_prop->type->array_length == 1); - mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, &value); + if (gz_prop->custom_func.value_set_fn) { + BLI_assert(gz_prop->type->array_length == 1); + gz_prop->custom_func.value_set_fn(gz, gz_prop, &value); return; } /* reset property */ - if (mpr_prop->index == -1) { - RNA_property_float_set(&mpr_prop->ptr, mpr_prop->prop, value); + if (gz_prop->index == -1) { + RNA_property_float_set(&gz_prop->ptr, gz_prop->prop, value); } else { - RNA_property_float_set_index(&mpr_prop->ptr, mpr_prop->prop, mpr_prop->index, value); + RNA_property_float_set_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index, value); } - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); + RNA_property_update(C, &gz_prop->ptr, gz_prop->prop); } void WM_gizmo_target_property_value_get_array( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, float *value) { - if (mpr_prop->custom_func.value_get_fn) { - mpr_prop->custom_func.value_get_fn(mpr, mpr_prop, value); + if (gz_prop->custom_func.value_get_fn) { + gz_prop->custom_func.value_get_fn(gz, gz_prop, value); return; } - RNA_property_float_get_array(&mpr_prop->ptr, mpr_prop->prop, value); + RNA_property_float_get_array(&gz_prop->ptr, gz_prop->prop, value); } void WM_gizmo_target_property_value_set_array( - bContext *C, const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + bContext *C, const wmGizmo *gz, wmGizmoProperty *gz_prop, const float *value) { - if (mpr_prop->custom_func.value_set_fn) { - mpr_prop->custom_func.value_set_fn(mpr, mpr_prop, value); + if (gz_prop->custom_func.value_set_fn) { + gz_prop->custom_func.value_set_fn(gz, gz_prop, value); return; } - RNA_property_float_set_array(&mpr_prop->ptr, mpr_prop->prop, value); + RNA_property_float_set_array(&gz_prop->ptr, gz_prop->prop, value); - RNA_property_update(C, &mpr_prop->ptr, mpr_prop->prop); + RNA_property_update(C, &gz_prop->ptr, gz_prop->prop); } bool WM_gizmo_target_property_range_get( - const wmGizmo *mpr, wmGizmoProperty *mpr_prop, + const wmGizmo *gz, wmGizmoProperty *gz_prop, float range[2]) { - if (mpr_prop->custom_func.value_get_fn) { - if (mpr_prop->custom_func.range_get_fn) { - mpr_prop->custom_func.range_get_fn(mpr, mpr_prop, range); + if (gz_prop->custom_func.value_get_fn) { + if (gz_prop->custom_func.range_get_fn) { + gz_prop->custom_func.range_get_fn(gz, gz_prop, range); return true; } else { @@ -267,17 +267,17 @@ bool WM_gizmo_target_property_range_get( } float step, precision; - RNA_property_float_ui_range(&mpr_prop->ptr, mpr_prop->prop, &range[0], &range[1], &step, &precision); + RNA_property_float_ui_range(&gz_prop->ptr, gz_prop->prop, &range[0], &range[1], &step, &precision); return true; } int WM_gizmo_target_property_array_length( - const wmGizmo *UNUSED(mpr), wmGizmoProperty *mpr_prop) + const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop) { - if (mpr_prop->custom_func.value_get_fn) { - return mpr_prop->type->array_length; + if (gz_prop->custom_func.value_get_fn) { + return gz_prop->type->array_length; } - return RNA_property_array_length(&mpr_prop->ptr, mpr_prop->prop); + return RNA_property_array_length(&gz_prop->ptr, gz_prop->prop); } /** \} */ @@ -289,26 +289,26 @@ int WM_gizmo_target_property_array_length( * \{ */ const wmGizmoPropertyType *WM_gizmotype_target_property_find( - const wmGizmoType *wt, const char *idname) + const wmGizmoType *gzt, const char *idname) { - return BLI_findstring(&wt->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname)); + return BLI_findstring(&gzt->target_property_defs, idname, offsetof(wmGizmoPropertyType, idname)); } void WM_gizmotype_target_property_def( - wmGizmoType *wt, const char *idname, int data_type, int array_length) + wmGizmoType *gzt, const char *idname, int data_type, int array_length) { wmGizmoPropertyType *mpt; - BLI_assert(WM_gizmotype_target_property_find(wt, idname) == NULL); + BLI_assert(WM_gizmotype_target_property_find(gzt, idname) == NULL); const uint idname_size = strlen(idname) + 1; mpt = MEM_callocN(sizeof(wmGizmoPropertyType) + idname_size, __func__); memcpy(mpt->idname, idname, idname_size); mpt->data_type = data_type; mpt->array_length = array_length; - mpt->index_in_type = wt->target_property_defs_len; - wt->target_property_defs_len += 1; - BLI_addtail(&wt->target_property_defs, mpt); + mpt->index_in_type = gzt->target_property_defs_len; + gzt->target_property_defs_len += 1; + BLI_addtail(&gzt->target_property_defs, mpt); } /** \} */ @@ -322,10 +322,10 @@ void WM_gizmo_do_msg_notify_tag_refresh( bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val) { ARegion *ar = msg_val->owner; - wmGizmoMap *mmap = msg_val->user_data; + wmGizmoMap *gzmap = msg_val->user_data; ED_region_tag_redraw(ar); - WM_gizmomap_tag_refresh(mmap); + WM_gizmomap_tag_refresh(gzmap); } /** @@ -333,26 +333,26 @@ void WM_gizmo_do_msg_notify_tag_refresh( * drawing the region clears. */ void WM_gizmo_target_property_subscribe_all( - wmGizmo *mpr, struct wmMsgBus *mbus, ARegion *ar) + wmGizmo *gz, struct wmMsgBus *mbus, ARegion *ar) { - if (mpr->type->target_property_defs_len) { - wmGizmoProperty *mpr_prop_array = WM_gizmo_target_property_array(mpr); - for (int i = 0; i < mpr->type->target_property_defs_len; i++) { - wmGizmoProperty *mpr_prop = &mpr_prop_array[i]; - if (WM_gizmo_target_property_is_valid(mpr_prop)) { - if (mpr_prop->prop) { + if (gz->type->target_property_defs_len) { + wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); + for (int i = 0; i < gz->type->target_property_defs_len; i++) { + wmGizmoProperty *gz_prop = &gz_prop_array[i]; + if (WM_gizmo_target_property_is_valid(gz_prop)) { + if (gz_prop->prop) { WM_msg_subscribe_rna( - mbus, &mpr_prop->ptr, mpr_prop->prop, + mbus, &gz_prop->ptr, gz_prop->prop, &(const wmMsgSubscribeValue){ .owner = ar, .user_data = ar, .notify = ED_region_do_msg_notify_tag_redraw, }, __func__); WM_msg_subscribe_rna( - mbus, &mpr_prop->ptr, mpr_prop->prop, + mbus, &gz_prop->ptr, gz_prop->prop, &(const wmMsgSubscribeValue){ .owner = ar, - .user_data = mpr->parent_mgroup->parent_mmap, + .user_data = gz->parent_gzgroup->parent_gzmap, .notify = WM_gizmo_do_msg_notify_tag_refresh, }, __func__); } diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c index ba145af9582..2ff0148044c 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c @@ -62,11 +62,11 @@ static GHash *global_gizmotype_hash = NULL; const wmGizmoType *WM_gizmotype_find(const char *idname, bool quiet) { if (idname[0]) { - wmGizmoType *wt; + wmGizmoType *gzt; - wt = BLI_ghash_lookup(global_gizmotype_hash, idname); - if (wt) { - return wt; + gzt = BLI_ghash_lookup(global_gizmotype_hash, idname); + if (gzt) { + return gzt; } if (!quiet) { @@ -90,56 +90,56 @@ void WM_gizmotype_iter(GHashIterator *ghi) static wmGizmoType *wm_gizmotype_append__begin(void) { - wmGizmoType *wt = MEM_callocN(sizeof(wmGizmoType), "gizmotype"); - wt->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_GizmoProperties); + wmGizmoType *gzt = MEM_callocN(sizeof(wmGizmoType), "gizmotype"); + gzt->srna = RNA_def_struct_ptr(&BLENDER_RNA, "", &RNA_GizmoProperties); #if 0 /* Set the default i18n context now, so that opfunc can redefine it if needed! */ RNA_def_struct_translation_context(ot->srna, BLT_I18NCONTEXT_OPERATOR_DEFAULT); ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT; #endif - return wt; + return gzt; } -static void wm_gizmotype_append__end(wmGizmoType *wt) +static void wm_gizmotype_append__end(wmGizmoType *gzt) { - BLI_assert(wt->struct_size >= sizeof(wmGizmo)); + BLI_assert(gzt->struct_size >= sizeof(wmGizmo)); - RNA_def_struct_identifier(&BLENDER_RNA, wt->srna, wt->idname); + RNA_def_struct_identifier(&BLENDER_RNA, gzt->srna, gzt->idname); - BLI_ghash_insert(global_gizmotype_hash, (void *)wt->idname, wt); + BLI_ghash_insert(global_gizmotype_hash, (void *)gzt->idname, gzt); } -void WM_gizmotype_append(void (*wtfunc)(struct wmGizmoType *)) +void WM_gizmotype_append(void (*gtfunc)(struct wmGizmoType *)) { - wmGizmoType *wt = wm_gizmotype_append__begin(); - wtfunc(wt); - wm_gizmotype_append__end(wt); + wmGizmoType *gzt = wm_gizmotype_append__begin(); + gtfunc(gzt); + wm_gizmotype_append__end(gzt); } -void WM_gizmotype_append_ptr(void (*wtfunc)(struct wmGizmoType *, void *), void *userdata) +void WM_gizmotype_append_ptr(void (*gtfunc)(struct wmGizmoType *, void *), void *userdata) { wmGizmoType *mt = wm_gizmotype_append__begin(); - wtfunc(mt, userdata); + gtfunc(mt, userdata); wm_gizmotype_append__end(mt); } /** * Free but don't remove from ghash. */ -static void gizmotype_free(wmGizmoType *wt) +static void gizmotype_free(wmGizmoType *gzt) { - if (wt->ext.srna) { /* python gizmo, allocs own string */ - MEM_freeN((void *)wt->idname); + if (gzt->ext.srna) { /* python gizmo, allocs own string */ + MEM_freeN((void *)gzt->idname); } - BLI_freelistN(&wt->target_property_defs); - MEM_freeN(wt); + BLI_freelistN(&gzt->target_property_defs); + MEM_freeN(gzt); } /** * \param C: May be NULL. */ static void gizmotype_unlink( - bContext *C, Main *bmain, wmGizmoType *wt) + bContext *C, Main *bmain, wmGizmoType *gzt) { /* Free instances. */ for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { @@ -147,15 +147,15 @@ static void gizmotype_unlink( for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { ListBase *lb = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase; for (ARegion *ar = lb->first; ar; ar = ar->next) { - wmGizmoMap *mmap = ar->gizmo_map; - if (mmap) { - wmGizmoGroup *mgroup; - for (mgroup = mmap->groups.first; mgroup; mgroup = mgroup->next) { - for (wmGizmo *mpr = mgroup->gizmos.first, *mpr_next; mpr; mpr = mpr_next) { - mpr_next = mpr->next; - BLI_assert(mgroup->parent_mmap == mmap); - if (mpr->type == wt) { - WM_gizmo_unlink(&mgroup->gizmos, mgroup->parent_mmap, mpr, C); + wmGizmoMap *gzmap = ar->gizmo_map; + if (gzmap) { + wmGizmoGroup *gzgroup; + for (gzgroup = gzmap->groups.first; gzgroup; gzgroup = gzgroup->next) { + for (wmGizmo *gz = gzgroup->gizmos.first, *gz_next; gz; gz = gz_next) { + gz_next = gz->next; + BLI_assert(gzgroup->parent_gzmap == gzmap); + if (gz->type == gzt) { + WM_gizmo_unlink(&gzgroup->gizmos, gzgroup->parent_gzmap, gz, C); ED_region_tag_redraw(ar); } } @@ -167,26 +167,26 @@ static void gizmotype_unlink( } } -void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *wt) +void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt) { - BLI_assert(wt == WM_gizmotype_find(wt->idname, false)); + BLI_assert(gzt == WM_gizmotype_find(gzt->idname, false)); - BLI_ghash_remove(global_gizmotype_hash, wt->idname, NULL, NULL); + BLI_ghash_remove(global_gizmotype_hash, gzt->idname, NULL, NULL); - gizmotype_unlink(C, bmain, wt); + gizmotype_unlink(C, bmain, gzt); - gizmotype_free(wt); + gizmotype_free(gzt); } bool WM_gizmotype_remove(bContext *C, Main *bmain, const char *idname) { - wmGizmoType *wt = BLI_ghash_lookup(global_gizmotype_hash, idname); + wmGizmoType *gzt = BLI_ghash_lookup(global_gizmotype_hash, idname); - if (wt == NULL) { + if (gzt == NULL) { return false; } - WM_gizmotype_remove_ptr(C, bmain, wt); + WM_gizmotype_remove_ptr(C, bmain, gzt); return true; } diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h index 5b1085db4a1..414109e89e5 100644 --- a/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h +++ b/source/blender/windowmanager/gizmo/wm_gizmo_wmapi.h @@ -61,12 +61,12 @@ void wm_gizmogrouptype_init(void); void GIZMOGROUP_OT_gizmo_select(struct wmOperatorType *ot); void GIZMOGROUP_OT_gizmo_tweak(struct wmOperatorType *ot); -bool wm_gizmogroup_is_any_selected(const struct wmGizmoGroup *mgroup); +bool wm_gizmogroup_is_any_selected(const struct wmGizmoGroup *gzgroup); /* -------------------------------------------------------------------- */ /* wmGizmoMap */ -void wm_gizmomap_remove(struct wmGizmoMap *mmap); +void wm_gizmomap_remove(struct wmGizmoMap *gzmap); void wm_gizmos_keymap(struct wmKeyConfig *keyconf); @@ -75,19 +75,19 @@ void wm_gizmomaps_handled_modal_update( void wm_gizmomap_handler_context(bContext *C, struct wmEventHandler *handler); struct wmGizmo *wm_gizmomap_highlight_find( - struct wmGizmoMap *mmap, bContext *C, const struct wmEvent *event, + struct wmGizmoMap *gzmap, bContext *C, const struct wmEvent *event, int *r_part); bool wm_gizmomap_highlight_set( - struct wmGizmoMap *mmap, const bContext *C, - struct wmGizmo *mpr, int part); -struct wmGizmo *wm_gizmomap_highlight_get(struct wmGizmoMap *mmap); + struct wmGizmoMap *gzmap, const bContext *C, + struct wmGizmo *gz, int part); +struct wmGizmo *wm_gizmomap_highlight_get(struct wmGizmoMap *gzmap); void wm_gizmomap_modal_set( - struct wmGizmoMap *mmap, bContext *C, struct wmGizmo *mpr, + struct wmGizmoMap *gzmap, bContext *C, struct wmGizmo *gz, const struct wmEvent *event, bool enable); -struct wmGizmo *wm_gizmomap_modal_get(struct wmGizmoMap *mmap); -struct wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *mmap, int *r_selected_len); -struct ListBase *wm_gizmomap_groups_get(wmGizmoMap *mmap); +struct wmGizmo *wm_gizmomap_modal_get(struct wmGizmoMap *gzmap); +struct wmGizmo **wm_gizmomap_selected_get(wmGizmoMap *gzmap, int *r_selected_len); +struct ListBase *wm_gizmomap_groups_get(wmGizmoMap *gzmap); /* -------------------------------------------------------------------- */ /* wmGizmoMapType */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index bc24b7698e2..e2247b2adff 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2395,8 +2395,8 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers else if (handler->gizmo_map) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - wmGizmoMap *mmap = handler->gizmo_map; - wmGizmo *mpr = wm_gizmomap_highlight_get(mmap); + wmGizmoMap *gzmap = handler->gizmo_map; + wmGizmo *gz = wm_gizmomap_highlight_get(gzmap); if (region->gizmo_map != handler->gizmo_map) { WM_gizmomap_tag_refresh(handler->gizmo_map); @@ -2406,10 +2406,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers wm_region_mouse_co(C, event); /* handle gizmo highlighting */ - if (event->type == MOUSEMOVE && !wm_gizmomap_modal_get(mmap)) { + if (event->type == MOUSEMOVE && !wm_gizmomap_modal_get(gzmap)) { int part; - mpr = wm_gizmomap_highlight_find(mmap, C, event, &part); - if (wm_gizmomap_highlight_set(mmap, C, mpr, part) && mpr != NULL) { + gz = wm_gizmomap_highlight_find(gzmap, C, event, &part); + if (wm_gizmomap_highlight_set(gzmap, C, gz, part) && gz != NULL) { WM_tooltip_timer_init(C, CTX_wm_window(C), region, WM_gizmomap_tooltip_init); } } @@ -2417,45 +2417,45 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers /* Either we operate on a single highlighted item * or groups attached to the selected gizmos. * To simplify things both cases loop over an array of items. */ - wmGizmoGroup *mgroup_first; - bool is_mgroup_single; + wmGizmoGroup *gzgroup_first; + bool is_gzgroup_single; if (ISMOUSE(event->type)) { - /* Keep mpr set as-is, just fake single selection. */ - if (mpr) { - mgroup_first = mpr->parent_mgroup; + /* Keep gz set as-is, just fake single selection. */ + if (gz) { + gzgroup_first = gz->parent_gzgroup; } else { - mgroup_first = NULL; + gzgroup_first = NULL; } - is_mgroup_single = true; + is_gzgroup_single = true; } else { - if (WM_gizmomap_is_any_selected(mmap)) { - const ListBase *groups = WM_gizmomap_group_list(mmap); - mgroup_first = groups->first; + if (WM_gizmomap_is_any_selected(gzmap)) { + const ListBase *groups = WM_gizmomap_group_list(gzmap); + gzgroup_first = groups->first; } else { - mgroup_first = NULL; + gzgroup_first = NULL; } - is_mgroup_single = false; + is_gzgroup_single = false; } /* Don't use from now on. */ - mpr = NULL; + gz = NULL; - for (wmGizmoGroup *mgroup = mgroup_first; mgroup; mgroup = mgroup->next) { + for (wmGizmoGroup *gzgroup = gzgroup_first; gzgroup; gzgroup = gzgroup->next) { /* get user customized keymap from default one */ - if ((is_mgroup_single == false) && + if ((is_gzgroup_single == false) && /* We might want to change the logic here and use some kind of gizmo edit-mode. * For now just use keymap when a selection exists. */ - wm_gizmogroup_is_any_selected(mgroup) == false) + wm_gizmogroup_is_any_selected(gzgroup) == false) { continue; } - wmKeyMap *keymap = WM_keymap_active(wm, mgroup->type->keymap); + wmKeyMap *keymap = WM_keymap_active(wm, gzgroup->type->keymap); wmKeyMapItem *kmi; PRINT("%s: checking '%s' ...", __func__, keymap->idname); @@ -2472,7 +2472,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers /* weak, but allows interactive callback to not use rawkey */ event->keymap_idname = kmi->idname; - CTX_wm_gizmo_group_set(C, mgroup); + CTX_wm_gizmo_group_set(C, gzgroup); /* handler->op is called later, we want keymap op to be triggered here */ handler->op = NULL; @@ -2515,7 +2515,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers break; } - if (is_mgroup_single) { + if (is_gzgroup_single) { break; } } diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index 350327e8590..dcb33376f05 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -132,8 +132,8 @@ static void toolsystem_unlink_ref(bContext *C, WorkSpace *workspace, bToolRef *t bToolRef_Runtime *tref_rt = tref->runtime; if (tref_rt->gizmo_group[0]) { - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false); - if (wgt != NULL) { + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(tref_rt->gizmo_group, false); + if (gzgt != NULL) { bool found = false; /* TODO(campbell) */ @@ -154,8 +154,8 @@ static void toolsystem_unlink_ref(bContext *C, WorkSpace *workspace, bToolRef *t UNUSED_VARS(workspace); #endif if (!found) { - wmGizmoMapType *mmap_type = WM_gizmomaptype_ensure(&wgt->mmap_params); - WM_gizmomaptype_group_unlink(C, bmain, mmap_type, wgt); + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(&gzgt->gzmap_params); + WM_gizmomaptype_group_unlink(C, bmain, gzmap_type, gzgt); } } } @@ -173,9 +173,9 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre bToolRef_Runtime *tref_rt = tref->runtime; if (tref_rt->gizmo_group[0]) { const char *idname = tref_rt->gizmo_group; - wmGizmoGroupType *wgt = WM_gizmogrouptype_find(idname, false); - if (wgt != NULL) { - WM_gizmo_group_type_ensure_ptr(wgt); + wmGizmoGroupType *gzgt = WM_gizmogrouptype_find(idname, false); + if (gzgt != NULL) { + WM_gizmo_group_type_ensure_ptr(gzgt); } else { CLOG_WARN(WM_LOG_TOOLS, "'%s' widget not found", idname); -- cgit v1.2.3 From 57ab7daa2aee436b0b0acfa00b2e2b1d28b55b2c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2018 15:27:15 +0200 Subject: GPU_matrix: use Blender's naming conventions Thanks to @sergey for review --- intern/gawain/gawain/gwn_batch.h | 2 +- intern/gawain/src/gwn_batch.c | 4 +- intern/gawain/src/gwn_immediate.c | 10 +- source/blender/blenfont/intern/blf.c | 12 +-- source/blender/blenfont/intern/blf_font.c | 8 +- .../draw/engines/external/external_engine.c | 4 +- source/blender/draw/intern/draw_manager.c | 18 ++-- source/blender/draw/intern/draw_manager_text.c | 10 +- source/blender/draw/intern/draw_view.c | 16 +-- source/blender/editors/animation/anim_draw.c | 6 +- source/blender/editors/animation/anim_markers.c | 6 +- source/blender/editors/curve/editcurve_paint.c | 14 +-- .../editors/gizmo_library/gizmo_library_presets.c | 12 +-- .../gizmo_library/gizmo_types/arrow2d_gizmo.c | 8 +- .../gizmo_library/gizmo_types/arrow3d_gizmo.c | 22 ++-- .../gizmo_library/gizmo_types/button2d_gizmo.c | 14 +-- .../gizmo_library/gizmo_types/cage2d_gizmo.c | 6 +- .../gizmo_library/gizmo_types/cage3d_gizmo.c | 6 +- .../gizmo_library/gizmo_types/dial3d_gizmo.c | 12 +-- .../gizmo_library/gizmo_types/grab3d_gizmo.c | 16 +-- .../gizmo_library/gizmo_types/primitive3d_gizmo.c | 12 +-- source/blender/editors/interface/interface.c | 12 +-- source/blender/editors/interface/interface_draw.c | 50 ++++----- source/blender/editors/interface/interface_icons.c | 2 +- .../blender/editors/interface/interface_widgets.c | 8 +- source/blender/editors/interface/view2d.c | 2 +- source/blender/editors/mask/mask_draw.c | 22 ++-- source/blender/editors/mesh/editmesh_knife.c | 6 +- source/blender/editors/mesh/editmesh_loopcut.c | 6 +- source/blender/editors/render/render_opengl.c | 2 +- source/blender/editors/screen/area.c | 16 +-- source/blender/editors/screen/glutil.c | 4 +- source/blender/editors/screen/screen_draw.c | 8 +- source/blender/editors/sculpt_paint/paint_cursor.c | 36 +++---- source/blender/editors/sculpt_paint/paint_utils.c | 4 +- source/blender/editors/space_action/action_draw.c | 8 +- source/blender/editors/space_clip/clip_draw.c | 70 ++++++------ .../blender/editors/space_clip/clip_graph_draw.c | 8 +- source/blender/editors/space_clip/space_clip.c | 12 +-- source/blender/editors/space_graph/graph_draw.c | 32 +++--- source/blender/editors/space_image/image_draw.c | 10 +- source/blender/editors/space_node/drawnode.c | 8 +- source/blender/editors/space_node/node_draw.c | 10 +- .../editors/space_sequencer/sequencer_draw.c | 6 +- source/blender/editors/space_view3d/drawobject.c | 4 +- source/blender/editors/space_view3d/space_view3d.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 16 +-- .../editors/space_view3d/view3d_draw_legacy.c | 14 +-- .../space_view3d/view3d_gizmo_navigate_type.c | 26 ++--- .../blender/editors/space_view3d/view3d_project.c | 4 +- .../blender/editors/space_view3d/view3d_select.c | 4 +- source/blender/editors/space_view3d/view3d_utils.c | 4 +- source/blender/editors/space_view3d/view3d_view.c | 6 +- source/blender/editors/transform/transform.c | 40 +++---- .../editors/transform/transform_constraints.c | 8 +- .../blender/editors/transform/transform_generics.c | 4 +- source/blender/editors/uvedit/uvedit_draw.c | 6 +- source/blender/gpu/GPU_matrix.h | 90 ++++++++-------- source/blender/gpu/intern/gpu_matrix.c | 118 ++++++++++----------- source/blender/gpu/intern/gpu_shader.c | 2 +- source/blender/python/intern/gpu_py_matrix.c | 40 +++---- source/blender/windowmanager/intern/wm_operators.c | 18 ++-- source/blender/windowmanager/intern/wm_playanim.c | 16 +-- source/blender/windowmanager/intern/wm_subwindow.c | 8 +- 64 files changed, 495 insertions(+), 495 deletions(-) diff --git a/intern/gawain/gawain/gwn_batch.h b/intern/gawain/gawain/gwn_batch.h index cf7b0c9f1b5..734df3c91b6 100644 --- a/intern/gawain/gawain/gwn_batch.h +++ b/intern/gawain/gawain/gwn_batch.h @@ -119,7 +119,7 @@ void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4] void GWN_batch_draw(Gwn_Batch*); -// This does not bind/unbind shader and does not call gpuBindMatrices() +// This does not bind/unbind shader and does not call GPU_matrix_bind() void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance); // Does not even need batch diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c index 62342cfc42f..4979d93b15e 100644 --- a/intern/gawain/src/gwn_batch.c +++ b/intern/gawain/src/gwn_batch.c @@ -18,7 +18,7 @@ #include // necessary functions from matrix API -extern void gpuBindMatrices(const Gwn_ShaderInterface* shaderface); +extern void GPU_matrix_bind(const Gwn_ShaderInterface* shaderface); static void batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first); @@ -537,7 +537,7 @@ void GWN_batch_draw(Gwn_Batch* batch) assert(batch->verts[0]->vbo_id != 0); #endif GWN_batch_program_use_begin(batch); - gpuBindMatrices(batch->interface); // external call. + GPU_matrix_bind(batch->interface); // external call. GWN_batch_draw_range_ex(batch, 0, 0, false); diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c index d43e52cc525..f6760b0e9da 100644 --- a/intern/gawain/src/gwn_immediate.c +++ b/intern/gawain/src/gwn_immediate.c @@ -19,8 +19,8 @@ #include // necessary functions from matrix API -extern void gpuBindMatrices(const Gwn_ShaderInterface*); -extern bool gpuMatricesDirty(void); +extern void GPU_matrix_bind(const Gwn_ShaderInterface*); +extern bool GPU_matrix_dirty_get(void); typedef struct { // TODO: organize this struct by frequency of change (run-time) @@ -129,7 +129,7 @@ void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) glUseProgram(program); get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface); - gpuBindMatrices(shaderface); + GPU_matrix_bind(shaderface); } void immUnbindProgram(void) @@ -341,8 +341,8 @@ static void immDrawSetup(void) } } - if (gpuMatricesDirty()) - gpuBindMatrices(imm.shader_interface); + if (GPU_matrix_dirty_get()) + GPU_matrix_bind(imm.shader_interface); } void immEnd(void) diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 5dd692d3855..b0e0cdac407 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -594,24 +594,24 @@ static void blf_draw_gl__start(FontBLF *font) if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0) return; /* glyphs will be translated individually and batched. */ - gpuPushMatrix(); + GPU_matrix_push(); if (font->flags & BLF_MATRIX) - gpuMultMatrix(font->m); + GPU_matrix_mul(font->m); - gpuTranslate3fv(font->pos); + GPU_matrix_translate_3fv(font->pos); if (font->flags & BLF_ASPECT) - gpuScale3fv(font->aspect); + GPU_matrix_scale_3fv(font->aspect); if (font->flags & BLF_ROTATION) - gpuRotate2D(RAD2DEG(font->angle)); + GPU_matrix_rotate_2d(RAD2DEG(font->angle)); } static void blf_draw_gl__end(FontBLF *font) { if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) != 0) - gpuPopMatrix(); + GPU_matrix_pop(); } void BLF_draw_ex( diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index b3ab36f7bcc..3f4c430ee4b 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -142,15 +142,15 @@ void blf_batch_draw_begin(FontBLF *font) if (g_batch.active) { float gpumat[4][4]; - gpuGetModelViewMatrix(gpumat); + GPU_matrix_model_view_get(gpumat); bool mat_changed = (memcmp(gpumat, g_batch.mat, sizeof(g_batch.mat)) != 0); if (mat_changed) { /* Modelviewmat is no longer the same. * Flush cache but with the previous mat. */ - gpuPushMatrix(); - gpuLoadMatrix(g_batch.mat); + GPU_matrix_push(); + GPU_matrix_set(g_batch.mat); } /* flush cache if config is not the same. */ @@ -165,7 +165,7 @@ void blf_batch_draw_begin(FontBLF *font) } if (mat_changed) { - gpuPopMatrix(); + GPU_matrix_pop(); /* Save for next memcmp. */ memcpy(g_batch.mat, gpumat, sizeof(g_batch.mat)); } diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 2917805d233..35ff777b885 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -165,14 +165,14 @@ static void external_draw_scene_do(void *vedata) } /* Rendered draw. */ - gpuPushProjectionMatrix(); + GPU_matrix_push_projection(); ED_region_pixelspace(ar); /* Render result draw. */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, draw_ctx->evil_C); - gpuPopProjectionMatrix(); + GPU_matrix_pop_projection(); /* Set render info. */ EXTERNAL_Data *data = vedata; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index a16d0bab104..1460f9a88f2 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -120,16 +120,16 @@ void DRW_draw_callbacks_pre_scene(void) { RegionView3D *rv3d = DST.draw_ctx.rv3d; - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); } void DRW_draw_callbacks_post_scene(void) { RegionView3D *rv3d = DST.draw_ctx.rv3d; - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); } struct DRWTextStore *DRW_text_cache_ensure(void) @@ -2074,18 +2074,18 @@ void DRW_draw_depth_loop( DRW_opengl_context_disable(); /* XXX Drawing the resulting buffer to the BACK_BUFFER */ - gpuPushMatrix(); - gpuPushProjectionMatrix(); + GPU_matrix_push(); + GPU_matrix_push_projection(); wmOrtho2_region_pixelspace(ar); - gpuLoadIdentity(); + GPU_matrix_identity_set(); glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */ glDepthFunc(GL_ALWAYS); draw_depth_texture_to_screen(g_select_buffer.texture_depth); glDepthFunc(GL_LEQUAL); - gpuPopMatrix(); - gpuPopProjectionMatrix(); + GPU_matrix_pop(); + GPU_matrix_pop_projection(); } /** \} */ diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c index 977374a00c5..b32853959c8 100644 --- a/source/blender/draw/intern/draw_manager_text.c +++ b/source/blender/draw/intern/draw_manager_text.c @@ -141,11 +141,11 @@ void DRW_text_cache_draw(DRWTextStore *dt, ARegion *ar) } float original_proj[4][4]; - gpuGetProjectionMatrix(original_proj); + GPU_matrix_projection_get(original_proj); wmOrtho2_region_pixelspace(ar); - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push(); + GPU_matrix_identity_set(); const int font_id = BLF_default(); @@ -173,8 +173,8 @@ void DRW_text_cache_draw(DRWTextStore *dt, ARegion *ar) } } - gpuPopMatrix(); - gpuLoadProjectionMatrix(original_proj); + GPU_matrix_pop(); + GPU_matrix_projection_set(original_proj); if (rv3d->rflag & RV3D_CLIPPING) { ED_view3d_clipping_enable(); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 75a7d567d5c..688712a97b6 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -548,8 +548,8 @@ void DRW_draw_grid(void) *(&grid_unit) = NULL; /* drawgrid need this to detect/affect smallest valid unit... */ drawgrid(&scene->unit, ar, v3d, &grid_unit); - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); } else { glDepthMask(GL_TRUE); @@ -587,9 +587,9 @@ void DRW_draw_background(void) uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); uchar col_hi[3], col_lo[3]; - gpuPushMatrix(); - gpuLoadIdentity(); - gpuLoadProjectionMatrix(m); + GPU_matrix_push(); + GPU_matrix_identity_set(); + GPU_matrix_projection_set(m); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER); @@ -608,7 +608,7 @@ void DRW_draw_background(void) immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -724,8 +724,8 @@ void DRW_draw_cursor(void) } ED_region_pixelspace(ar); - gpuTranslate2f(co[0] + 0.5f, co[1] + 0.5f); - gpuScale2f(U.widget_unit, U.widget_unit); + GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); + GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); Gwn_Batch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 51ba7d9c269..129cf07b7c4 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -87,8 +87,8 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag) /* because the frame number text is subject to the same scaling as the contents of the view */ UI_view2d_scale_get(v2d, &xscale, NULL); - gpuPushMatrix(); - gpuScale2f(1.0f / xscale, 1.0f); + GPU_matrix_push(); + GPU_matrix_scale_2f(1.0f / xscale, 1.0f); /* get timecode string * - padding on str-buf passed so that it doesn't sit on the frame indicator @@ -128,7 +128,7 @@ void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag) numstr, col); /* restore view transform */ - gpuPopMatrix(); + GPU_matrix_pop(); } /* General call for drawing current frame indicator in animation editor */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index c5f7782dcee..f809bff536f 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -505,8 +505,8 @@ void ED_markers_draw(const bContext *C, int flag) /* no time correction for framelen! space is drawn with old values */ ypixels = BLI_rcti_size_y(&v2d->mask); UI_view2d_scale_get(v2d, &xscale, &yscale); - gpuPushMatrix(); - gpuScale2f(1.0f / xscale, 1.0f); + GPU_matrix_push(); + GPU_matrix_scale_2f(1.0f / xscale, 1.0f); /* x-bounds with offset for text (adjust for long string, avoid checking string width) */ font_width_max = (10 * UI_DPI_FAC) / xscale; @@ -529,7 +529,7 @@ void ED_markers_draw(const bContext *C, int flag) } } - gpuPopMatrix(); + GPU_matrix_pop(); } /* ************************ Marker Wrappers API ********************* */ diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 90f9b2e0569..130e3cc5475 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -392,12 +392,12 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS GWN_batch_uniform_3fv(sphere, "color", color); /* scale to edit-mode space */ - gpuPushMatrix(); - gpuMultMatrix(obedit->obmat); + GPU_matrix_push(); + GPU_matrix_mul(obedit->obmat); BLI_mempool_iternew(cdd->stroke_elem_pool, &iter); for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) { - gpuTranslate3f( + GPU_matrix_translate_3f( selem->location_local[0] - location_prev[0], selem->location_local[1] - location_prev[1], selem->location_local[2] - location_prev[2]); @@ -405,15 +405,15 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS const float radius = stroke_elem_radius(cdd, selem); - gpuPushMatrix(); - gpuScaleUniform(radius); + GPU_matrix_push(); + GPU_matrix_scale_1f(radius); GWN_batch_draw(sphere); - gpuPopMatrix(); + GPU_matrix_pop(); location_prev = selem->location_local; } - gpuPopMatrix(); + GPU_matrix_pop(); } if (stroke_len > 1) { diff --git a/source/blender/editors/gizmo_library/gizmo_library_presets.c b/source/blender/editors/gizmo_library/gizmo_library_presets.c index e16f8ed21bf..ab92905192b 100644 --- a/source/blender/editors/gizmo_library/gizmo_library_presets.c +++ b/source/blender/editors/gizmo_library/gizmo_library_presets.c @@ -94,10 +94,10 @@ static void ed_gizmo_draw_preset_geometry( GPU_select_load_id(select_id); } - gpuPushMatrix(); - gpuMultMatrix(mat); + GPU_matrix_push(); + GPU_matrix_mul(mat); wm_gizmo_geometryinfo_draw(info, is_select, color); - gpuPopMatrix(); + GPU_matrix_pop(); if (is_select) { GPU_select_load_id(-1); @@ -139,10 +139,10 @@ void ED_gizmo_draw_preset_facemap( GPU_select_load_id(select_id); } - gpuPushMatrix(); - gpuMultMatrix(ob->obmat); + GPU_matrix_push(); + GPU_matrix_mul(ob->obmat); ED_draw_object_facemap(CTX_data_depsgraph(C), scene, ob, color, facemap); - gpuPopMatrix(); + GPU_matrix_pop(); if (is_select) { GPU_select_load_id(-1); diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c index 0faeeefb4a3..673e38e4a1a 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c @@ -72,9 +72,9 @@ static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - gpuPushMatrix(); - gpuMultMatrix(matrix); - gpuRotate2D(RAD2DEGF(arrow_angle)); + GPU_matrix_push(); + GPU_matrix_mul(matrix); + GPU_matrix_rotate_2d(RAD2DEGF(arrow_angle)); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -93,7 +93,7 @@ static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); } static void gizmo_arrow2d_draw(const bContext *UNUSED(C), wmGizmo *gz) diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index 09c6485c29e..da4bce680b8 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -143,15 +143,15 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const /* *** draw arrow head *** */ - gpuPushMatrix(); + GPU_matrix_push(); if (draw_style == ED_GIZMO_ARROW_STYLE_BOX) { const float size = 0.05f; /* translate to line end with some extra offset so box starts exactly where line ends */ - gpuTranslate3f(0.0f, 0.0f, arrow_length + size); + GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length + size); /* scale down to box size */ - gpuScale3f(size, size, size); + GPU_matrix_scale_3f(size, size, size); /* draw cube */ immUnbindProgram(); @@ -165,13 +165,13 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const const float width = 0.06f; /* translate to line end */ - gpuTranslate3f(0.0f, 0.0f, arrow_length); + GPU_matrix_translate_3f(0.0f, 0.0f, arrow_length); imm_draw_circle_fill_3d(pos, 0.0, 0.0, width, 8); imm_draw_cylinder_fill_3d(pos, width, 0.0, len, 8, 1); } - gpuPopMatrix(); + GPU_matrix_pop(); #endif /* USE_GIZMO_CUSTOM_ARROWS */ } @@ -190,26 +190,26 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool WM_gizmo_calc_matrix_final(gz, matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); GPU_blend(true); arrow_draw_geom(arrow, select, color); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); if (gz->interaction_data) { GizmoInteraction *inter = gz->interaction_data; - gpuPushMatrix(); - gpuMultMatrix(inter->init_matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(inter->init_matrix_final); GPU_blend(true); arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index dfe2c8b2413..13711325038 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -150,8 +150,8 @@ static void button2d_draw_intern( } bool need_to_pop = true; - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); if (is_3d) { RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -161,7 +161,7 @@ static void button2d_draw_intern( mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit); zero_v3(matrix_align[3]); transpose_m4(matrix_align); - gpuMultMatrix(matrix_align); + GPU_matrix_mul(matrix_align); } if (select) { @@ -195,15 +195,15 @@ static void button2d_draw_intern( float size[2]; if (is_3d) { const float fac = 2.0f; - gpuTranslate2f(-(fac / 2), -(fac / 2)); - gpuScale2f(fac / (ICON_DEFAULT_WIDTH * UI_DPI_FAC), fac / (ICON_DEFAULT_HEIGHT * UI_DPI_FAC)); + GPU_matrix_translate_2f(-(fac / 2), -(fac / 2)); + GPU_matrix_scale_2f(fac / (ICON_DEFAULT_WIDTH * UI_DPI_FAC), fac / (ICON_DEFAULT_HEIGHT * UI_DPI_FAC)); size[0] = 1.0f; size[1] = 1.0f; } else { size[0] = gz->matrix_basis[3][0] - (ICON_DEFAULT_WIDTH / 2.0) * UI_DPI_FAC; size[1] = gz->matrix_basis[3][1] - (ICON_DEFAULT_HEIGHT / 2.0) * UI_DPI_FAC; - gpuPopMatrix(); + GPU_matrix_pop(); need_to_pop = false; } UI_icon_draw(size[0], size[1], button->icon); @@ -212,7 +212,7 @@ static void button2d_draw_intern( } if (need_to_pop) { - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 8a830302f51..5e3b7bb21c6 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -551,8 +551,8 @@ static void gizmo_cage2d_draw_intern( WM_gizmo_calc_matrix_final(gz, matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); float margin[2]; gizmo_calc_rect_view_margin(gz, dims, margin); @@ -668,7 +668,7 @@ static void gizmo_cage2d_draw_intern( } GPU_line_width(1.0); - gpuPopMatrix(); + GPU_matrix_pop(); } /** diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index c3fb5a08cdb..9cad82619ba 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -296,8 +296,8 @@ static void gizmo_cage3d_draw_intern( WM_gizmo_calc_matrix_final(gz, matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); float margin[3]; gizmo_calc_rect_view_margin(gz, dims, margin); @@ -412,7 +412,7 @@ static void gizmo_cage3d_draw_intern( } GPU_line_width(1.0); - gpuPopMatrix(); + GPU_matrix_pop(); } /** diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c index b45f3d8a242..300ae222189 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c @@ -161,8 +161,8 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[ { GPU_line_width(1.0f); - gpuPushMatrix(); - gpuRotate3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f); + GPU_matrix_push(); + GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); @@ -177,7 +177,7 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[ immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); } static void dial_ghostarc_draw( @@ -292,8 +292,8 @@ static void dial_draw_intern( .matrix_basis = (void *)matrix_basis_adjust, }), matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); /* draw rotation indicator arc first */ if ((gz->flag & WM_GIZMO_DRAW_VALUE) && @@ -335,7 +335,7 @@ static void dial_draw_intern( /* draw actual dial gizmo */ dial_geom_draw(gz, color, select, matrix_basis_adjust, clip_plane); - gpuPopMatrix(); + GPU_matrix_pop(); } static void gizmo_dial_draw_select(const bContext *C, wmGizmo *gz, int select_id) diff --git a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c index c6d11347e9f..840ea793b89 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c @@ -176,8 +176,8 @@ static void grab3d_draw_intern( gizmo_color_get(gz, highlight, color); WM_gizmo_calc_matrix_final(gz, matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); if (align_view) { float matrix_final_unit[4][4]; @@ -186,26 +186,26 @@ static void grab3d_draw_intern( mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit); zero_v3(matrix_align[3]); transpose_m4(matrix_align); - gpuMultMatrix(matrix_align); + GPU_matrix_mul(matrix_align); } GPU_blend(true); grab_geom_draw(gz, color, select, draw_options); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); if (gz->interaction_data) { - gpuPushMatrix(); - gpuMultMatrix(inter->init_matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(inter->init_matrix_final); if (align_view) { - gpuMultMatrix(matrix_align); + GPU_matrix_mul(matrix_align); } GPU_blend(true); grab_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c index be2bf7d2c56..b61c16b8d65 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c @@ -99,14 +99,14 @@ static void gizmo_primitive_draw_intern( WM_gizmo_calc_matrix_final(gz, matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); GPU_blend(true); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); if (gz->interaction_data) { GizmoInteraction *inter = gz->interaction_data; @@ -115,14 +115,14 @@ static void gizmo_primitive_draw_intern( copy_v3_fl(color_outer, 0.5f); color_outer[3] = 0.8f; - gpuPushMatrix(); - gpuMultMatrix(inter->init_matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(inter->init_matrix_final); GPU_blend(true); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3e01c5f356f..37c56d454bb 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -280,7 +280,7 @@ static void ui_update_window_matrix(const wmWindow *window, const ARegion *regio /* window matrix and aspect */ if (region && region->visible) { /* Get projection matrix which includes View2D translation and zoom. */ - gpuGetProjectionMatrix(block->winmat); + GPU_matrix_projection_get(block->winmat); block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]); } else { @@ -1448,9 +1448,9 @@ void UI_block_draw(const bContext *C, uiBlock *block) ui_but_to_pixelrect(&rect, ar, block, NULL); /* pixel space for AA widgets */ - gpuPushProjectionMatrix(); - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push_projection(); + GPU_matrix_push(); + GPU_matrix_identity_set(); wmOrtho2_region_pixelspace(ar); @@ -1485,8 +1485,8 @@ void UI_block_draw(const bContext *C, uiBlock *block) BLF_batch_draw_end(); /* restore matrix */ - gpuPopProjectionMatrix(); - gpuPopMatrix(); + GPU_matrix_pop_projection(); + GPU_matrix_pop(); } static void ui_block_message_subscribe(ARegion *ar, struct wmMsgBus *mbus, uiBlock *block) diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 51f2c7e8ece..b1c3795b1af 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1027,13 +1027,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) { float col[3] = {alpha, alpha, alpha}; - gpuPushMatrix(); - gpuTranslate2f(rect.xmin, yofs); - gpuScale2f(w, h); + GPU_matrix_push(); + GPU_matrix_translate_2f(rect.xmin, yofs); + GPU_matrix_scale_2f(w, h); waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col); - gpuPopMatrix(); + GPU_matrix_pop(); /* min max */ immUniformColor3f(0.5f, 0.5f, 0.5f); @@ -1049,15 +1049,15 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE } /* RGB (3 channel) */ else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) { - gpuPushMatrix(); - gpuTranslate2f(rect.xmin, yofs); - gpuScale2f(w, h); + GPU_matrix_push(); + GPU_matrix_translate_2f(rect.xmin, yofs); + GPU_matrix_scale_2f(w, h); waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]); waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]); waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]); - gpuPopMatrix(); + GPU_matrix_pop(); } /* PARADE / YCC (3 channels) */ else if (ELEM(scopes->wavefrm_mode, @@ -1069,19 +1069,19 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE { int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE); - gpuPushMatrix(); - gpuTranslate2f(rect.xmin, yofs); - gpuScale2f(w3, h); + GPU_matrix_push(); + GPU_matrix_translate_2f(rect.xmin, yofs); + GPU_matrix_scale_2f(w3, h); waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]); - gpuTranslate2f(1.0f, 0.0f); + GPU_matrix_translate_2f(1.0f, 0.0f); waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]); - gpuTranslate2f(1.0f, 0.0f); + GPU_matrix_translate_2f(1.0f, 0.0f); waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]); - gpuPopMatrix(); + GPU_matrix_pop(); } /* min max */ @@ -1263,13 +1263,13 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN glBlendFunc(GL_ONE, GL_ONE); GPU_point_size(1.0); - gpuPushMatrix(); - gpuTranslate2f(centerx, centery); - gpuScaleUniform(diam); + GPU_matrix_push(); + GPU_matrix_translate_2f(centerx, centery); + GPU_matrix_scale_1f(diam); waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col); - gpuPopMatrix(); + GPU_matrix_pop(); } immUnbindProgram(); @@ -1548,15 +1548,15 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect) ui_but_v3_get(but, light); /* transform to button */ - gpuPushMatrix(); + GPU_matrix_push(); if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect)) size = 0.5f * BLI_rcti_size_x(rect); else size = 0.5f * BLI_rcti_size_y(rect); - gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect)); - gpuScaleUniform(size); + GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect)); + GPU_matrix_scale_1f(size); Gwn_Batch *sphere = GPU_batch_preset_sphere(2); GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); @@ -1580,7 +1580,7 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect) GPU_line_smooth(false); /* matrix after circle */ - gpuPopMatrix(); + GPU_matrix_pop(); immUnbindProgram(); } @@ -1900,7 +1900,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U } if (!ok && scopes->track_preview) { - gpuPushMatrix(); + GPU_matrix_push(); /* draw content of pattern area */ GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]); @@ -1919,7 +1919,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U immDrawPixelsTex(&state, rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, drawibuf->rect, 1.0f, 1.0f, NULL); /* draw cross for pixel position */ - gpuTranslate2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]); + GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]); GPU_scissor( rect.xmin, rect.ymin, @@ -1958,7 +1958,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U immUnbindProgram(); } - gpuPopMatrix(); + GPU_matrix_pop(); ok = true; } diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 62413e2434c..b9183461b4c 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1292,7 +1292,7 @@ static void icon_draw_texture_cached( { float mvp[4][4]; - gpuGetModelViewProjectionMatrix(mvp); + GPU_matrix_model_view_projection_get(mvp); IconDrawCall *call = &g_icon_draw_cache.drawcall_cache[g_icon_draw_cache.calls]; g_icon_draw_cache.calls++; diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index fea88388be7..aa3106b135b 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1110,7 +1110,7 @@ void UI_widgetbase_draw_cache_flush(void) GWN_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, (float *)g_widget_base_batch.params); GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); - gpuBindMatrices(batch->interface); + GPU_matrix_bind(batch->interface); GWN_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true); GWN_batch_program_use_end(batch); } @@ -4532,8 +4532,8 @@ void ui_draw_pie_center(uiBlock *block) float angle = atan2f(pie_dir[1], pie_dir[0]); float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4; - gpuPushMatrix(); - gpuTranslate2f(cx, cy); + GPU_matrix_push(); + GPU_matrix_translate_2f(cx, cy); GPU_blend(true); if (btheme->tui.wcol_pie_menu.shaded) { @@ -4579,7 +4579,7 @@ void ui_draw_pie_center(uiBlock *block) } GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); } diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 1b449877abe..7d9eb1181ed 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1151,7 +1151,7 @@ void UI_view2d_view_restore(const bContext *C) int height = BLI_rcti_size_y(&ar->winrct) + 1; wmOrtho2(0.0f, (float)width, 0.0f, (float)height); - gpuLoadIdentity(); + GPU_matrix_identity_set(); // ED_region_pixelspace(CTX_wm_region(C)); } diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 4717ef309f3..14cec724168 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -695,17 +695,17 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, GPU_blend_set_func(GPU_DST_COLOR, GPU_ZERO); } - gpuPushMatrix(); - gpuTranslate2f(x, y); - gpuScale2f(zoomx, zoomy); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); if (stabmat) { - gpuMultMatrix(stabmat); + GPU_matrix_mul(stabmat); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_uniform_vector(state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL); - gpuPopMatrix(); + GPU_matrix_pop(); if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { GPU_blend(false); @@ -715,13 +715,13 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, } /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ - gpuPushMatrix(); - gpuTranslate2f(x + xofs, y + yofs); - gpuScale2f(zoomx, zoomy); + GPU_matrix_push(); + GPU_matrix_translate_2f(x + xofs, y + yofs); + GPU_matrix_scale_2f(zoomx, zoomy); if (stabmat) { - gpuMultMatrix(stabmat); + GPU_matrix_mul(stabmat); } - gpuScale2f(maxdim, maxdim); + GPU_matrix_scale_2f(maxdim, maxdim); if (do_draw_cb) { ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); @@ -734,7 +734,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); } - gpuPopMatrix(); + GPU_matrix_pop(); } void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra, const int efra) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 8a9a5eadbdd..a2717e53358 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1045,8 +1045,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void glPolygonOffset(1.0f, 1.0f); - gpuPushMatrix(); - gpuMultMatrix(kcd->ob->obmat); + GPU_matrix_push(); + GPU_matrix_mul(kcd->ob->obmat); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); @@ -1193,7 +1193,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); /* Reset default */ GPU_depth_test(true); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 87c006095ed..9a58f1dcd08 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -113,8 +113,8 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a if ((lcd->totedge > 0) || (lcd->totpoint > 0)) { GPU_depth_test(false); - gpuPushMatrix(); - gpuMultMatrix(lcd->ob->obmat); + GPU_matrix_push(); + GPU_matrix_mul(lcd->ob->obmat); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); @@ -146,7 +146,7 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); /* Reset default */ GPU_depth_test(true); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index b5c1ffc64dd..1b8d8cf7af2 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -326,7 +326,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); wmOrtho2(0, sizex, 0, sizey); - gpuTranslate2f(sizex / 2, sizey / 2); + GPU_matrix_translate_2f(sizex / 2, sizey / 2); G.f |= G_RENDER_OGL; ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 41c3209dbb1..cb8fdba0ae1 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -146,7 +146,7 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides) void ED_region_pixelspace(ARegion *ar) { wmOrtho2_region_pixelspace(ar); - gpuLoadIdentity(); + GPU_matrix_identity_set(); } /* only exported for WM */ @@ -352,8 +352,8 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - gpuPushMatrix(); - gpuTranslate2f(-ar->winrct.xmin, -ar->winrct.ymin); + GPU_matrix_push(); + GPU_matrix_translate_2f(-ar->winrct.xmin, -ar->winrct.ymin); for (az = sa->actionzones.first; az; az = az->next) { /* test if action zone is over this region */ @@ -388,7 +388,7 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } } - gpuPopMatrix(); + GPU_matrix_pop(); GPU_blend(false); } @@ -2674,11 +2674,11 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, return; /* find window pixel coordinates of origin */ - gpuPushMatrix(); + GPU_matrix_push(); /* offset and zoom using ogl */ - gpuTranslate2f(x, y); - gpuScale2f(zoomx, zoomy); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi); @@ -2732,7 +2732,7 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, BLF_disable(blf_mono_font, BLF_CLIPPING); } - gpuPopMatrix(); + GPU_matrix_pop(); } void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 6cff82295f0..41404aee9c9 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -364,7 +364,7 @@ void bglPolygonOffset(float viewdist, float dist) // glPolygonOffset(-1.0, -1.0); /* hack below is to mimic polygon offset */ - gpuGetProjectionMatrix(winmat); + GPU_matrix_projection_get(winmat); /* dist is from camera to center point */ @@ -401,7 +401,7 @@ void bglPolygonOffset(float viewdist, float dist) offset = 0.0; } - gpuLoadProjectionMatrix(winmat); + GPU_matrix_projection_set(winmat); } /* **** Color management helper functions for GLSL display/transform ***** */ diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 9c46938a90f..6e512d6d4df 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -627,14 +627,14 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) wmOrtho2(0.0f, size_x, 0.0f, size_y); /* center */ - gpuPushMatrix(); - gpuLoadIdentity(); - gpuTranslate2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f); + GPU_matrix_push(); + GPU_matrix_identity_set(); + GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f); screen_preview_scale_get(screen, size_x, size_y, asp, scale); screen_preview_draw_areas(screen, scale, col, 1.5f); - gpuPopMatrix(); + GPU_matrix_pop(); } /** diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 6b3c358d2ac..e1de86910ff 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -618,19 +618,19 @@ static void paint_draw_tex_overlay( glDepthFunc(GL_ALWAYS); if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { - gpuPushMatrix(); + GPU_matrix_push(); /* brush rotation */ - gpuTranslate2f(x, y); - gpuRotate2D(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec)); - gpuTranslate2f(-x, -y); + GPU_matrix_translate_2f(x, y); + GPU_matrix_rotate_2d(-RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec)); + GPU_matrix_translate_2f(-x, -y); /* scale based on tablet pressure */ if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { const float scale = ups->size_pressure_value; - gpuTranslate2f(x, y); - gpuScale2f(scale, scale); - gpuTranslate2f(-x, -y); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(scale, scale); + GPU_matrix_translate_2f(-x, -y); } if (ups->draw_anchored) { @@ -671,12 +671,12 @@ static void paint_draw_tex_overlay( quad.xmax = brush->mask_stencil_dimension[0]; quad.ymax = brush->mask_stencil_dimension[1]; } - gpuPushMatrix(); + GPU_matrix_push(); if (primary) - gpuTranslate2fv(brush->stencil_pos); + GPU_matrix_translate_2fv(brush->stencil_pos); else - gpuTranslate2fv(brush->mask_stencil_pos); - gpuRotate2D(RAD2DEGF(mtex->rot)); + GPU_matrix_translate_2fv(brush->mask_stencil_pos); + GPU_matrix_rotate_2d(RAD2DEGF(mtex->rot)); } /* set quad color. Colored overlay does not get blending */ @@ -710,7 +710,7 @@ static void paint_draw_tex_overlay( immUnbindProgram(); if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) { - gpuPopMatrix(); + GPU_matrix_pop(); } } } @@ -762,11 +762,11 @@ static void paint_draw_cursor_overlay( /* scale based on tablet pressure */ if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { do_pop = true; - gpuPushMatrix(); - gpuLoadIdentity(); - gpuTranslate2fv(center); - gpuScaleUniform(ups->size_pressure_value); - gpuTranslate2f(-center[0], -center[1]); + GPU_matrix_push(); + GPU_matrix_identity_set(); + GPU_matrix_translate_2fv(center); + GPU_matrix_scale_1f(ups->size_pressure_value); + GPU_matrix_translate_2f(-center[0], -center[1]); } Gwn_VertFormat *format = immVertexFormat(); @@ -796,7 +796,7 @@ static void paint_draw_cursor_overlay( immUnbindProgram(); if (do_pop) - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 697ffc32759..e914a24092e 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -299,8 +299,8 @@ static void imapaint_pick_uv(Mesh *me_eval, Scene *scene, Object *ob_eval, unsig /* get the needed opengl matrices */ GPU_viewport_size_get_i(view); - gpuGetModelViewMatrix(matrix); - gpuGetProjectionMatrix(proj); + GPU_matrix_model_view_get(matrix); + GPU_matrix_projection_get(proj); view[0] = view[1] = 0; mul_m4_m4m4(matrix, matrix, ob_eval->obmat); mul_m4_m4m4(matrix, proj, matrix); diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 8e521c997fd..6ebb04fafc4 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -436,9 +436,9 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) if (pid->cache->cached_frames == NULL) continue; - gpuPushMatrix(); - gpuTranslate2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs); - gpuScale2f(1.0, cache_draw_height); + GPU_matrix_push(); + GPU_matrix_translate_2f(0.0, (float)V2D_SCROLL_HEIGHT_TEXT + yoffs); + GPU_matrix_scale_2f(1.0, cache_draw_height); switch (pid->type) { case PTCACHE_TYPE_SOFTBODY: @@ -512,7 +512,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); yoffs += cache_draw_height; } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 164565192fd..29bc0543426 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -356,11 +356,11 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); - gpuPushMatrix(); - gpuTranslate2f(x, y); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); - gpuScale2f(zoomx, zoomy); - gpuMultMatrix(sc->stabmat); + GPU_matrix_scale_2f(zoomx, zoomy); + GPU_matrix_mul(sc->stabmat); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -377,7 +377,7 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); glDisable(GL_COLOR_LOGIC_OP); } @@ -603,8 +603,8 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT } /* pattern and search outline */ - gpuPushMatrix(); - gpuTranslate2fv(marker_pos); + GPU_matrix_push(); + GPU_matrix_translate_2fv(marker_pos); if (sc->flag & SC_SHOW_MARKER_PATTERN) { immBegin(GWN_PRIM_LINE_LOOP, 4); @@ -625,7 +625,7 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT marker->search_max[1]); } - gpuPopMatrix(); + GPU_matrix_pop(); } static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3]) @@ -745,8 +745,8 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } /* pattern */ - gpuPushMatrix(); - gpuTranslate2fv(marker_pos); + GPU_matrix_push(); + GPU_matrix_translate_2fv(marker_pos); if (track->flag & TRACK_LOCKED) { if (act) { @@ -800,7 +800,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra marker->search_max[0], marker->search_max[1]); } - gpuPopMatrix(); + GPU_matrix_pop(); /* Restore default shader */ immUnbindProgram(); @@ -884,8 +884,8 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo immUniformThemeColor(TH_MARKER_OUTLINE); } - gpuPushMatrix(); - gpuTranslate2fv(marker_pos); + GPU_matrix_push(); + GPU_matrix_translate_2fv(marker_pos); dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; @@ -944,7 +944,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px, pos); } - gpuPopMatrix(); + GPU_matrix_pop(); } static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, @@ -1141,8 +1141,8 @@ static void draw_plane_marker_image(Scene *scene, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); - gpuPushMatrix(); - gpuMultMatrix(gl_matrix); + GPU_matrix_push(); + GPU_matrix_mul(gl_matrix); Gwn_VertFormat *imm_format = immVertexFormat(); uint pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -1170,7 +1170,7 @@ static void draw_plane_marker_image(Scene *scene, immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); glBindTexture(GL_TEXTURE_2D, 0); @@ -1342,13 +1342,13 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); - gpuPushMatrix(); - gpuTranslate2f(x, y); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); - gpuPushMatrix(); - gpuScale2f(zoomx, zoomy); - gpuMultMatrix(sc->stabmat); - gpuScale2f(width, height); + GPU_matrix_push(); + GPU_matrix_scale_2f(zoomx, zoomy); + GPU_matrix_mul(sc->stabmat); + GPU_matrix_scale_2f(width, height); act_track = BKE_tracking_track_get_active(tracking); @@ -1539,7 +1539,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); if (sc->flag & SC_SHOW_NAMES) { /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ @@ -1565,7 +1565,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie } } - gpuPopMatrix(); + GPU_matrix_pop(); if (marker_pos) MEM_freeN(marker_pos); @@ -1592,11 +1592,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y); - gpuPushMatrix(); - gpuTranslate2f(x, y); - gpuScale2f(zoomx, zoomy); - gpuMultMatrix(sc->stabmat); - gpuScale2f(width, height); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); + GPU_matrix_mul(sc->stabmat); + GPU_matrix_scale_2f(width, height); uint position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -1774,7 +1774,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); } void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar) @@ -1871,8 +1871,8 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) * associated with the clip is already drawn in draw_distortion */ if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) { - gpuPushMatrix(); - gpuMultMatrix(sc->unistabmat); + GPU_matrix_push(); + GPU_matrix_mul(sc->unistabmat); if (is_track_source) { MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking); @@ -1881,13 +1881,13 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - gpuTranslate2fv(marker->pos); + GPU_matrix_translate_2fv(marker->pos); } } ED_gpencil_draw_2dimage(C); - gpuPopMatrix(); + GPU_matrix_pop(); } } else { diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 34720b3a627..0bc9c74cd8c 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -119,13 +119,13 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, if (sel == data->sel) { immUniformThemeColor(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX); - gpuPushMatrix(); - gpuTranslate2f(scene_framenr, val); - gpuScale2f(1.0f / data->xscale * data->hsize, 1.0f / data->yscale * data->hsize); + GPU_matrix_push(); + GPU_matrix_translate_2f(scene_framenr, val); + GPU_matrix_scale_2f(1.0f / data->xscale * data->hsize, 1.0f / data->yscale * data->hsize); imm_draw_circle_wire_2d(data->pos, 0, 0, 0.7, 8); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 4ac9010d3b5..2b98ff43c5f 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -1185,13 +1185,13 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar) show_cursor |= sc->around == V3D_AROUND_CURSOR; if (show_cursor) { - gpuPushMatrix(); - gpuTranslate2f(x, y); - gpuScale2f(zoomx, zoomy); - gpuMultMatrix(sc->stabmat); - gpuScale2f(width, height); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); + GPU_matrix_mul(sc->stabmat); + GPU_matrix_scale_2f(width, height); ED_image_draw_cursor(ar, sc->cursor); - gpuPopMatrix(); + GPU_matrix_pop(); } clip_draw_cache_and_notes(C, sc, ar); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 16658c0d8db..2b2d404168f 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -422,9 +422,9 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu) static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize, unsigned int pos) { /* adjust view transform before starting */ - gpuPushMatrix(); - gpuTranslate2f(x, y); - gpuScale2f(1.0f / xscale * hsize, 1.0f / yscale * hsize); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(1.0f / xscale * hsize, 1.0f / yscale * hsize); /* draw X shape */ immBegin(GWN_PRIM_LINES, 4); @@ -436,7 +436,7 @@ static void draw_fcurve_sample_control(float x, float y, float xscale, float ysc immEnd(); /* restore view transform */ - gpuPopMatrix(); + GPU_matrix_pop(); } /* helper func - draw keyframe vertices only for an F-Curve */ @@ -585,10 +585,10 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie } /* apply unit mapping */ - gpuPushMatrix(); + GPU_matrix_push(); unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); - gpuScale2f(1.0f, unit_scale); - gpuTranslate2f(0.0f, offset); + GPU_matrix_scale_2f(1.0f, unit_scale); + GPU_matrix_translate_2f(0.0f, offset); immBegin(GWN_PRIM_LINE_STRIP, count); @@ -645,7 +645,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie immEnd(); - gpuPopMatrix(); + GPU_matrix_pop(); } /* helper func - check if the F-Curve only contains easily drawable segments @@ -679,10 +679,10 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 short mapping_flag = ANIM_get_normalization_flags(ac); /* apply unit mapping */ - gpuPushMatrix(); + GPU_matrix_push(); unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); - gpuScale2f(1.0f, unit_scale); - gpuTranslate2f(0.0f, offset); + GPU_matrix_scale_2f(1.0f, unit_scale); + GPU_matrix_translate_2f(0.0f, offset); /* For now, this assumes the worst case scenario, where all the keyframes have * bezier interpolation, and are drawn at full res. @@ -827,7 +827,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 immEnd(); - gpuPopMatrix(); + GPU_matrix_pop(); } /* Debugging -------------------------------- */ @@ -1136,9 +1136,9 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); /* apply unit-scaling to all values via OpenGL */ - gpuPushMatrix(); - gpuScale2f(1.0f, unit_scale); - gpuTranslate2f(0.0f, offset); + GPU_matrix_push(); + GPU_matrix_scale_2f(1.0f, unit_scale); + GPU_matrix_translate_2f(0.0f, offset); /* set this once and for all - all handles and handle-verts should use the same thickness */ GPU_line_width(1.0); @@ -1160,7 +1160,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid draw_fcurve_samples(sipo, ar, fcu); } - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 24b02106021..ff90e59540e 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -117,13 +117,13 @@ static void draw_render_info(const bContext *C, int x, y; UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); - gpuPushMatrix(); - gpuTranslate2f(x, y); - gpuScale2f(zoomx, zoomy); + GPU_matrix_push(); + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); if (rd->mode & R_BORDER) { /* TODO: round or floor instead of casting to int */ - gpuTranslate2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f), + GPU_matrix_translate_2f((int)(-rd->border.xmin * rd->xsch * rd->size * 0.01f), (int)(-rd->border.ymin * rd->ysch * rd->size * 0.01f)); } @@ -144,7 +144,7 @@ static void draw_render_info(const bContext *C, MEM_freeN(tiles); } - gpuPopMatrix(); + GPU_matrix_pop(); } } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 97b112ebbd1..dfb85d3c8a4 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3193,8 +3193,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b if (ibuf) { float x, y; - gpuPushProjectionMatrix(); - gpuPushMatrix(); + GPU_matrix_push_projection(); + GPU_matrix_push(); /* somehow the offset has to be calculated inverse */ wmOrtho2_region_pixelspace(ar); @@ -3277,8 +3277,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b } } - gpuPopProjectionMatrix(); - gpuPopMatrix(); + GPU_matrix_pop_projection(); + GPU_matrix_pop(); } BKE_image_release_ibuf(ima, ibuf, lock); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index c632b354440..6976edce563 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1405,17 +1405,17 @@ void drawnodespace(const bContext *C, ARegion *ar) { float original_proj[4][4]; - gpuGetProjectionMatrix(original_proj); + GPU_matrix_projection_get(original_proj); - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push(); + GPU_matrix_identity_set(); wmOrtho2_pixelspace(ar->winx, ar->winy); WM_gizmomap_draw(ar->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D); - gpuPopMatrix(); - gpuLoadProjectionMatrix(original_proj); + GPU_matrix_pop(); + GPU_matrix_projection_set(original_proj); } draw_nodetree(C, ar, ntree, path->parent_key); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index a10eda5c3e6..204559ebf4f 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1308,8 +1308,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq if (draw_backdrop) { /* XXX: need to load identity projection too? */ - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push(); + GPU_matrix_identity_set(); } glGenTextures(1, (GLuint *)&texid); @@ -1439,7 +1439,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq } if (draw_backdrop) { - gpuPopMatrix(); + GPU_matrix_pop(); return; } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index beb323fb21c..f48d7ef578f 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -621,7 +621,7 @@ void draw_object_backbufsel( select_mode = ts->selectmode; } - gpuMultMatrix(ob->obmat); + GPU_matrix_mul(ob->obmat); glClearDepth(1.0); GPU_clear(GPU_DEPTH_BIT); GPU_depth_test(true); @@ -688,7 +688,7 @@ void draw_object_backbufsel( break; } - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_set(rv3d->viewmat); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index dca4b3f4f76..75c9b4a050f 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -251,7 +251,7 @@ void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d) /* we have to multiply instead of loading viewmatob to make * it work with duplis using displists, otherwise it will * override the dupli-matrix */ - gpuMultMatrix(ob->obmat); + GPU_matrix_mul(ob->obmat); } #ifdef DEBUG diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 89d01727d9b..4928f6e1f28 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -184,8 +184,8 @@ static void view3d_main_region_setup_view( ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect); /* set for opengl */ - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); } static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d) @@ -1355,10 +1355,10 @@ void ED_view3d_draw_offscreen( GPU_free_images_anim(G.main); /* XXX :((( */ } - gpuPushProjectionMatrix(); - gpuLoadIdentity(); - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push_projection(); + GPU_matrix_identity_set(); + GPU_matrix_push(); + GPU_matrix_identity_set(); if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera) view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, ar, winmat, viewname); @@ -1375,8 +1375,8 @@ void ED_view3d_draw_offscreen( ar->winy = bwiny; ar->winrct = brect; - gpuPopProjectionMatrix(); - gpuPopMatrix(); + GPU_matrix_pop_projection(); + GPU_matrix_pop(); UI_Theme_Restore(&theme_state); diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index cfeb199de15..cc7f23e2c18 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -685,13 +685,13 @@ static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph, GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - gpuPushProjectionMatrix(); - gpuPushMatrix(); + GPU_matrix_push_projection(); + GPU_matrix_push(); ED_region_pixelspace(ar); - gpuTranslate2f(centx, centy); - gpuScaleUniform(bgpic->scale); - gpuRotate2D(RAD2DEGF(-bgpic->rotation)); + GPU_matrix_translate_2f(centx, centy); + GPU_matrix_scale_1f(bgpic->scale); + GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation)); if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) { zoomx *= -1.0f; @@ -707,8 +707,8 @@ static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph, immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect, zoomx, zoomy, col); - gpuPopProjectionMatrix(); - gpuPopMatrix(); + GPU_matrix_pop_projection(); + GPU_matrix_pop(); GPU_blend(false); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index f296c2ee874..6040e21aacb 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -195,8 +195,8 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U static const float axis_highlight[4] = {1, 1, 1, 1}; static const float axis_black[4] = {0, 0, 0, 1}; static float axis_color[3][4]; - gpuPushMatrix(); - gpuMultMatrix(gz->matrix_offset); + GPU_matrix_push(); + GPU_matrix_mul(gz->matrix_offset); bool draw_center_done = false; @@ -219,11 +219,11 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U /* Circle defining active area (revert back to 2D space). */ { - gpuPopMatrix(); + GPU_matrix_pop(); immUniformColor4fv(color); imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION); - gpuPushMatrix(); - gpuMultMatrix(gz->matrix_offset); + GPU_matrix_push(); + GPU_matrix_mul(gz->matrix_offset); } draw_center_done = true; } @@ -276,15 +276,15 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U /* Axis Ball. */ { - gpuPushMatrix(); - gpuTranslate3fv(v_final); - gpuScaleUniform(is_pos ? 0.22f : 0.18f); + GPU_matrix_push(); + GPU_matrix_translate_3fv(v_final); + GPU_matrix_scale_1f(is_pos ? 0.22f : 0.18f); Gwn_Batch *sphere = GPU_batch_preset_sphere(0); GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); GWN_batch_uniform_4fv(sphere, "color", is_pos ? color_current : color_current_fade); GWN_batch_draw(sphere); - gpuPopMatrix(); + GPU_matrix_pop(); } /* Axis XYZ Character. */ @@ -298,7 +298,7 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U } } - gpuPopMatrix(); + GPU_matrix_pop(); immUnbindProgram(); } @@ -318,13 +318,13 @@ static void axis3d_draw_intern( .matrix_offset = matrix_unit, }), matrix_final); - gpuPushMatrix(); - gpuMultMatrix(matrix_final); + GPU_matrix_push(); + GPU_matrix_mul(matrix_final); GPU_blend(true); axis_geom_draw(gz, color, select); GPU_blend(false); - gpuPopMatrix(); + GPU_matrix_pop(); } static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index 30b91c1a8ee..91e255aec82 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -677,7 +677,7 @@ void ED_view3d_project(const struct ARegion *ar, const float world[3], float reg RegionView3D *rv3d = ar->regiondata; int viewport[4] = {0, 0, ar->winx, ar->winy}; - gpuProject(world, rv3d->viewmat, rv3d->winmat, viewport, region); + GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, region); } bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, float regionz, float world[3]) @@ -686,5 +686,5 @@ bool ED_view3d_unproject(const struct ARegion *ar, float regionx, float regiony, int viewport[4] = {0, 0, ar->winx, ar->winy}; float region[3] = {regionx, regiony, regionz}; - return gpuUnProject(region, rv3d->viewmat, rv3d->winmat, viewport, world); + return GPU_matrix_unproject(region, rv3d->viewmat, rv3d->winmat, viewport, world); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 0f82dfa775c..3175075e9c3 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -510,7 +510,7 @@ static void do_lasso_select_mesh( /* for non zbuf projections, don't change the GL state */ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - gpuLoadMatrix(vc->rv3d->viewmat); + GPU_matrix_set(vc->rv3d->viewmat); bbsel = EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { @@ -1936,7 +1936,7 @@ static int do_mesh_box_select( /* for non zbuf projections, don't change the GL state */ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - gpuLoadMatrix(vc->rv3d->viewmat); + GPU_matrix_set(vc->rv3d->viewmat); bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax); if (ts->selectmode & SCE_SELECT_VERTEX) { diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index ca5375b6b54..9b006bf4d9b 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -189,8 +189,8 @@ void view3d_region_operator_needs_opengl(wmWindow *UNUSED(win), ARegion *ar) RegionView3D *rv3d = ar->regiondata; wmViewport(&ar->winrct); // TODO: bad - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); } } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index c9e915a6415..bb0745b1998 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -721,14 +721,14 @@ void view3d_winmatrix_set(Depsgraph *depsgraph, ARegion *ar, const View3D *v3d, } if (is_ortho) { - gpuOrtho(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); + GPU_matrix_ortho_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); } else { - gpuFrustum(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); + GPU_matrix_frustum_set(viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); } /* update matrix in 3d view region */ - gpuGetProjectionMatrix(rv3d->winmat); + GPU_matrix_projection_get(rv3d->winmat); } static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ad7b5d55ba5..c49c9a8706c 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1813,7 +1813,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) tmval[i] += offset[i]; } - gpuPushMatrix(); + GPU_matrix_push(); /* Dashed lines first. */ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) { @@ -1853,8 +1853,8 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) case HLP_SPRING: immUniformThemeColor(TH_VIEW_OVERLAY); - gpuTranslate3fv(mval); - gpuRotateAxis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z'); + GPU_matrix_translate_3fv(mval); + GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z'); GPU_line_width(3.0f); drawArrow(UP, 5, 10, 5); @@ -1862,7 +1862,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) break; case HLP_HARROW: immUniformThemeColor(TH_VIEW_OVERLAY); - gpuTranslate3fv(mval); + GPU_matrix_translate_3fv(mval); GPU_line_width(3.0f); drawArrow(RIGHT, 5, 10, 5); @@ -1871,7 +1871,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) case HLP_VARROW: immUniformThemeColor(TH_VIEW_OVERLAY); - gpuTranslate3fv(mval); + GPU_matrix_translate_3fv(mval); GPU_line_width(3.0f); drawArrow(UP, 5, 10, 5); @@ -1887,23 +1887,23 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) immUniformThemeColor(TH_VIEW_OVERLAY); - gpuTranslate3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0); + GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0); GPU_line_width(3.0f); drawArc(dist, angle - delta_angle, angle - spacing_angle, 10); drawArc(dist, angle + spacing_angle, angle + delta_angle, 10); - gpuPushMatrix(); + GPU_matrix_push(); - gpuTranslate3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); - gpuRotateAxis(RAD2DEGF(angle - delta_angle), 'Z'); + GPU_matrix_translate_3f(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); + GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z'); drawArrowHead(DOWN, 5); - gpuPopMatrix(); + GPU_matrix_pop(); - gpuTranslate3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); - gpuRotateAxis(RAD2DEGF(angle + delta_angle), 'Z'); + GPU_matrix_translate_3f(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); + GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z'); drawArrowHead(UP, 5); break; @@ -1913,7 +1913,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) unsigned char col[3], col2[3]; UI_GetThemeColor3ubv(TH_GRID, col); - gpuTranslate3fv(mval); + GPU_matrix_translate_3fv(mval); GPU_line_width(3.0f); @@ -1933,7 +1933,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) } immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); } } @@ -7049,8 +7049,8 @@ static void drawEdgeSlide(TransInfo *t) GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - gpuPushMatrix(); - gpuMultMatrix(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); + GPU_matrix_push(); + GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); @@ -7138,7 +7138,7 @@ static void drawEdgeSlide(TransInfo *t) immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); GPU_blend(false); @@ -7682,8 +7682,8 @@ static void drawVertSlide(TransInfo *t) GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - gpuPushMatrix(); - gpuMultMatrix(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); + GPU_matrix_push(); + GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); GPU_line_width(line_size); @@ -7769,7 +7769,7 @@ static void drawVertSlide(TransInfo *t) immUnbindProgram(); } - gpuPopMatrix(); + GPU_matrix_pop(); GPU_depth_test(true); } diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index d40602f8d43..a02948a9951 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -800,13 +800,13 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) unit_m4(imat); } - gpuPushMatrix(); + GPU_matrix_push(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { - gpuScale2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); + GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); } else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) { /* only scale y */ @@ -816,7 +816,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); - gpuScale2f(1.0f, (ysize / xsize) * (xmask / ymask)); + GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); } depth_test_enabled = GPU_depth_test_enabled(); @@ -837,7 +837,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) if (depth_test_enabled) GPU_depth_test(true); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index e54b154ee0d..c1aa0263ef8 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1116,7 +1116,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis if (t->spacetype == SPACE_VIEW3D) { View3D *v3d = t->view; - gpuPushMatrix(); + GPU_matrix_push(); copy_v3_v3(v3, dir); mul_v3_fl(v3, v3d->far); @@ -1144,7 +1144,7 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis immUnbindProgram(); - gpuPopMatrix(); + GPU_matrix_pop(); } } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index f0d6b5c2a71..5ff008e1de2 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -90,7 +90,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) GPU_line_width(1.0f); - gpuTranslate2fv(cursor); + GPU_matrix_translate_2fv(cursor); const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -141,7 +141,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUnbindProgram(); - gpuTranslate2f(-cursor[0], -cursor[1]); + GPU_matrix_translate_2f(-cursor[0], -cursor[1]); } static int draw_uvs_face_check(Scene *scene) @@ -814,7 +814,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje /* Now draw each face contour separately with another builtin program. */ GWN_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR); - gpuBindMatrices(loop_batch->interface); + GPU_matrix_bind(loop_batch->interface); GWN_batch_program_use_begin(loop_batch); index = 0; diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h index f22c0cd5c4d..f5e34bd4c90 100644 --- a/source/blender/gpu/GPU_matrix.h +++ b/source/blender/gpu/GPU_matrix.h @@ -40,79 +40,79 @@ extern "C" { struct Gwn_ShaderInterface; -void gpuMatrixReset(void); /* to Identity transform & empty stack */ +void GPU_matrix_reset(void); /* to Identity transform & empty stack */ /* ModelView Matrix (2D or 3D) */ -void gpuPushMatrix(void); /* TODO: PushCopy vs PushIdentity? */ -void gpuPopMatrix(void); +void GPU_matrix_push(void); /* TODO: PushCopy vs PushIdentity? */ +void GPU_matrix_pop(void); -void gpuLoadIdentity(void); +void GPU_matrix_identity_set(void); -void gpuScaleUniform(float factor); +void GPU_matrix_scale_1f(float factor); /* 3D ModelView Matrix */ -void gpuLoadMatrix(const float m[4][4]); -void gpuMultMatrix(const float m[4][4]); +void GPU_matrix_set(const float m[4][4]); +void GPU_matrix_mul(const float m[4][4]); -void gpuTranslate3f(float x, float y, float z); -void gpuTranslate3fv(const float vec[3]); -void gpuScale3f(float x, float y, float z); -void gpuScale3fv(const float vec[3]); -void gpuRotate3f(float deg, float x, float y, float z); /* axis of rotation should be a unit vector */ -void gpuRotate3fv(float deg, const float axis[3]); /* axis of rotation should be a unit vector */ -void gpuRotateAxis(float deg, char axis); /* TODO: enum for axis? */ +void GPU_matrix_translate_3f(float x, float y, float z); +void GPU_matrix_translate_3fv(const float vec[3]); +void GPU_matrix_scale_3f(float x, float y, float z); +void GPU_matrix_scale_3fv(const float vec[3]); +void GPU_matrix_rotate_3f(float deg, float x, float y, float z); /* axis of rotation should be a unit vector */ +void GPU_matrix_rotate_3fv(float deg, const float axis[3]); /* axis of rotation should be a unit vector */ +void GPU_matrix_rotate_axis(float deg, char axis); /* TODO: enum for axis? */ -void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ); +void GPU_matrix_look_at(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ); /* TODO: variant that takes eye[3], center[3], up[3] */ /* 2D ModelView Matrix */ -void gpuTranslate2f(float x, float y); -void gpuTranslate2fv(const float vec[2]); -void gpuScale2f(float x, float y); -void gpuScale2fv(const float vec[2]); -void gpuRotate2D(float deg); +void GPU_matrix_translate_2f(float x, float y); +void GPU_matrix_translate_2fv(const float vec[2]); +void GPU_matrix_scale_2f(float x, float y); +void GPU_matrix_scale_2fv(const float vec[2]); +void GPU_matrix_rotate_2d(float deg); /* Projection Matrix (2D or 3D) */ -void gpuPushProjectionMatrix(void); -void gpuPopProjectionMatrix(void); +void GPU_matrix_push_projection(void); +void GPU_matrix_pop_projection(void); /* 3D Projection Matrix */ -void gpuLoadIdentityProjectionMatrix(void); -void gpuLoadProjectionMatrix(const float m[4][4]); +void GPU_matrix_identity_projection_set(void); +void GPU_matrix_projection_set(const float m[4][4]); -void gpuOrtho(float left, float right, float bottom, float top, float near, float far); -void gpuFrustum(float left, float right, float bottom, float top, float near, float far); -void gpuPerspective(float fovy, float aspect, float near, float far); +void GPU_matrix_ortho_set(float left, float right, float bottom, float top, float near, float far); +void GPU_matrix_frustum_set(float left, float right, float bottom, float top, float near, float far); +void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far); /* 3D Projection between Window and World Space */ -void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]); -bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]); +void GPU_matrix_project(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]); +bool GPU_matrix_unproject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]); /* 2D Projection Matrix */ -void gpuOrtho2D(float left, float right, float bottom, float top); +void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top); /* functions to get matrix values */ -const float (*gpuGetModelViewMatrix(float m[4][4]))[4]; -const float (*gpuGetProjectionMatrix(float m[4][4]))[4]; -const float (*gpuGetModelViewProjectionMatrix(float m[4][4]))[4]; +const float (*GPU_matrix_model_view_get(float m[4][4]))[4]; +const float (*GPU_matrix_projection_get(float m[4][4]))[4]; +const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4]; -const float (*gpuGetNormalMatrix(float m[3][3]))[3]; -const float (*gpuGetNormalMatrixInverse(float m[3][3]))[3]; +const float (*GPU_matrix_normal_get(float m[3][3]))[3]; +const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3]; /* set uniform values for currently bound shader */ -void gpuBindMatrices(const struct Gwn_ShaderInterface *); -bool gpuMatricesDirty(void); /* since last bind */ +void GPU_matrix_bind(const struct Gwn_ShaderInterface *); +bool GPU_matrix_dirty_get(void); /* since last bind */ /* Python API needs to be able to inspect the stack so errors raise exceptions instead of crashing. */ @@ -177,14 +177,14 @@ int GPU_matrix_stack_level_get_projection(void); #endif /* C11 */ /* make matrix inputs generic, to avoid warnings */ -# define gpuMultMatrix(x) gpuMultMatrix(_GPU_MAT4_CONST_CAST(x)) -# define gpuLoadMatrix(x) gpuLoadMatrix(_GPU_MAT4_CONST_CAST(x)) -# define gpuLoadProjectionMatrix(x) gpuLoadProjectionMatrix(_GPU_MAT4_CONST_CAST(x)) -# define gpuGetModelViewMatrix(x) gpuGetModelViewMatrix(_GPU_MAT4_CAST(x)) -# define gpuGetProjectionMatrix(x) gpuGetProjectionMatrix(_GPU_MAT4_CAST(x)) -# define gpuGetModelViewProjectionMatrix(x) gpuGetModelViewProjectionMatrix(_GPU_MAT4_CAST(x)) -# define gpuGetNormalMatrix(x) gpuGetNormalMatrix(_GPU_MAT3_CAST(x)) -# define gpuGetNormalMatrixInverse(x) gpuGetNormalMatrixInverse(_GPU_MAT3_CAST(x)) +# define GPU_matrix_mul(x) GPU_matrix_mul(_GPU_MAT4_CONST_CAST(x)) +# define GPU_matrix_set(x) GPU_matrix_set(_GPU_MAT4_CONST_CAST(x)) +# define GPU_matrix_projection_set(x) GPU_matrix_projection_set(_GPU_MAT4_CONST_CAST(x)) +# define GPU_matrix_model_view_get(x) GPU_matrix_model_view_get(_GPU_MAT4_CAST(x)) +# define GPU_matrix_projection_get(x) GPU_matrix_projection_get(_GPU_MAT4_CAST(x)) +# define GPU_matrix_model_view_projection_get(x) GPU_matrix_model_view_projection_get(_GPU_MAT4_CAST(x)) +# define GPU_matrix_normal_get(x) GPU_matrix_normal_get(_GPU_MAT3_CAST(x)) +# define GPU_matrix_normal_inverse_get(x) GPU_matrix_normal_inverse_get(_GPU_MAT3_CAST(x)) #endif /* SUPPRESS_GENERIC_MATRIX_API */ #endif /* __GPU_MATRIX_H__ */ diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c index b6214f2778b..2af1375a620 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.c @@ -86,7 +86,7 @@ static MatrixState state = { #define ProjectionStack state.projection_stack #define Projection ProjectionStack.stack[ProjectionStack.top] -void gpuMatrixReset(void) +void GPU_matrix_reset(void) { state.model_view_stack.top = 0; state.projection_stack.top = 0; @@ -119,76 +119,76 @@ static void checkmat(cosnt float *m) #endif -void gpuPushMatrix(void) +void GPU_matrix_push(void) { BLI_assert(ModelViewStack.top + 1 < MATRIX_STACK_DEPTH); ModelViewStack.top++; copy_m4_m4(ModelView, ModelViewStack.stack[ModelViewStack.top - 1]); } -void gpuPopMatrix(void) +void GPU_matrix_pop(void) { BLI_assert(ModelViewStack.top > 0); ModelViewStack.top--; state.dirty = true; } -void gpuPushProjectionMatrix(void) +void GPU_matrix_push_projection(void) { BLI_assert(ProjectionStack.top + 1 < MATRIX_STACK_DEPTH); ProjectionStack.top++; copy_m4_m4(Projection, ProjectionStack.stack[ProjectionStack.top - 1]); } -void gpuPopProjectionMatrix(void) +void GPU_matrix_pop_projection(void) { BLI_assert(ProjectionStack.top > 0); ProjectionStack.top--; state.dirty = true; } -void gpuLoadMatrix(const float m[4][4]) +void GPU_matrix_set(const float m[4][4]) { copy_m4_m4(ModelView, m); CHECKMAT(ModelView3D); state.dirty = true; } -void gpuLoadIdentityProjectionMatrix(void) +void GPU_matrix_identity_projection_set(void) { unit_m4(Projection); CHECKMAT(Projection3D); state.dirty = true; } -void gpuLoadProjectionMatrix(const float m[4][4]) +void GPU_matrix_projection_set(const float m[4][4]) { copy_m4_m4(Projection, m); CHECKMAT(Projection3D); state.dirty = true; } -void gpuLoadIdentity(void) +void GPU_matrix_identity_set(void) { unit_m4(ModelView); state.dirty = true; } -void gpuTranslate2f(float x, float y) +void GPU_matrix_translate_2f(float x, float y) { Mat4 m; unit_m4(m); m[3][0] = x; m[3][1] = y; - gpuMultMatrix(m); + GPU_matrix_mul(m); } -void gpuTranslate2fv(const float vec[2]) +void GPU_matrix_translate_2fv(const float vec[2]) { - gpuTranslate2f(vec[0], vec[1]); + GPU_matrix_translate_2f(vec[0], vec[1]); } -void gpuTranslate3f(float x, float y, float z) +void GPU_matrix_translate_3f(float x, float y, float z) { #if 1 translate_m4(ModelView, x, y, z); @@ -199,61 +199,61 @@ void gpuTranslate3f(float x, float y, float z) m[3][0] = x; m[3][1] = y; m[3][2] = z; - gpuMultMatrix(m); + GPU_matrix_mul(m); #endif state.dirty = true; } -void gpuTranslate3fv(const float vec[3]) +void GPU_matrix_translate_3fv(const float vec[3]) { - gpuTranslate3f(vec[0], vec[1], vec[2]); + GPU_matrix_translate_3f(vec[0], vec[1], vec[2]); } -void gpuScaleUniform(float factor) +void GPU_matrix_scale_1f(float factor) { Mat4 m; scale_m4_fl(m, factor); - gpuMultMatrix(m); + GPU_matrix_mul(m); } -void gpuScale2f(float x, float y) +void GPU_matrix_scale_2f(float x, float y) { Mat4 m = {{0.0f}}; m[0][0] = x; m[1][1] = y; m[2][2] = 1.0f; m[3][3] = 1.0f; - gpuMultMatrix(m); + GPU_matrix_mul(m); } -void gpuScale2fv(const float vec[2]) +void GPU_matrix_scale_2fv(const float vec[2]) { - gpuScale2f(vec[0], vec[1]); + GPU_matrix_scale_2f(vec[0], vec[1]); } -void gpuScale3f(float x, float y, float z) +void GPU_matrix_scale_3f(float x, float y, float z) { Mat4 m = {{0.0f}}; m[0][0] = x; m[1][1] = y; m[2][2] = z; m[3][3] = 1.0f; - gpuMultMatrix(m); + GPU_matrix_mul(m); } -void gpuScale3fv(const float vec[3]) +void GPU_matrix_scale_3fv(const float vec[3]) { - gpuScale3f(vec[0], vec[1], vec[2]); + GPU_matrix_scale_3f(vec[0], vec[1], vec[2]); } -void gpuMultMatrix(const float m[4][4]) +void GPU_matrix_mul(const float m[4][4]) { mul_m4_m4_post(ModelView, m); CHECKMAT(ModelView); state.dirty = true; } -void gpuRotate2D(float deg) +void GPU_matrix_rotate_2d(float deg) { /* essentially RotateAxis('Z') * TODO: simpler math for 2D case @@ -261,20 +261,20 @@ void gpuRotate2D(float deg) rotate_m4(ModelView, 'Z', DEG2RADF(deg)); } -void gpuRotate3f(float deg, float x, float y, float z) +void GPU_matrix_rotate_3f(float deg, float x, float y, float z) { const float axis[3] = {x, y, z}; - gpuRotate3fv(deg, axis); + GPU_matrix_rotate_3fv(deg, axis); } -void gpuRotate3fv(float deg, const float axis[3]) +void GPU_matrix_rotate_3fv(float deg, const float axis[3]) { Mat4 m; axis_angle_to_mat4(m, axis, DEG2RADF(deg)); - gpuMultMatrix(m); + GPU_matrix_mul(m); } -void gpuRotateAxis(float deg, char axis) +void GPU_matrix_rotate_axis(float deg, char axis) { /* rotate_m4 works in place */ rotate_m4(ModelView, axis, DEG2RADF(deg)); @@ -398,14 +398,14 @@ static void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3 state.dirty = true; } -void gpuOrtho(float left, float right, float bottom, float top, float near, float far) +void GPU_matrix_ortho_set(float left, float right, float bottom, float top, float near, float far) { mat4_ortho_set(Projection, left, right, bottom, top, near, far); CHECKMAT(Projection); state.dirty = true; } -void gpuOrtho2D(float left, float right, float bottom, float top) +void GPU_matrix_ortho_2d_set(float left, float right, float bottom, float top) { Mat4 m; mat4_ortho_set(m, left, right, bottom, top, -1.0f, 1.0f); @@ -413,21 +413,21 @@ void gpuOrtho2D(float left, float right, float bottom, float top) state.dirty = true; } -void gpuFrustum(float left, float right, float bottom, float top, float near, float far) +void GPU_matrix_frustum_set(float left, float right, float bottom, float top, float near, float far) { mat4_frustum_set(Projection, left, right, bottom, top, near, far); CHECKMAT(Projection); state.dirty = true; } -void gpuPerspective(float fovy, float aspect, float near, float far) +void GPU_matrix_perspective_set(float fovy, float aspect, float near, float far) { float half_height = tanf(fovy * (float)(M_PI / 360.0)) * near; float half_width = half_height * aspect; - gpuFrustum(-half_width, +half_width, -half_height, +half_height, near, far); + GPU_matrix_frustum_set(-half_width, +half_width, -half_height, +half_height, near, far); } -void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) +void GPU_matrix_look_at(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { Mat4 cm; float lookdir[3]; @@ -439,11 +439,11 @@ void gpuLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, mat4_look_from_origin(cm, lookdir, camup); - gpuMultMatrix(cm); - gpuTranslate3f(-eyeX, -eyeY, -eyeZ); + GPU_matrix_mul(cm); + GPU_matrix_translate_3f(-eyeX, -eyeY, -eyeZ); } -void gpuProject(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]) +void GPU_matrix_project(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float win[3]) { float v[4]; @@ -459,7 +459,7 @@ void gpuProject(const float world[3], const float model[4][4], const float proj[ win[2] = (v[2] + 1) * 0.5f; } -bool gpuUnProject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]) +bool GPU_matrix_unproject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3]) { float pm[4][4]; float in[4]; @@ -497,7 +497,7 @@ bool gpuUnProject(const float win[3], const float model[4][4], const float proj[ return true; } -const float (*gpuGetModelViewMatrix(float m[4][4]))[4] +const float (*GPU_matrix_model_view_get(float m[4][4]))[4] { if (m) { copy_m4_m4(m, ModelView); @@ -508,7 +508,7 @@ const float (*gpuGetModelViewMatrix(float m[4][4]))[4] } } -const float (*gpuGetProjectionMatrix(float m[4][4]))[4] +const float (*GPU_matrix_projection_get(float m[4][4]))[4] { if (m) { copy_m4_m4(m, Projection); @@ -519,7 +519,7 @@ const float (*gpuGetProjectionMatrix(float m[4][4]))[4] } } -const float (*gpuGetModelViewProjectionMatrix(float m[4][4]))[4] +const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4] { if (m == NULL) { static Mat4 temp; @@ -530,14 +530,14 @@ const float (*gpuGetModelViewProjectionMatrix(float m[4][4]))[4] return m; } -const float (*gpuGetNormalMatrix(float m[3][3]))[3] +const float (*GPU_matrix_normal_get(float m[3][3]))[3] { if (m == NULL) { static Mat3 temp3; m = temp3; } - copy_m3_m4(m, (const float (*)[4])gpuGetModelViewMatrix(NULL)); + copy_m3_m4(m, (const float (*)[4])GPU_matrix_model_view_get(NULL)); invert_m3(m); transpose_m3(m); @@ -545,20 +545,20 @@ const float (*gpuGetNormalMatrix(float m[3][3]))[3] return m; } -const float (*gpuGetNormalMatrixInverse(float m[3][3]))[3] +const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3] { if (m == NULL) { static Mat3 temp3; m = temp3; } - gpuGetNormalMatrix(m); + GPU_matrix_normal_get(m); invert_m3(m); return m; } -void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) +void GPU_matrix_bind(const Gwn_ShaderInterface *shaderface) { /* set uniform values to matrix stack values * call this before a draw call if desired matrices are dirty @@ -578,7 +578,7 @@ void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) puts("setting MV matrix"); #endif - glUniformMatrix4fv(MV->location, 1, GL_FALSE, (const float *)gpuGetModelViewMatrix(NULL)); + glUniformMatrix4fv(MV->location, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL)); } if (P) { @@ -586,7 +586,7 @@ void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) puts("setting P matrix"); #endif - glUniformMatrix4fv(P->location, 1, GL_FALSE, (const float *)gpuGetProjectionMatrix(NULL)); + glUniformMatrix4fv(P->location, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL)); } if (MVP) { @@ -594,7 +594,7 @@ void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) puts("setting MVP matrix"); #endif - glUniformMatrix4fv(MVP->location, 1, GL_FALSE, (const float *)gpuGetModelViewProjectionMatrix(NULL)); + glUniformMatrix4fv(MVP->location, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL)); } if (N) { @@ -602,19 +602,19 @@ void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) puts("setting normal matrix"); #endif - glUniformMatrix3fv(N->location, 1, GL_FALSE, (const float *)gpuGetNormalMatrix(NULL)); + glUniformMatrix3fv(N->location, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL)); } if (MV_inv) { Mat4 m; - gpuGetModelViewMatrix(m); + GPU_matrix_model_view_get(m); invert_m4(m); glUniformMatrix4fv(MV_inv->location, 1, GL_FALSE, (const float *)m); } if (P_inv) { Mat4 m; - gpuGetProjectionMatrix(m); + GPU_matrix_projection_get(m); invert_m4(m); glUniformMatrix4fv(P_inv->location, 1, GL_FALSE, (const float *)m); } @@ -622,7 +622,7 @@ void gpuBindMatrices(const Gwn_ShaderInterface *shaderface) state.dirty = false; } -bool gpuMatricesDirty(void) +bool GPU_matrix_dirty_get(void) { return state.dirty; } diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 8c978be81c1..99baaa1164f 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -532,7 +532,7 @@ void GPU_shader_bind(GPUShader *shader) BLI_assert(shader && shader->program); glUseProgram(shader->program); - gpuBindMatrices(shader->interface); + GPU_matrix_bind(shader->interface); } void GPU_shader_unbind(void) diff --git a/source/blender/python/intern/gpu_py_matrix.c b/source/blender/python/intern/gpu_py_matrix.c index 68b08dfb324..2ab6fd864eb 100644 --- a/source/blender/python/intern/gpu_py_matrix.c +++ b/source/blender/python/intern/gpu_py_matrix.c @@ -102,7 +102,7 @@ static PyObject *pygpu_matrix_push(PyObject *UNUSED(self)) if (!pygpu_stack_is_push_model_view_ok_or_error()) { return NULL; } - gpuPushMatrix(); + GPU_matrix_push(); Py_RETURN_NONE; } @@ -116,7 +116,7 @@ static PyObject *pygpu_matrix_pop(PyObject *UNUSED(self)) if (!pygpu_stack_is_pop_model_view_ok_or_error()) { return NULL; } - gpuPopMatrix(); + GPU_matrix_pop(); Py_RETURN_NONE; } @@ -130,7 +130,7 @@ static PyObject *pygpu_matrix_push_projection(PyObject *UNUSED(self)) if (!pygpu_stack_is_push_projection_ok_or_error()) { return NULL; } - gpuPushProjectionMatrix(); + GPU_matrix_push_projection(); Py_RETURN_NONE; } @@ -144,7 +144,7 @@ static PyObject *pygpu_matrix_pop_projection(PyObject *UNUSED(self)) if (!pygpu_stack_is_pop_projection_ok_or_error()) { return NULL; } - gpuPopProjectionMatrix(); + GPU_matrix_pop_projection(); Py_RETURN_NONE; } @@ -197,14 +197,14 @@ static PyObject *pygpu_matrix_stack_context_enter(BPy_GPU_MatrixStackContext *se if (!pygpu_stack_is_push_model_view_ok_or_error()) { return NULL; } - gpuPushMatrix(); + GPU_matrix_push(); self->level = GPU_matrix_stack_level_get_model_view(); } else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) { if (!pygpu_stack_is_push_projection_ok_or_error()) { return NULL; } - gpuPushProjectionMatrix(); + GPU_matrix_push_projection(); self->level = GPU_matrix_stack_level_get_projection(); } else { @@ -227,7 +227,7 @@ static PyObject *pygpu_matrix_stack_context_exit(BPy_GPU_MatrixStackContext *sel fprintf(stderr, "Level push/pop mismatch, expected %d, got %d\n", self->level, level); } if (level != 0) { - gpuPopMatrix(); + GPU_matrix_pop(); } } else if (self->type == PYGPU_MATRIX_TYPE_PROJECTION) { @@ -236,7 +236,7 @@ static PyObject *pygpu_matrix_stack_context_exit(BPy_GPU_MatrixStackContext *sel fprintf(stderr, "Level push/pop mismatch, expected %d, got %d", self->level, level); } if (level != 0) { - gpuPopProjectionMatrix(); + GPU_matrix_pop_projection(); } } else { @@ -294,7 +294,7 @@ static PyObject *pygpu_matrix_multiply_matrix(PyObject *UNUSED(self), PyObject * if (!Matrix_Parse4x4(value, &pymat)) { return NULL; } - gpuMultMatrix(pymat->matrix); + GPU_matrix_mul(pymat->matrix); Py_RETURN_NONE; } @@ -314,10 +314,10 @@ static PyObject *pygpu_matrix_scale(PyObject *UNUSED(self), PyObject *value) return NULL; } if (len == 2) { - gpuScale2fv(scale); + GPU_matrix_scale_2fv(scale); } else { - gpuScale3fv(scale); + GPU_matrix_scale_3fv(scale); } Py_RETURN_NONE; } @@ -337,7 +337,7 @@ static PyObject *pygpu_matrix_scale_uniform(PyObject *UNUSED(self), PyObject *va Py_TYPE(value)->tp_name); return NULL; } - gpuScaleUniform(scalar); + GPU_matrix_scale_1f(scalar); Py_RETURN_NONE; } @@ -357,10 +357,10 @@ static PyObject *pygpu_matrix_translate(PyObject *UNUSED(self), PyObject *value) return NULL; } if (len == 2) { - gpuTranslate2fv(offset); + GPU_matrix_translate_2fv(offset); } else { - gpuTranslate3fv(offset); + GPU_matrix_translate_3fv(offset); } Py_RETURN_NONE; } @@ -378,7 +378,7 @@ PyDoc_STRVAR(pygpu_matrix_reset_doc, ); static PyObject *pygpu_matrix_reset(PyObject *UNUSED(self)) { - gpuMatrixReset(); + GPU_matrix_reset(); Py_RETURN_NONE; } @@ -389,7 +389,7 @@ PyDoc_STRVAR(pygpu_matrix_load_identity_doc, ); static PyObject *pygpu_matrix_load_identity(PyObject *UNUSED(self)) { - gpuLoadIdentity(); + GPU_matrix_identity_set(); Py_RETURN_NONE; } @@ -407,7 +407,7 @@ static PyObject *pygpu_matrix_load_matrix(PyObject *UNUSED(self), PyObject *valu if (!Matrix_Parse4x4(value, &pymat)) { return NULL; } - gpuLoadMatrix(pymat->matrix); + GPU_matrix_set(pymat->matrix); Py_RETURN_NONE; } @@ -428,7 +428,7 @@ PyDoc_STRVAR(pygpu_matrix_get_projection_matrix_doc, static PyObject *pygpu_matrix_get_projection_matrix(PyObject *UNUSED(self)) { float matrix[4][4]; - gpuGetModelViewMatrix(matrix); + GPU_matrix_model_view_get(matrix); return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL); } @@ -444,7 +444,7 @@ PyDoc_STRVAR(pygpu_matrix_get_modal_view_matrix_doc, static PyObject *pygpu_matrix_get_modal_view_matrix(PyObject *UNUSED(self)) { float matrix[4][4]; - gpuGetProjectionMatrix(matrix); + GPU_matrix_projection_get(matrix); return Matrix_CreatePyObject(&matrix[0][0], 4, 4, NULL); } @@ -459,7 +459,7 @@ PyDoc_STRVAR(pygpu_matrix_get_normal_matrix_doc, static PyObject *pygpu_matrix_get_normal_matrix(PyObject *UNUSED(self)) { float matrix[3][3]; - gpuGetNormalMatrix(matrix); + GPU_matrix_normal_get(matrix); return Matrix_CreatePyObject(&matrix[0][0], 3, 3, NULL); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5cf9ac625c3..64aa64e1478 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2118,8 +2118,8 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph /* set up rotation if available */ if (rc->rot_prop) { rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop); - gpuPushMatrix(); - gpuRotate2D(RAD2DEGF(rot)); + GPU_matrix_push(); + GPU_matrix_rotate_2d(RAD2DEGF(rot)); } /* draw textured quad */ @@ -2141,7 +2141,7 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph /* undo rotation */ if (rc->rot_prop) - gpuPopMatrix(); + GPU_matrix_pop(); } else { /* flat color if no texture available */ @@ -2208,7 +2208,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void /* Keep cursor in the original place */ x = rc->initial_mouse[0]; y = rc->initial_mouse[1]; - gpuTranslate2f((float)x, (float)y); + GPU_matrix_translate_2f((float)x, (float)y); glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -2216,7 +2216,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void /* apply zoom if available */ if (rc->zoom_prop) { RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom); - gpuScale2fv(zoom); + GPU_matrix_scale_2fv(zoom); } /* draw rotated texture */ @@ -2233,23 +2233,23 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void immUniformColor3fvAlpha(col, 0.5f); if (rc->subtype == PROP_ANGLE) { - gpuPushMatrix(); + GPU_matrix_push(); /* draw original angle line */ - gpuRotate2D(RAD2DEGF(rc->initial_value)); + GPU_matrix_rotate_2d(RAD2DEGF(rc->initial_value)); immBegin(GWN_PRIM_LINES, 2); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); immEnd(); /* draw new angle line */ - gpuRotate2D(RAD2DEGF(rc->current_value - rc->initial_value)); + GPU_matrix_rotate_2d(RAD2DEGF(rc->current_value - rc->initial_value)); immBegin(GWN_PRIM_LINES, 2); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); immEnd(); - gpuPopMatrix(); + GPU_matrix_pop(); } /* draw circles on top */ diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 003932930ed..7ddc87a2524 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -201,8 +201,8 @@ static void playanim_window_get_size(int *r_width, int *r_height) static void playanim_gl_matrix(void) { /* unified matrix, note it affects offset for drawing */ - /* note! cannot use gpuOrtho2D here because shader ignores. */ - gpuOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0, 1.0f); + /* note! cannot use GPU_matrix_ortho_2d_set here because shader ignores. */ + GPU_matrix_ortho_set(0.0f, 1.0f, 0.0f, 1.0f, -1.0, 1.0f); } /* implementation */ @@ -366,10 +366,10 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf float fac = ps->picture->frame / (double)(((PlayAnimPict *)picsbase.last)->frame - ((PlayAnimPict *)picsbase.first)->frame); fac = 2.0f * fac - 1.0f; - gpuPushProjectionMatrix(); - gpuLoadIdentityProjectionMatrix(); - gpuPushMatrix(); - gpuLoadIdentity(); + GPU_matrix_push_projection(); + GPU_matrix_identity_projection_set(); + GPU_matrix_push(); + GPU_matrix_identity_set(); uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -383,8 +383,8 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf immUnbindProgram(); - gpuPopMatrix(); - gpuPopProjectionMatrix(); + GPU_matrix_pop(); + GPU_matrix_pop_projection(); } GHOST_SwapWindowBuffers(g_WS.ghost_window); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index f55eee69f71..ff3c712dae0 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -50,7 +50,7 @@ void wmViewport(const rcti *winrct) glScissor(winrct->xmin, winrct->ymin, width, height); wmOrtho2_pixelspace(width, height); - gpuLoadIdentity(); + GPU_matrix_identity_set(); } void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct) @@ -89,7 +89,7 @@ void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct glScissor(x, y, scissor_width, scissor_height); wmOrtho2_pixelspace(width, height); - gpuLoadIdentity(); + GPU_matrix_identity_set(); } void wmWindowViewport(wmWindow *win) @@ -101,7 +101,7 @@ void wmWindowViewport(wmWindow *win) glScissor(0, 0, width, height); wmOrtho2_pixelspace(width, height); - gpuLoadIdentity(); + GPU_matrix_identity_set(); } void wmOrtho2(float x1, float x2, float y1, float y2) @@ -110,7 +110,7 @@ void wmOrtho2(float x1, float x2, float y1, float y2) if (x1 == x2) x2 += 1.0f; if (y1 == y2) y2 += 1.0f; - gpuOrtho(x1, x2, y1, y2, -100, 100); + GPU_matrix_ortho_set(x1, x2, y1, y2, -100, 100); } static void wmOrtho2_offset(const float x, const float y, const float ofs) -- cgit v1.2.3 From edbb2d22791f04af6b775f5d46321f533c705781 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 15 Jul 2018 18:34:31 +0200 Subject: Fix Cycles incorrect resize and CMYK conversion of uint16/half images. --- intern/cycles/render/image.cpp | 37 +++++++++++--------- intern/cycles/util/util_half.h | 2 +- intern/cycles/util/util_image.h | 62 +++++++++++++++++++++++++++++++++ intern/cycles/util/util_image_impl.h | 66 ++---------------------------------- 4 files changed, 86 insertions(+), 81 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7f0660cee07..27d6ae78289 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -33,15 +33,15 @@ CCL_NAMESPACE_BEGIN /* Some helpers to silence warning in templated function. */ static bool isfinite(uchar /*value*/) { - return false; + return true; } static bool isfinite(half /*value*/) { - return false; + return true; } static bool isfinite(uint16_t /*value*/) { - return false; + return true; } ImageManager::ImageManager(const DeviceInfo& info) @@ -508,7 +508,6 @@ bool ImageManager::file_load_image(Image *img, int texture_limit, device_vector& tex_img) { - const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1; ImageInput *in = NULL; if(!file_load_image_generic(img, &in)) { return false; @@ -601,13 +600,19 @@ bool ImageManager::file_load_image(Image *img, type == IMAGE_DATA_TYPE_BYTE4 || type == IMAGE_DATA_TYPE_USHORT4); if(is_rgba) { + const StorageType one = util_image_cast_from_float(1.0f); + if(cmyk) { /* CMYK */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+2] = (pixels[i*4+2]*pixels[i*4+3])/255; - pixels[i*4+1] = (pixels[i*4+1]*pixels[i*4+3])/255; - pixels[i*4+0] = (pixels[i*4+0]*pixels[i*4+3])/255; - pixels[i*4+3] = alpha_one; + float c = util_image_cast_to_float(pixels[i*4+0]); + float m = util_image_cast_to_float(pixels[i*4+1]); + float y = util_image_cast_to_float(pixels[i*4+2]); + float k = util_image_cast_to_float(pixels[i*4+3]); + pixels[i*4+0] = util_image_cast_from_float((1.0f - c) * (1.0f - k)); + pixels[i*4+1] = util_image_cast_from_float((1.0f - m) * (1.0f - k)); + pixels[i*4+2] = util_image_cast_from_float((1.0f - y) * (1.0f - k)); + pixels[i*4+3] = one; } } else if(components == 2) { @@ -622,7 +627,7 @@ bool ImageManager::file_load_image(Image *img, else if(components == 3) { /* RGB */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; pixels[i*4+2] = pixels[i*3+2]; pixels[i*4+1] = pixels[i*3+1]; pixels[i*4+0] = pixels[i*3+0]; @@ -631,7 +636,7 @@ bool ImageManager::file_load_image(Image *img, else if(components == 1) { /* grayscale */ for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; pixels[i*4+2] = pixels[i]; pixels[i*4+1] = pixels[i]; pixels[i*4+0] = pixels[i]; @@ -639,7 +644,7 @@ bool ImageManager::file_load_image(Image *img, } if(img->use_alpha == false) { for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) { - pixels[i*4+3] = alpha_one; + pixels[i*4+3] = one; } } } @@ -871,7 +876,7 @@ void ImageManager::device_load_image(Device *device, thread_scoped_lock device_lock(device_mutex); uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1); - pixels[0] = TEX_IMAGE_MISSING_R; + pixels[0] = (TEX_IMAGE_MISSING_R * 65535); } img->mem = tex_img; @@ -893,10 +898,10 @@ void ImageManager::device_load_image(Device *device, thread_scoped_lock device_lock(device_mutex); uint16_t *pixels = (uint16_t*)tex_img->alloc(1, 1); - pixels[0] = TEX_IMAGE_MISSING_R; - pixels[1] = TEX_IMAGE_MISSING_G; - pixels[2] = TEX_IMAGE_MISSING_B; - pixels[3] = TEX_IMAGE_MISSING_A; + pixels[0] = (TEX_IMAGE_MISSING_R * 65535); + pixels[1] = (TEX_IMAGE_MISSING_G * 65535); + pixels[2] = (TEX_IMAGE_MISSING_B * 65535); + pixels[3] = (TEX_IMAGE_MISSING_A * 65535); } img->mem = tex_img; diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h index 58f3f903619..53b7f2472bd 100644 --- a/intern/cycles/util/util_half.h +++ b/intern/cycles/util/util_half.h @@ -42,7 +42,7 @@ public: half() : v(0) {} half(const unsigned short& i) : v(i) {} operator unsigned short() { return v; } - half & operator =(const unsigned short& i) { v = i; return *this; } + half& operator =(const unsigned short& i) { v = i; return *this; } private: unsigned short v; }; diff --git a/intern/cycles/util/util_image.h b/intern/cycles/util/util_image.h index 18876841b5b..85bdb0d8050 100644 --- a/intern/cycles/util/util_image.h +++ b/intern/cycles/util/util_image.h @@ -38,6 +38,68 @@ void util_image_resize_pixels(const vector& input_pixels, size_t *output_height, size_t *output_depth); +/* Cast input pixel from unknown storage to float. */ +template +inline float util_image_cast_to_float(T value); + +template<> +inline float util_image_cast_to_float(float value) +{ + return value; +} +template<> +inline float util_image_cast_to_float(uchar value) +{ + return (float)value / 255.0f; +} +template<> +inline float util_image_cast_to_float(uint16_t value) +{ + return (float)value / 65535.0f; +} +template<> +inline float util_image_cast_to_float(half value) +{ + return half_to_float(value); +} + +/* Cast float value to output pixel type. */ +template +inline T util_image_cast_from_float(float value); + +template<> +inline float util_image_cast_from_float(float value) +{ + return value; +} +template<> +inline uchar util_image_cast_from_float(float value) +{ + if(value < 0.0f) { + return 0; + } + else if(value > (1.0f - 0.5f / 255.0f)) { + return 255; + } + return (uchar)((255.0f * value) + 0.5f); +} +template<> +inline uint16_t util_image_cast_from_float(float value) +{ + if(value < 0.0f) { + return 0; + } + else if(value > (1.0f - 0.5f / 65535.0f)) { + return 65535; + } + return (uint16_t)((65535.0f * value) + 0.5f); +} +template<> +inline half util_image_cast_from_float(float value) +{ + return float_to_half(value); +} + CCL_NAMESPACE_END #endif /* __UTIL_IMAGE_H__ */ diff --git a/intern/cycles/util/util_image_impl.h b/intern/cycles/util/util_image_impl.h index fb953a43ab2..5bc1c727595 100644 --- a/intern/cycles/util/util_image_impl.h +++ b/intern/cycles/util/util_image_impl.h @@ -38,68 +38,6 @@ const T *util_image_read(const vector& pixels, return &pixels[index]; } -/* Cast input pixel from unknown storage to float. */ -template -inline float cast_to_float(T value); - -template<> -inline float cast_to_float(float value) -{ - return value; -} -template<> -inline float cast_to_float(uchar value) -{ - return (float)value / 255.0f; -} -template<> -inline float cast_to_float(uint16_t value) -{ - return (float)value / 65535.0f; -} -template<> -inline float cast_to_float(half value) -{ - return half_to_float(value); -} - -/* Cast float value to output pixel type. */ -template -inline T cast_from_float(float value); - -template<> -inline float cast_from_float(float value) -{ - return value; -} -template<> -inline uchar cast_from_float(float value) -{ - if(value < 0.0f) { - return 0; - } - else if(value > (1.0f - 0.5f / 255.0f)) { - return 255; - } - return (uchar)((255.0f * value) + 0.5f); -} -template<> -inline uint16_t cast_from_float(float value) -{ - if(value < 0.0f) { - return 0; - } - else if(value >(1.0f - 0.5f / 65535.0f)) { - return 65535; - } - return (uchar)((65535.0f * value) + 0.5f); -} -template<> -inline half cast_from_float(float value) -{ - return float_to_half(value); -} - template void util_image_downscale_sample(const vector& pixels, const size_t width, @@ -133,7 +71,7 @@ void util_image_downscale_sample(const vector& pixels, components, nx, ny, nz); for(size_t k = 0; k < components; ++k) { - accum[k] += cast_to_float(pixel[k]); + accum[k] += util_image_cast_to_float(pixel[k]); } ++count; } @@ -142,7 +80,7 @@ void util_image_downscale_sample(const vector& pixels, if(count != 0) { const float inv_count = 1.0f / (float)count; for(size_t k = 0; k < components; ++k) { - result[k] = cast_from_float(accum[k] * inv_count); + result[k] = util_image_cast_from_float(accum[k] * inv_count); } } else { -- cgit v1.2.3 From b29b73a67eca3e5ac71c4b7c89f25bf3fb694cc3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2018 19:49:07 +0200 Subject: Gizmo: update Python templates --- doc/python_api/sphinx_doc_gen.py | 6 +++--- release/scripts/startup/bl_ui/space_toolsystem_common.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 2 +- release/scripts/templates_py/gizmo_operator_target.py | 2 +- release/scripts/templates_py/gizmo_simple.py | 2 +- source/blender/editors/gpencil/gpencil_brush.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index bfa8a295f5b..6c631891418 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -334,9 +334,9 @@ except ImportError: # to avoid having to match Blender's source tree. EXTRA_SOURCE_FILES = ( "../../../release/scripts/templates_py/bmesh_simple.py", - "../../../release/scripts/templates_py/manipulator_operator.py", - "../../../release/scripts/templates_py/manipulator_operator_target.py", - "../../../release/scripts/templates_py/manipulator_simple.py", + "../../../release/scripts/templates_py/gizmo_operator.py", + "../../../release/scripts/templates_py/gizmo_operator_target.py", + "../../../release/scripts/templates_py/gizmo_simple.py", "../../../release/scripts/templates_py/operator_simple.py", "../../../release/scripts/templates_py/ui_panel_simple.py", "../../../release/scripts/templates_py/ui_previews_custom_icon.py", diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 4c954874f0d..4f6e42d4a98 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -74,7 +74,7 @@ ToolDef = namedtuple( "icon", # An optional cursor to use when this tool is active. "cursor", - # An optional manipulator group to activate when the tool is set or None for no widget. + # An optional gizmo group to activate when the tool is set or None for no gizmo. "widget", # Optional keymap for tool, either: # - A function that populates a keymaps passed in as an argument. diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 682af76500b..36bfe5ec65e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -51,7 +51,7 @@ class VIEW3D_HT_header(Header): layout.template_header_3D_mode() - # Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode... + # Contains buttons like Mode, Pivot, Layer, Mesh Select Mode... shading_type = view.shading.type shading_item = bpy.types.View3DShading.bl_rna.properties["type"].enum_items[shading_type] diff --git a/release/scripts/templates_py/gizmo_operator_target.py b/release/scripts/templates_py/gizmo_operator_target.py index 28465ad2fa5..606aa6749d0 100644 --- a/release/scripts/templates_py/gizmo_operator_target.py +++ b/release/scripts/templates_py/gizmo_operator_target.py @@ -24,7 +24,7 @@ class MyCameraWidgetGroup(GizmoGroup): def setup(self, context): # Run an operator using the dial gizmo ob = context.object - mpr = self.gizmos.new("GIZMO_GGT_dial_3d") + mpr = self.gizmos.new("GIZMO_GT_dial_3d") props = mpr.target_set_operator("transform.rotate") props.constraint_axis = False, False, True props.constraint_orientation = 'LOCAL' diff --git a/release/scripts/templates_py/gizmo_simple.py b/release/scripts/templates_py/gizmo_simple.py index df80acea0ae..396378da04c 100644 --- a/release/scripts/templates_py/gizmo_simple.py +++ b/release/scripts/templates_py/gizmo_simple.py @@ -25,7 +25,7 @@ class MyLightWidgetGroup(GizmoGroup): def setup(self, context): # Arrow gizmo has one 'offset' property we can assign to the light energy. ob = context.object - mpr = self.gizmos.new("GIZMO_GGT_arrow_3d") + mpr = self.gizmos.new("GIZMO_GT_arrow_3d") mpr.target_set_prop("offset", ob.data, "energy") mpr.matrix_basis = ob.matrix_world.normalized() mpr.draw_style = 'BOX' diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 0ddd8700c09..a8810df35ff 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -1832,7 +1832,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even case DOWNARROWKEY: return OPERATOR_PASS_THROUGH; - /* Camera/View Manipulations - Allowed */ + /* Camera/View Gizmo's - Allowed */ /* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */ case PAD0: case PAD1: case PAD2: case PAD3: case PAD4: case PAD5: case PAD6: case PAD7: case PAD8: case PAD9: -- cgit v1.2.3 From ab9bd557added48a1f46b9624b874a40b46b71d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jul 2018 20:29:11 +0200 Subject: Cleanup: doxy comments --- source/blender/windowmanager/intern/wm_operator_type.c | 5 +++++ source/blender/windowmanager/intern/wm_playanim.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index 62b378e0866..25ca84f3d57 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -96,6 +96,11 @@ void WM_operatortype_iter(GHashIterator *ghi) BLI_ghashIterator_init(ghi, global_ops_hash); } +/** \} */ + +/** \name Operator Type Append + * \{ */ + /* all ops in 1 list (for time being... needs evaluation later) */ void WM_operatortype_append(void (*opfunc)(wmOperatorType *)) { diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index b4f2435ee2d..f2c24858e17 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -28,8 +28,11 @@ /** \file blender/windowmanager/intern/wm_playanim.c * \ingroup wm * + * Animation player for image sequences & video's with sound support. + * Launched in a separate process from Blender's #RENDER_OT_play_rendered_anim + * * \note This file uses ghost directly and none of the WM definitions. - * this could be made into its own module, alongside creator/ + * this could be made into its own module, alongside creator. */ #include -- cgit v1.2.3 From d9203820467665ba19e1956e035de663849e695c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 09:28:05 +0200 Subject: OpenSubdiv: Re-work C-API integration Main goal is to make API simpler to follow (at least ion terms what is defined/declared where, as opposite of handful big headers which includes all the declarations), and also avoid a big set of long and obscure functions. Now C-API files are split into smaller ones, following OpenSubdiv behavior more closely, and also function pointers in structures used a lot more, which shortens functions names, UV integration part in GL Mesh is mainly stripped away, it needs to be done differently. On a related topic, UV coordinates API in converter needs to be removed as well, we do not need coordinates, only island connectivity information there. Additional changes: - Varying interpolation in evaluator API are temporarily disabled, need to extend API somewhere (probably, evaluator's API) to inform layout information of vertex data (whether it contains varying data, width, stride and such). - Evaluator now can interpolate face-varying data. Only works for adaptive refiner, since some issues in OpenSubdiv itself. Planned changes: - Remove uv coordinates from TopologyConverter. - Support evaluation of patches (as opposite to individual coordinates as it happens currently). - Support more flexible layout of varying and face-varying data. It is stupid to assume varying is 3 floats and face-varying 2 floats. - Support of second order derivatives. - Everything else what i'm missing in this list. --- intern/opensubdiv/CMakeLists.txt | 48 +- .../opensubdiv/gpu_shader_opensubdiv_fragment.glsl | 172 ----- .../opensubdiv/gpu_shader_opensubdiv_geometry.glsl | 154 ---- .../opensubdiv/gpu_shader_opensubdiv_vertex.glsl | 46 -- intern/opensubdiv/internal/opensubdiv.cc | 99 +++ .../internal/opensubdiv_converter_factory.cc | 438 ++++++++++++ .../internal/opensubdiv_converter_factory.h | 37 + .../internal/opensubdiv_converter_internal.cc | 70 ++ .../internal/opensubdiv_converter_internal.h | 50 ++ .../internal/opensubdiv_converter_orient.cc | 66 ++ .../internal/opensubdiv_converter_orient.h | 50 ++ .../internal/opensubdiv_converter_orient_impl.h | 66 ++ .../internal/opensubdiv_device_context_cuda.cc | 226 ++++++ .../internal/opensubdiv_device_context_cuda.h | 54 ++ .../internal/opensubdiv_device_context_opencl.cc | 269 +++++++ .../internal/opensubdiv_device_context_opencl.h | 52 ++ intern/opensubdiv/internal/opensubdiv_evaluator.cc | 154 ++++ .../internal/opensubdiv_evaluator_internal.cc | 734 +++++++++++++++++++ .../internal/opensubdiv_evaluator_internal.h | 134 ++++ intern/opensubdiv/internal/opensubdiv_gl_mesh.cc | 287 ++++++++ .../opensubdiv/internal/opensubdiv_gl_mesh_draw.cc | 587 +++++++++++++++ .../opensubdiv/internal/opensubdiv_gl_mesh_draw.h | 39 + .../opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc | 175 +++++ .../opensubdiv/internal/opensubdiv_gl_mesh_fvar.h | 57 ++ .../internal/opensubdiv_gl_mesh_internal.cc | 32 + .../internal/opensubdiv_gl_mesh_internal.h | 43 ++ intern/opensubdiv/internal/opensubdiv_gpu.cc | 788 +++++++++++++++++++++ intern/opensubdiv/internal/opensubdiv_internal.h | 38 + .../internal/opensubdiv_topology_refiner.cc | 315 ++++++++ .../internal/opensubdiv_topology_refiner.h | 41 ++ .../opensubdiv_topology_refiner_internal.cc | 26 + .../opensubdiv_topology_refiner_internal.h | 47 ++ intern/opensubdiv/internal/opensubdiv_util.cc | 61 ++ intern/opensubdiv/internal/opensubdiv_util.h | 39 + intern/opensubdiv/opensubdiv_capi.cc | 441 ------------ intern/opensubdiv/opensubdiv_capi.h | 178 +---- intern/opensubdiv/opensubdiv_capi_type.h | 41 ++ intern/opensubdiv/opensubdiv_converter.cc | 764 -------------------- intern/opensubdiv/opensubdiv_converter_capi.h | 263 +++---- .../opensubdiv/opensubdiv_device_context_cuda.cc | 237 ------- intern/opensubdiv/opensubdiv_device_context_cuda.h | 54 -- .../opensubdiv/opensubdiv_device_context_opencl.cc | 251 ------- .../opensubdiv/opensubdiv_device_context_opencl.h | 58 -- intern/opensubdiv/opensubdiv_evaluator_capi.cc | 516 -------------- intern/opensubdiv/opensubdiv_evaluator_capi.h | 117 +++ intern/opensubdiv/opensubdiv_gl_mesh.h | 40 -- intern/opensubdiv/opensubdiv_gl_mesh_capi.h | 92 +++ intern/opensubdiv/opensubdiv_gpu_capi.cc | 788 --------------------- intern/opensubdiv/opensubdiv_intern.h | 46 -- intern/opensubdiv/opensubdiv_topology_refiner.h | 41 -- .../opensubdiv/opensubdiv_topology_refiner_capi.h | 110 +++ intern/opensubdiv/opensubdiv_utils_capi.cc | 88 --- .../shader/gpu_shader_opensubdiv_fragment.glsl | 172 +++++ .../shader/gpu_shader_opensubdiv_geometry.glsl | 154 ++++ .../shader/gpu_shader_opensubdiv_vertex.glsl | 46 ++ source/blender/blenkernel/intern/CCGSubSurf.c | 6 +- .../blender/blenkernel/intern/CCGSubSurf_intern.h | 4 +- .../blenkernel/intern/CCGSubSurf_opensubdiv.c | 139 ++-- .../intern/CCGSubSurf_opensubdiv_converter.c | 96 +-- 59 files changed, 6120 insertions(+), 4116 deletions(-) delete mode 100644 intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl delete mode 100644 intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl delete mode 100644 intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl create mode 100644 intern/opensubdiv/internal/opensubdiv.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_factory.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_factory.h create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_internal.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_internal.h create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_orient.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_orient.h create mode 100644 intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h create mode 100644 intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_device_context_cuda.h create mode 100644 intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_device_context_opencl.h create mode 100644 intern/opensubdiv/internal/opensubdiv_evaluator.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_evaluator_internal.h create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h create mode 100644 intern/opensubdiv/internal/opensubdiv_gpu.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_internal.h create mode 100644 intern/opensubdiv/internal/opensubdiv_topology_refiner.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_topology_refiner.h create mode 100644 intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h create mode 100644 intern/opensubdiv/internal/opensubdiv_util.cc create mode 100644 intern/opensubdiv/internal/opensubdiv_util.h delete mode 100644 intern/opensubdiv/opensubdiv_capi.cc create mode 100644 intern/opensubdiv/opensubdiv_capi_type.h delete mode 100644 intern/opensubdiv/opensubdiv_converter.cc delete mode 100644 intern/opensubdiv/opensubdiv_device_context_cuda.cc delete mode 100644 intern/opensubdiv/opensubdiv_device_context_cuda.h delete mode 100644 intern/opensubdiv/opensubdiv_device_context_opencl.cc delete mode 100644 intern/opensubdiv/opensubdiv_device_context_opencl.h delete mode 100644 intern/opensubdiv/opensubdiv_evaluator_capi.cc create mode 100644 intern/opensubdiv/opensubdiv_evaluator_capi.h delete mode 100644 intern/opensubdiv/opensubdiv_gl_mesh.h create mode 100644 intern/opensubdiv/opensubdiv_gl_mesh_capi.h delete mode 100644 intern/opensubdiv/opensubdiv_gpu_capi.cc delete mode 100644 intern/opensubdiv/opensubdiv_intern.h delete mode 100644 intern/opensubdiv/opensubdiv_topology_refiner.h create mode 100644 intern/opensubdiv/opensubdiv_topology_refiner_capi.h delete mode 100644 intern/opensubdiv/opensubdiv_utils_capi.cc create mode 100644 intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl create mode 100644 intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl create mode 100644 intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index 876b5c0181f..887eb399224 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -34,20 +34,40 @@ set(INC_SYS ) set(SRC - opensubdiv_capi.cc - opensubdiv_converter.cc - opensubdiv_device_context_cuda.cc - opensubdiv_device_context_opencl.cc - opensubdiv_evaluator_capi.cc - opensubdiv_gpu_capi.cc - opensubdiv_utils_capi.cc + internal/opensubdiv.cc + internal/opensubdiv_converter_factory.cc + internal/opensubdiv_converter_internal.cc + internal/opensubdiv_converter_orient.cc + internal/opensubdiv_device_context_cuda.cc + internal/opensubdiv_device_context_opencl.cc + internal/opensubdiv_evaluator.cc + internal/opensubdiv_evaluator_internal.cc + internal/opensubdiv_gl_mesh.cc + internal/opensubdiv_gl_mesh_draw.cc + internal/opensubdiv_gl_mesh_fvar.cc + internal/opensubdiv_gl_mesh_internal.cc + internal/opensubdiv_topology_refiner.cc + internal/opensubdiv_topology_refiner_internal.cc + internal/opensubdiv_util.cc + + internal/opensubdiv_converter_internal.h + internal/opensubdiv_converter_orient.h + internal/opensubdiv_converter_orient_impl.h + internal/opensubdiv_device_context_cuda.h + internal/opensubdiv_device_context_opencl.h + internal/opensubdiv_evaluator_internal.h + internal/opensubdiv_gl_mesh_fvar.h + internal/opensubdiv_gl_mesh_internal.h + internal/opensubdiv_internal.h + internal/opensubdiv_topology_refiner_internal.h + internal/opensubdiv_util.h opensubdiv_capi.h + opensubdiv_capi_type.h opensubdiv_converter_capi.h - opensubdiv_device_context_cuda.h - opensubdiv_device_context_opencl.h - opensubdiv_intern.h - opensubdiv_topology_refiner.h + opensubdiv_evaluator_capi.h + opensubdiv_gl_mesh_capi.h + opensubdiv_topology_refiner_capi.h ) macro(OPENSUBDIV_DEFINE_COMPONENT component) @@ -64,9 +84,9 @@ OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE) -data_to_c_simple(gpu_shader_opensubdiv_vertex.glsl SRC) -data_to_c_simple(gpu_shader_opensubdiv_geometry.glsl SRC) -data_to_c_simple(gpu_shader_opensubdiv_fragment.glsl SRC) +data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC) +data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC) +data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC) add_definitions(-DGLEW_STATIC) diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl deleted file mode 100644 index 1e36d549360..00000000000 --- a/intern/opensubdiv/gpu_shader_opensubdiv_fragment.glsl +++ /dev/null @@ -1,172 +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 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -struct VertexData { - vec4 position; - vec3 normal; - vec2 uv; -}; - -#define MAX_LIGHTS 8 -#define NUM_SOLID_LIGHTS 3 - -struct LightSource { - vec4 position; - vec4 ambient; - vec4 diffuse; - vec4 specular; - vec4 spotDirection; -#ifdef SUPPORT_COLOR_MATERIAL - float constantAttenuation; - float linearAttenuation; - float quadraticAttenuation; - float spotCutoff; - float spotExponent; - float spotCosCutoff; - float pad, pad2; -#endif -}; - -layout(std140) uniform Lighting { - LightSource lightSource[MAX_LIGHTS]; - int num_enabled_lights; -}; - -uniform vec4 diffuse; -uniform vec4 specular; -uniform float shininess; - -uniform sampler2D texture_buffer; - -in block { - VertexData v; -} inpt; - -void main() -{ -#ifdef WIREFRAME - gl_FragColor = diffuse; -#else - vec3 N = inpt.v.normal; - - if (!gl_FrontFacing) - N = -N; - - /* Compute diffuse and specular lighting. */ - vec3 L_diffuse = vec3(0.0); - vec3 L_specular = vec3(0.0); - -#ifdef USE_LIGHTING -#ifndef USE_COLOR_MATERIAL - /* Assume NUM_SOLID_LIGHTS directional lights. */ - for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { - vec4 Plight = lightSource[i].position; -#ifdef USE_DIRECTIONAL_LIGHT - vec3 l = (Plight.w == 0.0) - ? normalize(Plight.xyz) - : normalize(inpt.v.position.xyz); -#else /* USE_DIRECTIONAL_LIGHT */ - /* TODO(sergey): We can normalize it outside of the shader. */ - vec3 l = normalize(Plight.xyz); -#endif /* USE_DIRECTIONAL_LIGHT */ - vec3 h = normalize(l + vec3(0, 0, 1)); - float d = max(0.0, dot(N, l)); - float s = pow(max(0.0, dot(N, h)), shininess); - L_diffuse += d * lightSource[i].diffuse.rgb; - L_specular += s * lightSource[i].specular.rgb; - } -#else /* USE_COLOR_MATERIAL */ - vec3 varying_position = inpt.v.position.xyz; - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? - normalize(varying_position) : vec3(0.0, 0.0, -1.0); - for (int i = 0; i < num_enabled_lights; i++) { - /* todo: this is a slow check for disabled lights */ - if (lightSource[i].specular.a == 0.0) - continue; - - float intensity = 1.0; - vec3 light_direction; - - if (lightSource[i].position.w == 0.0) { - /* directional light */ - light_direction = lightSource[i].position.xyz; - } - else { - /* point light */ - vec3 d = lightSource[i].position.xyz - varying_position; - light_direction = normalize(d); - - /* spot light cone */ - if (lightSource[i].spotCutoff < 90.0) { - float cosine = max(dot(light_direction, - -lightSource[i].spotDirection.xyz), - 0.0); - intensity = pow(cosine, lightSource[i].spotExponent); - intensity *= step(lightSource[i].spotCosCutoff, cosine); - } - - /* falloff */ - float distance = length(d); - - intensity /= lightSource[i].constantAttenuation + - lightSource[i].linearAttenuation * distance + - lightSource[i].quadraticAttenuation * distance * distance; - } - - /* diffuse light */ - vec3 light_diffuse = lightSource[i].diffuse.rgb; - float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse * diffuse_bsdf * intensity; - - /* specular light */ - vec3 light_specular = lightSource[i].specular.rgb; - vec3 H = normalize(light_direction - V); - - float specular_bsdf = pow(max(dot(N, H), 0.0), - gl_FrontMaterial.shininess); - L_specular += light_specular * specular_bsdf * intensity; - } -#endif /* USE_COLOR_MATERIAL */ -#else /* USE_LIGHTING */ - L_diffuse = vec3(1.0); -#endif - - /* Compute diffuse color. */ -#ifdef USE_TEXTURE_2D - L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; -#else - L_diffuse *= diffuse.rgb; -#endif - - /* Sum lighting. */ - vec3 L = L_diffuse; - if (shininess != 0) { - L += L_specular * specular.rgb; - } - - /* Write out fragment color. */ - gl_FragColor = vec4(L, diffuse.a); -#endif -} diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl deleted file mode 100644 index b16a5cca733..00000000000 --- a/intern/opensubdiv/gpu_shader_opensubdiv_geometry.glsl +++ /dev/null @@ -1,154 +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 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -struct VertexData { - vec4 position; - vec3 normal; - vec2 uv; -}; - -layout(lines_adjacency) in; -#ifdef WIREFRAME -layout(line_strip, max_vertices = 8) out; -#else -layout(triangle_strip, max_vertices = 4) out; -#endif - -uniform mat4 modelViewMatrix; -uniform mat4 projectionMatrix; -uniform int PrimitiveIdBase; -uniform int osd_fvar_count; -uniform int osd_active_uv_offset; - -in block { - VertexData v; -} inpt[]; - -#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \ - { \ - vec2 v[4]; \ - int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \ - for (int i = 0; i < 4; ++i) { \ - int index = (primOffset + i) * osd_fvar_count + fvarOffset; \ - v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \ - texelFetch(FVarDataBuffer, index + 1).s); \ - } \ - result = mix(mix(v[0], v[1], tessCoord.s), \ - mix(v[3], v[2], tessCoord.s), \ - tessCoord.t); \ - } - -uniform samplerBuffer FVarDataBuffer; -uniform isamplerBuffer FVarDataOffsetBuffer; - -out block { - VertexData v; -} outpt; - -#ifdef FLAT_SHADING -void emit(int index, vec3 normal) -{ - outpt.v.position = inpt[index].v.position; - outpt.v.normal = normal; - - /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); - vec2 st = quadst[index]; - - INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); - - gl_Position = projectionMatrix * inpt[index].v.position; - EmitVertex(); -} - -# ifdef WIREFRAME -void emit_edge(int v0, int v1, vec3 normal) -{ - emit(v0, normal); - emit(v1, normal); -} -# endif - -#else -void emit(int index) -{ - outpt.v.position = inpt[index].v.position; - outpt.v.normal = inpt[index].v.normal; - - /* TODO(sergey): Only uniform subdivisions atm. */ - vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); - vec2 st = quadst[index]; - - INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); - - gl_Position = projectionMatrix * inpt[index].v.position; - EmitVertex(); -} - -# ifdef WIREFRAME -void emit_edge(int v0, int v1) -{ - emit(v0); - emit(v1); -} -# endif - -#endif - -void main() -{ - gl_PrimitiveID = gl_PrimitiveIDIn; - -#ifdef FLAT_SHADING - vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz; - vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz; - vec3 flat_normal = normalize(cross(B, A)); -# ifndef WIREFRAME - emit(0, flat_normal); - emit(1, flat_normal); - emit(3, flat_normal); - emit(2, flat_normal); -# else - emit_edge(0, 1, flat_normal); - emit_edge(1, 2, flat_normal); - emit_edge(2, 3, flat_normal); - emit_edge(3, 0, flat_normal); -# endif -#else -# ifndef WIREFRAME - emit(0); - emit(1); - emit(3); - emit(2); -# else - emit_edge(0, 1); - emit_edge(1, 2); - emit_edge(2, 3); - emit_edge(3, 0); -# endif -#endif - - EndPrimitive(); -} diff --git a/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl deleted file mode 100644 index 6fcf5ad20cd..00000000000 --- a/intern/opensubdiv/gpu_shader_opensubdiv_vertex.glsl +++ /dev/null @@ -1,46 +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 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -struct VertexData { - vec4 position; - vec3 normal; - vec2 uv; -}; - -in vec3 normal; -in vec4 position; - -uniform mat4 modelViewMatrix; -uniform mat3 normalMatrix; - -out block { - VertexData v; -} outpt; - -void main() -{ - outpt.v.position = modelViewMatrix * position; - outpt.v.normal = normalize(normalMatrix * normal); -} diff --git a/intern/opensubdiv/internal/opensubdiv.cc b/intern/opensubdiv/internal/opensubdiv.cc new file mode 100644 index 00000000000..c2945ed25ab --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv.cc @@ -0,0 +1,99 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin +// Contributor(s): Brecht van Lommel + +#include "opensubdiv_capi.h" + +#ifdef _MSC_VER +# include +#endif + +#include + +#include "opensubdiv_device_context_opencl.h" +#include "opensubdiv_device_context_cuda.h" +#include "opensubdiv_gl_mesh_capi.h" + +void openSubdiv_init(void) { + // Ensure all OpenGL strings are cached. + openSubdiv_getAvailableEvaluators(); +} + +void openSubdiv_cleanup(void) { + openSubdiv_deinitGLMeshDrawingResources(); +} + +int openSubdiv_getAvailableEvaluators(void) { + int flags = OPENSUBDIV_EVALUATOR_CPU; + +#ifdef OPENSUBDIV_HAS_OPENMP + flags |= OPENSUBDIV_EVALUATOR_OPENMP; +#endif + +#ifdef OPENSUBDIV_HAS_OPENCL + if (CLDeviceContext::HAS_CL_VERSION_1_1()) { + flags |= OPENSUBDIV_EVALUATOR_OPENCL; + } +#endif + +#ifdef OPENSUBDIV_HAS_CUDA + if (CudaDeviceContext::HAS_CUDA_VERSION_4_0()) { + flags |= OPENSUBDIV_EVALUATOR_CUDA; + } +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK + if (GLEW_VERSION_4_1) { + flags |= OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK; + } +#endif + +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE + if (GLEW_VERSION_4_3 || GLEW_ARB_compute_shader) { + flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE; + } +#endif + + return flags; +} + +int openSubdiv_getVersionHex(void) { +#if defined(OPENSUBDIV_VERSION_NUMBER) + return OPENSUBDIV_VERSION_NUMBER; +#elif defined(OPENSUBDIV_VERSION_MAJOR) + return OPENSUBDIV_VERSION_MAJOR * 10000 + + OPENSUBDIV_VERSION_MINOR * 100 + + OPENSUBDIV_VERSION_PATCH; +#elif defined(OPENSUBDIV_VERSION) + const char* version = STRINGIFY(OPENSUBDIV_VERSION); + if (version[0] == 'v') { + version += 1; + } + int major = 0, minor = 0, patch = 0; + vector tokens; + opensubdiv_capi::stringSplit(&tokens, version, "_", true); + if (tokens.size() == 3) { + major = atoi(tokens[0].c_str()); + minor = atoi(tokens[1].c_str()); + patch = atoi(tokens[2].c_str()); + } + return major * 10000 + minor * 100 + patch; +#else + return 0; +#endif +} diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc new file mode 100644 index 00000000000..bd6edbb9648 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -0,0 +1,438 @@ +// Copyright 2015 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifdef _MSC_VER +# include +#endif + +#include "internal/opensubdiv_converter_factory.h" + +#include +#include +#include +#include + +#include + +#include "internal/opensubdiv_converter_internal.h" +#include "internal/opensubdiv_converter_orient.h" +#include "internal/opensubdiv_internal.h" +#include "opensubdiv_converter_capi.h" + +struct TopologyRefinerData { + const OpenSubdiv_Converter* converter; +}; + +namespace OpenSubdiv { +namespace OPENSUBDIV_VERSION { +namespace Far { + +template <> +inline bool +TopologyRefinerFactory::resizeComponentTopology( + TopologyRefiner& refiner, + const TopologyRefinerData& cb_data) { + const OpenSubdiv_Converter* converter = cb_data.converter; + /// Faces and face-vertices. + const int num_faces = converter->getNumFaces(converter); + setNumBaseFaces(refiner, num_faces); + for (int face_index = 0; face_index < num_faces; ++face_index) { + const int num_face_vertices = + converter->getNumFaceVertices(converter, face_index); + setNumBaseFaceVertices(refiner, face_index, num_face_vertices); + } + // Edges and edge-faces. + const int num_edges = converter->getNumEdges(converter); + setNumBaseEdges(refiner, num_edges); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + const int num_edge_faces = + converter->getNumEdgeFaces(converter, edge_index); + setNumBaseEdgeFaces(refiner, edge_index, num_edge_faces); + } + // Vertices and vertex-faces and vertex-edges. + const int num_vertices = converter->getNumVertices(converter); + setNumBaseVertices(refiner, num_vertices); + for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { + const int num_vert_edges = + converter->getNumVertexEdges(converter, vertex_index); + const int num_vert_faces = + converter->getNumVertexFaces(converter, vertex_index); + setNumBaseVertexEdges(refiner, vertex_index, num_vert_edges); + setNumBaseVertexFaces(refiner, vertex_index, num_vert_faces); + } + return true; +} + +template <> +inline bool +TopologyRefinerFactory::assignComponentTopology( + TopologyRefiner& refiner, + const TopologyRefinerData& cb_data) { + using Far::IndexArray; + const OpenSubdiv_Converter* converter = cb_data.converter; + // Face relations. + const int num_faces = converter->getNumFaces(converter); + for (int face_index = 0; face_index < num_faces; ++face_index) { + IndexArray dst_face_verts = getBaseFaceVertices(refiner, face_index); + converter->getFaceVertices(converter, face_index, &dst_face_verts[0]); + IndexArray dst_face_edges = getBaseFaceEdges(refiner, face_index); + converter->getFaceEdges(converter, face_index, &dst_face_edges[0]); + } + // Edge relations. + const int num_edges = converter->getNumEdges(converter); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + // Edge-vertices. + IndexArray dst_edge_vertices = getBaseEdgeVertices(refiner, edge_index); + converter->getEdgeVertices(converter, edge_index, &dst_edge_vertices[0]); + // Edge-faces. + IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge_index); + converter->getEdgeFaces(converter, edge_index, &dst_edge_faces[0]); + } +// TODO(sergey): Find a way to move this to an utility function. +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + // Make face normals consistent. + std::vector face_used(num_faces, false); + std::stack traverse_stack; + int face_start = 0, num_traversed_faces = 0; + // Traverse all islands. + while (num_traversed_faces != num_faces) { + // Find first face of any untraversed islands. + while (face_used[face_start]) { + ++face_start; + } + // Add first face to the stack. + traverse_stack.push(face_start); + face_used[face_start] = true; + // Go over whole connected component. + while (!traverse_stack.empty()) { + int face = traverse_stack.top(); + traverse_stack.pop(); + IndexArray face_edges = getBaseFaceEdges(refiner, face); + ConstIndexArray face_vertices = getBaseFaceVertices(refiner, face); + for (int i = 0; i < face_edges.size(); ++i) { + const int edge = face_edges[i]; + ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); + if (edge_faces.size() != 2) { + /* Can't make consistent normals for non-manifolds. */ + continue; + } + ConstIndexArray edge_vertices = getBaseEdgeVertices(refiner, edge); + // Get winding of the reference face. + const int vert0_of_face = face_vertices.FindIndex(edge_vertices[0]); + const int vert1_of_face = face_vertices.FindIndex(edge_vertices[1]); + const int delta_face = + opensubdiv_capi::getLoopWinding(vert0_of_face, vert1_of_face); + for (int edge_face = 0; edge_face < edge_faces.size(); ++edge_face) { + const int other_face_index = edge_faces[edge_face]; + // Never re-traverse faces, only move forward. + if (face_used[other_face_index]) { + continue; + } + IndexArray other_face_vertics = + getBaseFaceVertices(refiner, other_face_index); + const int vert0_of_other_face = + other_face_vertics.FindIndex(edge_vertices[0]); + const int vert1_of_other_face = + other_face_vertics.FindIndex(edge_vertices[1]); + const int delta_other_face = opensubdiv_capi::getLoopWinding( + vert0_of_other_face, vert1_of_other_face); + if (delta_face * delta_other_face > 0) { + IndexArray other_face_vertices = + getBaseFaceVertices(refiner, other_face_index); + IndexArray other_face_edges = + getBaseFaceEdges(refiner, other_face_index); + opensubdiv_capi::reverseFaceLoops(&other_face_vertices, + &other_face_edges); + } + traverse_stack.push(other_face_index); + face_used[other_face_index] = true; + } + } + ++num_traversed_faces; + } + } +#endif // OPENSUBDIV_ORIENT_TOPOLOGY + // Vertex relations. + const int num_vertices = converter->getNumVertices(converter); + std::vector vertex_faces, vertex_edges; + for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { + // Vertex-faces. + IndexArray dst_vertex_faces = getBaseVertexFaces(refiner, vertex_index); + const int num_vertex_faces = + converter->getNumVertexFaces(converter, vertex_index); + vertex_faces.resize(num_vertex_faces); + converter->getVertexFaces(converter, vertex_index, &vertex_faces[0]); + // Vertex-edges. + IndexArray dst_vertex_edges = getBaseVertexEdges(refiner, vertex_index); + const int num_vertex_edges = + converter->getNumVertexEdges(converter, vertex_index); + vertex_edges.resize(num_vertex_edges); + converter->getVertexEdges(converter, vertex_index, &vertex_edges[0]); +// TODO(sergey): Find a way to move this to an utility function. +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + // Order vertex edges and faces to be in a CCW order. + std::fill(face_used.begin(), face_used.end(), false); + // Number of edges and faces added to the ordered array. + int edge_count_ordered = 0, face_count_ordered = 0; + // Add loose edges straight into the edges array. + bool has_fan_connections = false; + for (int i = 0; i < num_vertex_edges; ++i) { + IndexArray edge_faces = getBaseEdgeFaces(refiner, vertex_edges[i]); + if (edge_faces.size() == 0) { + dst_vertex_edges[edge_count_ordered++] = vertex_edges[i]; + } else if (edge_faces.size() > 2) { + has_fan_connections = true; + } + } + if (has_fan_connections) { + // OpenSubdiv currently doesn't give us clues how to handle fan face + // connections. and since handling such connections complicates the loop + // below we simply don't do special orientation for them. + memcpy(&dst_vertex_edges[0], &vertex_edges[0], + sizeof(int) * num_vertex_edges); + memcpy(&dst_vertex_faces[0], &vertex_faces[0], + sizeof(int) * num_vertex_faces); + continue; + } + // Perform at max numbder of vert-edges iteration and try to avoid + // deadlock here for malformed mesh. + for (int global_iter = 0; global_iter < num_vertex_edges; ++global_iter) { + // Number of edges and faces which are still to be ordered. + const int num_vertex_edges_remained = + num_vertex_edges - edge_count_ordered; + const int num_vertex_faces_remained = + num_vertex_faces - face_count_ordered; + if (num_vertex_edges_remained == 0 && num_vertex_faces_remained == 0) { + // All done, nothing to do anymore. + break; + } + // Face, edge and face-vertex index to start traversal from. + int face_start = -1, edge_start = -1, face_vertex_start = -1; + if (num_vertex_edges_remained == num_vertex_faces_remained) { + // Vertex is either complete manifold or is connected to several + // manifold islands (hourglass-like configuration), can pick up + // random edge unused and start from it. + // + // TODO(sergey): Start from previous edge from which traversal began at + // previous iteration. + for (int i = 0; i < num_vertex_edges; ++i) { + face_start = vertex_faces[i]; + if (!face_used[face_start]) { + ConstIndexArray face_vertices = + getBaseFaceVertices(refiner, face_start); + ConstIndexArray face_edges = getBaseFaceEdges(refiner, face_start); + face_vertex_start = face_vertices.FindIndex(vertex_index); + edge_start = face_edges[face_vertex_start]; + break; + } + } + } else { + // Special handle of non-manifold vertex. + for (int i = 0; i < num_vertex_edges; ++i) { + edge_start = vertex_edges[i]; + IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_start); + if (edge_faces.size() == 1) { + face_start = edge_faces[0]; + if (!face_used[face_start]) { + ConstIndexArray face_vertices = + getBaseFaceVertices(refiner, face_start); + ConstIndexArray face_edges = + getBaseFaceEdges(refiner, face_start); + face_vertex_start = face_vertices.FindIndex(vertex_index); + if (edge_start == face_edges[face_vertex_start]) { + break; + } + } + } + // Reset indices for sanity check below. + face_start = edge_start = face_vertex_start = -1; + } + } + // Sanity check. + assert(face_start != -1); + assert(edge_start != -1); + assert(face_vertex_start != -1); + // Traverse faces starting from the current one. */ + int edge_first = edge_start; + dst_vertex_faces[face_count_ordered++] = face_start; + dst_vertex_edges[edge_count_ordered++] = edge_start; + face_used[face_start] = true; + while (edge_count_ordered < num_vertex_edges) { + IndexArray face_vertices = getBaseFaceVertices(refiner, face_start); + IndexArray face_edges = getBaseFaceEdges(refiner, face_start); + int face_edge_start = face_vertex_start; + int face_edge_next = (face_edge_start > 0) ? (face_edge_start - 1) + : (face_vertices.size() - 1); + Index edge_next = face_edges[face_edge_next]; + if (edge_next == edge_first) { + // Multiple manifolds found, stop for now and handle rest + // in the next iteration. + break; + } + dst_vertex_edges[edge_count_ordered++] = edge_next; + if (face_count_ordered < num_vertex_faces) { + IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_next); + assert(edge_faces.size() != 0); + if (edge_faces.size() == 1) { + assert(edge_faces[0] == face_start); + break; + } else if (edge_faces.size() != 2) { + break; + } + assert(edge_faces.size() == 2); + face_start = edge_faces[(edge_faces[0] == face_start) ? 1 : 0]; + face_vertex_start = + getBaseFaceEdges(refiner, face_start).FindIndex(edge_next); + dst_vertex_faces[face_count_ordered++] = face_start; + face_used[face_start] = true; + } + edge_start = edge_next; + } + } + // Verify ordering doesn't ruin connectivity information. + assert(face_count_ordered == num_vertex_faces); + assert(edge_count_ordered == num_vertex_edges); + opensubdiv_capi::checkOrientedVertexConnectivity( + num_vertex_edges, num_vertex_faces, &vertex_edges[0], &vertex_faces[0], + &dst_vertex_edges[0], &dst_vertex_faces[0]); + // For the release builds we're failing mesh construction so instead of + // nasty bugs the unsupported mesh will simply disappear from the viewport. + if (face_count_ordered != num_vertex_faces || + edge_count_ordered != num_vertex_edges) { + return false; + } +#else // OPENSUBDIV_ORIENT_TOPOLOGY + memcpy(&dst_vertex_edges[0], &vertex_edges[0], + sizeof(int) * num_vertex_edges); + memcpy(&dst_vertex_faces[0], &vertex_faces[0], + sizeof(int) * num_vertex_faces); +#endif // OPENSUBDIV_ORIENT_TOPOLOGY + } + populateBaseLocalIndices(refiner); + return true; +} + +template <> +inline bool TopologyRefinerFactory::assignComponentTags( + TopologyRefiner& refiner, + const TopologyRefinerData& cb_data) { + using OpenSubdiv::Sdc::Crease; + const OpenSubdiv_Converter* converter = cb_data.converter; + const int num_edges = converter->getNumEdges(converter); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + const float sharpness = + opensubdiv_capi::getCompatibleEdgeSharpness(converter, edge_index); + setBaseEdgeSharpness(refiner, edge_index, sharpness); + } + // OpenSubdiv expects non-manifold vertices to be sharp but at the time it + // handles correct cases when vertex is a corner of plane. Currently mark + // vertices which are adjacent to a loose edge as sharp, but this decision + // needs some more investigation. + const int num_vertices = converter->getNumVertices(converter); + for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { + ConstIndexArray vertex_edges = getBaseVertexEdges(refiner, vertex_index); + for (int i = 0; i < vertex_edges.size(); ++i) { + const int edge_index = vertex_edges[i]; + ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge_index); + if (edge_faces.size() == 0) { + setBaseVertexSharpness(refiner, vertex_index, + Crease::SHARPNESS_INFINITE); + break; + } + } + if (vertex_edges.size() == 2) { + const int edge0 = vertex_edges[0], edge1 = vertex_edges[1]; + const float sharpness0 = converter->getEdgeSharpness(converter, edge0); + const float sharpness1 = converter->getEdgeSharpness(converter, edge1); + const float sharpness = std::min(sharpness0, sharpness1); + setBaseVertexSharpness(refiner, vertex_index, sharpness); + } + } + return true; +} + +template <> +inline bool +TopologyRefinerFactory::assignFaceVaryingTopology( + TopologyRefiner& refiner, + const TopologyRefinerData& cb_data) { + const OpenSubdiv_Converter* converter = cb_data.converter; + const int num_layers = converter->getNumUVLayers(converter); + if (num_layers <= 0) { + // No UV maps, we can skip any face-varying data. + return true; + } + const int num_faces = getNumBaseFaces(refiner); + for (int layer_index = 0; layer_index < num_layers; ++layer_index) { + converter->precalcUVLayer(converter, layer_index); + const int num_uvs = converter->getNumUVCoordinates(converter); + // Fill in per-corner index of the UV. + const int channel = createBaseFVarChannel(refiner, num_uvs); + for (int face_index = 0; face_index < num_faces; ++face_index) { + Far::IndexArray dst_face_uvs = + getBaseFaceFVarValues(refiner, face_index, channel); + for (int corner = 0; corner < dst_face_uvs.size(); ++corner) { + const int uv_index = + converter->getFaceCornerUVIndex(converter, face_index, corner); + dst_face_uvs[corner] = uv_index; + } + } + converter->finishUVLayer(converter); + } + return true; +} + +template <> +inline void TopologyRefinerFactory::reportInvalidTopology( + TopologyError /*errCode*/, const char* msg, + const TopologyRefinerData& /*mesh*/) { + printf("OpenSubdiv Error: %s\n", msg); +} + +} /* namespace Far */ +} /* namespace OPENSUBDIV_VERSION */ +} /* namespace OpenSubdiv */ + +namespace opensubdiv_capi { + +OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter( + OpenSubdiv_Converter* converter) { + using OpenSubdiv::Sdc::Options; + using OpenSubdiv::Far::TopologyRefinerFactory; + const OpenSubdiv::Sdc::SchemeType scheme_type = + getSchemeTypeFromCAPI(converter->getSchemeType(converter)); + const Options::FVarLinearInterpolation linear_interpolation = + getFVarLinearInterpolationFromCAPI( + converter->getFVarLinearInterpolation(converter)); + Options options; + options.SetVtxBoundaryInterpolation(Options::VTX_BOUNDARY_EDGE_ONLY); + options.SetCreasingMethod(Options::CREASE_UNIFORM); + options.SetFVarLinearInterpolation(linear_interpolation); + + TopologyRefinerFactory::Options topology_options( + scheme_type, options); +#ifdef OPENSUBDIV_VALIDATE_TOPOLOGY + topology_options.validateFullTopology = true; +#endif + TopologyRefinerData cb_data; + cb_data.converter = converter; + return TopologyRefinerFactory::Create( + cb_data, topology_options); +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.h b/intern/opensubdiv/internal/opensubdiv_converter_factory.h new file mode 100644 index 00000000000..451418813e1 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.h @@ -0,0 +1,37 @@ +// Copyright 2015 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CONVERTER_FACTORY_H_ +#define OPENSUBDIV_CONVERTER_FACTORY_H_ + +#ifdef _MSC_VER +# include +#endif + +#include + +struct OpenSubdiv_Converter; + +namespace opensubdiv_capi { + +OpenSubdiv::Far::TopologyRefiner* createOSDTopologyRefinerFromConverter( + struct OpenSubdiv_Converter* converter); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_CONVERTER_FACTORY_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc new file mode 100644 index 00000000000..56b5657121d --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc @@ -0,0 +1,70 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifdef _MSC_VER +# include +#endif + +#include "internal/opensubdiv_converter_internal.h" + +#include +#include + +namespace opensubdiv_capi { + +OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type) { + switch (type) { + case OSD_SCHEME_BILINEAR: + return OpenSubdiv::Sdc::SCHEME_BILINEAR; + case OSD_SCHEME_CATMARK: + return OpenSubdiv::Sdc::SCHEME_CATMARK; + case OSD_SCHEME_LOOP: + return OpenSubdiv::Sdc::SCHEME_LOOP; + } + assert(!"Unknown scheme type passed via C-API"); + return OpenSubdiv::Sdc::SCHEME_CATMARK; +} + +OpenSubdiv::Sdc::Options::FVarLinearInterpolation +getFVarLinearInterpolationFromCAPI( + OpenSubdiv_FVarLinearInterpolation linear_interpolation) { + typedef OpenSubdiv::Sdc::Options Options; + switch (linear_interpolation) { + case OSD_FVAR_LINEAR_INTERPOLATION_NONE: + return Options::FVAR_LINEAR_NONE; + case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: + return Options::FVAR_LINEAR_CORNERS_ONLY; + case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: + return Options::FVAR_LINEAR_BOUNDARIES; + case OSD_FVAR_LINEAR_INTERPOLATION_ALL: + return Options::FVAR_LINEAR_ALL; + } + assert(!"Unknown fvar linear interpolation passed via C-API"); + return Options::FVAR_LINEAR_NONE; +} + +float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, + int edge_index) { + if (converter->getNumEdgeFaces(converter, edge_index) == 2) { + return converter->getEdgeSharpness(converter, edge_index); + } else { + return OpenSubdiv::Sdc::Crease::SHARPNESS_INFINITE; + } +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h new file mode 100644 index 00000000000..68518d67884 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h @@ -0,0 +1,50 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CONVERTER_INTERNAL_H_ +#define OPENSUBDIV_CONVERTER_INTERNAL_H_ + +#ifdef _MSC_VER +# include +#endif + +#include +#include + +#include "opensubdiv_converter_capi.h" + +struct OpenSubdiv_Converter; + +namespace opensubdiv_capi { + +// Convert scheme type from C-API enum to an OpenSubdiv native enum. +OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type); + +// Convert face-varying interpolation type from C-API to an OpenSubdiv +// native enum. +OpenSubdiv::Sdc::Options::FVarLinearInterpolation +getFVarLinearInterpolationFromCAPI( + OpenSubdiv_FVarLinearInterpolation linear_interpolation); + +// Get edge sharpness in a way which makes OpenSubdiv happy. +float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, + int edge_index); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_CONVERTER_INTERNAL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.cc b/intern/opensubdiv/internal/opensubdiv_converter_orient.cc new file mode 100644 index 00000000000..449e9028180 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_orient.cc @@ -0,0 +1,66 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_converter_orient.h" + +#include "internal/opensubdiv_internal.h" + +namespace opensubdiv_capi { + +void checkOrientedVertexConnectivity(const int num_vertex_edges, + const int num_vertex_faces, + const int* vertex_edges, + const int* vertex_faces, + const int* dst_vertex_edges, + const int* dst_vertex_faces) { +#ifndef NDEBUG + for (int i = 0; i < num_vertex_faces; ++i) { + bool found = false; + for (int j = 0; j < num_vertex_faces; ++j) { + if (vertex_faces[i] == dst_vertex_faces[j]) { + found = true; + break; + } + } + if (!found) { + assert(!"vert-faces connectivity ruined"); + } + } + for (int i = 0; i < num_vertex_edges; ++i) { + bool found = false; + for (int j = 0; j < num_vertex_edges; ++j) { + if (vertex_edges[i] == dst_vertex_edges[j]) { + found = true; + break; + } + } + if (!found) { + assert(!"vert-edges connectivity ruined"); + } + } +#else + (void) num_vertex_edges; + (void) num_vertex_faces; + (void) vertex_edges; + (void) vertex_faces; + (void) dst_vertex_edges; + (void) dst_vertex_faces; +#endif +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient.h b/intern/opensubdiv/internal/opensubdiv_converter_orient.h new file mode 100644 index 00000000000..b783007a0cb --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_orient.h @@ -0,0 +1,50 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CONVERTER_ORIENT_H_ +#define OPENSUBDIV_CONVERTER_ORIENT_H_ + +#include + +// Set of utility functions which are needed to bring topology to an orientation +// (or, winding, if you wish) which OpenSubdiv expects. + +namespace opensubdiv_capi { + +inline void reverseFaceVertices(int* face_vertices, const int num_vertices); + +// TODO(sergey): Document which value corresponds to which winding. +inline int getLoopWinding(int vert0_of_face, int vert1_of_face); + +inline void reverseFaceLoops( + OpenSubdiv::Far::IndexArray* face_vertices, + OpenSubdiv::Far::IndexArray* face_edges); + +// Used for debugging, checks whether orientation happened correct. +void checkOrientedVertexConnectivity(const int num_vertex_edges, + const int num_vertex_faces, + const int* vertex_edges, + const int* vertex_faces, + const int* dst_vertex_edges, + const int* dst_vertex_faces); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_CONVERTER_ORIENT_H_ + +#include "internal/opensubdiv_converter_orient_impl.h" diff --git a/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h b/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h new file mode 100644 index 00000000000..3125bc600e5 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_converter_orient_impl.h @@ -0,0 +1,66 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_ +#define OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_ + +#include "internal/opensubdiv_converter_orient.h" + +#include +#include +#include + +namespace opensubdiv_capi { + +inline void reverseFaceVertices(int* face_vertices, const int num_vertices) { + int last_vert = face_vertices[num_vertices - 1]; + for (int i = num_vertices - 1; i > 0; --i) { + face_vertices[i] = face_vertices[i - 1]; + } + face_vertices[0] = last_vert; +} + +inline int getLoopWinding(int vert0_of_face, int vert1_of_face) { + int delta_face = vert1_of_face - vert0_of_face; + if (abs(delta_face) != 1) { + if (delta_face > 0) { + delta_face = -1; + } else { + delta_face = 1; + } + } + return delta_face; +} + +inline void reverseFaceLoops( + OpenSubdiv::Far::IndexArray* face_vertices, + OpenSubdiv::Far::IndexArray* face_edges) { + const int num_face_vertices = face_vertices->size(); + for (int i = 0; i < num_face_vertices / 2; ++i) { + const int j = num_face_vertices - i - 1; + if (i != j) { + std::swap((*face_vertices)[i], (*face_vertices)[j]); + std::swap((*face_edges)[i], (*face_edges)[j]); + } + } + reverseFaceVertices(&(*face_vertices)[0], num_face_vertices); +} + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc new file mode 100644 index 00000000000..875f503b9ab --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.cc @@ -0,0 +1,226 @@ +// Adopted from OpenSubdiv with the following license: +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. + +#ifdef OPENSUBDIV_HAS_CUDA + +#ifdef _MSC_VER +# include +#endif + +#include "opensubdiv_device_context_cuda.h" + +#if defined(_WIN32) +# include +#elif defined(__APPLE__) +# include +#else +# include +# include +#endif + +#include +#include +#include +#include +#include + +#define message(fmt, ...) +// #define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) +#define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) + +namespace { + +int getCudaDeviceForCurrentGLContext() { + // Find and use the CUDA device for the current GL context + unsigned int interop_device_count = 0; + int interopDevices[1]; + cudaError_t status = cudaGLGetDevices(&interop_device_count, + interopDevices, + 1, + cudaGLDeviceListCurrentFrame); + if (status == cudaErrorNoDevice || interop_device_count != 1) { + message("CUDA no interop devices found.\n"); + return 0; + } + int device = interopDevices[0]; +#if defined(_WIN32) + return device; +#elif defined(__APPLE__) + return device; +#else // X11 + Display* display = glXGetCurrentDisplay(); + int screen = DefaultScreen(display); + if (device != screen) { + error("The CUDA interop device (%d) does not match " + "the screen used by the current GL context (%d), " + "which may cause slow performance on systems " + "with multiple GPU devices.", + device, screen); + } + message("CUDA init using device for current GL context: %d\n", device); + return device; +#endif +} + +// Beginning of GPU Architecture definitions. +int convertSMVer2Cores_local(int major, int minor) { + // Defines for GPU Architecture types (using the SM version to determine + // the # of cores per SM + typedef struct { + int SM; // 0xMm (hexidecimal notation), + // M = SM Major version, + // and m = SM minor version + int Cores; + } sSMtoCores; + + sSMtoCores nGpuArchCoresPerSM[] = { + {0x10, 8}, // Tesla Generation (SM 1.0) G80 class. + {0x11, 8}, // Tesla Generation (SM 1.1) G8x class. + {0x12, 8}, // Tesla Generation (SM 1.2) G9x class. + {0x13, 8}, // Tesla Generation (SM 1.3) GT200 class. + {0x20, 32}, // Fermi Generation (SM 2.0) GF100 class. + {0x21, 48}, // Fermi Generation (SM 2.1) GF10x class. + {0x30, 192}, // Fermi Generation (SM 3.0) GK10x class. + {-1, -1}}; + int index = 0; + while (nGpuArchCoresPerSM[index].SM != -1) { + if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) { + return nGpuArchCoresPerSM[index].Cores; + } + index++; + } + printf("MapSMtoCores undefined SMversion %d.%d!\n", major, minor); + return -1; +} + +// This function returns the best GPU (with maximum GFLOPS). +int cutGetMaxGflopsDeviceId() { + int current_device = 0, sm_per_multiproc = 0; + int max_compute_perf = 0, max_perf_device = -1; + int device_count = 0, best_SM_arch = 0; + int compat_major, compat_minor; + cuDeviceGetCount(&device_count); + // Find the best major SM Architecture GPU device. + while (current_device < device_count) { + cuDeviceComputeCapability(&compat_major, &compat_minor, current_device); + if (compat_major > 0 && compat_major < 9999) { + best_SM_arch = std::max(best_SM_arch, compat_major); + } + current_device++; + } + // Find the best CUDA capable GPU device. + current_device = 0; + while (current_device < device_count) { + cuDeviceComputeCapability(&compat_major, &compat_minor, current_device); + if (compat_major == 9999 && compat_minor == 9999) { + sm_per_multiproc = 1; + } else { + sm_per_multiproc = convertSMVer2Cores_local(compat_major, compat_minor); + } + int multi_processor_count; + cuDeviceGetAttribute(&multi_processor_count, + CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, + current_device); + int clock_rate; + cuDeviceGetAttribute(&clock_rate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, + current_device); + int compute_perf = multi_processor_count * sm_per_multiproc * clock_rate; + if (compute_perf > max_compute_perf) { + /* If we find GPU with SM major > 2, search only these */ + if (best_SM_arch > 2) { + /* If our device==dest_SM_arch, choose this, or else pass. */ + if (compat_major == best_SM_arch) { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } else { + max_compute_perf = compute_perf; + max_perf_device = current_device; + } + } + ++current_device; + } + return max_perf_device; +} + +} // namespace + +bool CudaDeviceContext::HAS_CUDA_VERSION_4_0() { +#ifdef OPENSUBDIV_HAS_CUDA + static bool cuda_initialized = false; + static bool cuda_load_success = true; + if (!cuda_initialized) { + cuda_initialized = true; + +#ifdef OPENSUBDIV_HAS_CUEW + cuda_load_success = cuewInit(CUEW_INIT_CUDA) == CUEW_SUCCESS; + if (!cuda_load_success) { + fprintf(stderr, "Loading CUDA failed.\n"); + } +#endif + // Need to initialize CUDA here so getting device + // with the maximum FPLOS works fine. + if (cuInit(0) == CUDA_SUCCESS) { + // This is to deal with cases like NVidia Optimus, + // when there might be CUDA library installed but + // NVidia card is not being active. + if (cutGetMaxGflopsDeviceId() < 0) { + cuda_load_success = false; + } + } else { + cuda_load_success = false; + } + } + return cuda_load_success; +#else + return false; +#endif +} + +CudaDeviceContext::CudaDeviceContext() + : initialized_(false) { +} + +CudaDeviceContext::~CudaDeviceContext() { + cudaDeviceReset(); +} + +bool CudaDeviceContext::Initialize() { + // See if any cuda device is available. + int device_count = 0; + cudaGetDeviceCount(&device_count); + message("CUDA device count: %d\n", device_count); + if (device_count <= 0) { + return false; + } + cudaGLSetGLDevice(getCudaDeviceForCurrentGLContext()); + initialized_ = true; + return true; +} + +bool CudaDeviceContext::IsInitialized() const { + return initialized_; +} + +#endif // OPENSUBDIV_HAS_CUDA diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h new file mode 100644 index 00000000000..ef212df10f0 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_device_context_cuda.h @@ -0,0 +1,54 @@ +// Adopted from OpenSubdiv with the following license: +// +// Copyright 2013 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http: //www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. + +#ifndef OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_ +#define OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_ + +#ifdef OPENSUBDIV_HAS_CUDA + +struct ID3D11Device; + +class CudaDeviceContext { + public: + CudaDeviceContext(); + ~CudaDeviceContext(); + + static bool HAS_CUDA_VERSION_4_0(); + + // Initialze cuda device from the current GL context. + bool Initialize(); + + // Initialze cuda device from the ID3D11Device. + bool Initialize(ID3D11Device* device); + + // Returns true if the cuda device has already been initialized. + bool IsInitialized() const; + + private: + bool initialized_; +}; + +#endif // OPENSUBDIV_HAS_CUDA + +#endif // _OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc new file mode 100644 index 00000000000..00f58af894a --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.cc @@ -0,0 +1,269 @@ +// Adopted from OpenSubdiv with the following license: +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. + +#include "opensubdiv_device_context_opencl.h" + +#ifdef OPENSUBDIV_HAS_OPENCL + +#if defined(_WIN32) +# include +#elif defined(__APPLE__) +# include +#else +# include +#endif + +#include +#include +#include +#include + +#define message(...) // fprintf(stderr, __VA_ARGS__) +#define error(...) fprintf(stderr, __VA_ARGS__) + +namespace { + +// Returns the first found platform. +cl_platform_id findPlatform() { + cl_uint num_platforms; + cl_int ci_error_number = clGetPlatformIDs(0, NULL, &num_platforms); + if (ci_error_number != CL_SUCCESS) { + error("Error %d in clGetPlatformIDs call.\n", ci_error_number); + return NULL; + } + if (num_platforms == 0) { + error("No OpenCL platform found.\n"); + return NULL; + } + std::vector cl_platform_ids(num_platforms); + ci_error_number = clGetPlatformIDs(num_platforms, &cl_platform_ids[0], NULL); + char ch_buffer[1024]; + for (cl_uint i = 0; i < num_platforms; ++i) { + ci_error_number = clGetPlatformInfo(cl_platform_ids[i], + CL_PLATFORM_NAME, + sizeof(ch_buffer), + ch_buffer, + NULL); + if (ci_error_number == CL_SUCCESS) { + cl_platform_id platform_id = cl_platform_ids[i]; + return platform_id; + } + } + return NULL; +} + +// Return the device in cl_devices which supports the extension. +int findExtensionSupportedDevice(cl_device_id* cl_devices, + int num_devices, + const char* extension_name) { + // Find a device that supports sharing with GL/D3D11 + // (SLI / X-fire configurations) + cl_int cl_error_number; + for (int i = 0; i < num_devices; ++i) { + // Get extensions string size. + size_t extensions_size; + cl_error_number = clGetDeviceInfo(cl_devices[i], + CL_DEVICE_EXTENSIONS, + 0, + NULL, + &extensions_size); + if (cl_error_number != CL_SUCCESS) { + error("Error %d in clGetDeviceInfo\n", cl_error_number); + return -1; + } + if (extensions_size > 0) { + // Get extensions string. + std::string extensions('\0', extensions_size); + cl_error_number = clGetDeviceInfo(cl_devices[i], + CL_DEVICE_EXTENSIONS, + extensions_size, + &extensions[0], + &extensions_size); + if (cl_error_number != CL_SUCCESS) { + error("Error %d in clGetDeviceInfo\n", cl_error_number); + continue; + } + // Parse string. This is bit deficient since the extentions + // is space separated. + // + // The actual string would be "cl_khr_d3d11_sharing" + // or "cl_nv_d3d11_sharing" + if (extensions.find(extension_name) != std::string::npos) { + return i; + } + } + } + return -1; +} + +} // namespace + +CLDeviceContext::CLDeviceContext() + : cl_context_(NULL), + cl_command_queue_(NULL) { +} + +CLDeviceContext::~CLDeviceContext() { + if (cl_command_queue_) { + clReleaseCommandQueue(cl_command_queue_); + } + if (cl_context_) { + clReleaseContext(cl_context_); + } +} + +bool CLDeviceContext::HAS_CL_VERSION_1_1() { +#ifdef OPENSUBDIV_HAS_CLEW + static bool clew_initialized = false; + static bool clew_load_success; + if (!clew_initialized) { + clew_initialized = true; + clew_load_success = clewInit() == CLEW_SUCCESS; + if (!clew_load_success) { + error("Loading OpenCL failed.\n"); + } + } + return clew_load_success; +#endif + return true; +} + +bool CLDeviceContext::Initialize() { +#ifdef OPENSUBDIV_HAS_CLEW + if (!clGetPlatformIDs) { + error("Error clGetPlatformIDs function not bound.\n"); + return false; + } +#endif + cl_int cl_error_number; + cl_platform_id cp_platform = findPlatform(); + +#if defined(_WIN32) + cl_context_properties props[] = { + CL_GL_CONTEXT_KHR, + (cl_context_properties)wglGetCurrentContext(), + CL_WGL_HDC_KHR, + (cl_context_properties)wglGetCurrentDC(), + CL_CONTEXT_PLATFORM, + (cl_context_properties)cp_platform, + 0}; +#elif defined(__APPLE__) + CGLContextObj kCGLContext = CGLGetCurrentContext(); + CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); + cl_context_properties props[] = {CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, + (cl_context_properties)kCGLShareGroup, + 0}; +#else + cl_context_properties props[] = { + CL_GL_CONTEXT_KHR, + (cl_context_properties)glXGetCurrentContext(), + CL_GLX_DISPLAY_KHR, + (cl_context_properties)glXGetCurrentDisplay(), + CL_CONTEXT_PLATFORM, + (cl_context_properties)cp_platform, + 0}; +#endif + +#if defined(__APPLE__) + _clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, + &cl_error_number); + if (cl_error_number != CL_SUCCESS) { + error("Error %d in clCreateContext\n", cl_error_number); + return false; + } + size_t devices_size = 0; + clGetGLContextInfoAPPLE(_clContext, kCGLContext, + CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, + 0, + NULL, + &devices_size); + const int num_devices = devices_size / sizeof(cl_device_id); + if (num_devices == 0) { + error("No sharable devices.\n"); + return false; + } + std::vector cl_devices(num_devices); + clGetGLContextInfoAPPLE(_clContext, kCGLContext, + CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, + num_devices * sizeof(cl_device_id), + &cl_devices[0], + NULL); + int cl_device_used = 0; +#else // not __APPLE__ + // Get the number of GPU devices available to the platform. + cl_uint num_devices = 0; + clGetDeviceIDs(cp_platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices); + if (num_devices == 0) { + error("No CL GPU device found.\n"); + return false; + } + // Create the device list. + std::vector cl_devices(num_devices); + clGetDeviceIDs(cp_platform, + CL_DEVICE_TYPE_GPU, + num_devices, + &cl_devices[0], + NULL); + const char* extension = "cl_khr_gl_sharing"; + int cl_device_used = findExtensionSupportedDevice(&cl_devices[0], + num_devices, + extension); + if (cl_device_used < 0) { + error("No device found that supports CL/GL context sharing\n"); + return false; + } + cl_context_ = clCreateContext(props, + 1, + &cl_devices[cl_device_used], + NULL, NULL, + &cl_error_number); +#endif // not __APPLE__ + if (cl_error_number != CL_SUCCESS) { + error("Error %d in clCreateContext\n", cl_error_number); + return false; + } + cl_command_queue_ = clCreateCommandQueue(cl_context_, + cl_devices[cl_device_used], + 0, + &cl_error_number); + if (cl_error_number != CL_SUCCESS) { + error("Error %d in clCreateCommandQueue\n", cl_error_number); + return false; + } + return true; +} + +bool CLDeviceContext::IsInitialized() const { + return (cl_context_ != NULL); +} + +cl_context CLDeviceContext::GetContext() const { + return cl_context_; +} + +cl_command_queue CLDeviceContext::GetCommandQueue() const { + return cl_command_queue_; +} + +#endif // OPENSUBDIV_HAS_OPENCL diff --git a/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h new file mode 100644 index 00000000000..bc751cb6954 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_device_context_opencl.h @@ -0,0 +1,52 @@ +// Adopted from OpenSubdiv with the following license: +// +// Copyright 2015 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. + +#ifndef OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_ +#define OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_ + +#ifdef OPENSUBDIV_HAS_OPENCL +#include + +class CLDeviceContext { + public: + static bool HAS_CL_VERSION_1_1(); + + CLDeviceContext(); + ~CLDeviceContext(); + + bool Initialize(); + + bool IsInitialized() const; + + cl_context GetContext() const; + cl_command_queue GetCommandQueue() const; + + protected: + cl_context cl_context_; + cl_command_queue cl_command_queue_; +}; + +#endif // OPENSUBDIV_HAS_OPENCL + +#endif // _OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator.cc b/intern/opensubdiv/internal/opensubdiv_evaluator.cc new file mode 100644 index 00000000000..29d42a903ba --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_evaluator.cc @@ -0,0 +1,154 @@ +// Copyright 2015 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "opensubdiv_evaluator_capi.h" + +#include +#include "MEM_guardedalloc.h" + +#include "internal/opensubdiv_evaluator_internal.h" + +namespace { + +void setCoarsePositions(OpenSubdiv_Evaluator* evaluator, + const float* positions, + const int start_vertex_index, const int num_vertices) { + evaluator->internal->eval_output->setCoarsePositions(positions, + start_vertex_index, + num_vertices); +} + +void setVaryingData(OpenSubdiv_Evaluator* evaluator, + const float* varying_data, + const int start_vertex_index, const int num_vertices) { + evaluator->internal->eval_output->setVaryingData(varying_data, + start_vertex_index, + num_vertices); +} + +void setFaceVaryingData(OpenSubdiv_Evaluator* evaluator, + const float* face_varying_data, + const int start_vertex_index, const int num_vertices) { + evaluator->internal->eval_output->setFaceVaryingData(face_varying_data, + start_vertex_index, + num_vertices); +} + +void setCoarsePositionsFromBuffer(OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + evaluator->internal->eval_output->setCoarsePositionsFromBuffer( + buffer, + start_offset, + stride, + start_vertex_index, + num_vertices); +} + +void setVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + evaluator->internal->eval_output->setVaryingDataFromBuffer( + buffer, + start_offset, + stride, + start_vertex_index, + num_vertices); +} + +void setFaceVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + evaluator->internal->eval_output->setFaceVaryingDataFromBuffer( + buffer, + start_offset, + stride, + start_vertex_index, + num_vertices); +} + +void refine(OpenSubdiv_Evaluator* evaluator) { + evaluator->internal->eval_output->refine(); +} + +void evaluateLimit(OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + const float face_u, const float face_v, + float P[3], float dPdu[3], float dPdv[3]) { + evaluator->internal->eval_output->evaluateLimit(ptex_face_index, + face_u, face_v, + P, dPdu, dPdv); +} + +void evaluateVarying(OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + float face_u, float face_v, + float varying[3]) { + evaluator->internal->eval_output->evaluateVarying(ptex_face_index, + face_u, face_v, + varying); +} + +void evaluateFaceVarying(OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + float face_u, float face_v, + float face_varying[2]) { + evaluator->internal->eval_output->evaluateFaceVarying(ptex_face_index, + face_u, face_v, + face_varying); +} + +void assignFunctionPointers(OpenSubdiv_Evaluator* evaluator) { + evaluator->setCoarsePositions = setCoarsePositions; + evaluator->setVaryingData = setVaryingData; + evaluator->setFaceVaryingData = setFaceVaryingData; + + evaluator->setCoarsePositionsFromBuffer = setCoarsePositionsFromBuffer; + evaluator->setVaryingDataFromBuffer = setVaryingDataFromBuffer; + evaluator->setFaceVaryingDataFromBuffer = setFaceVaryingDataFromBuffer; + + evaluator->refine = refine; + + evaluator->evaluateLimit = evaluateLimit; + evaluator->evaluateVarying = evaluateVarying; + evaluator->evaluateFaceVarying = evaluateFaceVarying; +} + +} // namespace + +OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner( + OpenSubdiv_TopologyRefiner* topology_refiner) { + OpenSubdiv_Evaluator* evaluator = OBJECT_GUARDED_NEW(OpenSubdiv_Evaluator); + assignFunctionPointers(evaluator); + evaluator->internal = openSubdiv_createEvaluatorInternal(topology_refiner); + return evaluator; +} + +void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* evaluator) { + openSubdiv_deleteEvaluatorInternal(evaluator->internal); + OBJECT_GUARDED_DELETE(evaluator, OpenSubdiv_Evaluator); +} diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc new file mode 100644 index 00000000000..595df3eaa75 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -0,0 +1,734 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_evaluator_internal.h" + +#include +#include +#include + +#ifdef _MSC_VER +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "internal/opensubdiv_topology_refiner_internal.h" +#include "opensubdiv_topology_refiner_capi.h" + +using OpenSubdiv::Osd::BufferDescriptor; +using OpenSubdiv::Osd::CpuEvaluator; +using OpenSubdiv::Osd::CpuPatchTable; +using OpenSubdiv::Osd::CpuVertexBuffer; +using OpenSubdiv::Osd::PatchCoord; +using OpenSubdiv::Far::PatchMap; +using OpenSubdiv::Far::PatchTable; +using OpenSubdiv::Far::PatchTableFactory; +using OpenSubdiv::Far::StencilTable; +using OpenSubdiv::Far::StencilTableFactory; +using OpenSubdiv::Far::TopologyRefiner; + +namespace opensubdiv_capi { + +namespace { + +// Helper class to wrap numerous of patch coordinates into a buffer. +// Used to pass coordinates to the CPU evaluator. Other evaluators are not +// supported. +class PatchCoordBuffer : public std::vector { + public: + static PatchCoordBuffer* Create(int size) { + PatchCoordBuffer* buffer = new PatchCoordBuffer(); + buffer->resize(size); + return buffer; + } + + PatchCoord* BindCpuBuffer() { + return reinterpret_cast(&(*this)[0]); + } + + int GetNumVertices() { + return size(); + } + + void UpdateData(const PatchCoord* patch_coords, int num_patch_coords) { + memcpy(&(*this)[0], + reinterpret_cast(patch_coords), + sizeof(PatchCoord) * num_patch_coords); + } +}; + +// Helper class to wrap single of patch coord into a buffer. Used to pass +// coordinates to the CPU evaluator. Other evaluators are not supported. +class SinglePatchCoordBuffer { + public: + static SinglePatchCoordBuffer* Create() { + return new SinglePatchCoordBuffer(); + } + + SinglePatchCoordBuffer() { + } + + explicit SinglePatchCoordBuffer(const PatchCoord &patch_coord) + : patch_coord_(patch_coord) { + } + + PatchCoord* BindCpuBuffer() { + return &patch_coord_; + } + + int GetNumVertices() { + return 1; + } + + void UpdateData(const PatchCoord &patch_coord) { + patch_coord_ = patch_coord; + } + + protected: + PatchCoord patch_coord_; +}; + +// Helper class which is aimed to be used in cases when buffer is small enough +// and better to be allocated in stack rather than in heap. +// +// TODO(sergey): Check if bare arrays could be used by CPU evaluator. +template +class StackAllocatedBuffer { + public: + static PatchCoordBuffer* Create(int /*size*/) { + // TODO(sergey): Validate that requested dize is smaller than static + // stack memory size. + return new StackAllocatedBuffer(); + } + + float* BindCpuBuffer() { + return &data_[0]; + } + + int GetNumVertices() { + return num_vertices; + } + + // TODO(sergey): Support UpdateData(). + protected: + float data_[element_size * num_vertices]; +}; + +// Volatile evaluator which can be used from threads. +// +// TODO(sergey): Make it possible to evaluate coordinates in chunks. +// TODO(sergey): Make it possible to evaluate multiple face varying layers. +// (or maybe, it's cheap to create new evaluator for existing +// topology to evaluate all needed face varying layers?) +template +class VolatileEvalOutput { + public: + typedef OpenSubdiv::Osd::EvaluatorCacheT EvaluatorCache; + + VolatileEvalOutput(const StencilTable* vertex_stencils, + const StencilTable* varying_stencils, + const StencilTable* face_varying_stencils, + const int face_varying_channel, + const int face_varying_width, + const PatchTable* patch_table, + EvaluatorCache* evaluator_cache = NULL, + DEVICE_CONTEXT* device_context = NULL) + : src_desc_(0, 3, 3), + src_varying_desc_(0, 3, 3), + src_face_varying_desc_(0, face_varying_width, face_varying_width), + face_varying_channel_(face_varying_channel), + face_varying_width_(face_varying_width), + evaluator_cache_(evaluator_cache), + device_context_(device_context) { + // Total number of vertices = coarse points + refined points + local points. + int num_total_vertices = vertex_stencils->GetNumControlVertices() + + vertex_stencils->GetNumStencils(); + num_coarse_vertices_ = vertex_stencils->GetNumControlVertices(); + using OpenSubdiv::Osd::convertToCompatibleStencilTable; + src_data_ = + SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_); + src_varying_data_ = + SRC_VERTEX_BUFFER::Create(3, num_total_vertices, device_context_); + patch_table_ = PATCH_TABLE::Create(patch_table, device_context_); + patch_coords_ = NULL; + vertex_stencils_ = convertToCompatibleStencilTable( + vertex_stencils, device_context_); + varying_stencils_ = convertToCompatibleStencilTable( + varying_stencils, device_context_); + if (face_varying_stencils != NULL) { + num_coarse_face_varying_vertices_ = + face_varying_stencils->GetNumControlVertices(); + const int num_total_face_varying_vertices = + face_varying_stencils->GetNumControlVertices() + + face_varying_stencils->GetNumStencils(); + src_face_varying_data_ = + EVAL_VERTEX_BUFFER::Create(2, + num_total_face_varying_vertices, + device_context_); + face_varying_stencils_ = convertToCompatibleStencilTable( + face_varying_stencils, device_context_); + } else { + num_coarse_face_varying_vertices_ = 0; + src_face_varying_data_ = NULL; + face_varying_stencils_ = NULL; + } + } + + ~VolatileEvalOutput() { + delete src_data_; + delete src_varying_data_; + delete src_face_varying_data_; + delete patch_table_; + delete vertex_stencils_; + delete varying_stencils_; + delete face_varying_stencils_; + } + + // TODO(sergey): Implement binding API. + + void updateData(const float* src, int start_vertex, int num_vertices) { + src_data_->UpdateData(src, start_vertex, num_vertices, device_context_); + } + + void updateVaryingData(const float* src, int start_vertex, int num_vertices) { + src_varying_data_->UpdateData(src, + start_vertex, + num_vertices, + device_context_); + } + + void updateFaceVaryingData(const float* src, + int start_vertex, + int num_vertices) { + src_face_varying_data_->UpdateData(src, + start_vertex, + num_vertices, + device_context_); + } + + bool hasVaryingData() const { + // return varying_stencils_ != NULL; + // TODO(sergey): Check this based on actual topology. + return false; + } + + bool hasFaceVaryingData() const { + return face_varying_stencils_ != NULL; + } + + void refine() { + // Evaluate vertex positions. + BufferDescriptor dst_desc = src_desc_; + dst_desc.offset += num_coarse_vertices_ * src_desc_.stride; + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_desc_, + dst_desc, + device_context_); + EVALUATOR::EvalStencils(src_data_, src_desc_, + src_data_, dst_desc, + vertex_stencils_, + eval_instance, + device_context_); + // Evaluate varying data. + if (hasVaryingData()) { + BufferDescriptor dst_varying_desc = src_varying_desc_; + dst_varying_desc.offset += + num_coarse_vertices_ * src_varying_desc_.stride; + eval_instance = OpenSubdiv::Osd::GetEvaluator( + evaluator_cache_, + src_varying_desc_, + dst_varying_desc, + device_context_); + EVALUATOR::EvalStencils(src_varying_data_, src_varying_desc_, + src_varying_data_, dst_varying_desc, + varying_stencils_, + eval_instance, device_context_); + } + // Evaluate face-varying data. + if (hasFaceVaryingData()) { + BufferDescriptor dst_face_varying_desc = src_face_varying_desc_; + dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ * + src_face_varying_desc_.stride; + eval_instance = OpenSubdiv::Osd::GetEvaluator( + evaluator_cache_, + src_face_varying_desc_, + dst_face_varying_desc, + device_context_); + EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_, + src_face_varying_data_, dst_face_varying_desc, + face_varying_stencils_, + eval_instance, + device_context_); + } + } + + void evalPatchCoord(const PatchCoord& patch_coord, float P[3]) { + StackAllocatedBuffer<6, 1> vertex_data; + // TODO(sergey): Varying data is interleaved in vertex array, so need to + // adjust stride if there is a varying data. + // BufferDescriptor vertex_desc(0, 3, 6); + BufferDescriptor vertex_desc(0, 3, 3); + SinglePatchCoordBuffer patch_coord_buffer(patch_coord); + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_desc_, + vertex_desc, + device_context_); + EVALUATOR::EvalPatches(src_data_, + src_desc_, + &vertex_data, + vertex_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + eval_instance, + device_context_); + const float* refined_vertices = vertex_data.BindCpuBuffer(); + memcpy(P, refined_vertices, sizeof(float) * 3); + } + + void evalPatchesWithDerivatives(const PatchCoord& patch_coord, + float P[3], + float dPdu[3], float dPdv[3]) { + StackAllocatedBuffer<6, 1> vertex_data, derivatives; + // TODO(sergey): Varying data is interleaved in vertex array, so need to + // adjust stride if there is a varying data. + // BufferDescriptor vertex_desc(0, 3, 6); + BufferDescriptor vertex_desc(0, 3, 3); + BufferDescriptor du_desc(0, 3, 6), dv_desc(3, 3, 6); + SinglePatchCoordBuffer patch_coord_buffer(patch_coord); + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_desc_, + vertex_desc, + du_desc, dv_desc, + device_context_); + EVALUATOR::EvalPatches(src_data_, src_desc_, + &vertex_data, vertex_desc, + &derivatives, du_desc, + &derivatives, dv_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + eval_instance, + device_context_); + const float* refined_vertices = vertex_data.BindCpuBuffer(); + memcpy(P, refined_vertices, sizeof(float) * 3); + if (dPdu != NULL || dPdv != NULL) { + const float* refined_derivatives = derivatives.BindCpuBuffer(); + if (dPdu != NULL) { + memcpy(dPdu, refined_derivatives, sizeof(float) * 3); + } + if (dPdv != NULL) { + memcpy(dPdv, refined_derivatives + 3, sizeof(float) * 3); + } + } + } + + void evalPatchVarying(const PatchCoord& patch_coord, float varying[3]) { + StackAllocatedBuffer<6, 1> varying_data; + BufferDescriptor varying_desc(3, 3, 6); + SinglePatchCoordBuffer patch_coord_buffer(patch_coord); + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_varying_desc_, + varying_desc, + device_context_); + EVALUATOR::EvalPatchesVarying(src_varying_data_, src_varying_desc_, + &varying_data, varying_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + eval_instance, + device_context_); + const float* refined_varying = varying_data.BindCpuBuffer(); + memcpy(varying, refined_varying, sizeof(float) * 3); + } + + void evalPatchFaceVarying(const PatchCoord& patch_coord, + float face_varying[2]) { + StackAllocatedBuffer<2, 1> face_varying_data; + BufferDescriptor face_varying_desc(0, 2, 2); + SinglePatchCoordBuffer patch_coord_buffer(patch_coord); + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_face_varying_desc_, + face_varying_desc, + device_context_); + EVALUATOR::EvalPatchesFaceVarying( + src_face_varying_data_, src_face_varying_desc_, + &face_varying_data, face_varying_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + face_varying_channel_, + eval_instance, + device_context_); + const float* refined_face_varying = face_varying_data.BindCpuBuffer(); + memcpy(face_varying, refined_face_varying, sizeof(float) * 2); + } + + private: + SRC_VERTEX_BUFFER* src_data_; + SRC_VERTEX_BUFFER* src_varying_data_; + EVAL_VERTEX_BUFFER* src_face_varying_data_; + PatchCoordBuffer* patch_coords_; + PATCH_TABLE* patch_table_; + BufferDescriptor src_desc_; + BufferDescriptor src_varying_desc_; + BufferDescriptor src_face_varying_desc_; + + int num_coarse_vertices_; + int face_varying_channel_; + int face_varying_width_; + int num_coarse_face_varying_vertices_; + + const STENCIL_TABLE* vertex_stencils_; + const STENCIL_TABLE* varying_stencils_; + const STENCIL_TABLE* face_varying_stencils_; + + EvaluatorCache* evaluator_cache_; + DEVICE_CONTEXT* device_context_; +}; + +} // namespace + +// Note: Define as a class instead of typedcef to make it possible +// to have anonymous class in opensubdiv_evaluator_internal.h +class CpuEvalOutput : public VolatileEvalOutput { + public: + CpuEvalOutput(const StencilTable* vertex_stencils, + const StencilTable* varying_stencils, + const StencilTable* face_varying_stencils, + const int face_varying_channel, + const int face_varying_width, + const PatchTable* patch_table, + EvaluatorCache* evaluator_cache = NULL) + : VolatileEvalOutput (vertex_stencils, + varying_stencils, + face_varying_stencils, + face_varying_channel, + face_varying_width, + patch_table, + evaluator_cache) { + } +}; + +//////////////////////////////////////////////////////////////////////////////// +// Evaluator wrapper for anonymous API. + +CpuEvalOutputAPI::CpuEvalOutputAPI(CpuEvalOutput* implementation, + OpenSubdiv::Far::PatchMap* patch_map) + : implementation_(implementation), + patch_map_(patch_map) { +} + +CpuEvalOutputAPI::~CpuEvalOutputAPI() { + delete implementation_; +} + +void CpuEvalOutputAPI::setCoarsePositions(const float* positions, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + implementation_->updateData(positions, start_vertex_index, num_vertices); +} + +void CpuEvalOutputAPI::setVaryingData(const float* varying_data, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + implementation_->updateVaryingData(varying_data, + start_vertex_index, + num_vertices); +} + +void CpuEvalOutputAPI::setFaceVaryingData(const float* face_varying_data, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + implementation_->updateFaceVaryingData(face_varying_data, + start_vertex_index, + num_vertices); +} + +void CpuEvalOutputAPI::setCoarsePositionsFromBuffer( + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + const unsigned char* current_buffer = (unsigned char *)buffer; + current_buffer += start_offset; + for (int i = 0; i < num_vertices; ++i) { + const int current_vertex_index = start_vertex_index + i; + implementation_->updateData(reinterpret_cast(current_buffer), + current_vertex_index, 1); + current_buffer += stride; + } +} + +void CpuEvalOutputAPI::setVaryingDataFromBuffer( + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + const unsigned char* current_buffer = (unsigned char *)buffer; + current_buffer += start_offset; + for (int i = 0; i < num_vertices; ++i) { + const int current_vertex_index = start_vertex_index + i; + implementation_->updateVaryingData( + reinterpret_cast(current_buffer), + current_vertex_index, 1); + current_buffer += stride; + } +} + +void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer( + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices) { + // TODO(sergey): Add sanity check on indices. + const unsigned char* current_buffer = (unsigned char *)buffer; + current_buffer += start_offset; + for (int i = 0; i < num_vertices; ++i) { + const int current_vertex_index = start_vertex_index + i; + implementation_->updateFaceVaryingData( + reinterpret_cast(current_buffer), + current_vertex_index, 1); + current_buffer += stride; + } +} + +void CpuEvalOutputAPI::refine() { + implementation_->refine(); +} + +void CpuEvalOutputAPI::evaluateLimit(const int ptex_face_index, + float face_u, float face_v, + float P[3], float dPdu[3], float dPdv[3]) { + assert(face_u >= 0.0f); + assert(face_u <= 1.0f); + assert(face_v >= 0.0f); + assert(face_v <= 1.0f); + const PatchTable::PatchHandle* handle = + patch_map_->FindPatch(ptex_face_index, face_u, face_v); + PatchCoord patch_coord(*handle, face_u, face_v); + if (dPdu != NULL || dPdv != NULL) { + implementation_->evalPatchesWithDerivatives(patch_coord, P, dPdu, dPdv); + } else { + implementation_->evalPatchCoord(patch_coord, P); + }} + +void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index, + float face_u, float face_v, + float varying[3]) { + assert(face_u >= 0.0f); + assert(face_u <= 1.0f); + assert(face_v >= 0.0f); + assert(face_v <= 1.0f); + const PatchTable::PatchHandle* handle = + patch_map_->FindPatch(ptex_face_index, face_u, face_v); + PatchCoord patch_coord(*handle, face_u, face_v); + implementation_->evalPatchVarying(patch_coord, varying); +} + +void CpuEvalOutputAPI::evaluateFaceVarying(const int ptex_face_index, + float face_u, float face_v, + float face_varying[2]) { + assert(face_u >= 0.0f); + assert(face_u <= 1.0f); + assert(face_v >= 0.0f); + assert(face_v <= 1.0f); + const PatchTable::PatchHandle* handle = + patch_map_->FindPatch(ptex_face_index, face_u, face_v); + PatchCoord patch_coord(*handle, face_u, face_v); + implementation_->evalPatchFaceVarying(patch_coord, face_varying); +} + +} // namespace opensubdiv_capi + +OpenSubdiv_EvaluatorInternal::OpenSubdiv_EvaluatorInternal() + : eval_output(NULL), + patch_map(NULL), + patch_table(NULL) { +} + +OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal() { + delete eval_output; + delete patch_map; + delete patch_table; +} + +OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( + OpenSubdiv_TopologyRefiner* topology_refiner) { + TopologyRefiner* refiner = topology_refiner->internal->osd_topology_refiner; + if (refiner == NULL) { + // Happens on bad topology. + return NULL; + } + // TODO(sergey): Base this on actual topology. + // const bool bas_varying_data = false; + const bool has_face_varying_data = + (refiner->GetNumFVarChannels() != 0); + const int level = topology_refiner->getSubdivisionLevel(topology_refiner); + // TODO(sergey): Query from topology refiner. + const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner); + // Refine the topology with given settings. + // TODO(sergey): What if topology is already refined? + if (is_adaptive) { + TopologyRefiner::AdaptiveOptions options(level); + options.considerFVarChannels = has_face_varying_data; + options.useInfSharpPatch = false; + refiner->RefineAdaptive(options); + } else { + TopologyRefiner::UniformOptions options(level); + refiner->RefineUniform(options); + } + // Generate stencil table to update the bi-cubic patches control vertices + // after they have been re-posed (both for vertex & varying interpolation). + // + // Vertex stencils. + StencilTableFactory::Options vertex_stencil_options; + vertex_stencil_options.generateOffsets = true; + vertex_stencil_options.generateIntermediateLevels = is_adaptive; + const StencilTable* vertex_stencils = + StencilTableFactory::Create(*refiner, vertex_stencil_options); + // Varying stencils. + // + // TODO(sergey): Seems currently varying stencils are always required in + // OpenSubdiv itself. + const StencilTable* varying_stencils = NULL; + StencilTableFactory::Options varying_stencil_options; + varying_stencil_options.generateOffsets = true; + varying_stencil_options.generateIntermediateLevels = is_adaptive; + varying_stencil_options.interpolationMode = + StencilTableFactory::INTERPOLATE_VARYING; + varying_stencils = + StencilTableFactory::Create(*refiner, varying_stencil_options); + // Face warying stencil. + const StencilTable* face_varying_stencils = NULL; + if (has_face_varying_data) { + StencilTableFactory::Options face_varying_stencil_options; + face_varying_stencil_options.generateOffsets = true; + face_varying_stencil_options.generateIntermediateLevels = is_adaptive; + face_varying_stencil_options.interpolationMode = + StencilTableFactory::INTERPOLATE_FACE_VARYING; + // TODO(sergey): Make it configurable which face varying channel is being + // interpolated. + face_varying_stencil_options.fvarChannel = 0; + face_varying_stencils = + StencilTableFactory::Create(*refiner, face_varying_stencil_options); + } + // Generate bi-cubic patch table for the limit surface. + // TODO(sergey): Ideally we would want to expose end-cap settings via + // C-API to make it more generic. Currently it matches old Blender's + // subsurf code. + PatchTableFactory::Options patch_options(level); + patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS); + patch_options.useInfSharpPatch = false; + patch_options.generateFVarTables = has_face_varying_data; + patch_options.generateFVarLegacyLinearPatches = false; + const PatchTable* patch_table = PatchTableFactory::Create( + *refiner, patch_options); + // Append local points stencils. + const StencilTable* local_point_stencil_table = + patch_table->GetLocalPointStencilTable(); + if (local_point_stencil_table != NULL) { + const StencilTable* table = + StencilTableFactory::AppendLocalPointStencilTable( + *refiner, vertex_stencils, local_point_stencil_table); + delete vertex_stencils; + vertex_stencils = table; + } + const StencilTable* local_point_varying_stencil_table = + patch_table->GetLocalPointVaryingStencilTable(); + if (local_point_varying_stencil_table != NULL) { + const StencilTable* table = + StencilTableFactory::AppendLocalPointStencilTable( + *refiner, varying_stencils, local_point_varying_stencil_table); + delete varying_stencils; + varying_stencils = table; + } + const StencilTable* local_point_face_varying_stencil_table = + patch_table->GetLocalPointFaceVaryingStencilTable(); + if (local_point_face_varying_stencil_table != NULL) { + const StencilTable* table = + StencilTableFactory::AppendLocalPointStencilTableFaceVarying( + *refiner, + face_varying_stencils, + local_point_face_varying_stencil_table); + delete face_varying_stencils; + face_varying_stencils = table; + } + // Create OpenSubdiv's CPU side evaluator. + // TODO(sergey): Make it possible to use different evaluators. + opensubdiv_capi::CpuEvalOutput* eval_output = + new opensubdiv_capi::CpuEvalOutput(vertex_stencils, + varying_stencils, + face_varying_stencils, + 0, 2, + patch_table); + OpenSubdiv::Far::PatchMap* patch_map = new PatchMap(*patch_table); + // Wrap everything we need into an object which we control from our side. + OpenSubdiv_EvaluatorInternal* evaluator_descr; + evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorInternal); + evaluator_descr->eval_output = + new opensubdiv_capi::CpuEvalOutputAPI(eval_output, patch_map); + evaluator_descr->patch_map = patch_map; + evaluator_descr->patch_table = patch_table; + // TOOD(sergey): Look into whether we've got duplicated stencils arrays. + delete vertex_stencils; + delete varying_stencils; + delete face_varying_stencils; + return evaluator_descr; +} + +void openSubdiv_deleteEvaluatorInternal( + OpenSubdiv_EvaluatorInternal* evaluator) { + OBJECT_GUARDED_DELETE(evaluator, OpenSubdiv_EvaluatorInternal); +} diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h new file mode 100644 index 00000000000..cc69db6abc6 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h @@ -0,0 +1,134 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_EVALUATOR_INTERNAL_H_ +#define OPENSUBDIV_EVALUATOR_INTERNAL_H_ + +#ifdef _MSC_VER +# include +#endif + +#include +#include + +struct OpenSubdiv_TopologyRefiner; + +namespace opensubdiv_capi { + +// Anonymous forward declaration of actual evaluator implementation. +class CpuEvalOutput; + +// Wrapper around implementaiton, which defines API which we are capable to +// provide over the implementation. +// +// TODO(sergey): It is almost the same as C-API object, so ideally need to +// merge them somehow, but how to do this and keep files with all the templates +// and such separate? +class CpuEvalOutputAPI { + public: + // NOTE: API object becomes an owner of evaluator. Patch we are referencing. + CpuEvalOutputAPI(CpuEvalOutput* implementation, + OpenSubdiv::Far::PatchMap* patch_map); + ~CpuEvalOutputAPI(); + + // Set coarse positions from a continuous array of coordinates. + void setCoarsePositions(const float* positions, + const int start_vertex_index, + const int num_vertices); + // Set varying data from a continuous array of data. + void setVaryingData(const float* varying_data, + const int start_vertex_index, const int num_vertices); + // Set face varying data from a continuous array of data. + // + // TODO(sergey): Find a better name for vertex here. It is not the vertex of + // geometry, but a vertex of UV map. + void setFaceVaryingData(const float* varying_data, + const int start_vertex_index, const int num_vertices); + + // Set coarse vertex position from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + void setCoarsePositionsFromBuffer(const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + // Set varying data from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + void setVaryingDataFromBuffer(const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + // Set face varying data from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + // + // TODO(sergey): Find a better name for vertex here. It is not the vertex of + // geometry, but a vertex of UV map. + void setFaceVaryingDataFromBuffer(const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + + // Refine after coarse positions update. + void refine(); + + // Evaluate given ptex face at given bilinear coordinate. + // If derivatives are NULL, they will not be evaluated. + void evaluateLimit(const int ptex_face_index, + float face_u, float face_v, + float P[3], float dPdu[3], float dPdv[3]); + + // Evaluate varying data at a given bilinear coordinate of given ptex face. + void evaluateVarying(const int ptes_face_index, + float face_u, float face_v, + float varying[3]); + + // Evaluate facee-varying data at a given bilinear coordinate of given + // ptex face. + void evaluateFaceVarying(const int ptes_face_index, + float face_u, float face_v, + float face_varying[2]); + + protected: + CpuEvalOutput* implementation_; + OpenSubdiv::Far::PatchMap* patch_map_; +}; + +} // namespace opensubdiv_capi + +struct OpenSubdiv_EvaluatorInternal { + public: + OpenSubdiv_EvaluatorInternal(); + ~OpenSubdiv_EvaluatorInternal(); + + opensubdiv_capi::CpuEvalOutputAPI* eval_output; + const OpenSubdiv::Far::PatchMap* patch_map; + const OpenSubdiv::Far::PatchTable* patch_table; +}; + +OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( + struct OpenSubdiv_TopologyRefiner* topology_refiner); + +void openSubdiv_deleteEvaluatorInternal( + OpenSubdiv_EvaluatorInternal* evaluator); + +#endif // OPENSUBDIV_EVALUATOR_INTERNAL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc new file mode 100644 index 00000000000..34d27591d0b --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh.cc @@ -0,0 +1,287 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin +// Contributor(s): Brecht van Lommel + +#include "opensubdiv_gl_mesh_capi.h" + +#ifdef _MSC_VER +# include +#endif + +#include +#include +#include + +using OpenSubdiv::Far::StencilTable; +using OpenSubdiv::Osd::GLMeshInterface; +using OpenSubdiv::Osd::GLPatchTable; +using OpenSubdiv::Osd::Mesh; +using OpenSubdiv::Osd::MeshBitset; + +// CPU backend. +#include +#include +using OpenSubdiv::Osd::CpuGLVertexBuffer; +using OpenSubdiv::Osd::CpuEvaluator; +typedef Mesh OsdCpuMesh; +// OpenMP backend. +#ifdef OPENSUBDIV_HAS_OPENMP +# include +using OpenSubdiv::Osd::OmpEvaluator; +typedef Mesh OsdOmpMesh; +#endif +// OpenCL backend. +#ifdef OPENSUBDIV_HAS_OPENCL +# include +# include +# include "opensubdiv_device_context_opencl.h" +using OpenSubdiv::Osd::CLEvaluator; +using OpenSubdiv::Osd::CLGLVertexBuffer; +using OpenSubdiv::Osd::CLStencilTable; +/* TODO(sergey): Use CLDeviceContext similar to OSD examples? */ +typedef Mesh OsdCLMesh; +static CLDeviceContext g_cl_device_context; +#endif +// CUDA backend. +#ifdef OPENSUBDIV_HAS_CUDA +# include +# include +# include "opensubdiv_device_context_cuda.h" +using OpenSubdiv::Osd::CudaEvaluator; +using OpenSubdiv::Osd::CudaGLVertexBuffer; +using OpenSubdiv::Osd::CudaStencilTable; +typedef Mesh OsdCudaMesh; +static CudaDeviceContext g_cuda_device_context; +#endif +// Transform feedback backend. +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK +# include +# include +using OpenSubdiv::Osd::GLXFBEvaluator; +using OpenSubdiv::Osd::GLStencilTableTBO; +using OpenSubdiv::Osd::GLVertexBuffer; +typedef Mesh OsdGLSLTransformFeedbackMesh; +#endif +// GLSL compute backend. +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE +# include +# include +using OpenSubdiv::Osd::GLComputeEvaluator; +using OpenSubdiv::Osd::GLStencilTableSSBO; +using OpenSubdiv::Osd::GLVertexBuffer; +typedef Mesh OsdGLSLComputeMesh; +#endif + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "opensubdiv_topology_refiner_capi.h" +#include "internal/opensubdiv_gl_mesh_draw.h" +#include "internal/opensubdiv_gl_mesh_fvar.h" +#include "internal/opensubdiv_gl_mesh_internal.h" +#include "internal/opensubdiv_topology_refiner_internal.h" + +namespace { + +GLMeshInterface* createGLMeshInterface( + OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const MeshBitset& bits, + const int num_vertex_elements, + const int num_varying_elements, + const int level, + eOpenSubdivEvaluator evaluator_type) { + GLMeshInterface* mesh = NULL; + switch (evaluator_type) { +#define CHECK_EVALUATOR_TYPE(type, class) \ + case OPENSUBDIV_EVALUATOR_##type: \ + mesh = new class(topology_refiner, \ + num_vertex_elements, \ + num_varying_elements, \ + level, \ + bits); \ + break; + +#define CHECK_EVALUATOR_TYPE_STUB(type) \ + case OPENSUBDIV_EVALUATOR_##type: \ + mesh = NULL; \ + break; + + CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh) +#ifdef OPENSUBDIV_HAS_OPENMP + CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh) +#else + CHECK_EVALUATOR_TYPE_STUB(OPENMP) +#endif +#ifdef OPENSUBDIV_HAS_OPENCL + CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh) +#else + CHECK_EVALUATOR_TYPE_STUB(OPENCL) +#endif +#ifdef OPENSUBDIV_HAS_CUDA + CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh) +#else + CHECK_EVALUATOR_TYPE_STUB(CUDA) +#endif +#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK + CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, OsdGLSLTransformFeedbackMesh) +#else + CHECK_EVALUATOR_TYPE_STUB(GLSL_TRANSFORM_FEEDBACK) +#endif +#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE + CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh) +#else + CHECK_EVALUATOR_TYPE_STUB(GLSL_COMPUTE) +#endif + +#undef CHECK_EVALUATOR_TYPE +#undef CHECK_EVALUATOR_TYPE_STUB + } + return mesh; +} + +//////////////////////////////////////////////////////////////////////////////// +// GLMesh structure "methods". + +opensubdiv_capi::GLMeshFVarData* createFVarData( + OpenSubdiv::Far::TopologyRefiner* topology_refiner, + GLMeshInterface* mesh, + const float *fvar_src_buffer) { + using opensubdiv_capi::GLMeshFVarData; + GLMeshFVarData* fvar_data = new GLMeshFVarData(); + fvar_data->create(topology_refiner, + mesh->GetFarPatchTable(), + 2, + fvar_src_buffer); + return fvar_data; +} + +unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh* gl_mesh) { + return gl_mesh->internal->mesh_interface + ->GetPatchTable() + ->GetPatchIndexBuffer(); +} + +void bindVertexBuffer(OpenSubdiv_GLMesh* gl_mesh) { + gl_mesh->internal->mesh_interface->BindVertexBuffer(); +} + +void setCoarsePositions(OpenSubdiv_GLMesh* gl_mesh, + const float* positions, + const int start_vertex, + const int num_vertices) { + gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions, + start_vertex, + num_vertices); +} + +void refine(OpenSubdiv_GLMesh* gl_mesh) { + gl_mesh->internal->mesh_interface->Refine(); +} + +void synchronize(struct OpenSubdiv_GLMesh* gl_mesh) { + gl_mesh->internal->mesh_interface->Synchronize(); +} + +void assignFunctionPointers(OpenSubdiv_GLMesh* gl_mesh) { + gl_mesh->getPatchIndexBuffer = getPatchIndexBuffer; + gl_mesh->bindVertexBuffer = bindVertexBuffer; + gl_mesh->setCoarsePositions = setCoarsePositions; + gl_mesh->refine = refine; + gl_mesh->synchronize = synchronize; + + gl_mesh->prepareDraw = opensubdiv_capi::GLMeshDisplayPrepare; + gl_mesh->drawPatches = opensubdiv_capi::GLMeshDisplayDrawPatches; +} + +} // namespace + +struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( + OpenSubdiv_TopologyRefiner* topology_refiner, + eOpenSubdivEvaluator evaluator_type) { + using OpenSubdiv::Far::TopologyRefiner; + TopologyRefiner* osd_topology_refiner = + topology_refiner->internal->osd_topology_refiner; + // TODO(sergey): Query this from refiner. + const bool is_adaptive = false; + MeshBitset bits; + bits.set(OpenSubdiv::Osd::MeshAdaptive, is_adaptive); + bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0); + bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1); + bits.set(OpenSubdiv::Osd::MeshFVarData, 1); + bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1); + const int num_vertex_elements = 3; + const int num_varying_elements = 3; + GLMeshInterface* mesh = createGLMeshInterface( + osd_topology_refiner, + bits, + num_vertex_elements, + num_varying_elements, + osd_topology_refiner->GetMaxLevel(), + evaluator_type); + if (mesh == NULL) { + return NULL; + } + OpenSubdiv_GLMesh* gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh); + assignFunctionPointers(gl_mesh); + gl_mesh->internal = new OpenSubdiv_GLMeshInternal(); + gl_mesh->internal->evaluator_type = evaluator_type; + gl_mesh->internal->mesh_interface = mesh; + // Face-varying support. + // TODO(sergey): This part needs to be re-done. + if (osd_topology_refiner->GetNumFVarChannels() > 0) { + // TODO(sergey): This is a temporary stub to get things compiled. Need + // to store base level UVs somewhere else. + std::vector uvs; + std::vector fvar_data_buffer; + opensubdiv_capi::interpolateFVarData(*osd_topology_refiner, + uvs, + &fvar_data_buffer); + gl_mesh->internal->fvar_data = createFVarData(osd_topology_refiner, + mesh, + &fvar_data_buffer[0]); + } else { + gl_mesh->internal->fvar_data = NULL; + } + return gl_mesh; +} + +void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh) { + delete gl_mesh->internal; + OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh); +} diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc new file mode 100644 index 00000000000..0d2f8dc9842 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.cc @@ -0,0 +1,587 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_gl_mesh_draw.h" + +#ifdef _MSC_VER +# include +#endif + +#include +#include +#include + +#include + +#ifdef OPENSUBDIV_HAS_CUDA +# include +#endif // OPENSUBDIV_HAS_CUDA + +#include +#include + +#include "internal/opensubdiv_gl_mesh_fvar.h" +#include "internal/opensubdiv_gl_mesh_internal.h" +#include "opensubdiv_capi.h" +#include "opensubdiv_gl_mesh_capi.h" + +using OpenSubdiv::Osd::GLMeshInterface; + +extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[]; + +// TODO(sergey): Those are a bit of bad level calls :S +extern "C" { +void copy_m3_m3(float m1[3][3], float m2[3][3]); +void copy_m3_m4(float m1[3][3], float m2[4][4]); +void adjoint_m3_m3(float m1[3][3], float m[3][3]); +float determinant_m3_array(float m[3][3]); +bool invert_m3_m3(float m1[3][3], float m2[3][3]); +bool invert_m3(float m[3][3]); +void transpose_m3(float mat[3][3]); +} + +#define MAX_LIGHTS 8 +#define SUPPORT_COLOR_MATERIAL + +typedef struct Light { + float position[4]; + float ambient[4]; + float diffuse[4]; + float specular[4]; + float spot_direction[4]; +#ifdef SUPPORT_COLOR_MATERIAL + float constant_attenuation; + float linear_attenuation; + float quadratic_attenuation; + float spot_cutoff; + float spot_exponent; + float spot_cos_cutoff; + float pad, pad2; +#endif +} Light; + +typedef struct Lighting { + Light lights[MAX_LIGHTS]; + int num_enabled; +} Lighting; + +typedef struct Transform { + float projection_matrix[16]; + float model_view_matrix[16]; + float normal_matrix[9]; +} Transform; + +static bool g_use_osd_glsl = false; +static int g_active_uv_index = 0; + +static GLuint g_flat_fill_solid_program = 0; +static GLuint g_flat_fill_texture2d_program = 0; +static GLuint g_smooth_fill_solid_program = 0; +static GLuint g_smooth_fill_texture2d_program = 0; + +static GLuint g_flat_fill_solid_shadeless_program = 0; +static GLuint g_flat_fill_texture2d_shadeless_program = 0; +static GLuint g_smooth_fill_solid_shadeless_program = 0; +static GLuint g_smooth_fill_texture2d_shadeless_program = 0; + +static GLuint g_wireframe_program = 0; + +static GLuint g_lighting_ub = 0; +static Lighting g_lighting_data; +static Transform g_transform; + +namespace { + +GLuint compileShader(GLenum shaderType, + const char* version, + const char* define, + const char* source) { + const char* sources[] = { + version, define, +#ifdef SUPPORT_COLOR_MATERIAL + "#define SUPPORT_COLOR_MATERIAL\n", +#else + "", +#endif + source, + }; + + GLuint shader = glCreateShader(shaderType); + glShaderSource(shader, 4, sources, NULL); + glCompileShader(shader); + + GLint status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLchar emsg[1024]; + glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg); + fprintf(stderr, "Error compiling GLSL: %s\n", emsg); + fprintf(stderr, "Version: %s\n", version); + fprintf(stderr, "Defines: %s\n", define); + fprintf(stderr, "Source: %s\n", source); + return 0; + } + + return shader; +} + +GLuint linkProgram(const char* version, const char* define) { + GLuint vertexShader = + compileShader(GL_VERTEX_SHADER, version, define, + datatoc_gpu_shader_opensubdiv_vertex_glsl); + if (vertexShader == 0) { + return 0; + } + GLuint geometryShader = + compileShader(GL_GEOMETRY_SHADER, version, define, + datatoc_gpu_shader_opensubdiv_geometry_glsl); + if (geometryShader == 0) { + return 0; + } + GLuint fragmentShader = + compileShader(GL_FRAGMENT_SHADER, version, define, + datatoc_gpu_shader_opensubdiv_fragment_glsl); + if (fragmentShader == 0) { + return 0; + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vertexShader); + glAttachShader(program, geometryShader); + glAttachShader(program, fragmentShader); + + glBindAttribLocation(program, 0, "position"); + glBindAttribLocation(program, 1, "normal"); + + glLinkProgram(program); + + glDeleteShader(vertexShader); + glDeleteShader(geometryShader); + glDeleteShader(fragmentShader); + + GLint status; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLchar emsg[1024]; + glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); + fprintf(stderr, "Error linking GLSL program : %s\n", emsg); + fprintf(stderr, "Defines: %s\n", define); + glDeleteProgram(program); + return 0; + } + + glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"), + 0); + + if (GLEW_VERSION_4_1) { + glProgramUniform1i( + program, glGetUniformLocation(program, "texture_buffer"), 0); + glProgramUniform1i( + program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); + glProgramUniform1i( + program, glGetUniformLocation(program, "FVarDataBuffer"), 31); + } else { + glUseProgram(program); + glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); + glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); + glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); + glUseProgram(0); + } + + return program; +} + +void bindProgram(OpenSubdiv_GLMesh* gl_mesh, int program) { + glUseProgram(program); + // Matrices + glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"), + 1, + false, + g_transform.model_view_matrix); + glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), + 1, + false, + g_transform.projection_matrix); + glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"), + 1, + false, + g_transform.normal_matrix); + // Lighting. + glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); + glBufferSubData( + GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); + // Color. + { + // TODO(sergey): Stop using glGetMaterial. + float color[4]; + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); + glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color); + glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); + glUniform4fv(glGetUniformLocation(program, "specular"), 1, color); + glGetMaterialfv(GL_FRONT, GL_SHININESS, color); + glUniform1f(glGetUniformLocation(program, "shininess"), color[0]); + } + // Face-vertex data. + opensubdiv_capi::GLMeshFVarData* fvar_data = gl_mesh->internal->fvar_data; + if (fvar_data != NULL) { + if (fvar_data->texture_buffer) { + glActiveTexture(GL_TEXTURE31); + glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer); + glActiveTexture(GL_TEXTURE0); + } + if (fvar_data->offset_buffer) { + glActiveTexture(GL_TEXTURE30); + glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer); + glActiveTexture(GL_TEXTURE0); + } + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), + fvar_data->fvar_width); + if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) { + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), + fvar_data->channel_offsets[g_active_uv_index]); + } else { + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } + } else { + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } +} + +} // namespace + +bool openSubdiv_initGLMeshDrawingResources(void) { + static bool need_init = true; + static bool init_success = false; + if (!need_init) { + return init_success; + } + // TODO(sergey): Update OSD drawing to OpenGL 3.3 core, + // then remove following line. + return false; + const char* version = ""; + if (GLEW_VERSION_3_2) { + version = "#version 150 compatibility\n"; + } else if (GLEW_VERSION_3_1) { + version = "#version 140\n" + "#extension GL_ARB_compatibility: enable\n"; + } else { + version = "#version 130\n"; + // Minimum supported for OpenSubdiv. + } + g_flat_fill_solid_program = linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define FLAT_SHADING\n"); + g_flat_fill_texture2d_program = linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define USE_TEXTURE_2D\n" + "#define FLAT_SHADING\n"); + g_smooth_fill_solid_program = linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_program = linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define USE_TEXTURE_2D\n" + "#define SMOOTH_SHADING\n"); + + g_flat_fill_solid_shadeless_program = + linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define FLAT_SHADING\n"); + g_flat_fill_texture2d_shadeless_program = + linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define FLAT_SHADING\n"); + g_smooth_fill_solid_shadeless_program = + linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_shadeless_program = + linkProgram(version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define SMOOTH_SHADING\n"); + g_wireframe_program = linkProgram(version, "#define WIREFRAME\n"); + + glGenBuffers(1, &g_lighting_ub); + glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); + glBufferData(GL_UNIFORM_BUFFER, + sizeof(g_lighting_data), + NULL, + GL_STATIC_DRAW); + need_init = false; + init_success = g_flat_fill_solid_program != 0 && + g_flat_fill_texture2d_program != 0 && + g_smooth_fill_solid_program != 0 && + g_smooth_fill_texture2d_program != 0 && g_wireframe_program; + return init_success; +} + +void openSubdiv_deinitGLMeshDrawingResources(void) { + if (g_lighting_ub != 0) { + glDeleteBuffers(1, &g_lighting_ub); + } +#define SAFE_DELETE_PROGRAM(program) \ + do { \ + if (program) { \ + glDeleteProgram(program); \ + } \ + } while (false) + + SAFE_DELETE_PROGRAM(g_flat_fill_solid_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_wireframe_program); + +#undef SAFE_DELETE_PROGRAM +} + +namespace opensubdiv_capi { + +namespace { + +GLuint prepare_patchDraw(OpenSubdiv_GLMesh* gl_mesh, bool fill_quads) { + GLint program = 0; + if (!g_use_osd_glsl) { + glGetIntegerv(GL_CURRENT_PROGRAM, &program); + if (program) { + GLint model; + glGetIntegerv(GL_SHADE_MODEL, &model); + GLint location = glGetUniformLocation(program, "osd_flat_shading"); + if (location != -1) { + glUniform1i(location, model == GL_FLAT); + } + // Face-vertex data. + opensubdiv_capi::GLMeshFVarData* fvar_data = gl_mesh->internal->fvar_data; + if (fvar_data != NULL) { + if (fvar_data->texture_buffer) { + glActiveTexture(GL_TEXTURE31); + glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer); + glActiveTexture(GL_TEXTURE0); + } + if (fvar_data->offset_buffer) { + glActiveTexture(GL_TEXTURE30); + glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer); + glActiveTexture(GL_TEXTURE0); + } + GLint location = glGetUniformLocation(program, "osd_fvar_count"); + if (location != -1) { + glUniform1i(location, fvar_data->fvar_width); + } + location = glGetUniformLocation(program, "osd_active_uv_offset"); + if (location != -1) { + if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) { + glUniform1i(location, + fvar_data->channel_offsets[g_active_uv_index]); + } else { + glUniform1i(location, 0); + } + } + } else { + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } + } + return program; + } + if (fill_quads) { + int model; + GLboolean use_texture_2d; + glGetIntegerv(GL_SHADE_MODEL, &model); + glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); + if (model == GL_FLAT) { + if (use_texture_2d) { + program = g_flat_fill_texture2d_program; + } else { + program = g_flat_fill_solid_program; + } + } else { + if (use_texture_2d) { + program = g_smooth_fill_texture2d_program; + } else { + program = g_smooth_fill_solid_program; + } + } + + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + program = g_wireframe_program; + } + bindProgram(gl_mesh, program); + return program; +} + +void perform_drawElements(GLuint program, + int patch_index, + int num_elements, + int start_element) { + if (program) { + glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index); + } + glDrawElements(GL_LINES_ADJACENCY, + num_elements, + GL_UNSIGNED_INT, + reinterpret_cast(start_element * sizeof(unsigned int))); +} + +void finishPatchDraw(bool fill_quads) { + // TODO(sergey): Some of the stuff could be done once after the whole + // mesh is displayed. + /// Restore state. + if (!fill_quads) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + glBindVertexArray(0); + if (g_use_osd_glsl) { + // TODO(sergey): Store previously used program and roll back to it? + glUseProgram(0); + } +} + +void drawPartitionPatchesRange(GLMeshInterface* mesh, + GLuint program, + int start_patch, + int num_patches) { + int traversed_patches = 0, num_remained_patches = num_patches; + const OpenSubdiv::Osd::PatchArrayVector &patches = + mesh->GetPatchTable()->GetPatchArrays(); + for (int i = 0; i < patches.size(); ++i) { + const OpenSubdiv::Osd::PatchArray &patch = patches[i]; + OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); + OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); + if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { + const int num_block_patches = patch.GetNumPatches(); + if (start_patch >= traversed_patches && + start_patch < traversed_patches + num_block_patches) { + const int num_control_verts = desc.GetNumControlVertices(); + const int start_draw_patch = start_patch - traversed_patches; + const int num_draw_patches = std::min( + num_remained_patches, num_block_patches - start_draw_patch); + perform_drawElements( + program, i + start_draw_patch, num_draw_patches * num_control_verts, + patch.GetIndexBase() + start_draw_patch * num_control_verts); + num_remained_patches -= num_draw_patches; + } + if (num_remained_patches == 0) { + break; + } + traversed_patches += num_block_patches; + } + } +} + +static void drawAllPatches(GLMeshInterface* mesh, GLuint program) { + const OpenSubdiv::Osd::PatchArrayVector &patches = + mesh->GetPatchTable()->GetPatchArrays(); + for (int i = 0; i < patches.size(); ++i) { + const OpenSubdiv::Osd::PatchArray &patch = patches[i]; + OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); + OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); + + if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { + perform_drawElements(program, i, + patch.GetNumPatches() * desc.GetNumControlVertices(), + patch.GetIndexBase()); + } + } +} + +} // namespace + +void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh* /*gl_mesh*/, + const bool use_osd_glsl, + const int active_uv_index) { + g_active_uv_index = active_uv_index; + g_use_osd_glsl = (use_osd_glsl != 0); + // Update transformation matrices. + glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix); + glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix); + copy_m3_m4((float(*)[3])g_transform.normal_matrix, + (float(*)[4])g_transform.model_view_matrix); + invert_m3((float(*)[3])g_transform.normal_matrix); + transpose_m3((float(*)[3])g_transform.normal_matrix); + // Update OpenGL lights positions, colors etc. + g_lighting_data.num_enabled = 0; + for (int i = 0; i < MAX_LIGHTS; ++i) { + GLboolean enabled; + glGetBooleanv(GL_LIGHT0 + i, &enabled); + if (enabled) { + g_lighting_data.num_enabled++; + } + // TODO(sergey): Stop using glGetLight. + glGetLightfv(GL_LIGHT0 + i, GL_POSITION, + g_lighting_data.lights[i].position); + glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, g_lighting_data.lights[i].ambient); + glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, g_lighting_data.lights[i].diffuse); + glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, + g_lighting_data.lights[i].specular); + glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, + g_lighting_data.lights[i].spot_direction); +#ifdef SUPPORT_COLOR_MATERIAL + glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, + &g_lighting_data.lights[i].constant_attenuation); + glGetLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, + &g_lighting_data.lights[i].linear_attenuation); + glGetLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, + &g_lighting_data.lights[i].quadratic_attenuation); + glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, + &g_lighting_data.lights[i].spot_cutoff); + glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, + &g_lighting_data.lights[i].spot_exponent); + g_lighting_data.lights[i].spot_cos_cutoff = + cos(g_lighting_data.lights[i].spot_cutoff); +#endif + } +} + +void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh* gl_mesh, + const bool fill_quads, + const int start_patch, + const int num_patches) { + GLMeshInterface* mesh = gl_mesh->internal->mesh_interface; + // Make sure all global invariants are initialized. + if (!openSubdiv_initGLMeshDrawingResources()) { + return; + } + /// Setup GLSL/OpenGL to draw patches in current context. + GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0); + if (start_patch != -1) { + drawPartitionPatchesRange(mesh, program, start_patch, num_patches); + } else { + drawAllPatches(mesh, program); + } + // Finish patch drawing by restoring all changes to the OpenGL context. + finishPatchDraw(fill_quads != 0); +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h new file mode 100644 index 00000000000..5421b5cf707 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_draw.h @@ -0,0 +1,39 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_GL_MESH_DRAW_H_ +#define OPENSUBDIV_GL_MESH_DRAW_H_ + +#include // for bool + +struct OpenSubdiv_GLMesh; + +namespace opensubdiv_capi { + +void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh* gl_mesh, + const bool use_osd_glsl, + const int active_uv_index); + +void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh* gl_mesh, + const bool fill_quads, + const int start_patch, + const int num_patches); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_GL_MESH_DRAW_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc new file mode 100644 index 00000000000..5c9033c8dd1 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.cc @@ -0,0 +1,175 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_gl_mesh_fvar.h" + +#include +#include + +namespace opensubdiv_capi { + +//////////////////////////////////////////////////////////////////////////////// +// GLMeshFVarData + +GLMeshFVarData::GLMeshFVarData() + : texture_buffer(0), + offset_buffer(0) { +} + +GLMeshFVarData::~GLMeshFVarData() { + release(); +} + +void GLMeshFVarData::release() { + if (texture_buffer) { + glDeleteTextures(1, &texture_buffer); + } + if (offset_buffer) { + glDeleteTextures(1, &offset_buffer); + } + texture_buffer = 0; + offset_buffer = 0; + fvar_width = 0; + channel_offsets.clear(); +} + +void GLMeshFVarData::create( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv::Far::PatchTable* patch_table, + int fvar_width, + const float* fvar_src_data) { + release(); + this->fvar_width = fvar_width; + /// Expand fvar data to per-patch array. + const int max_level = topology_refiner->GetMaxLevel(); + const int num_channels = patch_table->GetNumFVarChannels(); + std::vector data; + int fvar_data_offset = 0; + channel_offsets.resize(num_channels); + for (int channel = 0; channel < num_channels; ++channel) { + OpenSubdiv::Far::ConstIndexArray indices = + patch_table->GetFVarValues(channel); + channel_offsets[channel] = data.size(); + data.reserve(data.size() + indices.size() * fvar_width); + for (int fvert = 0; fvert < indices.size(); ++fvert) { + int index = indices[fvert] * fvar_width; + for (int i = 0; i < fvar_width; ++i) { + data.push_back(fvar_src_data[fvar_data_offset + index++]); + } + } + if (topology_refiner->IsUniform()) { + const int num_values_max = + topology_refiner->GetLevel(max_level).GetNumFVarValues(channel); + fvar_data_offset += num_values_max * fvar_width; + } else { + const int num_values_total = + topology_refiner->GetNumFVarValuesTotal(channel); + fvar_data_offset += num_values_total * fvar_width; + } + } + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + data.size() * sizeof(float), &data[0], + GL_STATIC_DRAW); + glGenTextures(1, &texture_buffer); + glBindTexture(GL_TEXTURE_BUFFER, texture_buffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); + glDeleteBuffers(1, &buffer); + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, + channel_offsets.size() * sizeof(int), + &channel_offsets[0], + GL_STATIC_DRAW); + glGenTextures(1, &offset_buffer); + glBindTexture(GL_TEXTURE_BUFFER, offset_buffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +// Helper functions. + +struct FVarVertex { + float u, v; + + void Clear() { + u = v = 0.0f; + } + + void AddWithWeight(FVarVertex const& src, float weight) { + u += weight * src.u; + v += weight * src.v; + } +}; + +void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner& refiner, + const std::vector& uvs, + std::vector* fvar_data) { + const int fvar_width = 2; + const int max_level = refiner.GetMaxLevel(); + size_t fvar_data_offset = 0, values_offset = 0; + for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) { + const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2; + const int num_values_max = + refiner.GetLevel(max_level).GetNumFVarValues(channel); + const int num_values_total = refiner.GetNumFVarValuesTotal(channel); + if (num_values_total <= 0) { + continue; + } + OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner); + if (refiner.IsUniform()) { + // For uniform we only keep the highest level of refinement. + fvar_data->resize(fvar_data->size() + num_values_max * fvar_width); + std::vector buffer(num_values_total - num_values_max); + FVarVertex* src = &buffer[0]; + memcpy(src, &uvs[values_offset], num_values * sizeof(float)); + // Defer the last level to treat separately with its alternate + // destination. + for (int level = 1; level < max_level; ++level) { + FVarVertex* dst = + src + refiner.GetLevel(level - 1).GetNumFVarValues(channel); + primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); + src = dst; + } + FVarVertex* dst = + reinterpret_cast(&(*fvar_data)[fvar_data_offset]); + primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel); + fvar_data_offset += num_values_max * fvar_width; + } else { + // For adaptive we keep all levels. + fvar_data->resize(fvar_data->size() + num_values_total * fvar_width); + FVarVertex* src = + reinterpret_cast(&(*fvar_data)[fvar_data_offset]); + memcpy(src, &uvs[values_offset], num_values * sizeof(float)); + for (int level = 1; level <= max_level; ++level) { + FVarVertex* dst = + src + refiner.GetLevel(level - 1).GetNumFVarValues(channel); + primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); + src = dst; + } + fvar_data_offset += num_values_total * fvar_width; + } + values_offset += num_values; + } +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h new file mode 100644 index 00000000000..039a94eaf86 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_fvar.h @@ -0,0 +1,57 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_GL_MESH_FVAR_H_ +#define OPENSUBDIV_GL_MESH_FVAR_H_ + +// NOTE: This is a [sane(er)] port of previous ground work for getting UVs to +// work. Still needs a lot of work to make it easy, correct and have proper +// data ownership. + +#include +#include + +#include + +namespace opensubdiv_capi { + +// The buffer which holds GPU resources for face-varying elements. +class GLMeshFVarData { + public: + GLMeshFVarData(); + ~GLMeshFVarData(); + + void release(); + void create(const OpenSubdiv::Far::TopologyRefiner* refiner, + const OpenSubdiv::Far::PatchTable* patch_table, + int fvar_width, + const float* fvar_src_data); + + unsigned int texture_buffer; + unsigned int offset_buffer; + std::vector channel_offsets; + int fvar_width; +}; + +void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner& refiner, + const std::vector& uvs, + std::vector* fvar_data); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_GL_MESH_FVAR_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc new file mode 100644 index 00000000000..3abba9cf8f8 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.cc @@ -0,0 +1,32 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_gl_mesh_internal.h" + +#include "internal/opensubdiv_gl_mesh_fvar.h" + +OpenSubdiv_GLMeshInternal::OpenSubdiv_GLMeshInternal() + : evaluator_type(OPENSUBDIV_EVALUATOR_CPU), + mesh_interface(NULL), + fvar_data(NULL) { +} + +OpenSubdiv_GLMeshInternal::~OpenSubdiv_GLMeshInternal() { + delete mesh_interface; + delete fvar_data; +} diff --git a/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h new file mode 100644 index 00000000000..7796b450e69 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gl_mesh_internal.h @@ -0,0 +1,43 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_GL_MESH_INTERNAL_H_ +#define OPENSUBDIV_GL_MESH_INTERNAL_H_ + +#ifdef _MSC_VER +# include +#endif + +#include + +#include "opensubdiv_capi_type.h" + +namespace opensubdiv_capi { +class GLMeshFVarData; +} // namespace opensubdiv_capi + +typedef struct OpenSubdiv_GLMeshInternal { + OpenSubdiv_GLMeshInternal(); + ~OpenSubdiv_GLMeshInternal(); + + eOpenSubdivEvaluator evaluator_type; + OpenSubdiv::Osd::GLMeshInterface* mesh_interface; + opensubdiv_capi::GLMeshFVarData* fvar_data; +} OpenSubdiv_GLMeshInternal; + +#endif // OPENSUBDIV_GL_MESH_INTERNAL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_gpu.cc b/intern/opensubdiv/internal/opensubdiv_gpu.cc new file mode 100644 index 00000000000..d28b48ddd18 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_gpu.cc @@ -0,0 +1,788 @@ +/* + * ***** 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) 2013 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "opensubdiv_capi.h" + +#ifdef _MSC_VER +# include "iso646.h" +#endif + +#include +#include +#include + +#include + +#ifdef OPENSUBDIV_HAS_CUDA +# include +#endif /* OPENSUBDIV_HAS_CUDA */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "opensubdiv_capi.h" +#include "opensubdiv_gl_mesh.h" +#include "opensubdiv_topology_refiner.h" + +using OpenSubdiv::Osd::GLMeshInterface; + +extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[]; +extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[]; + +/* TODO(sergey): This is bit of bad level calls :S */ +extern "C" { +void copy_m3_m3(float m1[3][3], float m2[3][3]); +void copy_m3_m4(float m1[3][3], float m2[4][4]); +void adjoint_m3_m3(float m1[3][3], float m[3][3]); +float determinant_m3_array(float m[3][3]); +bool invert_m3_m3(float m1[3][3], float m2[3][3]); +bool invert_m3(float m[3][3]); +void transpose_m3(float mat[3][3]); +} + +#define MAX_LIGHTS 8 +#define SUPPORT_COLOR_MATERIAL + +typedef struct Light { + float position[4]; + float ambient[4]; + float diffuse[4]; + float specular[4]; + float spot_direction[4]; +#ifdef SUPPORT_COLOR_MATERIAL + float constant_attenuation; + float linear_attenuation; + float quadratic_attenuation; + float spot_cutoff; + float spot_exponent; + float spot_cos_cutoff; + float pad, pad2; +#endif +} Light; + +typedef struct Lighting { + Light lights[MAX_LIGHTS]; + int num_enabled; +} Lighting; + +typedef struct Transform { + float projection_matrix[16]; + float model_view_matrix[16]; + float normal_matrix[9]; +} Transform; + +static bool g_use_osd_glsl = false; +static int g_active_uv_index = 0; + +static GLuint g_flat_fill_solid_program = 0; +static GLuint g_flat_fill_texture2d_program = 0; +static GLuint g_smooth_fill_solid_program = 0; +static GLuint g_smooth_fill_texture2d_program = 0; + +static GLuint g_flat_fill_solid_shadeless_program = 0; +static GLuint g_flat_fill_texture2d_shadeless_program = 0; +static GLuint g_smooth_fill_solid_shadeless_program = 0; +static GLuint g_smooth_fill_texture2d_shadeless_program = 0; + +static GLuint g_wireframe_program = 0; + +static GLuint g_lighting_ub = 0; +static Lighting g_lighting_data; +static Transform g_transform; + +struct OpenSubdiv_GLMeshFVarData +{ + OpenSubdiv_GLMeshFVarData() : + texture_buffer(0), offset_buffer(0) { + } + + ~OpenSubdiv_GLMeshFVarData() + { + Release(); + } + + void Release() + { + if (texture_buffer) { + glDeleteTextures(1, &texture_buffer); + } + if (offset_buffer) { + glDeleteTextures(1, &offset_buffer); + } + texture_buffer = 0; + offset_buffer = 0; + fvar_width = 0; + channel_offsets.clear(); + } + + void Create(const OpenSubdiv::Far::TopologyRefiner *refiner, + const OpenSubdiv::Far::PatchTable *patch_table, + int fvar_width, + const float *fvar_src_data) + { + Release(); + + this->fvar_width = fvar_width; + + /* Expand fvar data to per-patch array */ + const int max_level = refiner->GetMaxLevel(); + const int num_channels = patch_table->GetNumFVarChannels(); + std::vector data; + int fvar_data_offset = 0; + channel_offsets.resize(num_channels); + for (int channel = 0; channel < num_channels; ++channel) { + OpenSubdiv::Far::ConstIndexArray indices = + patch_table->GetFVarValues(channel); + + channel_offsets[channel] = data.size(); + data.reserve(data.size() + indices.size() * fvar_width); + + for (int fvert = 0; fvert < (int)indices.size(); ++fvert) { + int index = indices[fvert] * fvar_width; + for (int i = 0; i < fvar_width; ++i) { + data.push_back(fvar_src_data[fvar_data_offset + index++]); + } + } + if (refiner->IsUniform()) { + const int num_values_max = refiner->GetLevel(max_level).GetNumFVarValues(channel); + fvar_data_offset += num_values_max * fvar_width; + } else { + const int num_values_total = refiner->GetNumFVarValuesTotal(channel); + fvar_data_offset += num_values_total * fvar_width; + } + } + + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float), + &data[0], GL_STATIC_DRAW); + + glGenTextures(1, &texture_buffer); + glBindTexture(GL_TEXTURE_BUFFER, texture_buffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); + + glDeleteBuffers(1, &buffer); + + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, channel_offsets.size()*sizeof(int), + &channel_offsets[0], GL_STATIC_DRAW); + + glGenTextures(1, &offset_buffer); + glBindTexture(GL_TEXTURE_BUFFER, offset_buffer); + glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer); + glBindTexture(GL_TEXTURE_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + GLuint texture_buffer; + GLuint offset_buffer; + std::vector channel_offsets; + int fvar_width; +}; + +namespace { + +GLuint compileShader(GLenum shaderType, + const char *version, + const char *define, + const char *source) +{ + const char *sources[] = { + version, + define, +#ifdef SUPPORT_COLOR_MATERIAL + "#define SUPPORT_COLOR_MATERIAL\n", +#else + "", +#endif + source, + }; + + GLuint shader = glCreateShader(shaderType); + glShaderSource(shader, 4, sources, NULL); + glCompileShader(shader); + + GLint status; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) { + GLchar emsg[1024]; + glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg); + fprintf(stderr, "Error compiling GLSL: %s\n", emsg); + fprintf(stderr, "Version: %s\n", version); + fprintf(stderr, "Defines: %s\n", define); + fprintf(stderr, "Source: %s\n", source); + return 0; + } + + return shader; +} + +GLuint linkProgram(const char *version, const char *define) +{ + GLuint vertexShader = compileShader(GL_VERTEX_SHADER, + version, + define, + datatoc_gpu_shader_opensubdiv_vertex_glsl); + if (vertexShader == 0) { + return 0; + } + GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, + version, + define, + datatoc_gpu_shader_opensubdiv_geometry_glsl); + if (geometryShader == 0) { + return 0; + } + GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, + version, + define, + datatoc_gpu_shader_opensubdiv_fragment_glsl ); + if (fragmentShader == 0) { + return 0; + } + + GLuint program = glCreateProgram(); + + glAttachShader(program, vertexShader); + glAttachShader(program, geometryShader); + glAttachShader(program, fragmentShader); + + glBindAttribLocation(program, 0, "position"); + glBindAttribLocation(program, 1, "normal"); + + glLinkProgram(program); + + glDeleteShader(vertexShader); + glDeleteShader(geometryShader); + glDeleteShader(fragmentShader); + + GLint status; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLchar emsg[1024]; + glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); + fprintf(stderr, "Error linking GLSL program : %s\n", emsg); + fprintf(stderr, "Defines: %s\n", define); + glDeleteProgram(program); + return 0; + } + + glUniformBlockBinding(program, + glGetUniformBlockIndex(program, "Lighting"), + 0); + + if (GLEW_VERSION_4_1) { + glProgramUniform1i(program, + glGetUniformLocation(program, "texture_buffer"), + 0); /* GL_TEXTURE0 */ + + glProgramUniform1i(program, + glGetUniformLocation(program, "FVarDataOffsetBuffer"), + 30); /* GL_TEXTURE30 */ + + glProgramUniform1i(program, + glGetUniformLocation(program, "FVarDataBuffer"), + 31); /* GL_TEXTURE31 */ + } + else { + glUseProgram(program); + glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */ + glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); /* GL_TEXTURE30 */ + glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ + glUseProgram(0); + } + + return program; +} + +void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program) +{ + glUseProgram(program); + + /* Matrices */ + glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"), + 1, false, + g_transform.model_view_matrix); + glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), + 1, false, + g_transform.projection_matrix); + glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"), + 1, false, + g_transform.normal_matrix); + + /* Lighting */ + glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); + glBufferSubData(GL_UNIFORM_BUFFER, + 0, sizeof(g_lighting_data), &g_lighting_data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); + + /* Color */ + { + /* TODO: stop using glGetMaterial */ + float color[4]; + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); + glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color); + + glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); + glUniform4fv(glGetUniformLocation(program, "specular"), 1, color); + + glGetMaterialfv(GL_FRONT, GL_SHININESS, color); + glUniform1f(glGetUniformLocation(program, "shininess"), color[0]); + } + + /* Face-vertex data */ + if (gl_mesh->fvar_data != NULL) { + if (gl_mesh->fvar_data->texture_buffer) { + glActiveTexture(GL_TEXTURE31); + glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->texture_buffer); + glActiveTexture(GL_TEXTURE0); + } + + if (gl_mesh->fvar_data->offset_buffer) { + glActiveTexture(GL_TEXTURE30); + glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->offset_buffer); + glActiveTexture(GL_TEXTURE0); + } + + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), + gl_mesh->fvar_data->fvar_width); + if (gl_mesh->fvar_data->channel_offsets.size() > 0 && + g_active_uv_index >= 0) + { + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), + gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); + } else { + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } + } else { + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } +} + +} /* namespace */ + +bool openSubdiv_osdGLDisplayInit(void) +{ + static bool need_init = true; + static bool init_success = false; + + if (need_init) { + /* TODO: update OSD drawing to OpenGL 3.3 core, then remove following line */ + return false; + + const char *version = ""; + if (GLEW_VERSION_3_2) { + version = "#version 150 compatibility\n"; + } + else if (GLEW_VERSION_3_1) { + version = "#version 140\n" + "#extension GL_ARB_compatibility: enable\n"; + } + else { + version = "#version 130\n"; + /* minimum supported for OpenSubdiv */ + } + + g_flat_fill_solid_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define FLAT_SHADING\n"); + g_flat_fill_texture2d_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define USE_TEXTURE_2D\n" + "#define FLAT_SHADING\n"); + g_smooth_fill_solid_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_LIGHTING\n" + "#define USE_TEXTURE_2D\n" + "#define SMOOTH_SHADING\n"); + + g_flat_fill_solid_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define FLAT_SHADING\n"); + g_flat_fill_texture2d_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define FLAT_SHADING\n"); + g_smooth_fill_solid_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_shadeless_program = linkProgram( + version, + "#define USE_COLOR_MATERIAL\n" + "#define USE_TEXTURE_2D\n" + "#define SMOOTH_SHADING\n"); + + g_wireframe_program = linkProgram( + version, + "#define WIREFRAME\n"); + + glGenBuffers(1, &g_lighting_ub); + glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); + glBufferData(GL_UNIFORM_BUFFER, + sizeof(g_lighting_data), NULL, GL_STATIC_DRAW); + + need_init = false; + init_success = g_flat_fill_solid_program != 0 && + g_flat_fill_texture2d_program != 0 && + g_smooth_fill_solid_program != 0 && + g_smooth_fill_texture2d_program != 0 && + g_wireframe_program; + } + return init_success; +} + +void openSubdiv_osdGLDisplayDeinit(void) +{ + if (g_lighting_ub != 0) { + glDeleteBuffers(1, &g_lighting_ub); + } +#define SAFE_DELETE_PROGRAM(program) \ + do { \ + if (program) { \ + glDeleteProgram(program); \ + } \ + } while (false) + + SAFE_DELETE_PROGRAM(g_flat_fill_solid_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program); + SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program); + SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program); + SAFE_DELETE_PROGRAM(g_wireframe_program); + +#undef SAFE_DELETE_PROGRAM +} + +void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, + int active_uv_index) +{ + g_active_uv_index = active_uv_index; + g_use_osd_glsl = (use_osd_glsl != 0); + + /* Update transformation matrices. */ + glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix); + glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix); + + copy_m3_m4((float (*)[3])g_transform.normal_matrix, + (float (*)[4])g_transform.model_view_matrix); + invert_m3((float (*)[3])g_transform.normal_matrix); + transpose_m3((float (*)[3])g_transform.normal_matrix); + + /* Update OpenGL lights positions, colors etc. */ + g_lighting_data.num_enabled = 0; + for (int i = 0; i < MAX_LIGHTS; ++i) { + GLboolean enabled; + glGetBooleanv(GL_LIGHT0 + i, &enabled); + if (enabled) { + g_lighting_data.num_enabled++; + } + + /* TODO: stop using glGetLight */ + glGetLightfv(GL_LIGHT0 + i, + GL_POSITION, + g_lighting_data.lights[i].position); + glGetLightfv(GL_LIGHT0 + i, + GL_AMBIENT, + g_lighting_data.lights[i].ambient); + glGetLightfv(GL_LIGHT0 + i, + GL_DIFFUSE, + g_lighting_data.lights[i].diffuse); + glGetLightfv(GL_LIGHT0 + i, + GL_SPECULAR, + g_lighting_data.lights[i].specular); + glGetLightfv(GL_LIGHT0 + i, + GL_SPOT_DIRECTION, + g_lighting_data.lights[i].spot_direction); +#ifdef SUPPORT_COLOR_MATERIAL + glGetLightfv(GL_LIGHT0 + i, + GL_CONSTANT_ATTENUATION, + &g_lighting_data.lights[i].constant_attenuation); + glGetLightfv(GL_LIGHT0 + i, + GL_LINEAR_ATTENUATION, + &g_lighting_data.lights[i].linear_attenuation); + glGetLightfv(GL_LIGHT0 + i, + GL_QUADRATIC_ATTENUATION, + &g_lighting_data.lights[i].quadratic_attenuation); + glGetLightfv(GL_LIGHT0 + i, + GL_SPOT_CUTOFF, + &g_lighting_data.lights[i].spot_cutoff); + glGetLightfv(GL_LIGHT0 + i, + GL_SPOT_EXPONENT, + &g_lighting_data.lights[i].spot_exponent); + g_lighting_data.lights[i].spot_cos_cutoff = + cos(g_lighting_data.lights[i].spot_cutoff); +#endif + } +} + +static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, + bool fill_quads) +{ + GLint program = 0; + if (!g_use_osd_glsl) { + glGetIntegerv(GL_CURRENT_PROGRAM, &program); + if (program) { + GLint model; + glGetIntegerv(GL_SHADE_MODEL, &model); + + GLint location = glGetUniformLocation(program, "osd_flat_shading"); + if (location != -1) { + glUniform1i(location, model == GL_FLAT); + } + + /* Face-vertex data */ + if (gl_mesh->fvar_data != NULL) { + if (gl_mesh->fvar_data->texture_buffer) { + glActiveTexture(GL_TEXTURE31); + glBindTexture(GL_TEXTURE_BUFFER, + gl_mesh->fvar_data->texture_buffer); + glActiveTexture(GL_TEXTURE0); + } + + if (gl_mesh->fvar_data->offset_buffer) { + glActiveTexture(GL_TEXTURE30); + glBindTexture(GL_TEXTURE_BUFFER, + gl_mesh->fvar_data->offset_buffer); + glActiveTexture(GL_TEXTURE0); + } + + GLint location = glGetUniformLocation(program, "osd_fvar_count"); + if (location != -1) { + glUniform1i(location, gl_mesh->fvar_data->fvar_width); + } + + location = glGetUniformLocation(program, "osd_active_uv_offset"); + if (location != -1) { + if (gl_mesh->fvar_data->channel_offsets.size() > 0 && + g_active_uv_index >= 0) + { + glUniform1i(location, + gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); + } else { + glUniform1i(location, 0); + } + } + } else { + glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); + glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); + } + } + return program; + } + + if (fill_quads) { + int model; + GLboolean use_texture_2d; + glGetIntegerv(GL_SHADE_MODEL, &model); + glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); + + if (model == GL_FLAT) { + if (use_texture_2d) { + program = g_flat_fill_texture2d_program; + } + else { + program = g_flat_fill_solid_program; + } + } + else { + if (use_texture_2d) { + program = g_smooth_fill_texture2d_program; + } + else { + program = g_smooth_fill_solid_program; + } + } + + } + else { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + program = g_wireframe_program; + } + + bindProgram(gl_mesh, program); + + return program; +} + +static void perform_drawElements(GLuint program, + int patch_index, + int num_elements, + int start_element) +{ + if (program) { + glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), + patch_index); + } + glDrawElements(GL_LINES_ADJACENCY, + num_elements, + GL_UNSIGNED_INT, + (void *)(start_element * sizeof(unsigned int))); +} + +static void finish_patchDraw(bool fill_quads) +{ + /* TODO(sergey): Some of the stuff could be done once after the whole + * mesh is displayed. + */ + + /* Restore state. */ + if (!fill_quads) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + glBindVertexArray(0); + + if (g_use_osd_glsl) { + /* TODO(sergey): Store previously used program and roll back to it? */ + glUseProgram(0); + } +} + +static void draw_partition_patches_range(GLMeshInterface *mesh, + GLuint program, + int start_patch, + int num_patches) +{ + int traversed_patches = 0, num_remained_patches = num_patches; + const OpenSubdiv::Osd::PatchArrayVector& patches = + mesh->GetPatchTable()->GetPatchArrays(); + for (int i = 0; i < (int)patches.size(); ++i) { + const OpenSubdiv::Osd::PatchArray& patch = patches[i]; + OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); + OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); + + if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { + const int num_block_patches = patch.GetNumPatches(); + if (start_patch >= traversed_patches && + start_patch < traversed_patches + num_block_patches) + { + const int num_control_verts = desc.GetNumControlVertices(); + const int start_draw_patch = start_patch - traversed_patches; + const int num_draw_patches = std::min(num_remained_patches, + num_block_patches - start_draw_patch); + perform_drawElements(program, + i + start_draw_patch, + num_draw_patches * num_control_verts, + patch.GetIndexBase() + start_draw_patch * num_control_verts); + num_remained_patches -= num_draw_patches; + } + if (num_remained_patches == 0) { + break; + } + traversed_patches += num_block_patches; + } + } +} + +static void draw_all_patches(GLMeshInterface *mesh, + GLuint program) +{ + const OpenSubdiv::Osd::PatchArrayVector& patches = + mesh->GetPatchTable()->GetPatchArrays(); + for (int i = 0; i < (int)patches.size(); ++i) { + const OpenSubdiv::Osd::PatchArray& patch = patches[i]; + OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); + OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); + + if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { + perform_drawElements(program, + i, + patch.GetNumPatches() * desc.GetNumControlVertices(), + patch.GetIndexBase()); + } + } +} + +void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, + int fill_quads, + int start_patch, + int num_patches) +{ + GLMeshInterface *mesh = + (GLMeshInterface *)(gl_mesh->descriptor); + + /* Make sure all global invariants are initialized. */ + if (!openSubdiv_osdGLDisplayInit()) { + return; + } + + /* Setup GLSL/OpenGL to draw patches in current context. */ + GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0); + + if (start_patch != -1) { + draw_partition_patches_range(mesh, + program, + start_patch, + num_patches); + } + else { + draw_all_patches(mesh, program); + } + + /* Finish patch drawing by restoring all changes to the OpenGL context. */ + finish_patchDraw(fill_quads != 0); +} + +void openSubdiv_osdGLAllocFVar(OpenSubdiv_TopologyRefinerDescr *topology_refiner, + OpenSubdiv_GLMesh *gl_mesh, + const float *fvar_data) +{ + GLMeshInterface *mesh = + (GLMeshInterface *)(gl_mesh->descriptor); + gl_mesh->fvar_data = OBJECT_GUARDED_NEW(OpenSubdiv_GLMeshFVarData); + gl_mesh->fvar_data->Create(topology_refiner->osd_refiner, + mesh->GetFarPatchTable(), + 2, + fvar_data); +} + +void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh) +{ + if (gl_mesh->fvar_data != NULL) { + OBJECT_GUARDED_DELETE(gl_mesh->fvar_data, OpenSubdiv_GLMeshFVarData); + } +} diff --git a/intern/opensubdiv/internal/opensubdiv_internal.h b/intern/opensubdiv/internal/opensubdiv_internal.h new file mode 100644 index 00000000000..b9d196bbe9e --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_internal.h @@ -0,0 +1,38 @@ +// Copyright 2015 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_INTERNAL_H_ +#define OPENSUBDIV_INTERNAL_H_ + +// Perform full topology validation when exporting it to OpenSubdiv. +#ifdef NDEBUG +// Never do for release builds. +# undef OPENSUBDIV_VALIDATE_TOPOLOGY +#else +// TODO(sergey): Always disabled for now, the check doesn't handle multiple +// non-manifolds from the OpenSubdiv side currently. +// # undef OPENSUBDIV_VALIDATE_TOPOLOGY +# define OPENSUBDIV_VALIDATE_TOPOLOGY +#endif + +// Currently OpenSubdiv expects topology to be oriented, but sometimes it's +// handy to disable orientation code to check whether it causes some weird +// issues by using pre-oriented model. +#define OPENSUBDIV_ORIENT_TOPOLOGY + +#endif // OPENSUBDIV_INTERNAL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc new file mode 100644 index 00000000000..aa6ba953ef9 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc @@ -0,0 +1,315 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "opensubdiv_topology_refiner_capi.h" + +#include + +#include "MEM_guardedalloc.h" +#include "internal/opensubdiv_converter_factory.h" +#include "internal/opensubdiv_converter_internal.h" +#include "internal/opensubdiv_internal.h" +#include "internal/opensubdiv_topology_refiner_internal.h" + +namespace { + +const OpenSubdiv::Far::TopologyRefiner* getOSDTopologyRefiner( + const OpenSubdiv_TopologyRefiner* topology_refiner) { + return topology_refiner->internal->osd_topology_refiner; +} + +const OpenSubdiv::Far::TopologyLevel* getOSDTopologyBaseLevel( + const OpenSubdiv_TopologyRefiner* topology_refiner) { + return &getOSDTopologyRefiner(topology_refiner)->GetLevel(0); +} + +int getSubdivisionLevel(const OpenSubdiv_TopologyRefiner* topology_refiner) { + return topology_refiner->internal->settings.level; +} + +bool getIsAdaptive(const OpenSubdiv_TopologyRefiner* topology_refiner) { + return topology_refiner->internal->settings.is_adaptive; +} + +int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) { + return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices(); +} + +int getNumEdges(const OpenSubdiv_TopologyRefiner* topology_refiner) { + return getOSDTopologyBaseLevel(topology_refiner)->GetNumEdges(); +} + +int getNumFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) { + return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces(); +} + +int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index) { + const OpenSubdiv::Far::TopologyLevel* base_level = + getOSDTopologyBaseLevel(topology_refiner); + return base_level->GetFaceVertices(face_index).size(); +} + +int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index) { + const int num_face_vertices = + topology_refiner->getNumFaceVertices(topology_refiner, face_index); + if (num_face_vertices == 4) { + return 1; + } else { + return num_face_vertices; + } +} + +int getNumPtexFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) { + const int num_faces = topology_refiner->getNumFaces(topology_refiner); + int num_ptex_faces = 0; + for (int face_index = 0; face_index < num_faces; ++face_index) { + num_ptex_faces += + topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); + } + return num_ptex_faces; +} + +void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner* topology_refiner, + int* face_ptex_index_offset) { + const int num_faces = topology_refiner->getNumFaces(topology_refiner); + int num_ptex_faces = 0; + for (int face_index = 0; face_index < num_faces; ++face_index) { + face_ptex_index_offset[face_index] = num_ptex_faces; + num_ptex_faces += + topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); + } +} + +void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) { + topology_refiner->getSubdivisionLevel = getSubdivisionLevel; + topology_refiner->getIsAdaptive = getIsAdaptive; + + topology_refiner->getNumVertices = getNumVertices; + topology_refiner->getNumEdges = getNumEdges; + topology_refiner->getNumFaces = getNumFaces; + topology_refiner->getNumFaceVertices = getNumFaceVertices; + + topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces; + topology_refiner->getNumPtexFaces = getNumPtexFaces; + topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset; +} + +OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() { + OpenSubdiv_TopologyRefiner* topology_refiner = + OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefiner); + topology_refiner->internal = + OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefinerInternal); + assignFunctionPointers(topology_refiner); + return topology_refiner; +} + +} // namespace + +OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter( + OpenSubdiv_Converter* converter, + const OpenSubdiv_TopologyRefinerSettings* settings) { + OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner(); + topology_refiner->internal->osd_topology_refiner = + opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter); + // Store setting which we want to keep track of and which can not be stored + // in OpenSubdiv's descriptor yet. + topology_refiner->internal->settings = *settings; + return topology_refiner; +} + +void openSubdiv_deleteTopologyRefiner( + OpenSubdiv_TopologyRefiner* topology_refiner) { + OBJECT_GUARDED_DELETE(topology_refiner->internal, + OpenSubdiv_TopologyRefinerInternal); + OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefiner); +} + +//////////////////////////////////////////////////////////////////////////////// +// Comparison with converter. + +namespace { + +/////////////////////////////////////////////////////////// +// Quick preliminary checks. + +bool checkSchemeTypeMatches( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + const OpenSubdiv::Sdc::SchemeType converter_scheme_type = + opensubdiv_capi::getSchemeTypeFromCAPI( + converter->getSchemeType(converter)); + return (converter_scheme_type == topology_refiner->GetSchemeType()); +} + +bool checkOptionsMatches( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + typedef OpenSubdiv::Sdc::Options Options; + const Options options = topology_refiner->GetSchemeOptions(); + const Options::FVarLinearInterpolation fvar_interpolation = + options.GetFVarLinearInterpolation(); + const Options::FVarLinearInterpolation converter_fvar_interpolation = + opensubdiv_capi::getFVarLinearInterpolationFromCAPI( + converter->getFVarLinearInterpolation(converter)); + if (fvar_interpolation != converter_fvar_interpolation) { + return false; + } + return true; +} + +bool checkGeometryCoountersMatches( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + using OpenSubdiv::Far::TopologyLevel; + const TopologyLevel& base_level = topology_refiner->GetLevel(0); + return ( + (converter->getNumVertices(converter) == base_level.GetNumVertices()) && + (converter->getNumEdges(converter) == base_level.GetNumEdges()) && + (converter->getNumFaces(converter) == base_level.GetNumFaces())); +} + +bool checkPreliminaryMatches( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + return checkSchemeTypeMatches(topology_refiner, converter) && + checkOptionsMatches(topology_refiner, converter) && + checkGeometryCoountersMatches(topology_refiner, converter); +} + +/////////////////////////////////////////////////////////// +// Geometry comparison. + +bool checkGeometryEdgesMatch( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + using OpenSubdiv::Far::ConstIndexArray; + using OpenSubdiv::Far::TopologyLevel; + const TopologyLevel& base_level = topology_refiner->GetLevel(0); + const int num_edges = base_level.GetNumEdges(); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + const ConstIndexArray& edge_vertices = + base_level.GetEdgeVertices(edge_index); + int conv_edge_vertices[2]; + converter->getEdgeVertices(converter, edge_index, conv_edge_vertices); + if (conv_edge_vertices[0] != edge_vertices[0] || + conv_edge_vertices[1] != edge_vertices[1]) { + return false; + } + } + return true; +} + +bool checkGeometryFacesMatch( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + using OpenSubdiv::Far::ConstIndexArray; + using OpenSubdiv::Far::TopologyLevel; + const TopologyLevel& base_level = topology_refiner->GetLevel(0); + const int num_faces = base_level.GetNumFaces(); + // TODO(sergey): Consider using data structure which keeps handful of + // elements on stack before doing heep allocation. + std::vector conv_face_vertices; + for (int face_index = 0; face_index < num_faces; ++face_index) { + const ConstIndexArray& face_vertices = + base_level.GetFaceVertices(face_index); + const int num_face_vertices = face_vertices.size(); + if (num_face_vertices != + converter->getNumFaceVertices(converter, face_index)) { + return false; + } + conv_face_vertices.resize(num_face_vertices); + converter->getFaceVertices(converter, face_index, &conv_face_vertices[0]); + // Check face-vertex indices in the direct order (assuming topology + // orientation is disabled or did not flip order of the face-vertices). + // + // TODO(sergey): Can we simply memcmp() with OpenSubdiv's array? + bool direct_match = true; + for (int face_vertex_index = 0; face_vertex_index < num_face_vertices; + ++face_vertex_index) { + if (conv_face_vertices[face_vertex_index] != + face_vertices[face_vertex_index]) { + direct_match = false; + break; + } + } + if (!direct_match) { +// If face didn't match in direct direction we also test if it matches in +// reversed direction. This is because conversion might reverse loops to +// make normals consistent. +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + for (int face_vertex_index = 0; face_vertex_index < num_face_vertices; + ++face_vertex_index) { + if (conv_face_vertices[face_vertex_index] != + face_vertices[num_face_vertices - face_vertex_index - 1]) { + return false; + } + } +#endif + return false; + } + } + return true; +} + +bool checkGeometryMatches( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + return checkGeometryEdgesMatch(topology_refiner, converter) && + checkGeometryFacesMatch(topology_refiner, converter); +} + +/////////////////////////////////////////////////////////// +// Compare attributes which affects on topology + +bool checkEdgeSharpnessMatch( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + using OpenSubdiv::Far::ConstIndexArray; + using OpenSubdiv::Far::TopologyLevel; + const TopologyLevel& base_level = topology_refiner->GetLevel(0); + const int num_edges = base_level.GetNumEdges(); + for (int edge_index = 0; edge_index < num_edges; ++edge_index) { + const float sharpness = base_level.GetEdgeSharpness(edge_index); + const float conv_sharpness = + opensubdiv_capi::getCompatibleEdgeSharpness(converter, edge_index); + if (sharpness != conv_sharpness) { + return false; + } + } + return false; +} + +bool checkTopologyAttributesMatch( + const OpenSubdiv::Far::TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + return checkEdgeSharpnessMatch(topology_refiner, converter); +} + +} // namespace + +bool openSubdiv_topologyRefinerCompareWithConverter( + const OpenSubdiv_TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter) { + const OpenSubdiv::Far::TopologyRefiner* refiner = + getOSDTopologyRefiner(topology_refiner); + return (checkPreliminaryMatches(refiner, converter) && + checkGeometryMatches(refiner, converter) && + checkTopologyAttributesMatch(refiner, converter)); +} diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.h b/intern/opensubdiv/internal/opensubdiv_topology_refiner.h new file mode 100644 index 00000000000..b00f6a54201 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.h @@ -0,0 +1,41 @@ +/* + * ***** 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) 2016 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __OPENSUBDIV_TOPOLOGY_REFINER_H__ +#define __OPENSUBDIV_TOPOLOGY_REFINER_H__ + +#include + +typedef struct OpenSubdiv_TopologyRefinerDescr { + OpenSubdiv::Far::TopologyRefiner *osd_refiner; + + /* TODO(sergey): For now only, need to find better place + * after revisiting whole OSD drawing pipeline and Blender + * integration. + */ + std::vector uvs; +} OpenSubdiv_TopologyRefinerDescr; + +#endif /* __OPENSUBDIV_TOPOLOGY_REFINER_H__ */ diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc new file mode 100644 index 00000000000..4636679761f --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.cc @@ -0,0 +1,26 @@ +// Copyright 2016 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#include "internal/opensubdiv_topology_refiner_internal.h" + +OpenSubdiv_TopologyRefinerInternal::OpenSubdiv_TopologyRefinerInternal() + : osd_topology_refiner(NULL) {} + +OpenSubdiv_TopologyRefinerInternal::~OpenSubdiv_TopologyRefinerInternal() { + delete osd_topology_refiner; +} diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h new file mode 100644 index 00000000000..f7ca6a7ad5e --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner_internal.h @@ -0,0 +1,47 @@ +// Copyright 2016 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_TOPOLOGY_REFINER_INTERNAL_H_ +#define OPENSUBDIV_TOPOLOGY_REFINER_INTERNAL_H_ + +#ifdef _MSC_VER +# include +#endif + +#include + +#include "opensubdiv_topology_refiner_capi.h" + +struct OpenSubdiv_TopologyRefinerInternal { + public: + OpenSubdiv_TopologyRefinerInternal(); + ~OpenSubdiv_TopologyRefinerInternal(); + + OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner; + + // Subdivision settingsa this refiner is created for. + // + // We store it here since OpenSubdiv's refiner will only know about level and + // "adaptivity" after performing actual "refine" step. + // + // Ideally, we would also support refining topology without re-importing it + // from external world, but that is for later. + OpenSubdiv_TopologyRefinerSettings settings; +}; + +#endif // OPENSUBDIV_TOPOLOGY_REFINER_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_util.cc b/intern/opensubdiv/internal/opensubdiv_util.cc new file mode 100644 index 00000000000..87bfce2116c --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_util.cc @@ -0,0 +1,61 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin +// Contributor(s): Brecht van Lommel + +#include "internal/opensubdiv_util.h" + +#include +#include + +#ifdef _MSC_VER +# include +#endif + +namespace opensubdiv_capi { + +void stringSplit(std::vector* tokens, + const std::string& str, + const std::string& separators, + bool skip_empty) { + size_t token_start = 0, token_length = 0; + for (size_t i = 0; i < str.length(); ++i) { + const char ch = str[i]; + if (separators.find(ch) == std::string::npos) { + // Append non-separator char to a token. + ++token_length; + } else { + // Append current token to the list (if any). + if (token_length > 0 || !skip_empty) { + std::string token = str.substr(token_start, token_length); + tokens->push_back(token); + } + // Re-set token pointers, + token_start = i + 1; + token_length = 0; + } + } + // Append token which might be at the end of the string. + if ((token_length != 0) || + (!skip_empty && token_start > 0 && + separators.find(str[token_start-1]) != std::string::npos)) { + std::string token = str.substr(token_start, token_length); + tokens->push_back(token); + } +} + +} // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_util.h b/intern/opensubdiv/internal/opensubdiv_util.h new file mode 100644 index 00000000000..6ed19b37e33 --- /dev/null +++ b/intern/opensubdiv/internal/opensubdiv_util.h @@ -0,0 +1,39 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin +// Contributor(s): Brecht van Lommel + +#ifndef OPENSUBDIV_UTIL_H_ +#define OPENSUBDIV_UTIL_H_ + +#include +#include + +namespace opensubdiv_capi { + +#define STRINGIFY_ARG(x) "" #x +#define STRINGIFY_APPEND(a, b) "" a #b +#define STRINGIFY(x) STRINGIFY_APPEND("", x) + +void stringSplit(std::vector* tokens, + const std::string& str, + const std::string& separators, + bool skip_empty); + +} // namespace opensubdiv_capi + +#endif // OPENSUBDIV_UTIL_H_ diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc deleted file mode 100644 index 638039f4f3e..00000000000 --- a/intern/opensubdiv/opensubdiv_capi.cc +++ /dev/null @@ -1,441 +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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * Brecht van Lommel - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include -#include - -#include -#include - -/* CPU Backend */ -#include -#include - -#ifdef OPENSUBDIV_HAS_OPENMP -# include -#endif /* OPENSUBDIV_HAS_OPENMP */ - -#ifdef OPENSUBDIV_HAS_OPENCL -# include -# include -# include "opensubdiv_device_context_opencl.h" -#endif /* OPENSUBDIV_HAS_OPENCL */ - -#ifdef OPENSUBDIV_HAS_CUDA -# include -# include -# include "opensubdiv_device_context_cuda.h" -#endif /* OPENSUBDIV_HAS_CUDA */ - -#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK -# include -# include -#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ - -#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE -# include -# include -#endif /* OPENSUBDIV_HAS_GLSL_COMPUTE */ - -#include -#include -#include - -#include "opensubdiv_gl_mesh.h" -#include "opensubdiv_intern.h" -#include "opensubdiv_topology_refiner.h" - -#include "MEM_guardedalloc.h" - -#include -#include - -using std::string; -using std::vector; - -#define STRINGIFY_ARG(x) "" #x -#define STRINGIFY_APPEND(a, b) "" a #b -#define STRINGIFY(x) STRINGIFY_APPEND("", x) - -/* **************** Types declaration **************** */ - -using OpenSubdiv::Osd::GLMeshInterface; -using OpenSubdiv::Osd::Mesh; -using OpenSubdiv::Osd::MeshBitset; -using OpenSubdiv::Far::StencilTable; -using OpenSubdiv::Osd::GLPatchTable; - -using OpenSubdiv::Osd::Mesh; - -/* CPU backend */ -using OpenSubdiv::Osd::CpuGLVertexBuffer; -using OpenSubdiv::Osd::CpuEvaluator; -typedef Mesh OsdCpuMesh; - -#ifdef OPENSUBDIV_HAS_OPENMP -using OpenSubdiv::Osd::OmpEvaluator; -typedef Mesh OsdOmpMesh; -#endif /* OPENSUBDIV_HAS_OPENMP */ - -#ifdef OPENSUBDIV_HAS_OPENCL -using OpenSubdiv::Osd::CLEvaluator; -using OpenSubdiv::Osd::CLGLVertexBuffer; -using OpenSubdiv::Osd::CLStencilTable; -/* TODO(sergey): Use CLDeviceCOntext similar to OSD examples? */ -typedef Mesh OsdCLMesh; -static CLDeviceContext g_clDeviceContext; -#endif /* OPENSUBDIV_HAS_OPENCL */ - -#ifdef OPENSUBDIV_HAS_CUDA -using OpenSubdiv::Osd::CudaEvaluator; -using OpenSubdiv::Osd::CudaGLVertexBuffer; -using OpenSubdiv::Osd::CudaStencilTable; -typedef Mesh OsdCudaMesh; -static CudaDeviceContext g_cudaDeviceContext; -#endif /* OPENSUBDIV_HAS_CUDA */ - -#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK -using OpenSubdiv::Osd::GLXFBEvaluator; -using OpenSubdiv::Osd::GLStencilTableTBO; -using OpenSubdiv::Osd::GLVertexBuffer; -typedef Mesh OsdGLSLTransformFeedbackMesh; -#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ - -#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE -using OpenSubdiv::Osd::GLComputeEvaluator; -using OpenSubdiv::Osd::GLStencilTableSSBO; -using OpenSubdiv::Osd::GLVertexBuffer; -typedef Mesh OsdGLSLComputeMesh; -#endif - -namespace { - -#if !defined(OPENSUBDIV_VERSION_NUMBER) && !defined(OPENSUBDIV_VERSION_MINOR) -void stringSplit(vector* tokens, - const string& str, - const string& separators, - bool skip_empty) { - size_t token_start = 0, token_length = 0; - for (size_t i = 0; i < str.length(); ++i) { - const char ch = str[i]; - if (separators.find(ch) == string::npos) { - /* Append non-separator char to a token. */ - ++token_length; - } else { - /* Append current token to the list (if any). */ - if (token_length > 0 || !skip_empty) { - string token = str.substr(token_start, token_length); - tokens->push_back(token); - } - /* Re-set token pointers, */ - token_start = i + 1; - token_length = 0; - } - } - /* Append token which might be at the end of the string. */ - if ((token_length != 0) || - (!skip_empty && token_start > 0 && - separators.find(str[token_start-1]) != string::npos)) { - string token = str.substr(token_start, token_length); - tokens->push_back(token); - } -} -#endif - -struct FVarVertex { - float u, v; - void Clear() { - u = v = 0.0f; - } - void AddWithWeight(FVarVertex const & src, float weight) { - u += weight * src.u; - v += weight * src.v; - } -}; - -static void interpolate_fvar_data(OpenSubdiv::Far::TopologyRefiner& refiner, - const std::vector uvs, - std::vector &fvar_data) { - /* TODO(sergey): Make it somehow more generic way. */ - const int fvar_width = 2; - const int max_level = refiner.GetMaxLevel(); - size_t fvar_data_offset = 0, values_offset = 0; - for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) { - const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2, - num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel), - num_values_total = refiner.GetNumFVarValuesTotal(channel); - if (num_values_total <= 0) { - continue; - } - OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner); - if (refiner.IsUniform()) { - /* For uniform we only keep the highest level of refinement. */ - fvar_data.resize(fvar_data.size() + num_values_max * fvar_width); - std::vector buffer(num_values_total - num_values_max); - FVarVertex *src = &buffer[0]; - memcpy(src, &uvs[values_offset], num_values * sizeof(float)); - /* Defer the last level to treat separately with its alternate - * destination. - */ - for (int level = 1; level < max_level; ++level) { - FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); - primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); - src = dst; - } - FVarVertex *dst = reinterpret_cast(&fvar_data[fvar_data_offset]); - primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel); - fvar_data_offset += num_values_max * fvar_width; - } else { - /* For adaptive we keep all levels. */ - fvar_data.resize(fvar_data.size() + num_values_total * fvar_width); - FVarVertex *src = reinterpret_cast(&fvar_data[fvar_data_offset]); - memcpy(src, &uvs[values_offset], num_values * sizeof(float)); - for (int level = 1; level <= max_level; ++level) { - FVarVertex *dst = src + refiner.GetLevel(level-1).GetNumFVarValues(channel); - primvar_refiner.InterpolateFaceVarying(level, src, dst, channel); - src = dst; - } - fvar_data_offset += num_values_total * fvar_width; - } - values_offset += num_values; - } -} - -} // namespace - -struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( - OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int evaluator_type, - int level) -{ - using OpenSubdiv::Far::TopologyRefiner; - - MeshBitset bits; - /* TODO(sergey): Adaptive subdivisions are not currently - * possible because of the lack of tessellation shader. - */ - bits.set(OpenSubdiv::Osd::MeshAdaptive, 0); - bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0); - bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1); - bits.set(OpenSubdiv::Osd::MeshFVarData, 1); - bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1); - - const int num_vertex_elements = 3; - const int num_varying_elements = 3; - - GLMeshInterface *mesh = NULL; - TopologyRefiner *refiner = topology_refiner->osd_refiner; - - switch(evaluator_type) { -#define CHECK_EVALUATOR_TYPE(type, class) \ - case OPENSUBDIV_EVALUATOR_ ## type: \ - mesh = new class(refiner, \ - num_vertex_elements, \ - num_varying_elements, \ - level, \ - bits); \ - break; - - CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh) - -#ifdef OPENSUBDIV_HAS_OPENMP - CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh) -#endif - -#ifdef OPENSUBDIV_HAS_OPENCL - CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh) -#endif - -#ifdef OPENSUBDIV_HAS_CUDA - CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh) -#endif - -#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK - CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, - OsdGLSLTransformFeedbackMesh) -#endif - -#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE - CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh) -#endif - -#undef CHECK_EVALUATOR_TYPE - } - - if (mesh == NULL) { - return NULL; - } - - OpenSubdiv_GLMesh *gl_mesh = - (OpenSubdiv_GLMesh *) OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh); - gl_mesh->evaluator_type = evaluator_type; - gl_mesh->descriptor = (OpenSubdiv_GLMeshDescr *) mesh; - gl_mesh->topology_refiner = topology_refiner; - - if (refiner->GetNumFVarChannels() > 0) { - std::vector fvar_data; - interpolate_fvar_data(*refiner, topology_refiner->uvs, fvar_data); - openSubdiv_osdGLAllocFVar(topology_refiner, gl_mesh, &fvar_data[0]); - } - else { - gl_mesh->fvar_data = NULL; - } - - return gl_mesh; -} - -void openSubdiv_deleteOsdGLMesh(struct OpenSubdiv_GLMesh *gl_mesh) -{ - openSubdiv_osdGLDestroyFVar(gl_mesh); - switch (gl_mesh->evaluator_type) { -#define CHECK_EVALUATOR_TYPE(type, class) \ - case OPENSUBDIV_EVALUATOR_ ## type: \ - delete (class *) gl_mesh->descriptor; \ - break; - - CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh) - -#ifdef OPENSUBDIV_HAS_OPENMP - CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh) -#endif - -#ifdef OPENSUBDIV_HAS_OPENCL - CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh) -#endif - -#ifdef OPENSUBDIV_HAS_CUDA - CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh) -#endif - -#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK - CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, - OsdGLSLTransformFeedbackMesh) -#endif - -#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE - CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh) -#endif - -#undef CHECK_EVALUATOR_TYPE - } - - /* NOTE: OSD refiner was owned by gl_mesh, no need to free it here. */ - OBJECT_GUARDED_DELETE(gl_mesh->topology_refiner, OpenSubdiv_TopologyRefinerDescr); - OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh); -} - -unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer(struct OpenSubdiv_GLMesh *gl_mesh) -{ - return ((GLMeshInterface *)gl_mesh->descriptor)->GetPatchTable()->GetPatchIndexBuffer(); -} - -unsigned int openSubdiv_getOsdGLMeshVertexBuffer(struct OpenSubdiv_GLMesh *gl_mesh) -{ - return ((GLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer(); -} - -void openSubdiv_osdGLMeshUpdateVertexBuffer(struct OpenSubdiv_GLMesh *gl_mesh, - const float *vertex_data, - int start_vertex, - int num_verts) -{ - ((GLMeshInterface *)gl_mesh->descriptor)->UpdateVertexBuffer(vertex_data, - start_vertex, - num_verts); -} - -void openSubdiv_osdGLMeshRefine(struct OpenSubdiv_GLMesh *gl_mesh) -{ - ((GLMeshInterface *)gl_mesh->descriptor)->Refine(); -} - -void openSubdiv_osdGLMeshSynchronize(struct OpenSubdiv_GLMesh *gl_mesh) -{ - ((GLMeshInterface *)gl_mesh->descriptor)->Synchronize(); -} - -void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh) -{ - ((GLMeshInterface *)gl_mesh->descriptor)->BindVertexBuffer(); -} - -const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner( - OpenSubdiv_GLMesh *gl_mesh) -{ - return gl_mesh->topology_refiner; -} - -int openSubdiv_getVersionHex(void) -{ -#if defined(OPENSUBDIV_VERSION_NUMBER) - return OPENSUBDIV_VERSION_NUMBER; -#elif defined(OPENSUBDIV_VERSION_MAJOR) - return OPENSUBDIV_VERSION_MAJOR * 10000 + - OPENSUBDIV_VERSION_MINOR * 100 + - OPENSUBDIV_VERSION_PATCH; -#elif defined(OPENSUBDIV_VERSION) - const char* version = STRINGIFY(OPENSUBDIV_VERSION); - if (version[0] == 'v') { - version += 1; - } - int major = 0, minor = 0, patch = 0; - vector tokens; - stringSplit(&tokens, version, "_", true); - if (tokens.size() == 3) { - major = atoi(tokens[0].c_str()); - minor = atoi(tokens[1].c_str()); - patch = atoi(tokens[2].c_str()); - } - return major * 10000 + minor * 100 + patch; -#else - return 0; -#endif -} diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h index c29d08a77e1..a26ea36b863 100644 --- a/intern/opensubdiv/opensubdiv_capi.h +++ b/intern/opensubdiv/opensubdiv_capi.h @@ -1,163 +1,43 @@ -/* - * ***** 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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_CAPI_H__ -#define __OPENSUBDIV_CAPI_H__ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CAPI_H_ +#define OPENSUBDIV_CAPI_H_ + +#include "opensubdiv_capi_type.h" #ifdef __cplusplus extern "C" { #endif -// Types declaration. -struct OpenSubdiv_GLMesh; -struct OpenSubdiv_GLMeshDescr; -struct OpenSubdiv_GLMeshFVarData; -struct OpenSubdiv_TopologyRefinerDescr; - -typedef struct OpenSubdiv_GLMesh OpenSubdiv_GLMesh; - -// Keep this a bitmask os it's possible to pass available -// evaluators to Blender. -enum { - OPENSUBDIV_EVALUATOR_CPU = (1 << 0), - OPENSUBDIV_EVALUATOR_OPENMP = (1 << 1), - OPENSUBDIV_EVALUATOR_OPENCL = (1 << 2), - OPENSUBDIV_EVALUATOR_CUDA = (1 << 3), - OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK = (1 << 4), - OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5), -}; - -enum { - OPENSUBDIV_SCHEME_CATMARK, - OPENSUBDIV_SCHEME_BILINEAR, - OPENSUBDIV_SCHEME_LOOP, -}; - -/* TODO(sergey): Re-name and avoid bad level data access. */ -OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( - struct OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int evaluator_type, - int level); - -void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh); -unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer( - OpenSubdiv_GLMesh *gl_mesh); -unsigned int openSubdiv_getOsdGLMeshVertexBuffer(OpenSubdiv_GLMesh *gl_mesh); -void openSubdiv_osdGLMeshUpdateVertexBuffer(OpenSubdiv_GLMesh *gl_mesh, - const float *vertex_data, - int start_vertex, - int num_verts); -void openSubdiv_osdGLMeshRefine(OpenSubdiv_GLMesh *gl_mesh); -void openSubdiv_osdGLMeshSynchronize(OpenSubdiv_GLMesh *gl_mesh); -void openSubdiv_osdGLMeshBindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh); - -const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefiner( - OpenSubdiv_GLMesh *gl_mesh); - -/* ============================= Evaluator API ============================== */ - -struct OpenSubdiv_EvaluatorDescr; -typedef struct OpenSubdiv_EvaluatorDescr OpenSubdiv_EvaluatorDescr; - -/* TODO(sergey): Avoid bad-level data access, */ -OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr( - struct OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int subsurf_level); - -void openSubdiv_deleteEvaluatorDescr( - OpenSubdiv_EvaluatorDescr *evaluator_descr); - -void openSubdiv_setEvaluatorCoarsePositions( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const float *positions, - int start_vertex_index, - int num_vertices); -void openSubdiv_setEvaluatorVaryingData( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const float *varying_data, - int start_vertex_index, - int num_vertices); - -void openSubdiv_setEvaluatorCoarsePositionsFromBuffer( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const void *buffer, - int start_offset, - int stride, - int start_vertex_index, - int num_vertices); - -void openSubdiv_refineEvaluator(OpenSubdiv_EvaluatorDescr *evaluator_descr); - -void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr, - int osd_face_index, - float face_u, float face_v, - float P[3], - float dPdu[3], - float dPdv[3]); - -void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr, - int osd_face_index, - float face_u, float face_v, - float varying[3]); - -/* ============================== Mesh drawing =============================== */ - -/* Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs. */ -bool openSubdiv_osdGLDisplayInit(void); -void openSubdiv_osdGLDisplayDeinit(void); - -/* Initialize all the invariants which stays the same for every single path, - * for example lighting model stays untouched for the whole mesh. - * - * TODO(sergey): Some of the stuff could be initialized once for all meshes. - */ -void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, int active_uv_index); - -/* Draw specified patches. */ -void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, - int fill_quads, - int start_patch, - int num_patches); - -void openSubdiv_osdGLAllocFVar( - struct OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_GLMesh *gl_mesh, - const float *fvar_data); - -void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh); - -/* =========================== Utility functions ============================ */ - -int openSubdiv_getAvailableEvaluators(void); +// Global initialization/deinitialization. +// +// Supposed to be called from main thread. void openSubdiv_init(void); void openSubdiv_cleanup(void); +// Bitmask of eOpenSubdivEvaluator. +int openSubdiv_getAvailableEvaluators(void); + int openSubdiv_getVersionHex(void); #ifdef __cplusplus } #endif -#endif // __OPENSUBDIV_CAPI_H__ +#endif // OPENSUBDIV_CAPI_H_ diff --git a/intern/opensubdiv/opensubdiv_capi_type.h b/intern/opensubdiv/opensubdiv_capi_type.h new file mode 100644 index 00000000000..04fe2afff53 --- /dev/null +++ b/intern/opensubdiv/opensubdiv_capi_type.h @@ -0,0 +1,41 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CAPI_TYPES_H_ +#define OPENSUBDIV_CAPI_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// Keep this a bitmask os it's possible to pass available +// evaluators to Blender. +typedef enum eOpenSubdivEvaluator { + OPENSUBDIV_EVALUATOR_CPU = (1 << 0), + OPENSUBDIV_EVALUATOR_OPENMP = (1 << 1), + OPENSUBDIV_EVALUATOR_OPENCL = (1 << 2), + OPENSUBDIV_EVALUATOR_CUDA = (1 << 3), + OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK = (1 << 4), + OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5), +} eOpenSubdivEvaluator; + +#ifdef __cplusplus +} +#endif + +#endif // OPENSUBDIV_CAPI_TYPES_H_ diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc deleted file mode 100644 index fec15b118ae..00000000000 --- a/intern/opensubdiv/opensubdiv_converter.cc +++ /dev/null @@ -1,764 +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) 2015 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include -#include - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include - -#include "MEM_guardedalloc.h" - -#include "opensubdiv_converter_capi.h" -#include "opensubdiv_intern.h" -#include "opensubdiv_topology_refiner.h" - - -#include - -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY -namespace { - -inline void reverse_face_verts(int *face_verts, int num_verts) -{ - int last_vert = face_verts[num_verts - 1]; - for (int i = num_verts - 1; i > 0; --i) { - face_verts[i] = face_verts[i - 1]; - } - face_verts[0] = last_vert; -} - -struct TopologyRefinerData { - const OpenSubdiv_Converter& conv; - std::vector *uvs; -}; - -} /* namespace */ -#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { -namespace Far { - -namespace { - -template -inline int findInArray(T array, int value) -{ - return (int)(std::find(array.begin(), array.end(), value) - array.begin()); -} - -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY -inline int get_loop_winding(int vert0_of_face, int vert1_of_face) -{ - int delta_face = vert1_of_face - vert0_of_face; - if (abs(delta_face) != 1) { - if (delta_face > 0) { - delta_face = -1; - } - else { - delta_face = 1; - } - } - return delta_face; -} - -inline void reverse_face_loops(IndexArray face_verts, IndexArray face_edges) -{ - for (int i = 0; i < face_verts.size() / 2; ++i) { - int j = face_verts.size() - i - 1; - if (i != j) { - std::swap(face_verts[i], face_verts[j]); - std::swap(face_edges[i], face_edges[j]); - } - } - reverse_face_verts(&face_verts[0], face_verts.size()); -} - -inline void check_oriented_vert_connectivity(const int num_vert_edges, - const int num_vert_faces, - const int *vert_edges, - const int *vert_faces, - const int *dst_vert_edges, - const int *dst_vert_faces) -{ -# ifndef NDEBUG - for (int i = 0; i < num_vert_faces; ++i) { - bool found = false; - for (int j = 0; j < num_vert_faces; ++j) { - if (vert_faces[i] == dst_vert_faces[j]) { - found = true; - break; - } - } - if (!found) { - assert(!"vert-faces connectivity ruined"); - } - } - for (int i = 0; i < num_vert_edges; ++i) { - bool found = false; - for (int j = 0; j < num_vert_edges; ++j) { - if (vert_edges[i] == dst_vert_edges[j]) { - found = true; - break; - } - } - if (!found) { - assert(!"vert-edges connectivity ruined"); - } - } -# else - (void)num_vert_edges; - (void)num_vert_faces; - (void)vert_edges; - (void)vert_faces; - (void)dst_vert_edges; - (void)dst_vert_faces; -# endif -} -#endif - -} /* namespace */ - -template <> -inline bool TopologyRefinerFactory::resizeComponentTopology( - TopologyRefiner& refiner, - const TopologyRefinerData& cb_data) -{ - const OpenSubdiv_Converter& conv = cb_data.conv; - /* Faces and face-verts */ - const int num_faces = conv.get_num_faces(&conv); - setNumBaseFaces(refiner, num_faces); - for (int face = 0; face < num_faces; ++face) { - const int num_verts = conv.get_num_face_verts(&conv, face); - setNumBaseFaceVertices(refiner, face, num_verts); - } - /* Edges and edge-faces. */ - const int num_edges = conv.get_num_edges(&conv); - setNumBaseEdges(refiner, num_edges); - for (int edge = 0; edge < num_edges; ++edge) { - const int num_edge_faces = conv.get_num_edge_faces(&conv, edge); - setNumBaseEdgeFaces(refiner, edge, num_edge_faces); - } - /* Vertices and vert-faces and vert-edges/ */ - const int num_verts = conv.get_num_verts(&conv); - setNumBaseVertices(refiner, num_verts); - for (int vert = 0; vert < num_verts; ++vert) { - const int num_vert_edges = conv.get_num_vert_edges(&conv, vert), - num_vert_faces = conv.get_num_vert_faces(&conv, vert); - setNumBaseVertexEdges(refiner, vert, num_vert_edges); - setNumBaseVertexFaces(refiner, vert, num_vert_faces); - } - return true; -} - -template <> -inline bool TopologyRefinerFactory::assignComponentTopology( - TopologyRefiner& refiner, - const TopologyRefinerData &cb_data) -{ - const OpenSubdiv_Converter& conv = cb_data.conv; - using Far::IndexArray; - /* Face relations. */ - const int num_faces = conv.get_num_faces(&conv); - for (int face = 0; face < num_faces; ++face) { - IndexArray dst_face_verts = getBaseFaceVertices(refiner, face); - conv.get_face_verts(&conv, face, &dst_face_verts[0]); - IndexArray dst_face_edges = getBaseFaceEdges(refiner, face); - conv.get_face_edges(&conv, face, &dst_face_edges[0]); - } - /* Edge relations. */ - const int num_edges = conv.get_num_edges(&conv); - for (int edge = 0; edge < num_edges; ++edge) { - /* Edge-vertices */ - IndexArray dst_edge_verts = getBaseEdgeVertices(refiner, edge); - conv.get_edge_verts(&conv, edge, &dst_edge_verts[0]); - /* Edge-faces */ - IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge); - conv.get_edge_faces(&conv, edge, &dst_edge_faces[0]); - } -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY - /* Make face normals consistent. */ - bool *face_used = new bool[num_faces]; - memset(face_used, 0, sizeof(bool) * num_faces); - std::stack traverse_stack; - int face_start = 0, num_traversed_faces = 0; - /* Traverse all islands. */ - while (num_traversed_faces != num_faces) { - /* Find first face of any untraversed islands. */ - while (face_used[face_start]) { - ++face_start; - } - /* Add first face to the stack. */ - traverse_stack.push(face_start); - face_used[face_start] = true; - /* Go over whole connected component. */ - while (!traverse_stack.empty()) { - int face = traverse_stack.top(); - traverse_stack.pop(); - IndexArray face_edges = getBaseFaceEdges(refiner, face); - ConstIndexArray face_verts = getBaseFaceVertices(refiner, face); - for (int edge_index = 0; edge_index < face_edges.size(); ++edge_index) { - const int edge = face_edges[edge_index]; - ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); - if (edge_faces.size() != 2) { - /* Can't make consistent normals for non-manifolds. */ - continue; - } - ConstIndexArray edge_verts = getBaseEdgeVertices(refiner, edge); - /* Get winding of the reference face. */ - int vert0_of_face = findInArray(face_verts, edge_verts[0]), - vert1_of_face = findInArray(face_verts, edge_verts[1]); - int delta_face = get_loop_winding(vert0_of_face, vert1_of_face); - for (int edge_face = 0; edge_face < edge_faces.size(); ++edge_face) { - int other_face = edge_faces[edge_face]; - /* Never re-traverse faces, only move forward. */ - if (face_used[other_face]) { - continue; - } - IndexArray other_face_verts = getBaseFaceVertices(refiner, - other_face); - int vert0_of_other_face = findInArray(other_face_verts, - edge_verts[0]), - vert1_of_other_face = findInArray(other_face_verts, - edge_verts[1]); - int delta_other_face = get_loop_winding(vert0_of_other_face, - vert1_of_other_face); - if (delta_face * delta_other_face > 0) { - IndexArray other_face_verts = getBaseFaceVertices(refiner, - other_face), - other_face_edges = getBaseFaceEdges(refiner, - other_face); - reverse_face_loops(other_face_verts, - other_face_edges); - } - traverse_stack.push(other_face); - face_used[other_face] = true; - } - } - ++num_traversed_faces; - } - } -#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ - /* Vertex relations */ - const int num_verts = conv.get_num_verts(&conv); - for (int vert = 0; vert < num_verts; ++vert) { - - /* Vert-Faces */ - IndexArray dst_vert_faces = getBaseVertexFaces(refiner, vert); - int num_vert_faces = conv.get_num_vert_faces(&conv, vert); - int *vert_faces = new int[num_vert_faces]; - conv.get_vert_faces(&conv, vert, vert_faces); - /* Vert-Edges */ - IndexArray dst_vert_edges = getBaseVertexEdges(refiner, vert); - int num_vert_edges = conv.get_num_vert_edges(&conv, vert); - int *vert_edges = new int[num_vert_edges]; - conv.get_vert_edges(&conv, vert, vert_edges); -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY - /* ** Order vertex edges and faces in a CCW order. ** */ - memset(face_used, 0, sizeof(bool) * num_faces); - /* Number of edges and faces added to the ordered array. */ - int edge_count_ordered = 0, face_count_ordered = 0; - /* Add loose edges straight into the edges array. */ - bool has_fan_connections = false; - for (int i = 0; i < num_vert_edges; ++i) { - IndexArray edge_faces = getBaseEdgeFaces(refiner, vert_edges[i]); - if (edge_faces.size() == 0) { - dst_vert_edges[edge_count_ordered++] = vert_edges[i]; - } - else if (edge_faces.size() > 2) { - has_fan_connections = true; - } - } - if (has_fan_connections) { - /* OpenSubdiv currently doesn't give us clues how to handle - * fan face connections. and since handling such connections - * complicates the loop below we simply don't do special - * orientation for them. - */ - memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges); - memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces); - delete [] vert_edges; - delete [] vert_faces; - continue; - } - /* Perform at max numbder of vert-edges iteration and try to avoid - * deadlock here for malformed mesh. - */ - for (int global_iter = 0; global_iter < num_vert_edges; ++global_iter) { - /* Numbr of edges and faces which are still to be ordered. */ - int num_vert_edges_remained = num_vert_edges - edge_count_ordered, - num_vert_faces_remained = num_vert_faces - face_count_ordered; - if (num_vert_edges_remained == 0 && num_vert_faces_remained == 0) { - /* All done, nothing to do anymore. */ - break; - } - /* Face, edge and face-vertex inndex to start traversal from. */ - int face_start = -1, edge_start = -1, face_vert_start = -1; - if (num_vert_edges_remained == num_vert_faces_remained) { - /* Vertex is eitehr complete manifold or is connected to seevral - * manifold islands (hourglass-like configuration), can pick up - * random edge unused and start from it. - */ - /* TODO(sergey): Start from previous edge from which traversal - * began at previous iteration. - */ - for (int i = 0; i < num_vert_edges; ++i) { - face_start = vert_faces[i]; - if (!face_used[face_start]) { - ConstIndexArray - face_verts = getBaseFaceVertices(refiner, face_start), - face_edges = getBaseFaceEdges(refiner, face_start); - face_vert_start = findInArray(face_verts, vert); - edge_start = face_edges[face_vert_start]; - break; - } - } - } - else { - /* Special handle of non-manifold vertex. */ - for (int i = 0; i < num_vert_edges; ++i) { - edge_start = vert_edges[i]; - IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_start); - if (edge_faces.size() == 1) { - face_start = edge_faces[0]; - if (!face_used[face_start]) { - ConstIndexArray - face_verts = getBaseFaceVertices(refiner, face_start), - face_edges = getBaseFaceEdges(refiner, face_start); - face_vert_start = findInArray(face_verts, vert); - if (edge_start == face_edges[face_vert_start]) { - break; - } - } - } - /* Reset indices for sanity check below. */ - face_start = edge_start = face_vert_start = -1; - } - } - /* Sanity check. */ - assert(face_start != -1 && - edge_start != -1 && - face_vert_start != -1); - /* Traverse faces starting from the current one. */ - int edge_first = edge_start; - dst_vert_faces[face_count_ordered++] = face_start; - dst_vert_edges[edge_count_ordered++] = edge_start; - face_used[face_start] = true; - while (edge_count_ordered < num_vert_edges) { - IndexArray face_verts = getBaseFaceVertices(refiner, face_start); - IndexArray face_edges = getBaseFaceEdges(refiner, face_start); - int face_edge_start = face_vert_start; - int face_edge_next = (face_edge_start > 0) ? (face_edge_start - 1) : (face_verts.size() - 1); - Index edge_next = face_edges[face_edge_next]; - if (edge_next == edge_first) { - /* Multiple manifolds found, stop for now and handle rest - * in the next iteration. - */ - break; - } - dst_vert_edges[edge_count_ordered++] = edge_next; - if (face_count_ordered < num_vert_faces) { - IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_next); - assert(edge_faces.size() != 0); - if (edge_faces.size() == 1) { - assert(edge_faces[0] == face_start); - break; - } - else if (edge_faces.size() != 2) { - break; - } - assert(edge_faces.size() == 2); - face_start = edge_faces[(edge_faces[0] == face_start) ? 1 : 0]; - face_vert_start = findInArray(getBaseFaceEdges(refiner, face_start), edge_next); - dst_vert_faces[face_count_ordered++] = face_start; - face_used[face_start] = true; - } - edge_start = edge_next; - } - } - /* Verify ordering doesn't ruin connectivity information. */ - assert(face_count_ordered == num_vert_faces); - assert(edge_count_ordered == num_vert_edges); - check_oriented_vert_connectivity(num_vert_edges, - num_vert_faces, - vert_edges, - vert_faces, - &dst_vert_edges[0], - &dst_vert_faces[0]); - /* For the release builds we're failing mesh construction so instead - * of nasty bugs the unsupported mesh will simply disappear from the - * viewport. - */ - if (face_count_ordered != num_vert_faces || - edge_count_ordered != num_vert_edges) - { - delete [] vert_edges; - delete [] vert_faces; - return false; - } -#else /* OPENSUBDIV_ORIENT_TOPOLOGY */ - memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges); - memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces); -#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ - delete [] vert_edges; - delete [] vert_faces; - } -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY - delete [] face_used; -#endif - populateBaseLocalIndices(refiner); - return true; -}; - -template <> -inline bool TopologyRefinerFactory::assignComponentTags( - TopologyRefiner& refiner, - const TopologyRefinerData& cb_data) -{ - const OpenSubdiv_Converter& conv = cb_data.conv; - typedef OpenSubdiv::Sdc::Crease Crease; - - int num_edges = conv.get_num_edges(&conv); - for (int edge = 0; edge < num_edges; ++edge) { - float sharpness; - ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); - if (edge_faces.size() == 2) { - sharpness = conv.get_edge_sharpness(&conv, edge); - } - else { - /* Non-manifold edges must be sharp. */ - sharpness = Crease::SHARPNESS_INFINITE; - } - setBaseEdgeSharpness(refiner, edge, sharpness); - } - - /* OpenSubdiv expects non-manifold vertices to be sharp but at the - * time it handles correct cases when vertex is a corner of plane. - * Currently mark verts which are adjacent to a loose edge as sharp, - * but this decision needs some more investigation. - */ - int num_vert = conv.get_num_verts(&conv); - for (int vert = 0; vert < num_vert; ++vert) { - ConstIndexArray vert_edges = getBaseVertexEdges(refiner, vert); - for (int edge_index = 0; edge_index < vert_edges.size(); ++edge_index) { - int edge = vert_edges[edge_index]; - ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); - if (edge_faces.size() == 0) { - setBaseVertexSharpness(refiner, vert, Crease::SHARPNESS_INFINITE); - break; - } - } - if (vert_edges.size() == 2) { - int edge0 = vert_edges[0], - edge1 = vert_edges[1]; - float sharpness0 = conv.get_edge_sharpness(&conv, edge0), - sharpness1 = conv.get_edge_sharpness(&conv, edge1); - float sharpness = std::min(sharpness0, sharpness1); - setBaseVertexSharpness(refiner, vert, sharpness); - } - } - - return true; -} - -template <> -inline void TopologyRefinerFactory::reportInvalidTopology( - TopologyError /*errCode*/, - const char *msg, - const TopologyRefinerData& /*mesh*/) -{ - printf("OpenSubdiv Error: %s\n", msg); -} - -template <> -inline bool TopologyRefinerFactory::assignFaceVaryingTopology( - TopologyRefiner& refiner, - const TopologyRefinerData& cb_data) -{ - const OpenSubdiv_Converter& conv = cb_data.conv; - const int num_layers = conv.get_num_uv_layers(&conv); - if (num_layers <= 0) { - /* No UV maps, we can skip any face-varying data. */ - return true; - } - const int num_faces = getNumBaseFaces(refiner); - size_t uvs_offset = 0; - for (int layer = 0; layer < num_layers; ++layer) { - conv.precalc_uv_layer(&conv, layer); - const int num_uvs = conv.get_num_uvs(&conv); - /* Fill in UV coordinates. */ - cb_data.uvs->resize(cb_data.uvs->size() + num_uvs * 2); - conv.get_uvs(&conv, &cb_data.uvs->at(uvs_offset)); - uvs_offset += num_uvs * 2; - /* Fill in per-corner index of the UV. */ - const int channel = createBaseFVarChannel(refiner, num_uvs); - for (int face = 0; face < num_faces; ++face) { - Far::IndexArray dst_face_uvs = getBaseFaceFVarValues(refiner, - face, - channel); - for (int corner = 0; corner < dst_face_uvs.size(); ++corner) { - const int uv_index = conv.get_face_corner_uv_index(&conv, - face, - corner); - dst_face_uvs[corner] = uv_index; - } - } - conv.finish_uv_layer(&conv); - } - return true; -} - -} /* namespace Far */ -} /* namespace OPENSUBDIV_VERSION */ -} /* namespace OpenSubdiv */ - -namespace { - -OpenSubdiv::Sdc::SchemeType get_capi_scheme_type(OpenSubdiv_SchemeType type) -{ - switch (type) { - case OSD_SCHEME_BILINEAR: - return OpenSubdiv::Sdc::SCHEME_BILINEAR; - case OSD_SCHEME_CATMARK: - return OpenSubdiv::Sdc::SCHEME_CATMARK; - case OSD_SCHEME_LOOP: - return OpenSubdiv::Sdc::SCHEME_LOOP; - } - assert(!"Unknown scheme type passed via C-API"); - return OpenSubdiv::Sdc::SCHEME_CATMARK; -} - -OpenSubdiv::Sdc::Options::FVarLinearInterpolation -get_capi_fvar_linear_interpolation( - OpenSubdiv_FVarLinearInterpolation linear_interpolation) -{ - typedef OpenSubdiv::Sdc::Options Options; - switch (linear_interpolation) { - case OSD_FVAR_LINEAR_INTERPOLATION_NONE: - return Options::FVAR_LINEAR_NONE; - case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: - return Options::FVAR_LINEAR_CORNERS_ONLY; - case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: - return Options::FVAR_LINEAR_BOUNDARIES; - case OSD_FVAR_LINEAR_INTERPOLATION_ALL: - return Options::FVAR_LINEAR_ALL; - } - assert(!"Unknown fvar linear interpolation passed via C-API"); - return Options::FVAR_LINEAR_NONE; -} - -} /* namespace */ - -struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr( - OpenSubdiv_Converter *converter) -{ - typedef OpenSubdiv::Sdc::Options Options; - - using OpenSubdiv::Far::TopologyRefinerFactory; - const OpenSubdiv::Sdc::SchemeType scheme_type = - get_capi_scheme_type(converter->get_scheme_type(converter)); - const Options::FVarLinearInterpolation linear_interpolation = - get_capi_fvar_linear_interpolation( - converter->get_fvar_linear_interpolation(converter)); - Options options; - options.SetVtxBoundaryInterpolation(Options::VTX_BOUNDARY_EDGE_ONLY); - options.SetCreasingMethod(Options::CREASE_UNIFORM); - options.SetFVarLinearInterpolation(linear_interpolation); - - TopologyRefinerFactory::Options - topology_options(scheme_type, options); -#ifdef OPENSUBDIV_VALIDATE_TOPOLOGY - topology_options.validateFullTopology = true; -#endif - OpenSubdiv_TopologyRefinerDescr *result = OBJECT_GUARDED_NEW(OpenSubdiv_TopologyRefinerDescr); - TopologyRefinerData cb_data = {*converter, &result->uvs}; - /* We don't use guarded allocation here so we can re-use the refiner - * for GL mesh creation directly. - */ - result->osd_refiner = - TopologyRefinerFactory::Create( - cb_data, - topology_options); - - return result; -} - -void openSubdiv_deleteTopologyRefinerDescr( - OpenSubdiv_TopologyRefinerDescr *topology_refiner) -{ - delete topology_refiner->osd_refiner; - OBJECT_GUARDED_DELETE(topology_refiner, OpenSubdiv_TopologyRefinerDescr); -} - -int openSubdiv_topologyRefinerGetSubdivLevel( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner) -{ - using OpenSubdiv::Far::TopologyRefiner; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - return refiner->GetMaxLevel(); -} - -int openSubdiv_topologyRefinerGetNumVerts( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner) -{ - using OpenSubdiv::Far::TopologyLevel; - using OpenSubdiv::Far::TopologyRefiner; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - const TopologyLevel &base_level = refiner->GetLevel(0); - return base_level.GetNumVertices(); -} - -int openSubdiv_topologyRefinerGetNumEdges( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner) -{ - using OpenSubdiv::Far::TopologyLevel; - using OpenSubdiv::Far::TopologyRefiner; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - const TopologyLevel &base_level = refiner->GetLevel(0); - return base_level.GetNumEdges(); -} - -int openSubdiv_topologyRefinerGetNumFaces( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner) -{ - using OpenSubdiv::Far::TopologyLevel; - using OpenSubdiv::Far::TopologyRefiner; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - const TopologyLevel &base_level = refiner->GetLevel(0); - return base_level.GetNumFaces(); -} - -int openSubdiv_topologyRefinerGetNumFaceVerts( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int face) -{ - using OpenSubdiv::Far::TopologyLevel; - using OpenSubdiv::Far::TopologyRefiner; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - const TopologyLevel &base_level = refiner->GetLevel(0); - return base_level.GetFaceVertices(face).size(); -} - -int openSubdiv_topologyRefnerCompareConverter( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_Converter *converter) -{ - typedef OpenSubdiv::Sdc::Options Options; - using OpenSubdiv::Far::ConstIndexArray; - using OpenSubdiv::Far::TopologyRefiner; - using OpenSubdiv::Far::TopologyLevel; - const TopologyRefiner *refiner = topology_refiner->osd_refiner; - const TopologyLevel &base_level = refiner->GetLevel(0); - const int num_verts = base_level.GetNumVertices(); - const int num_edges = base_level.GetNumEdges(); - const int num_faces = base_level.GetNumFaces(); - /* Quick preliminary check. */ - OpenSubdiv::Sdc::SchemeType scheme_type = - get_capi_scheme_type(converter->get_scheme_type(converter)); - if (scheme_type != refiner->GetSchemeType()) { - return false; - } - const Options options = refiner->GetSchemeOptions(); - const Options::FVarLinearInterpolation interp = - options.GetFVarLinearInterpolation(); - const Options::FVarLinearInterpolation new_interp = - get_capi_fvar_linear_interpolation( - converter->get_fvar_linear_interpolation(converter)); - if (new_interp != interp) { - return false; - } - if (converter->get_num_verts(converter) != num_verts || - converter->get_num_edges(converter) != num_edges || - converter->get_num_faces(converter) != num_faces) - { - return false; - } - /* Compare all edges. */ - for (int edge = 0; edge < num_edges; ++edge) { - ConstIndexArray edge_verts = base_level.GetEdgeVertices(edge); - int conv_edge_verts[2]; - converter->get_edge_verts(converter, edge, conv_edge_verts); - if (conv_edge_verts[0] != edge_verts[0] || - conv_edge_verts[1] != edge_verts[1]) - { - return false; - } - } - /* Compare all faces. */ - std::vector conv_face_verts; - for (int face = 0; face < num_faces; ++face) { - ConstIndexArray face_verts = base_level.GetFaceVertices(face); - if (face_verts.size() != converter->get_num_face_verts(converter, - face)) - { - return false; - } - conv_face_verts.resize(face_verts.size()); - converter->get_face_verts(converter, face, &conv_face_verts[0]); - bool direct_match = true; - for (int i = 0; i < face_verts.size(); ++i) { - if (conv_face_verts[i] != face_verts[i]) { - direct_match = false; - break; - } - } - if (!direct_match) { - /* If face didn't match in direct direction we also test if it - * matches in reversed direction. This is because conversion might - * reverse loops to make normals consistent. - */ -#ifdef OPENSUBDIV_ORIENT_TOPOLOGY - reverse_face_verts(&conv_face_verts[0], conv_face_verts.size()); - for (int i = 0; i < face_verts.size(); ++i) { - if (conv_face_verts[i] != face_verts[i]) { - return false; - } - } -#else - return false; -#endif - } - } - /* Compare sharpness. */ - for (int edge = 0; edge < num_edges; ++edge) { - ConstIndexArray edge_faces = base_level.GetEdgeFaces(edge); - float sharpness = base_level.GetEdgeSharpness(edge); - float conv_sharpness; - if (edge_faces.size() == 2) { - conv_sharpness = converter->get_edge_sharpness(converter, edge); - } - else { - conv_sharpness = OpenSubdiv::Sdc::Crease::SHARPNESS_INFINITE; - } - if (sharpness != conv_sharpness) { - return false; - } - } - return true; -} diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index ea4f20c5961..1d76da4d76b 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -1,149 +1,150 @@ -/* - * ***** 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) 2015 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_CONVERTER_CAPI_H__ -#define __OPENSUBDIV_CONVERTER_CAPI_H__ +// Copyright 2015 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CONVERTER_CAPI_H_ +#define OPENSUBDIV_CONVERTER_CAPI_H_ #ifdef __cplusplus extern "C" { #endif -struct OpenSubdiv_TopologyRefinerDescr; -typedef struct OpenSubdiv_TopologyRefinerDescr OpenSubdiv_TopologyRefinerDescr; - -typedef struct OpenSubdiv_Converter OpenSubdiv_Converter; - typedef enum OpenSubdiv_SchemeType { - OSD_SCHEME_BILINEAR, - OSD_SCHEME_CATMARK, - OSD_SCHEME_LOOP, + OSD_SCHEME_BILINEAR, + OSD_SCHEME_CATMARK, + OSD_SCHEME_LOOP, } OpenSubdiv_SchemeType; typedef enum OpenSubdiv_FVarLinearInterpolation { - OSD_FVAR_LINEAR_INTERPOLATION_NONE, - OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, - OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, - OSD_FVAR_LINEAR_INTERPOLATION_ALL, + OSD_FVAR_LINEAR_INTERPOLATION_NONE, + OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, + OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, + OSD_FVAR_LINEAR_INTERPOLATION_ALL, } OpenSubdiv_FVarLinearInterpolation; typedef struct OpenSubdiv_Converter { - /* TODO(sergey): Needs to be implemented. */ - /* OpenSubdiv::Sdc::Options get_options() const; */ - - OpenSubdiv_SchemeType (*get_scheme_type)( - const OpenSubdiv_Converter *converter); - - OpenSubdiv_FVarLinearInterpolation (*get_fvar_linear_interpolation)( - const OpenSubdiv_Converter *converter); - - int (*get_num_faces)(const OpenSubdiv_Converter *converter); - int (*get_num_edges)(const OpenSubdiv_Converter *converter); - int (*get_num_verts)(const OpenSubdiv_Converter *converter); - - /* Face relationships. */ - int (*get_num_face_verts)(const OpenSubdiv_Converter *converter, - int face); - void (*get_face_verts)(const OpenSubdiv_Converter *converter, - int face, - int *face_verts); - void (*get_face_edges)(const OpenSubdiv_Converter *converter, - int face, - int *face_edges); - - /* Edge relationships. */ - void (*get_edge_verts)(const OpenSubdiv_Converter *converter, - int edge, - int *edge_verts); - int (*get_num_edge_faces)(const OpenSubdiv_Converter *converter, - int edge); - void (*get_edge_faces)(const OpenSubdiv_Converter *converter, - int edge, - int *edge_faces); - float (*get_edge_sharpness)(const OpenSubdiv_Converter *converter, - int edge); - - /* Vertex relationships. */ - int (*get_num_vert_edges)(const OpenSubdiv_Converter *converter, int vert); - void (*get_vert_edges)(const OpenSubdiv_Converter *converter, - int vert, - int *vert_edges); - int (*get_num_vert_faces)(const OpenSubdiv_Converter *converter, int vert); - void (*get_vert_faces)(const OpenSubdiv_Converter *converter, - int vert, - int *vert_faces); - - /* Face-varying data. */ - int (*get_num_uv_layers)(const OpenSubdiv_Converter *converter); - - void (*precalc_uv_layer)(const OpenSubdiv_Converter *converter, int layer); - void (*finish_uv_layer)(const OpenSubdiv_Converter *converter); - - int (*get_num_uvs)(const OpenSubdiv_Converter *converter); - void (*get_uvs)(const OpenSubdiv_Converter *converter, float *uvs); - - int (*get_face_corner_uv_index)(const OpenSubdiv_Converter *converter, - int face, - int corner); - - /* User data associated with this converter. */ - void (*free_user_data)(const OpenSubdiv_Converter *converter); - void *user_data; + OpenSubdiv_SchemeType (*getSchemeType)( + const struct OpenSubdiv_Converter* converter); + + OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)( + const struct OpenSubdiv_Converter* converter); + + ////////////////////////////////////////////////////////////////////////////// + // Global geometry counters. + // Number of faces/edges/vertices in the base mesh. + int (*getNumFaces)(const struct OpenSubdiv_Converter* converter); + int (*getNumEdges)(const struct OpenSubdiv_Converter* converter); + int (*getNumVertices)(const struct OpenSubdiv_Converter* converter); + + ////////////////////////////////////////////////////////////////////////////// + // Face relationships. + + // Number of vertices the face consists of. + int (*getNumFaceVertices)(const struct OpenSubdiv_Converter* converter, + const int face_index); + // Array of vertex indices the face consists of. + void (*getFaceVertices)(const struct OpenSubdiv_Converter* converter, + const int face_index, + int* face_vertices); + // Array of edge indices the face consists of. + // Aligned with the vertex indices array, edge i connects face vertex i + // with face index i+1. + void (*getFaceEdges)(const struct OpenSubdiv_Converter *converter, + const int face_index, + int *face_edges); + + ////////////////////////////////////////////////////////////////////////////// + // Edge relationships. + + // Vertices the edge consists of. + void (*getEdgeVertices)(const struct OpenSubdiv_Converter* converter, + const int edge_index, + int edge_vertices[2]); + // Number of faces which are sharing the given edge. + int (*getNumEdgeFaces)(const struct OpenSubdiv_Converter* converter, + const int edge_index); + // Array of face indices which are sharing the given edge. + void (*getEdgeFaces)(const struct OpenSubdiv_Converter* converter, + const int edge, + int* edge_faces); + // Edge sharpness (aka crease). + float (*getEdgeSharpness)(const struct OpenSubdiv_Converter* converter, + const int edge_index); + + ////////////////////////////////////////////////////////////////////////////// + // Vertex relationships. + + // Number of edges which are adjacent to the given vertex. + int (*getNumVertexEdges)(const struct OpenSubdiv_Converter* converter, + const int vertex_index); + // Array fo edge indices which are adjacent to the given vertex. + void (*getVertexEdges)(const struct OpenSubdiv_Converter* converter, + const int vertex_index, + int* vertex_edges); + // Number of faces which are adjacent to the given vertex. + int (*getNumVertexFaces)(const struct OpenSubdiv_Converter* converter, + const int vertex_index); + // Array fo face indices which are adjacent to the given vertex. + void (*getVertexFaces)(const struct OpenSubdiv_Converter* converter, + const int vertex_index, + int* vertex_faces); + + ////////////////////////////////////////////////////////////////////////////// + // Face-varying data. + + ///////////////////////////////////// + // UV coordinates. + + // Number of UV layers. + int (*getNumUVLayers)(const struct OpenSubdiv_Converter* converter); + + // We need some corner connectivity information, which might not be trivial + // to be gathered (might require multiple matching calculations per corver + // query). + // precalc() is called before any corner connectivity or UV coordinate is + // queried from the given layer, allowing converter to calculate and cache + // complex complex-to-calculate information. + // finish() is called after converter is done porting UV layer to OpenSubdiv, + // allowing to free cached data. + void (*precalcUVLayer)(const struct OpenSubdiv_Converter* converter, + const int layer_index); + void (*finishUVLayer)(const struct OpenSubdiv_Converter* converter); + + // Get number of UV coordinates in the current layer (layer which was + // specified in precalcUVLayer(). + int (*getNumUVCoordinates)(const struct OpenSubdiv_Converter* converter); + // Get cooridnates themselves. + void (*getUVCoordinates)(const struct OpenSubdiv_Converter* converter, + float* uvs_coordinates); + // For the given face index and its corner (known as loop in Blender) + // get corrsponding UV coordinate index. + int (*getFaceCornerUVIndex)(const struct OpenSubdiv_Converter* converter, + const int face_index, + const int corner_index); + + ////////////////////////////////////////////////////////////////////////////// + // User data associated with this converter. + + void (*freeUserData)(const struct OpenSubdiv_Converter* converter); + void* user_data; } OpenSubdiv_Converter; -OpenSubdiv_TopologyRefinerDescr *openSubdiv_createTopologyRefinerDescr( - OpenSubdiv_Converter *converter); - -void openSubdiv_deleteTopologyRefinerDescr( - OpenSubdiv_TopologyRefinerDescr *topology_refiner); - -/* TODO(sergey): Those calls are not strictly related to conversion. - * needs some dedicated file perhaps. - */ - -int openSubdiv_topologyRefinerGetSubdivLevel( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner); - -int openSubdiv_topologyRefinerGetNumVerts( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner); - -int openSubdiv_topologyRefinerGetNumEdges( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner); - -int openSubdiv_topologyRefinerGetNumFaces( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner); - -int openSubdiv_topologyRefinerGetNumFaceVerts( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int face); - -int openSubdiv_topologyRefnerCompareConverter( - const OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_Converter *converter); - #ifdef __cplusplus } #endif -#endif /* __OPENSUBDIV_CONVERTER_CAPI_H__ */ +#endif /* OPENSUBDIV_CONVERTER_CAPI_H_ */ diff --git a/intern/opensubdiv/opensubdiv_device_context_cuda.cc b/intern/opensubdiv/opensubdiv_device_context_cuda.cc deleted file mode 100644 index 46b66a6b35e..00000000000 --- a/intern/opensubdiv/opensubdiv_device_context_cuda.cc +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Adopted from OpenSubdiv with the following license: - * - * Copyright 2015 Pixar - * - * Licensed under the Apache License, Version 2.0 (the "Apache License") - * with the following modification; you may not use this file except in - * compliance with the Apache License and the following modification to it: - * Section 6. Trademarks. is deleted and replaced with: - * - * 6. Trademarks. This License does not grant permission to use the trade - * names, trademarks, service marks, or product names of the Licensor - * and its affiliates, except as required to comply with Section 4(c) of - * the License and to reproduce the content of the NOTICE file. - * - * You may obtain a copy of the Apache License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Apache License with the above modification is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the Apache License for the specific - * language governing permissions and limitations under the Apache License. - */ - -#ifdef OPENSUBDIV_HAS_CUDA - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include "opensubdiv_device_context_cuda.h" - -#if defined(_WIN32) -# include -#elif defined(__APPLE__) -# include -#else -# include -# include -#endif - -#include -#include -#include -#include -#include - -#define message(fmt, ...) -//#define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) -#define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) - -static int _GetCudaDeviceForCurrentGLContext() -{ - // Find and use the CUDA device for the current GL context - unsigned int interopDeviceCount = 0; - int interopDevices[1]; - cudaError_t status = cudaGLGetDevices(&interopDeviceCount, interopDevices, - 1, cudaGLDeviceListCurrentFrame); - if (status == cudaErrorNoDevice or interopDeviceCount != 1) { - message("CUDA no interop devices found.\n"); - return 0; - } - int device = interopDevices[0]; - -#if defined(_WIN32) - return device; - -#elif defined(__APPLE__) - return device; - -#else // X11 - Display * display = glXGetCurrentDisplay(); - int screen = DefaultScreen(display); - if (device != screen) { - error("The CUDA interop device (%d) does not match " - "the screen used by the current GL context (%d), " - "which may cause slow performance on systems " - "with multiple GPU devices.", device, screen); - } - message("CUDA init using device for current GL context: %d\n", device); - return device; -#endif -} - -/* From "NVIDIA GPU Computing SDK 4.2/C/common/inc/cutil_inline_runtime.h": */ - -/* Beginning of GPU Architecture definitions */ -inline int _ConvertSMVer2Cores_local(int major, int minor) -{ - /* Defines for GPU Architecture types (using the SM version to determine - * the # of cores per SM - */ - typedef struct { - int SM; /* 0xMm (hexidecimal notation), - * M = SM Major version, - * and m = SM minor version - */ - int Cores; - } sSMtoCores; - - sSMtoCores nGpuArchCoresPerSM[] = - { { 0x10, 8 }, /* Tesla Generation (SM 1.0) G80 class */ - { 0x11, 8 }, /* Tesla Generation (SM 1.1) G8x class */ - { 0x12, 8 }, /* Tesla Generation (SM 1.2) G9x class */ - { 0x13, 8 }, /* Tesla Generation (SM 1.3) GT200 class */ - { 0x20, 32 }, /* Fermi Generation (SM 2.0) GF100 class */ - { 0x21, 48 }, /* Fermi Generation (SM 2.1) GF10x class */ - { 0x30, 192}, /* Fermi Generation (SM 3.0) GK10x class */ - { -1, -1 } - }; - - int index = 0; - while (nGpuArchCoresPerSM[index].SM != -1) { - if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) { - return nGpuArchCoresPerSM[index].Cores; - } - index++; - } - printf("MapSMtoCores undefined SMversion %d.%d!\n", major, minor); - return -1; -} -/* End of GPU Architecture definitions. */ - -/* This function returns the best GPU (with maximum GFLOPS) */ -inline int cutGetMaxGflopsDeviceId() -{ - int current_device = 0, sm_per_multiproc = 0; - int max_compute_perf = 0, max_perf_device = -1; - int device_count = 0, best_SM_arch = 0; - int compat_major, compat_minor; - - cuDeviceGetCount(&device_count); - /* Find the best major SM Architecture GPU device. */ - while (current_device < device_count) { - cuDeviceComputeCapability(&compat_major, &compat_minor, current_device); - if (compat_major > 0 && compat_major < 9999) { - best_SM_arch = std::max(best_SM_arch, compat_major); - } - current_device++; - } - - /* Find the best CUDA capable GPU device. */ - current_device = 0; - while (current_device < device_count) { - cuDeviceComputeCapability(&compat_major, &compat_minor, current_device); - if (compat_major == 9999 && compat_minor == 9999) { - sm_per_multiproc = 1; - } else { - sm_per_multiproc = _ConvertSMVer2Cores_local(compat_major, - compat_minor); - } - int multi_processor_count; - cuDeviceGetAttribute(&multi_processor_count, - CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, - current_device); - int clock_rate; - cuDeviceGetAttribute(&clock_rate, - CU_DEVICE_ATTRIBUTE_CLOCK_RATE, - current_device); - int compute_perf = multi_processor_count * sm_per_multiproc * clock_rate; - if (compute_perf > max_compute_perf) { - /* If we find GPU with SM major > 2, search only these */ - if (best_SM_arch > 2) { - /* If our device==dest_SM_arch, choose this, or else pass. */ - if (compat_major == best_SM_arch) { - max_compute_perf = compute_perf; - max_perf_device = current_device; - } - } else { - max_compute_perf = compute_perf; - max_perf_device = current_device; - } - } - ++current_device; - } - return max_perf_device; -} - -bool CudaDeviceContext::HAS_CUDA_VERSION_4_0() -{ -#ifdef OPENSUBDIV_HAS_CUDA - static bool cudaInitialized = false; - static bool cudaLoadSuccess = true; - if (!cudaInitialized) { - cudaInitialized = true; - -# ifdef OPENSUBDIV_HAS_CUEW - cudaLoadSuccess = cuewInit(CUEW_INIT_CUDA) == CUEW_SUCCESS; - if (!cudaLoadSuccess) { - fprintf(stderr, "Loading CUDA failed.\n"); - } -# endif - // Need to initialize CUDA here so getting device - // with the maximum FPLOS works fine. - if (cuInit(0) == CUDA_SUCCESS) { - // This is to deal with cases like NVidia Optimus, - // when there might be CUDA library installed but - // NVidia card is not being active. - if (cutGetMaxGflopsDeviceId() < 0) { - cudaLoadSuccess = false; - } - } - else { - cudaLoadSuccess = false; - } - } - return cudaLoadSuccess; -#else - return false; -#endif -} - -CudaDeviceContext::CudaDeviceContext() - : _initialized(false) { -} - -CudaDeviceContext::~CudaDeviceContext() { - cudaDeviceReset(); -} - -bool CudaDeviceContext::Initialize() -{ - /* See if any cuda device is available. */ - int deviceCount = 0; - cudaGetDeviceCount(&deviceCount); - message("CUDA device count: %d\n", deviceCount); - if (deviceCount <= 0) { - return false; - } - cudaGLSetGLDevice(_GetCudaDeviceForCurrentGLContext()); - _initialized = true; - return true; -} - -#endif /* OPENSUBDIV_HAS_CUDA */ diff --git a/intern/opensubdiv/opensubdiv_device_context_cuda.h b/intern/opensubdiv/opensubdiv_device_context_cuda.h deleted file mode 100644 index eb30b76f507..00000000000 --- a/intern/opensubdiv/opensubdiv_device_context_cuda.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Adopted from OpenSubdiv with the following license: - * - * Copyright 2013 Pixar - * - * Licensed under the Apache License, Version 2.0 (the "Apache License") - * with the following modification; you may not use this file except in - * compliance with the Apache License and the following modification to it: - * Section 6. Trademarks. is deleted and replaced with: - * - * 6. Trademarks. This License does not grant permission to use the trade - * names, trademarks, service marks, or product names of the Licensor - * and its affiliates, except as required to comply with Section 4(c) of - * the License and to reproduce the content of the NOTICE file. - * - * You may obtain a copy of the Apache License at - * - * http: //www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Apache License with the above modification is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the Apache License for the specific - * language governing permissions and limitations under the Apache License. - * - */ - -#ifndef __OPENSUBDIV_DEV_CE_CONTEXT_CUDA_H__ -#define __OPENSUBDIV_DEV_CE_CONTEXT_CUDA_H__ - -struct ID3D11Device; - -class CudaDeviceContext { -public: - CudaDeviceContext(); - ~CudaDeviceContext(); - - static bool HAS_CUDA_VERSION_4_0(); - - /* Initialze cuda device from the current GL context. */ - bool Initialize(); - - /* Initialze cuda device from the ID3D11Device/ */ - bool Initialize(ID3D11Device *device); - - /* Returns true if the cuda device has already been initialized. */ - bool IsInitialized() const { - return _initialized; - } -private: - bool _initialized; -}; - -#endif /* __OPENSUBDIV_DEV_CE_CONTEXT_OPENCL_H__ */ diff --git a/intern/opensubdiv/opensubdiv_device_context_opencl.cc b/intern/opensubdiv/opensubdiv_device_context_opencl.cc deleted file mode 100644 index 4cacdc9e845..00000000000 --- a/intern/opensubdiv/opensubdiv_device_context_opencl.cc +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Adopted from OpenSubdiv with the following license: - * - * Copyright 2015 Pixar - * - * Licensed under the Apache License, Version 2.0 (the "Apache License") - * with the following modification; you may not use this file except in - * compliance with the Apache License and the following modification to it: - * Section 6. Trademarks. is deleted and replaced with: - * - * 6. Trademarks. This License does not grant permission to use the trade - * names, trademarks, service marks, or product names of the Licensor - * and its affiliates, except as required to comply with Section 4(c) of - * the License and to reproduce the content of the NOTICE file. - * - * You may obtain a copy of the Apache License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Apache License with the above modification is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the Apache License for the specific - * language governing permissions and limitations under the Apache License. - * - */ - -#ifdef OPENSUBDIV_HAS_OPENCL - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include "opensubdiv_device_context_opencl.h" - -#if defined(_WIN32) -# include -#elif defined(__APPLE__) -# include -#else -# include -#endif - -#include -#include -#include - -#define message(...) // fprintf(stderr, __VA_ARGS__) -#define error(...) fprintf(stderr, __VA_ARGS__) - -/* Returns the first found platform. */ -static cl_platform_id findPlatform() { - cl_uint numPlatforms; - cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clGetPlatformIDs call.\n", ciErrNum); - return NULL; - } - if (numPlatforms == 0) { - error("No OpenCL platform found.\n"); - return NULL; - } - cl_platform_id *clPlatformIDs = new cl_platform_id[numPlatforms]; - ciErrNum = clGetPlatformIDs(numPlatforms, clPlatformIDs, NULL); - char chBuffer[1024]; - for (cl_uint i = 0; i < numPlatforms; ++i) { - ciErrNum = clGetPlatformInfo(clPlatformIDs[i], CL_PLATFORM_NAME, - 1024, chBuffer,NULL); - if (ciErrNum == CL_SUCCESS) { - cl_platform_id platformId = clPlatformIDs[i]; - delete[] clPlatformIDs; - return platformId; - } - } - delete[] clPlatformIDs; - return NULL; -} - -/* Return. the device in clDevices which supports the extension. */ -static int findExtensionSupportedDevice(cl_device_id *clDevices, - int numDevices, - const char *extensionName) { - /* Find a device that supports sharing with GL/D3D11 - * (SLI / X-fire configurations) - */ - cl_int ciErrNum; - for (int i = 0; i < numDevices; ++i) { - /* Get extensions string size. */ - size_t extensionSize; - ciErrNum = clGetDeviceInfo(clDevices[i], - CL_DEVICE_EXTENSIONS, 0, NULL, - &extensionSize); - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clGetDeviceInfo\n", ciErrNum); - return -1; - } - if (extensionSize > 0) { - /* Get extensions string. */ - char *extensions = new char[extensionSize]; - ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, - extensionSize, extensions, - &extensionSize); - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clGetDeviceInfo\n", ciErrNum); - delete[] extensions; - continue; - } - std::string extString(extensions); - delete[] extensions; - /* Parse string. This is bit deficient since the extentions - * is space separated. - * - * The actual string would be "cl_khr_d3d11_sharing" - * or "cl_nv_d3d11_sharing" - */ - if (extString.find(extensionName) != std::string::npos) { - return i; - } - } - } - return -1; -} - -CLDeviceContext::CLDeviceContext() - : _clContext(NULL), - _clCommandQueue(NULL) { -} - -CLDeviceContext::~CLDeviceContext() { - if (_clCommandQueue) - clReleaseCommandQueue(_clCommandQueue); - if (_clContext) - clReleaseContext(_clContext); -} - -bool CLDeviceContext::HAS_CL_VERSION_1_1() -{ -#ifdef OPENSUBDIV_HAS_CLEW - static bool clewInitialized = false; - static bool clewLoadSuccess; - if (not clewInitialized) { - clewInitialized = true; - clewLoadSuccess = clewInit() == CLEW_SUCCESS; - if (!clewLoadSuccess) { - error("Loading OpenCL failed.\n"); - } - } - return clewLoadSuccess; -#endif - return true; -} - -bool CLDeviceContext::Initialize() -{ -#ifdef OPENSUBDIV_HAS_CLEW - if (!clGetPlatformIDs) { - error("Error clGetPlatformIDs function not bound.\n"); - return false; - } -#endif - cl_int ciErrNum; - cl_platform_id cpPlatform = findPlatform(); - -#if defined(_WIN32) - cl_context_properties props[] = { - CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), - CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), - CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, - 0 - }; -#elif defined(__APPLE__) - CGLContextObj kCGLContext = CGLGetCurrentContext(); - CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); - cl_context_properties props[] = { - CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, - 0 - }; -#else - cl_context_properties props[] = { - CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), - CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), - CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform, - 0 - }; -#endif - -#if defined(__APPLE__) - _clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, - NULL, &ciErrNum); - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clCreateContext\n", ciErrNum); - return false; - } - - size_t devicesSize = 0; - clGetGLContextInfoAPPLE(_clContext, kCGLContext, - CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, - 0, NULL, &devicesSize); - int numDevices = int(devicesSize / sizeof(cl_device_id)); - if (numDevices == 0) { - error("No sharable devices.\n"); - return false; - } - cl_device_id *clDevices = new cl_device_id[numDevices]; - clGetGLContextInfoAPPLE(_clContext, kCGLContext, - CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE, - numDevices * sizeof(cl_device_id), clDevices, NULL); - int clDeviceUsed = 0; - -#else // not __APPLE__ - /* Get the number of GPU devices available to the platform. */ - cl_uint numDevices = 0; - clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); - if (numDevices == 0) { - error("No CL GPU device found.\n"); - return false; - } - - /* Create the device list. */ - cl_device_id *clDevices = new cl_device_id[numDevices]; - clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL); - - const char *extension = "cl_khr_gl_sharing"; - int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices, - extension); - - if (clDeviceUsed < 0) { - error("No device found that supports CL/GL context sharing\n"); - delete[] clDevices; - return false; - } - - _clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed], - NULL, NULL, &ciErrNum); -#endif // not __APPLE__ - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clCreateContext\n", ciErrNum); - delete[] clDevices; - return false; - } - _clCommandQueue = clCreateCommandQueue(_clContext, clDevices[clDeviceUsed], - 0, &ciErrNum); - delete[] clDevices; - if (ciErrNum != CL_SUCCESS) { - error("Error %d in clCreateCommandQueue\n", ciErrNum); - return false; - } - return true; -} - -#endif /* OPENSUBDIV_HAS_OPENCL */ diff --git a/intern/opensubdiv/opensubdiv_device_context_opencl.h b/intern/opensubdiv/opensubdiv_device_context_opencl.h deleted file mode 100644 index a640dce1f07..00000000000 --- a/intern/opensubdiv/opensubdiv_device_context_opencl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Adopted from OpenSubdiv with the following license: - * - * Copyright 2015 Pixar - * - * Licensed under the Apache License, Version 2.0 (the "Apache License") - * with the following modification; you may not use this file except in - * compliance with the Apache License and the following modification to it: - * Section 6. Trademarks. is deleted and replaced with: - * - * 6. Trademarks. This License does not grant permission to use the trade - * names, trademarks, service marks, or product names of the Licensor - * and its affiliates, except as required to comply with Section 4(c) of - * the License and to reproduce the content of the NOTICE file. - * - * You may obtain a copy of the Apache License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Apache License with the above modification is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the Apache License for the specific - * language governing permissions and limitations under the Apache License. - * - */ - -#ifndef __OPENSUBDIV_DEV_CE_CONTEXT_OPENCL_H__ -#define __OPENSUBDIV_DEV_CE_CONTEXT_OPENCL_H__ - -#include - -class CLDeviceContext { -public: - CLDeviceContext(); - ~CLDeviceContext(); - - static bool HAS_CL_VERSION_1_1 (); - - bool Initialize(); - - bool IsInitialized() const { - return (_clContext != NULL); - } - - cl_context GetContext() const { - return _clContext; - } - cl_command_queue GetCommandQueue() const { - return _clCommandQueue; - } - -protected: - cl_context _clContext; - cl_command_queue _clCommandQueue; -}; - -#endif /* __OPENSUBDIV_DEV_CE_CONTEXT_OPENCL_H__ */ diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc deleted file mode 100644 index fb5313b8501..00000000000 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc +++ /dev/null @@ -1,516 +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) 2015 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#include -#include - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "opensubdiv_intern.h" -#include "opensubdiv_topology_refiner.h" - -#include "MEM_guardedalloc.h" - -using OpenSubdiv::Osd::BufferDescriptor; -using OpenSubdiv::Osd::PatchCoord; -using OpenSubdiv::Far::PatchMap; -using OpenSubdiv::Far::PatchTable; -using OpenSubdiv::Far::PatchTableFactory; -using OpenSubdiv::Far::StencilTable; -using OpenSubdiv::Far::StencilTableFactory; -using OpenSubdiv::Far::TopologyRefiner; - -namespace { - -/* Helper class to wrap numerous of patch coords into a buffer. - * Used to pass coordinates to the CPU evaluator. Other evaluators - * are not supported. - */ -class PatchCoordBuffer : public std::vector { -public: - static PatchCoordBuffer *Create(int size) - { - PatchCoordBuffer *buffer = new PatchCoordBuffer(); - buffer->resize(size); - return buffer; - } - PatchCoord *BindCpuBuffer() { - return (PatchCoord*)&(*this)[0]; - } - int GetNumVertices() { - return size(); - } - void UpdateData(const PatchCoord *patch_coords, - int num_patch_coords) - { - memcpy(&(*this)[0], - (void*)patch_coords, - num_patch_coords * sizeof(PatchCoord)); - } -}; - -/* Helper class to wrap single of patch coord into a buffer. - * Used to pass coordinates to the CPU evaluator. Other evaluators - * are not supported. - */ -class SinglePatchCoordBuffer { -public: - SinglePatchCoordBuffer() { - } - SinglePatchCoordBuffer(const PatchCoord& patch_coord) - : patch_coord_(patch_coord){ - } - static SinglePatchCoordBuffer *Create() - { - SinglePatchCoordBuffer *buffer = new SinglePatchCoordBuffer(); - return buffer; - } - PatchCoord *BindCpuBuffer() { - return (PatchCoord*)&patch_coord_; - } - int GetNumVertices() { - return 1; - } - void UpdateData(const PatchCoord& patch_coord) - { - patch_coord_ = patch_coord; - } -protected: - PatchCoord patch_coord_; -}; - -/* Helper class which is aimed to be used in cases when buffer - * is small enough and better to be allocated in stack rather - * than in heap. - * - * TODO(sergey): Check if bare arrays could be used by CPU evaluator. - */ -template -class StackAllocatedBuffer { -public: - static PatchCoordBuffer *Create(int /*size*/) - { - StackAllocatedBuffer *buffer = - new StackAllocatedBuffer(); - return buffer; - } - float *BindCpuBuffer() { - return &data_[0]; - } - int GetNumVertices() { - return num_verts; - } - /* TODO(sergey): Support UpdateData(). */ -protected: - float data_[element_size * num_verts]; -}; - -/* Volatile evaluator which can be used from threads. - * - * TODO(sergey): Make it possible to evaluate coordinates in chunks. - */ -template -class VolatileEvalOutput { -public: - typedef OpenSubdiv::Osd::EvaluatorCacheT EvaluatorCache; - - VolatileEvalOutput(const StencilTable *vertex_stencils, - const StencilTable *varying_stencils, - int num_coarse_verts, - int num_total_verts, - const PatchTable *patch_table, - EvaluatorCache *evaluator_cache = NULL, - DEVICE_CONTEXT *device_context = NULL) - : src_desc_( /*offset*/ 0, /*length*/ 3, /*stride*/ 3), - src_varying_desc_(/*offset*/ 0, /*length*/ 3, /*stride*/ 3), - num_coarse_verts_(num_coarse_verts), - evaluator_cache_ (evaluator_cache), - device_context_(device_context) - { - using OpenSubdiv::Osd::convertToCompatibleStencilTable; - src_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_verts, device_context_); - src_varying_data_ = SRC_VERTEX_BUFFER::Create(3, num_total_verts, device_context_); - patch_table_ = PATCH_TABLE::Create(patch_table, device_context_); - patch_coords_ = NULL; - vertex_stencils_ = convertToCompatibleStencilTable(vertex_stencils, - device_context_); - varying_stencils_ = convertToCompatibleStencilTable(varying_stencils, - device_context_); - } - - ~VolatileEvalOutput() - { - delete src_data_; - delete src_varying_data_; - delete patch_table_; - delete vertex_stencils_; - delete varying_stencils_; - } - - void UpdateData(const float *src, int start_vertex, int num_vertices) - { - src_data_->UpdateData(src, start_vertex, num_vertices, device_context_); - } - - void UpdateVaryingData(const float *src, int start_vertex, int num_vertices) - { - src_varying_data_->UpdateData(src, - start_vertex, - num_vertices, - device_context_); - } - - void Refine() - { - BufferDescriptor dst_desc = src_desc_; - dst_desc.offset += num_coarse_verts_ * src_desc_.stride; - - const EVALUATOR *eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_desc_, - dst_desc, - device_context_); - - EVALUATOR::EvalStencils(src_data_, src_desc_, - src_data_, dst_desc, - vertex_stencils_, - eval_instance, - device_context_); - - dst_desc = src_varying_desc_; - dst_desc.offset += num_coarse_verts_ * src_varying_desc_.stride; - eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_varying_desc_, - dst_desc, - device_context_); - - EVALUATOR::EvalStencils(src_varying_data_, src_varying_desc_, - src_varying_data_, dst_desc, - varying_stencils_, - eval_instance, - device_context_); - } - - void EvalPatchCoord(PatchCoord& patch_coord, float P[3]) - { - StackAllocatedBuffer<6, 1> vertex_data; - BufferDescriptor vertex_desc(0, 3, 6); - SinglePatchCoordBuffer patch_coord_buffer(patch_coord); - const EVALUATOR *eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_desc_, - vertex_desc, - device_context_); - EVALUATOR::EvalPatches(src_data_, src_desc_, - &vertex_data, vertex_desc, - patch_coord_buffer.GetNumVertices(), - &patch_coord_buffer, - patch_table_, eval_instance, device_context_); - float *refined_verts = vertex_data.BindCpuBuffer(); - memcpy(P, refined_verts, sizeof(float) * 3); - } - - void EvalPatchesWithDerivatives(PatchCoord& patch_coord, - float P[3], - float dPdu[3], - float dPdv[3]) - { - StackAllocatedBuffer<6, 1> vertex_data, derivatives; - BufferDescriptor vertex_desc(0, 3, 6), - du_desc(0, 3, 6), - dv_desc(3, 3, 6); - SinglePatchCoordBuffer patch_coord_buffer(patch_coord); - const EVALUATOR *eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_desc_, - vertex_desc, - du_desc, - dv_desc, - device_context_); - EVALUATOR::EvalPatches(src_data_, src_desc_, - &vertex_data, vertex_desc, - &derivatives, du_desc, - &derivatives, dv_desc, - patch_coord_buffer.GetNumVertices(), - &patch_coord_buffer, - patch_table_, eval_instance, device_context_); - float *refined_verts = vertex_data.BindCpuBuffer(); - memcpy(P, refined_verts, sizeof(float) * 3); - if (dPdu != NULL || dPdv != NULL) { - float *refined_drivatives = derivatives.BindCpuBuffer(); - if (dPdu) { - memcpy(dPdu, refined_drivatives, sizeof(float) * 3); - } - if (dPdv) { - memcpy(dPdv, refined_drivatives + 3, sizeof(float) * 3); - } - } - } - - void EvalPatchVarying(PatchCoord& patch_coord, - float varying[3]) { - StackAllocatedBuffer<3, 1> varying_data; - BufferDescriptor varying_desc(0, 3, 3); - SinglePatchCoordBuffer patch_coord_buffer(patch_coord); - EVALUATOR const *eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_varying_desc_, - varying_desc, - device_context_); - - EVALUATOR::EvalPatches(src_varying_data_, src_varying_desc_, - &varying_data, varying_desc, - patch_coord_buffer.GetNumVertices(), - &patch_coord_buffer, - patch_table_, eval_instance, device_context_); - float *refined_varying = varying_data.BindCpuBuffer(); - memcpy(varying, refined_varying, sizeof(float) * 3); - } -private: - SRC_VERTEX_BUFFER *src_data_; - SRC_VERTEX_BUFFER *src_varying_data_; - PatchCoordBuffer *patch_coords_; - PATCH_TABLE *patch_table_; - BufferDescriptor src_desc_; - BufferDescriptor src_varying_desc_; - int num_coarse_verts_; - - const STENCIL_TABLE *vertex_stencils_; - const STENCIL_TABLE *varying_stencils_; - - EvaluatorCache *evaluator_cache_; - DEVICE_CONTEXT *device_context_; -}; - -} /* namespace */ - -typedef VolatileEvalOutput CpuEvalOutput; - -typedef struct OpenSubdiv_EvaluatorDescr { - CpuEvalOutput *eval_output; - const PatchMap *patch_map; - const PatchTable *patch_table; -} OpenSubdiv_EvaluatorDescr; - -OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr( - OpenSubdiv_TopologyRefinerDescr *topology_refiner, - int subsurf_level) -{ - /* TODO(sergey): Look into re-using refiner with GLMesh. */ - TopologyRefiner *refiner = topology_refiner->osd_refiner; - if(refiner == NULL) { - /* Happens on bad topology. */ - return NULL; - } - /* Apply uniform refinement to the mesh so that we can use the - * limit evaluation API features. - */ - TopologyRefiner::UniformOptions options(subsurf_level); - refiner->RefineUniform(options); - /* Generate stencil table to update the bi-cubic patches control - * vertices after they have been re-posed (both for vertex & varying - * interpolation). - */ - StencilTableFactory::Options vertex_stencil_options; - vertex_stencil_options.generateOffsets = true; - vertex_stencil_options.generateIntermediateLevels = false; - const StencilTable *vertex_stencils = - StencilTableFactory::Create(*refiner, vertex_stencil_options); - StencilTableFactory::Options varying_stencil_options; - varying_stencil_options.generateOffsets = true; - varying_stencil_options.generateIntermediateLevels = false; - varying_stencil_options.interpolationMode = - StencilTableFactory::INTERPOLATE_VARYING; - const StencilTable *varying_stencils = - StencilTableFactory::Create(*refiner, varying_stencil_options); - /* Generate bi-cubic patch table for the limit surface. */ - PatchTableFactory::Options poptions; - poptions.SetEndCapType(PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS); - const PatchTable *patch_table = - PatchTableFactory::Create(*refiner, poptions); - /* Append local points stencils. */ - const StencilTable *local_point_stencil_table = - patch_table->GetLocalPointStencilTable(); - if (local_point_stencil_table != NULL) { - const StencilTable *table = - StencilTableFactory::AppendLocalPointStencilTable( - *refiner, - vertex_stencils, - local_point_stencil_table); - delete vertex_stencils; - vertex_stencils = table; - } - const StencilTable *local_point_varying_stencil_table = - patch_table->GetLocalPointVaryingStencilTable(); - if (local_point_varying_stencil_table != NULL) { - const StencilTable *table = - StencilTableFactory::AppendLocalPointStencilTable( - *refiner, - varying_stencils, - local_point_varying_stencil_table); - delete varying_stencils; - varying_stencils = table; - } - - /* Total number of vertices = coarse verts + refined verts + gregory - * basis verts. - */ - const int num_total_verts = vertex_stencils->GetNumControlVertices() + - vertex_stencils->GetNumStencils(); - const int num_coarse_verts = refiner->GetLevel(0).GetNumVertices(); - /* Create OpenSubdiv's CPU side evaluator. */ - CpuEvalOutput *eval_output = new CpuEvalOutput(vertex_stencils, - varying_stencils, - num_coarse_verts, - num_total_verts, - patch_table); - OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table); - /* Wrap everything we need into an object which we control from our - * side. - */ - OpenSubdiv_EvaluatorDescr *evaluator_descr; - evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorDescr); - evaluator_descr->eval_output = eval_output; - evaluator_descr->patch_map = patch_map; - evaluator_descr->patch_table = patch_table; - /* TOOD(sergey): Look into whether we've got duplicated stencils arrays. */ - delete varying_stencils; - delete vertex_stencils; - return evaluator_descr; -} - -void openSubdiv_deleteEvaluatorDescr(OpenSubdiv_EvaluatorDescr *evaluator_descr) -{ - delete evaluator_descr->eval_output; - delete evaluator_descr->patch_map; - delete evaluator_descr->patch_table; - OBJECT_GUARDED_DELETE(evaluator_descr, OpenSubdiv_EvaluatorDescr); -} - -void openSubdiv_setEvaluatorCoarsePositions( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const float *positions, - int start_vertex_index, - int num_vertices) -{ - /* TODO(sergey): Add sanity check on indices. */ - evaluator_descr->eval_output->UpdateData(positions, - start_vertex_index, - num_vertices); -} - -void openSubdiv_setEvaluatorVaryingData( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const float *varying_data, - int start_vertex_index, - int num_vertices) -{ - /* TODO(sergey): Add sanity check on indices. */ - evaluator_descr->eval_output->UpdateVaryingData(varying_data, - start_vertex_index, - num_vertices); -} - -void openSubdiv_setEvaluatorCoarsePositionsFromBuffer( - OpenSubdiv_EvaluatorDescr *evaluator_descr, - const void *buffer, - int start_offset, - int stride, - int start_vertex_index, - int num_vertices) -{ - const unsigned char *current_buffer = (unsigned char *)buffer; - current_buffer += start_offset; - /* TODO(sergey): Add sanity check on indices. */ - for (int i = 0; i < num_vertices; ++i) { - const int current_vertex_index = start_vertex_index + i; - evaluator_descr->eval_output->UpdateData((float *)current_buffer, - current_vertex_index, - 1); - current_buffer += stride; - } -} - -void openSubdiv_refineEvaluator(OpenSubdiv_EvaluatorDescr *evaluator_descr) -{ - evaluator_descr->eval_output->Refine(); -} - -void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr, - int osd_face_index, - float face_u, float face_v, - float P[3], - float dPdu[3], - float dPdv[3]) -{ - assert((face_u >= 0.0f) && (face_u <= 1.0f) && (face_v >= 0.0f) && (face_v <= 1.0f)); - const PatchTable::PatchHandle *handle = - evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v); - PatchCoord patch_coord(*handle, face_u, face_v); - if (dPdu != NULL || dPdv != NULL) { - evaluator_descr->eval_output->EvalPatchesWithDerivatives(patch_coord, - P, - dPdu, - dPdv); - } - else { - evaluator_descr->eval_output->EvalPatchCoord(patch_coord, P); - } -} - -void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr, - int osd_face_index, - float face_u, float face_v, - float varying[3]) -{ - assert((face_u >= 0.0f) && (face_u <= 1.0f) && (face_v >= 0.0f) && (face_v <= 1.0f)); - const PatchTable::PatchHandle *handle = - evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v); - PatchCoord patch_coord(*handle, face_u, face_v); - evaluator_descr->eval_output->EvalPatchVarying(patch_coord, varying); -} diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h new file mode 100644 index 00000000000..07a55cfd349 --- /dev/null +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h @@ -0,0 +1,117 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_EVALUATOR_CAPI_H_ +#define OPENSUBDIV_EVALUATOR_CAPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct OpenSubdiv_EvaluatorInternal; +struct OpenSubdiv_TopologyRefiner; + +typedef struct OpenSubdiv_Evaluator { + // Set coarse positions from a continuous array of coordinates. + void (*setCoarsePositions)(struct OpenSubdiv_Evaluator* evaluator, + const float* positions, + const int start_vertex_index, + const int num_vertices); + // Set varying data from a continuous array of data. + void (*setVaryingData)(struct OpenSubdiv_Evaluator* evaluator, + const float* varying_data, + const int start_vertex_index, const int num_vertices); + // Set face varying data from a continuous array of data. + // + // TODO(sergey): Find a better name for vertex here. It is not the vertex of + // geometry, but a vertex of UV map. + void (*setFaceVaryingData)(struct OpenSubdiv_Evaluator* evaluator, + const float* face_varying_data, + const int start_vertex_index, + const int num_vertices); + + // Set coarse vertex position from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + void (*setCoarsePositionsFromBuffer)(struct OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + // Set varying data from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + void (*setVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + // Set face varying data from a continuous memory buffer where + // first coordinate starts at offset of `start_offset` and there is `stride` + // bytes between adjacent vertex coordinates. + // + // TODO(sergey): Find a better name for vertex here. It is not the vertex of + // geometry, but a vertex of UV map. + void (*setFaceVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator, + const void* buffer, + const int start_offset, + const int stride, + const int start_vertex_index, + const int num_vertices); + + // Refine after coarse positions update. + void (*refine)(struct OpenSubdiv_Evaluator* evaluator); + + // Evaluate given ptex face at given bilinear coordinate. + // If derivatives are NULL, they will not be evaluated. + void (*evaluateLimit)(struct OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + float face_u, float face_v, + float P[3], float dPdu[3], float dPdv[3]); + + // Evaluate varying data at a given bilinear coordinate of given ptex face. + void (*evaluateVarying)(struct OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + float face_u, float face_v, + float varying[3]); + + // Evaluate face-varying data at a given bilinear coordinate of given + // ptex face. + void (*evaluateFaceVarying)(struct OpenSubdiv_Evaluator* evaluator, + const int ptex_face_index, + float face_u, float face_v, + float face_varying[2]); + + // Internal storage for the use in this module only. + // + // This is where actual OpenSubdiv's evaluator is living. + struct OpenSubdiv_EvaluatorInternal* internal; +} OpenSubdiv_Evaluator; + +OpenSubdiv_Evaluator* openSubdiv_createEvaluatorFromTopologyRefiner( + struct OpenSubdiv_TopologyRefiner* topology_refiner); + +void openSubdiv_deleteEvaluator(OpenSubdiv_Evaluator* evaluator); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSUBDIV_EVALUATOR_CAPI_H_ diff --git a/intern/opensubdiv/opensubdiv_gl_mesh.h b/intern/opensubdiv/opensubdiv_gl_mesh.h deleted file mode 100644 index 1e99fc5bce4..00000000000 --- a/intern/opensubdiv/opensubdiv_gl_mesh.h +++ /dev/null @@ -1,40 +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) 2018 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_GL_MESH_H__ -#define __OPENSUBDIV_GL_MESH_H__ - -struct OpenSubdiv_GLMeshDescr; -struct OpenSubdiv_TopologyRefinerDescr; -struct OpenSubdiv_GLMeshFVarData; - -typedef struct OpenSubdiv_GLMesh { - int evaluator_type; - OpenSubdiv_GLMeshDescr *descriptor; - OpenSubdiv_TopologyRefinerDescr *topology_refiner; - OpenSubdiv_GLMeshFVarData *fvar_data; -} OpenSubdiv_GLMesh; - -#endif /* __OPENSUBDIV_GL_MESH_H__ */ diff --git a/intern/opensubdiv/opensubdiv_gl_mesh_capi.h b/intern/opensubdiv/opensubdiv_gl_mesh_capi.h new file mode 100644 index 00000000000..971f6b9dcd3 --- /dev/null +++ b/intern/opensubdiv/opensubdiv_gl_mesh_capi.h @@ -0,0 +1,92 @@ +// Copyright 2013 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_CAPI_GL_MESH_CAPI_H_ +#define OPENSUBDIV_CAPI_GL_MESH_CAPI_H_ + +#include // for bool + +#include "opensubdiv_capi_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct OpenSubdiv_GLMeshInternal; + +// Mesh which is displayable in OpenGL context. +typedef struct OpenSubdiv_GLMesh { + ////////////////////////////////////////////////////////////////////////////// + // Subdivision/topology part. + + // Returns the GL index buffer containing the patch control vertices. + unsigned int (*getPatchIndexBuffer)(struct OpenSubdiv_GLMesh* gl_mesh); + + // Bind GL buffer which contains vertices (VBO). + // TODO(sergey): Is this a coarse vertices? + void (*bindVertexBuffer)(struct OpenSubdiv_GLMesh* gl_mesh); + + // Set coarse positions from a continuous array of coordinates. + void (*setCoarsePositions)(struct OpenSubdiv_GLMesh* gl_mesh, + const float* positions, + const int start_vertex, + const int num_vertices); + // TODO(sergey): setCoarsePositionsFromBuffer(). + + // Refine after coarse positions update. + void (*refine)(struct OpenSubdiv_GLMesh* gl_mesh); + + // Synchronize after coarse positions update and refine. + void (*synchronize)(struct OpenSubdiv_GLMesh* gl_mesh); + + ////////////////////////////////////////////////////////////////////////////// + // Drawing part. + + // Prepare mesh for display. + void (*prepareDraw)(struct OpenSubdiv_GLMesh* gl_mesh, + const bool use_osd_glsl, + const int active_uv_index); + + // Draw given range of patches. + // + // If fill_quads is false, then patches are drawn in wireframe. + void (*drawPatches)(struct OpenSubdiv_GLMesh *gl_mesh, + const bool fill_quads, + const int start_patch, const int num_patches); + + // Internal storage for the use in this module only. + // + // Tease: This contains an actual OpenSubdiv's Mesh object. + struct OpenSubdiv_GLMeshInternal* internal; +} OpenSubdiv_GLMesh; + +OpenSubdiv_GLMesh* openSubdiv_createOsdGLMeshFromTopologyRefiner( + struct OpenSubdiv_TopologyRefiner* topology_refiner, + eOpenSubdivEvaluator evaluator_type); + +void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh); + +// Global resources needed for GL mesh drawing. +bool openSubdiv_initGLMeshDrawingResources(void); +void openSubdiv_deinitGLMeshDrawingResources(void); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSUBDIV_CAPI_GL_MESH_CAPI_H_ diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc deleted file mode 100644 index d28b48ddd18..00000000000 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ /dev/null @@ -1,788 +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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include -#include -#include - -#include - -#ifdef OPENSUBDIV_HAS_CUDA -# include -#endif /* OPENSUBDIV_HAS_CUDA */ - -#include -#include - -#include "MEM_guardedalloc.h" - -#include "opensubdiv_capi.h" -#include "opensubdiv_gl_mesh.h" -#include "opensubdiv_topology_refiner.h" - -using OpenSubdiv::Osd::GLMeshInterface; - -extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[]; -extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[]; -extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[]; - -/* TODO(sergey): This is bit of bad level calls :S */ -extern "C" { -void copy_m3_m3(float m1[3][3], float m2[3][3]); -void copy_m3_m4(float m1[3][3], float m2[4][4]); -void adjoint_m3_m3(float m1[3][3], float m[3][3]); -float determinant_m3_array(float m[3][3]); -bool invert_m3_m3(float m1[3][3], float m2[3][3]); -bool invert_m3(float m[3][3]); -void transpose_m3(float mat[3][3]); -} - -#define MAX_LIGHTS 8 -#define SUPPORT_COLOR_MATERIAL - -typedef struct Light { - float position[4]; - float ambient[4]; - float diffuse[4]; - float specular[4]; - float spot_direction[4]; -#ifdef SUPPORT_COLOR_MATERIAL - float constant_attenuation; - float linear_attenuation; - float quadratic_attenuation; - float spot_cutoff; - float spot_exponent; - float spot_cos_cutoff; - float pad, pad2; -#endif -} Light; - -typedef struct Lighting { - Light lights[MAX_LIGHTS]; - int num_enabled; -} Lighting; - -typedef struct Transform { - float projection_matrix[16]; - float model_view_matrix[16]; - float normal_matrix[9]; -} Transform; - -static bool g_use_osd_glsl = false; -static int g_active_uv_index = 0; - -static GLuint g_flat_fill_solid_program = 0; -static GLuint g_flat_fill_texture2d_program = 0; -static GLuint g_smooth_fill_solid_program = 0; -static GLuint g_smooth_fill_texture2d_program = 0; - -static GLuint g_flat_fill_solid_shadeless_program = 0; -static GLuint g_flat_fill_texture2d_shadeless_program = 0; -static GLuint g_smooth_fill_solid_shadeless_program = 0; -static GLuint g_smooth_fill_texture2d_shadeless_program = 0; - -static GLuint g_wireframe_program = 0; - -static GLuint g_lighting_ub = 0; -static Lighting g_lighting_data; -static Transform g_transform; - -struct OpenSubdiv_GLMeshFVarData -{ - OpenSubdiv_GLMeshFVarData() : - texture_buffer(0), offset_buffer(0) { - } - - ~OpenSubdiv_GLMeshFVarData() - { - Release(); - } - - void Release() - { - if (texture_buffer) { - glDeleteTextures(1, &texture_buffer); - } - if (offset_buffer) { - glDeleteTextures(1, &offset_buffer); - } - texture_buffer = 0; - offset_buffer = 0; - fvar_width = 0; - channel_offsets.clear(); - } - - void Create(const OpenSubdiv::Far::TopologyRefiner *refiner, - const OpenSubdiv::Far::PatchTable *patch_table, - int fvar_width, - const float *fvar_src_data) - { - Release(); - - this->fvar_width = fvar_width; - - /* Expand fvar data to per-patch array */ - const int max_level = refiner->GetMaxLevel(); - const int num_channels = patch_table->GetNumFVarChannels(); - std::vector data; - int fvar_data_offset = 0; - channel_offsets.resize(num_channels); - for (int channel = 0; channel < num_channels; ++channel) { - OpenSubdiv::Far::ConstIndexArray indices = - patch_table->GetFVarValues(channel); - - channel_offsets[channel] = data.size(); - data.reserve(data.size() + indices.size() * fvar_width); - - for (int fvert = 0; fvert < (int)indices.size(); ++fvert) { - int index = indices[fvert] * fvar_width; - for (int i = 0; i < fvar_width; ++i) { - data.push_back(fvar_src_data[fvar_data_offset + index++]); - } - } - if (refiner->IsUniform()) { - const int num_values_max = refiner->GetLevel(max_level).GetNumFVarValues(channel); - fvar_data_offset += num_values_max * fvar_width; - } else { - const int num_values_total = refiner->GetNumFVarValuesTotal(channel); - fvar_data_offset += num_values_total * fvar_width; - } - } - - GLuint buffer; - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float), - &data[0], GL_STATIC_DRAW); - - glGenTextures(1, &texture_buffer); - glBindTexture(GL_TEXTURE_BUFFER, texture_buffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); - - glDeleteBuffers(1, &buffer); - - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, channel_offsets.size()*sizeof(int), - &channel_offsets[0], GL_STATIC_DRAW); - - glGenTextures(1, &offset_buffer); - glBindTexture(GL_TEXTURE_BUFFER, offset_buffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - GLuint texture_buffer; - GLuint offset_buffer; - std::vector channel_offsets; - int fvar_width; -}; - -namespace { - -GLuint compileShader(GLenum shaderType, - const char *version, - const char *define, - const char *source) -{ - const char *sources[] = { - version, - define, -#ifdef SUPPORT_COLOR_MATERIAL - "#define SUPPORT_COLOR_MATERIAL\n", -#else - "", -#endif - source, - }; - - GLuint shader = glCreateShader(shaderType); - glShaderSource(shader, 4, sources, NULL); - glCompileShader(shader); - - GLint status; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - GLchar emsg[1024]; - glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg); - fprintf(stderr, "Error compiling GLSL: %s\n", emsg); - fprintf(stderr, "Version: %s\n", version); - fprintf(stderr, "Defines: %s\n", define); - fprintf(stderr, "Source: %s\n", source); - return 0; - } - - return shader; -} - -GLuint linkProgram(const char *version, const char *define) -{ - GLuint vertexShader = compileShader(GL_VERTEX_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_vertex_glsl); - if (vertexShader == 0) { - return 0; - } - GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_geometry_glsl); - if (geometryShader == 0) { - return 0; - } - GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_fragment_glsl ); - if (fragmentShader == 0) { - return 0; - } - - GLuint program = glCreateProgram(); - - glAttachShader(program, vertexShader); - glAttachShader(program, geometryShader); - glAttachShader(program, fragmentShader); - - glBindAttribLocation(program, 0, "position"); - glBindAttribLocation(program, 1, "normal"); - - glLinkProgram(program); - - glDeleteShader(vertexShader); - glDeleteShader(geometryShader); - glDeleteShader(fragmentShader); - - GLint status; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if (status == GL_FALSE) { - GLchar emsg[1024]; - glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); - fprintf(stderr, "Error linking GLSL program : %s\n", emsg); - fprintf(stderr, "Defines: %s\n", define); - glDeleteProgram(program); - return 0; - } - - glUniformBlockBinding(program, - glGetUniformBlockIndex(program, "Lighting"), - 0); - - if (GLEW_VERSION_4_1) { - glProgramUniform1i(program, - glGetUniformLocation(program, "texture_buffer"), - 0); /* GL_TEXTURE0 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataOffsetBuffer"), - 30); /* GL_TEXTURE30 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataBuffer"), - 31); /* GL_TEXTURE31 */ - } - else { - glUseProgram(program); - glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */ - glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); /* GL_TEXTURE30 */ - glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ - glUseProgram(0); - } - - return program; -} - -void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program) -{ - glUseProgram(program); - - /* Matrices */ - glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"), - 1, false, - g_transform.model_view_matrix); - glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), - 1, false, - g_transform.projection_matrix); - glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"), - 1, false, - g_transform.normal_matrix); - - /* Lighting */ - glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); - glBufferSubData(GL_UNIFORM_BUFFER, - 0, sizeof(g_lighting_data), &g_lighting_data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); - - /* Color */ - { - /* TODO: stop using glGetMaterial */ - float color[4]; - glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); - glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color); - - glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); - glUniform4fv(glGetUniformLocation(program, "specular"), 1, color); - - glGetMaterialfv(GL_FRONT, GL_SHININESS, color); - glUniform1f(glGetUniformLocation(program, "shininess"), color[0]); - } - - /* Face-vertex data */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), - gl_mesh->fvar_data->fvar_width); - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), - gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); - } else { - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } - } else { - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } -} - -} /* namespace */ - -bool openSubdiv_osdGLDisplayInit(void) -{ - static bool need_init = true; - static bool init_success = false; - - if (need_init) { - /* TODO: update OSD drawing to OpenGL 3.3 core, then remove following line */ - return false; - - const char *version = ""; - if (GLEW_VERSION_3_2) { - version = "#version 150 compatibility\n"; - } - else if (GLEW_VERSION_3_1) { - version = "#version 140\n" - "#extension GL_ARB_compatibility: enable\n"; - } - else { - version = "#version 130\n"; - /* minimum supported for OpenSubdiv */ - } - - g_flat_fill_solid_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define FLAT_SHADING\n"); - g_flat_fill_texture2d_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define USE_TEXTURE_2D\n" - "#define FLAT_SHADING\n"); - g_smooth_fill_solid_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define SMOOTH_SHADING\n"); - g_smooth_fill_texture2d_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define USE_TEXTURE_2D\n" - "#define SMOOTH_SHADING\n"); - - g_flat_fill_solid_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define FLAT_SHADING\n"); - g_flat_fill_texture2d_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_TEXTURE_2D\n" - "#define FLAT_SHADING\n"); - g_smooth_fill_solid_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define SMOOTH_SHADING\n"); - g_smooth_fill_texture2d_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_TEXTURE_2D\n" - "#define SMOOTH_SHADING\n"); - - g_wireframe_program = linkProgram( - version, - "#define WIREFRAME\n"); - - glGenBuffers(1, &g_lighting_ub); - glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); - glBufferData(GL_UNIFORM_BUFFER, - sizeof(g_lighting_data), NULL, GL_STATIC_DRAW); - - need_init = false; - init_success = g_flat_fill_solid_program != 0 && - g_flat_fill_texture2d_program != 0 && - g_smooth_fill_solid_program != 0 && - g_smooth_fill_texture2d_program != 0 && - g_wireframe_program; - } - return init_success; -} - -void openSubdiv_osdGLDisplayDeinit(void) -{ - if (g_lighting_ub != 0) { - glDeleteBuffers(1, &g_lighting_ub); - } -#define SAFE_DELETE_PROGRAM(program) \ - do { \ - if (program) { \ - glDeleteProgram(program); \ - } \ - } while (false) - - SAFE_DELETE_PROGRAM(g_flat_fill_solid_program); - SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program); - SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program); - SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program); - SAFE_DELETE_PROGRAM(g_wireframe_program); - -#undef SAFE_DELETE_PROGRAM -} - -void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, - int active_uv_index) -{ - g_active_uv_index = active_uv_index; - g_use_osd_glsl = (use_osd_glsl != 0); - - /* Update transformation matrices. */ - glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix); - glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix); - - copy_m3_m4((float (*)[3])g_transform.normal_matrix, - (float (*)[4])g_transform.model_view_matrix); - invert_m3((float (*)[3])g_transform.normal_matrix); - transpose_m3((float (*)[3])g_transform.normal_matrix); - - /* Update OpenGL lights positions, colors etc. */ - g_lighting_data.num_enabled = 0; - for (int i = 0; i < MAX_LIGHTS; ++i) { - GLboolean enabled; - glGetBooleanv(GL_LIGHT0 + i, &enabled); - if (enabled) { - g_lighting_data.num_enabled++; - } - - /* TODO: stop using glGetLight */ - glGetLightfv(GL_LIGHT0 + i, - GL_POSITION, - g_lighting_data.lights[i].position); - glGetLightfv(GL_LIGHT0 + i, - GL_AMBIENT, - g_lighting_data.lights[i].ambient); - glGetLightfv(GL_LIGHT0 + i, - GL_DIFFUSE, - g_lighting_data.lights[i].diffuse); - glGetLightfv(GL_LIGHT0 + i, - GL_SPECULAR, - g_lighting_data.lights[i].specular); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_DIRECTION, - g_lighting_data.lights[i].spot_direction); -#ifdef SUPPORT_COLOR_MATERIAL - glGetLightfv(GL_LIGHT0 + i, - GL_CONSTANT_ATTENUATION, - &g_lighting_data.lights[i].constant_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_LINEAR_ATTENUATION, - &g_lighting_data.lights[i].linear_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_QUADRATIC_ATTENUATION, - &g_lighting_data.lights[i].quadratic_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_CUTOFF, - &g_lighting_data.lights[i].spot_cutoff); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_EXPONENT, - &g_lighting_data.lights[i].spot_exponent); - g_lighting_data.lights[i].spot_cos_cutoff = - cos(g_lighting_data.lights[i].spot_cutoff); -#endif - } -} - -static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, - bool fill_quads) -{ - GLint program = 0; - if (!g_use_osd_glsl) { - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - if (program) { - GLint model; - glGetIntegerv(GL_SHADE_MODEL, &model); - - GLint location = glGetUniformLocation(program, "osd_flat_shading"); - if (location != -1) { - glUniform1i(location, model == GL_FLAT); - } - - /* Face-vertex data */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - GLint location = glGetUniformLocation(program, "osd_fvar_count"); - if (location != -1) { - glUniform1i(location, gl_mesh->fvar_data->fvar_width); - } - - location = glGetUniformLocation(program, "osd_active_uv_offset"); - if (location != -1) { - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(location, - gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); - } else { - glUniform1i(location, 0); - } - } - } else { - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } - } - return program; - } - - if (fill_quads) { - int model; - GLboolean use_texture_2d; - glGetIntegerv(GL_SHADE_MODEL, &model); - glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); - - if (model == GL_FLAT) { - if (use_texture_2d) { - program = g_flat_fill_texture2d_program; - } - else { - program = g_flat_fill_solid_program; - } - } - else { - if (use_texture_2d) { - program = g_smooth_fill_texture2d_program; - } - else { - program = g_smooth_fill_solid_program; - } - } - - } - else { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - program = g_wireframe_program; - } - - bindProgram(gl_mesh, program); - - return program; -} - -static void perform_drawElements(GLuint program, - int patch_index, - int num_elements, - int start_element) -{ - if (program) { - glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), - patch_index); - } - glDrawElements(GL_LINES_ADJACENCY, - num_elements, - GL_UNSIGNED_INT, - (void *)(start_element * sizeof(unsigned int))); -} - -static void finish_patchDraw(bool fill_quads) -{ - /* TODO(sergey): Some of the stuff could be done once after the whole - * mesh is displayed. - */ - - /* Restore state. */ - if (!fill_quads) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - glBindVertexArray(0); - - if (g_use_osd_glsl) { - /* TODO(sergey): Store previously used program and roll back to it? */ - glUseProgram(0); - } -} - -static void draw_partition_patches_range(GLMeshInterface *mesh, - GLuint program, - int start_patch, - int num_patches) -{ - int traversed_patches = 0, num_remained_patches = num_patches; - const OpenSubdiv::Osd::PatchArrayVector& patches = - mesh->GetPatchTable()->GetPatchArrays(); - for (int i = 0; i < (int)patches.size(); ++i) { - const OpenSubdiv::Osd::PatchArray& patch = patches[i]; - OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); - OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); - - if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { - const int num_block_patches = patch.GetNumPatches(); - if (start_patch >= traversed_patches && - start_patch < traversed_patches + num_block_patches) - { - const int num_control_verts = desc.GetNumControlVertices(); - const int start_draw_patch = start_patch - traversed_patches; - const int num_draw_patches = std::min(num_remained_patches, - num_block_patches - start_draw_patch); - perform_drawElements(program, - i + start_draw_patch, - num_draw_patches * num_control_verts, - patch.GetIndexBase() + start_draw_patch * num_control_verts); - num_remained_patches -= num_draw_patches; - } - if (num_remained_patches == 0) { - break; - } - traversed_patches += num_block_patches; - } - } -} - -static void draw_all_patches(GLMeshInterface *mesh, - GLuint program) -{ - const OpenSubdiv::Osd::PatchArrayVector& patches = - mesh->GetPatchTable()->GetPatchArrays(); - for (int i = 0; i < (int)patches.size(); ++i) { - const OpenSubdiv::Osd::PatchArray& patch = patches[i]; - OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); - OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); - - if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { - perform_drawElements(program, - i, - patch.GetNumPatches() * desc.GetNumControlVertices(), - patch.GetIndexBase()); - } - } -} - -void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, - int fill_quads, - int start_patch, - int num_patches) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - - /* Make sure all global invariants are initialized. */ - if (!openSubdiv_osdGLDisplayInit()) { - return; - } - - /* Setup GLSL/OpenGL to draw patches in current context. */ - GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0); - - if (start_patch != -1) { - draw_partition_patches_range(mesh, - program, - start_patch, - num_patches); - } - else { - draw_all_patches(mesh, program); - } - - /* Finish patch drawing by restoring all changes to the OpenGL context. */ - finish_patchDraw(fill_quads != 0); -} - -void openSubdiv_osdGLAllocFVar(OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_GLMesh *gl_mesh, - const float *fvar_data) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - gl_mesh->fvar_data = OBJECT_GUARDED_NEW(OpenSubdiv_GLMeshFVarData); - gl_mesh->fvar_data->Create(topology_refiner->osd_refiner, - mesh->GetFarPatchTable(), - 2, - fvar_data); -} - -void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh) -{ - if (gl_mesh->fvar_data != NULL) { - OBJECT_GUARDED_DELETE(gl_mesh->fvar_data, OpenSubdiv_GLMeshFVarData); - } -} diff --git a/intern/opensubdiv/opensubdiv_intern.h b/intern/opensubdiv/opensubdiv_intern.h deleted file mode 100644 index ccb32f9d0ac..00000000000 --- a/intern/opensubdiv/opensubdiv_intern.h +++ /dev/null @@ -1,46 +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) 2015 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_INTERN_H__ -#define __OPENSUBDIV_INTERN_H__ - -/* Perform full topology validation when exporting it to OpenSubdiv. */ -#ifdef NDEBUG -# undef OPENSUBDIV_VALIDATE_TOPOLOGY -#else -/* TODO(sergey): Always disabled for now, the check doesn't handle - * multiple non-manifolds from the OpenSubdiv side currently. - */ -# undef OPENSUBDIV_VALIDATE_TOPOLOGY -#endif - -/* Currently OpenSubdiv expects topology to be oriented, - * but sometimes it's handy to disable orientation code - * to check whether it causes some weird issues by using - * pre-oriented model. - */ -#define OPENSUBDIV_ORIENT_TOPOLOGY - -#endif /* __OPENSUBDIV_INTERN_H__ */ diff --git a/intern/opensubdiv/opensubdiv_topology_refiner.h b/intern/opensubdiv/opensubdiv_topology_refiner.h deleted file mode 100644 index b00f6a54201..00000000000 --- a/intern/opensubdiv/opensubdiv_topology_refiner.h +++ /dev/null @@ -1,41 +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) 2016 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_TOPOLOGY_REFINER_H__ -#define __OPENSUBDIV_TOPOLOGY_REFINER_H__ - -#include - -typedef struct OpenSubdiv_TopologyRefinerDescr { - OpenSubdiv::Far::TopologyRefiner *osd_refiner; - - /* TODO(sergey): For now only, need to find better place - * after revisiting whole OSD drawing pipeline and Blender - * integration. - */ - std::vector uvs; -} OpenSubdiv_TopologyRefinerDescr; - -#endif /* __OPENSUBDIV_TOPOLOGY_REFINER_H__ */ diff --git a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h new file mode 100644 index 00000000000..103ccd2c1f9 --- /dev/null +++ b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h @@ -0,0 +1,110 @@ +// Copyright 2018 Blender Foundation. All rights reserved. +// +// 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. +// +// Author: Sergey Sharybin + +#ifndef OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_ +#define OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_ + +#include // for bool + +#ifdef __cplusplus +extern "C" { +#endif + +struct OpenSubdiv_Converter; +struct OpenSubdiv_TopologyRefinerInternal; + +// Those settings don't really belong to OpenSubdiv's topology refiner, but +// we are keeping track of them on our side of topology refiner. This is to +// make it possible to ensure we are not trying to abuse same OpenSubdiv's +// topology refiner with different subdivision levels or with different +// adaptive settings. +typedef struct OpenSubdiv_TopologyRefinerSettings { + bool is_adaptive; + int level; +} OpenSubdiv_TopologyRefinerSettings; + +typedef struct OpenSubdiv_TopologyRefiner { + // Query subdivision level the refiner is created for. + int (*getSubdivisionLevel)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + bool (*getIsAdaptive)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + + // Query basic topology information from base level. + int (*getNumVertices)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + int (*getNumEdges)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + int (*getNumFaces)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + int (*getNumFaceVertices)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index); + + // Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's + // subdivision grid. The rule commes as: + // - Triangle face consist of 3 ptex faces, ordered in the order of + // face-vertices. + // - Quad face consists of a single ptex face. + // - N-gons (similar to triangle) consists of N ptex faces, ordered same + // way as for triangle. + int (*getNumFacePtexFaces)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index); + int (*getNumPtexFaces)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + + // Initialize a per-base-face offset measured in ptex face indices. + // + // Basically, face_ptex_offset[base_face_index] is a total number of ptex + // faces created for bases faces [0 .. base_face_index - 1]. + // + // The array must contain at least total number of ptex faces elements. + void (*fillFacePtexIndexOffset)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + int* face_ptex_index_offset); + + // Internal storage for the use in this module only. + // + // Tease: Contains actual OpenSubdiv's refiner and (optionally) some other + // data and state needed for an internbal use. + struct OpenSubdiv_TopologyRefinerInternal* internal; +} OpenSubdiv_TopologyRefiner; + +OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter( + struct OpenSubdiv_Converter* converter, + const OpenSubdiv_TopologyRefinerSettings* settings); + +void openSubdiv_deleteTopologyRefiner( + OpenSubdiv_TopologyRefiner* topology_refiner); + +// Compare given topology refiner with converter. Returns truth if topology +// refiner matches given converter, false otherwise. +// +// This allows users to construct converter (which is supposed to be cheap) +// and compare with existing refiner before going into more computationally +// complicated parts of subdivision process. +bool openSubdiv_topologyRefinerCompareWithConverter( + const OpenSubdiv_TopologyRefiner* topology_refiner, + const OpenSubdiv_Converter* converter); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSUBDIV_TOPOLOGY_REFINER_CAPI_H_ diff --git a/intern/opensubdiv/opensubdiv_utils_capi.cc b/intern/opensubdiv/opensubdiv_utils_capi.cc deleted file mode 100644 index 72e3751e6b3..00000000000 --- a/intern/opensubdiv/opensubdiv_utils_capi.cc +++ /dev/null @@ -1,88 +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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * Brecht van Lommel - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#include -#include - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#ifdef OPENSUBDIV_HAS_OPENCL -# include "opensubdiv_device_context_opencl.h" -#endif /* OPENSUBDIV_HAS_OPENCL */ - -#ifdef OPENSUBDIV_HAS_CUDA -# include "opensubdiv_device_context_cuda.h" -#endif /* OPENSUBDIV_HAS_CUDA */ - -int openSubdiv_getAvailableEvaluators(void) -{ - int flags = OPENSUBDIV_EVALUATOR_CPU; - -#ifdef OPENSUBDIV_HAS_OPENMP - flags |= OPENSUBDIV_EVALUATOR_OPENMP; -#endif /* OPENSUBDIV_HAS_OPENMP */ - -#ifdef OPENSUBDIV_HAS_OPENCL - if (CLDeviceContext::HAS_CL_VERSION_1_1()) { - flags |= OPENSUBDIV_EVALUATOR_OPENCL; - } -#endif /* OPENSUBDIV_HAS_OPENCL */ - -#ifdef OPENSUBDIV_HAS_CUDA - if (CudaDeviceContext::HAS_CUDA_VERSION_4_0()) { - flags |= OPENSUBDIV_EVALUATOR_CUDA; - } -#endif /* OPENSUBDIV_HAS_OPENCL */ - -#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK - if (GLEW_VERSION_4_1) { - flags |= OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK; - } -#endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ - -#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE - if (GLEW_VERSION_4_3 || GLEW_ARB_compute_shader) { - flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE; - } -#endif /* OPENSUBDIV_HAS_GLSL_COMPUTE */ - - return flags; -} - -void openSubdiv_init(void) -{ - /* Ensure all OpenGL strings are cached. */ - (void)openSubdiv_getAvailableEvaluators(); -} - -void openSubdiv_cleanup(void) -{ - openSubdiv_osdGLDisplayDeinit(); -} diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl new file mode 100644 index 00000000000..1e36d549360 --- /dev/null +++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_fragment.glsl @@ -0,0 +1,172 @@ +/* + * ***** 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 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct VertexData { + vec4 position; + vec3 normal; + vec2 uv; +}; + +#define MAX_LIGHTS 8 +#define NUM_SOLID_LIGHTS 3 + +struct LightSource { + vec4 position; + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 spotDirection; +#ifdef SUPPORT_COLOR_MATERIAL + float constantAttenuation; + float linearAttenuation; + float quadraticAttenuation; + float spotCutoff; + float spotExponent; + float spotCosCutoff; + float pad, pad2; +#endif +}; + +layout(std140) uniform Lighting { + LightSource lightSource[MAX_LIGHTS]; + int num_enabled_lights; +}; + +uniform vec4 diffuse; +uniform vec4 specular; +uniform float shininess; + +uniform sampler2D texture_buffer; + +in block { + VertexData v; +} inpt; + +void main() +{ +#ifdef WIREFRAME + gl_FragColor = diffuse; +#else + vec3 N = inpt.v.normal; + + if (!gl_FrontFacing) + N = -N; + + /* Compute diffuse and specular lighting. */ + vec3 L_diffuse = vec3(0.0); + vec3 L_specular = vec3(0.0); + +#ifdef USE_LIGHTING +#ifndef USE_COLOR_MATERIAL + /* Assume NUM_SOLID_LIGHTS directional lights. */ + for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { + vec4 Plight = lightSource[i].position; +#ifdef USE_DIRECTIONAL_LIGHT + vec3 l = (Plight.w == 0.0) + ? normalize(Plight.xyz) + : normalize(inpt.v.position.xyz); +#else /* USE_DIRECTIONAL_LIGHT */ + /* TODO(sergey): We can normalize it outside of the shader. */ + vec3 l = normalize(Plight.xyz); +#endif /* USE_DIRECTIONAL_LIGHT */ + vec3 h = normalize(l + vec3(0, 0, 1)); + float d = max(0.0, dot(N, l)); + float s = pow(max(0.0, dot(N, h)), shininess); + L_diffuse += d * lightSource[i].diffuse.rgb; + L_specular += s * lightSource[i].specular.rgb; + } +#else /* USE_COLOR_MATERIAL */ + vec3 varying_position = inpt.v.position.xyz; + vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? + normalize(varying_position) : vec3(0.0, 0.0, -1.0); + for (int i = 0; i < num_enabled_lights; i++) { + /* todo: this is a slow check for disabled lights */ + if (lightSource[i].specular.a == 0.0) + continue; + + float intensity = 1.0; + vec3 light_direction; + + if (lightSource[i].position.w == 0.0) { + /* directional light */ + light_direction = lightSource[i].position.xyz; + } + else { + /* point light */ + vec3 d = lightSource[i].position.xyz - varying_position; + light_direction = normalize(d); + + /* spot light cone */ + if (lightSource[i].spotCutoff < 90.0) { + float cosine = max(dot(light_direction, + -lightSource[i].spotDirection.xyz), + 0.0); + intensity = pow(cosine, lightSource[i].spotExponent); + intensity *= step(lightSource[i].spotCosCutoff, cosine); + } + + /* falloff */ + float distance = length(d); + + intensity /= lightSource[i].constantAttenuation + + lightSource[i].linearAttenuation * distance + + lightSource[i].quadraticAttenuation * distance * distance; + } + + /* diffuse light */ + vec3 light_diffuse = lightSource[i].diffuse.rgb; + float diffuse_bsdf = max(dot(N, light_direction), 0.0); + L_diffuse += light_diffuse * diffuse_bsdf * intensity; + + /* specular light */ + vec3 light_specular = lightSource[i].specular.rgb; + vec3 H = normalize(light_direction - V); + + float specular_bsdf = pow(max(dot(N, H), 0.0), + gl_FrontMaterial.shininess); + L_specular += light_specular * specular_bsdf * intensity; + } +#endif /* USE_COLOR_MATERIAL */ +#else /* USE_LIGHTING */ + L_diffuse = vec3(1.0); +#endif + + /* Compute diffuse color. */ +#ifdef USE_TEXTURE_2D + L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; +#else + L_diffuse *= diffuse.rgb; +#endif + + /* Sum lighting. */ + vec3 L = L_diffuse; + if (shininess != 0) { + L += L_specular * specular.rgb; + } + + /* Write out fragment color. */ + gl_FragColor = vec4(L, diffuse.a); +#endif +} diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl new file mode 100644 index 00000000000..b16a5cca733 --- /dev/null +++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_geometry.glsl @@ -0,0 +1,154 @@ +/* + * ***** 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 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct VertexData { + vec4 position; + vec3 normal; + vec2 uv; +}; + +layout(lines_adjacency) in; +#ifdef WIREFRAME +layout(line_strip, max_vertices = 8) out; +#else +layout(triangle_strip, max_vertices = 4) out; +#endif + +uniform mat4 modelViewMatrix; +uniform mat4 projectionMatrix; +uniform int PrimitiveIdBase; +uniform int osd_fvar_count; +uniform int osd_active_uv_offset; + +in block { + VertexData v; +} inpt[]; + +#define INTERP_FACE_VARYING_2(result, fvarOffset, tessCoord) \ + { \ + vec2 v[4]; \ + int primOffset = (gl_PrimitiveID + PrimitiveIdBase) * 4; \ + for (int i = 0; i < 4; ++i) { \ + int index = (primOffset + i) * osd_fvar_count + fvarOffset; \ + v[i] = vec2(texelFetch(FVarDataBuffer, index).s, \ + texelFetch(FVarDataBuffer, index + 1).s); \ + } \ + result = mix(mix(v[0], v[1], tessCoord.s), \ + mix(v[3], v[2], tessCoord.s), \ + tessCoord.t); \ + } + +uniform samplerBuffer FVarDataBuffer; +uniform isamplerBuffer FVarDataOffsetBuffer; + +out block { + VertexData v; +} outpt; + +#ifdef FLAT_SHADING +void emit(int index, vec3 normal) +{ + outpt.v.position = inpt[index].v.position; + outpt.v.normal = normal; + + /* TODO(sergey): Only uniform subdivisions atm. */ + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); + vec2 st = quadst[index]; + + INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); + + gl_Position = projectionMatrix * inpt[index].v.position; + EmitVertex(); +} + +# ifdef WIREFRAME +void emit_edge(int v0, int v1, vec3 normal) +{ + emit(v0, normal); + emit(v1, normal); +} +# endif + +#else +void emit(int index) +{ + outpt.v.position = inpt[index].v.position; + outpt.v.normal = inpt[index].v.normal; + + /* TODO(sergey): Only uniform subdivisions atm. */ + vec2 quadst[4] = vec2[](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 1)); + vec2 st = quadst[index]; + + INTERP_FACE_VARYING_2(outpt.v.uv, osd_active_uv_offset, st); + + gl_Position = projectionMatrix * inpt[index].v.position; + EmitVertex(); +} + +# ifdef WIREFRAME +void emit_edge(int v0, int v1) +{ + emit(v0); + emit(v1); +} +# endif + +#endif + +void main() +{ + gl_PrimitiveID = gl_PrimitiveIDIn; + +#ifdef FLAT_SHADING + vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz; + vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz; + vec3 flat_normal = normalize(cross(B, A)); +# ifndef WIREFRAME + emit(0, flat_normal); + emit(1, flat_normal); + emit(3, flat_normal); + emit(2, flat_normal); +# else + emit_edge(0, 1, flat_normal); + emit_edge(1, 2, flat_normal); + emit_edge(2, 3, flat_normal); + emit_edge(3, 0, flat_normal); +# endif +#else +# ifndef WIREFRAME + emit(0); + emit(1); + emit(3); + emit(2); +# else + emit_edge(0, 1); + emit_edge(1, 2); + emit_edge(2, 3); + emit_edge(3, 0); +# endif +#endif + + EndPrimitive(); +} diff --git a/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl b/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl new file mode 100644 index 00000000000..6fcf5ad20cd --- /dev/null +++ b/intern/opensubdiv/shader/gpu_shader_opensubdiv_vertex.glsl @@ -0,0 +1,46 @@ +/* + * ***** 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 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +struct VertexData { + vec4 position; + vec3 normal; + vec2 uv; +}; + +in vec3 normal; +in vec4 position; + +uniform mat4 modelViewMatrix; +uniform mat3 normalMatrix; + +out block { + VertexData v; +} outpt; + +void main() +{ + outpt.v.position = modelViewMatrix * position; + outpt.v.normal = normalize(normalMatrix * normal); +} diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 81b1afa3621..dd5a87a445d 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -40,6 +40,8 @@ #ifdef WITH_OPENSUBDIV # include "opensubdiv_capi.h" # include "opensubdiv_converter_capi.h" +# include "opensubdiv_evaluator_capi.h" +# include "opensubdiv_topology_refiner_capi.h" #endif #include "GPU_glew.h" @@ -329,7 +331,7 @@ void ccgSubSurf_free(CCGSubSurf *ss) CCGAllocatorHDL allocator = ss->allocator; #ifdef WITH_OPENSUBDIV if (ss->osd_evaluator != NULL) { - openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator); + openSubdiv_deleteEvaluator(ss->osd_evaluator); } if (ss->osd_mesh != NULL) { ccgSubSurf__delete_osdGLMesh(ss->osd_mesh); @@ -341,7 +343,7 @@ void ccgSubSurf_free(CCGSubSurf *ss) MEM_freeN(ss->osd_coarse_coords); } if (ss->osd_topology_refiner != NULL) { - openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner); + openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner); } #endif diff --git a/source/blender/blenkernel/intern/CCGSubSurf_intern.h b/source/blender/blenkernel/intern/CCGSubSurf_intern.h index 9df1c9021ef..29e327d8973 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_intern.h +++ b/source/blender/blenkernel/intern/CCGSubSurf_intern.h @@ -236,7 +236,7 @@ struct CCGSubSurf { * Refiner is created from the modifier stack and used later from the main * thread to construct GL mesh to avoid threaded access to GL. */ - struct OpenSubdiv_TopologyRefinerDescr *osd_topology_refiner; /* Only used at synchronization stage. */ + struct OpenSubdiv_TopologyRefiner *osd_topology_refiner; /* Only used at synchronization stage. */ /* Denotes whether osd_mesh is invalid now due to topology changes and needs * to be reconstructed. * @@ -249,7 +249,7 @@ struct CCGSubSurf { /* ** CPU backend. ** */ /* Limit evaluator, used to evaluate CCG. */ - struct OpenSubdiv_EvaluatorDescr *osd_evaluator; + struct OpenSubdiv_Evaluator *osd_evaluator; /* Next PTex face index, used while CCG synchronization * to fill in PTex index of CCGFace. */ diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c index 46204898709..98a17ad8009 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c @@ -42,6 +42,9 @@ #include "opensubdiv_capi.h" #include "opensubdiv_converter_capi.h" +#include "opensubdiv_evaluator_capi.h" +#include "opensubdiv_gl_mesh_capi.h" +#include "opensubdiv_topology_refiner_capi.h" #include "GPU_glew.h" #include "GPU_extensions.h" @@ -131,7 +134,6 @@ static bool compare_ccg_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm) static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm) { - const OpenSubdiv_TopologyRefinerDescr *topology_refiner; OpenSubdiv_Converter converter; bool result; if (ss->osd_mesh == NULL && ss->osd_topology_refiner == NULL) { @@ -140,15 +142,10 @@ static bool compare_osd_derivedmesh_topology(CCGSubSurf *ss, DerivedMesh *dm) /* TODO(sergey): De-duplicate with topology counter at the bottom of * the file. */ - if (ss->osd_topology_refiner != NULL) { - topology_refiner = ss->osd_topology_refiner; - } - else { - topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); - } ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter); - result = openSubdiv_topologyRefnerCompareConverter(topology_refiner, - &converter); + result = openSubdiv_topologyRefinerCompareWithConverter( + ss->osd_topology_refiner, + &converter); ccgSubSurf_converter_free(&converter); return result; } @@ -159,22 +156,13 @@ static bool opensubdiv_is_topology_changed(CCGSubSurf *ss, DerivedMesh *dm) return true; } if (ss->osd_topology_refiner != NULL) { - int levels = openSubdiv_topologyRefinerGetSubdivLevel( + const int levels = ss->osd_topology_refiner->getSubdivisionLevel( ss->osd_topology_refiner); BLI_assert(ss->osd_mesh_invalid == true); if (levels != ss->subdivLevels) { return true; } } - if (ss->osd_mesh != NULL && ss->osd_mesh_invalid == false) { - const OpenSubdiv_TopologyRefinerDescr *topology_refiner = - openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); - int levels = openSubdiv_topologyRefinerGetSubdivLevel(topology_refiner); - BLI_assert(ss->osd_topology_refiner == NULL); - if (levels != ss->subdivLevels) { - return true; - } - } if (ss->skip_grids == false) { return compare_ccg_derivedmesh_topology(ss, dm) == false; } @@ -194,13 +182,13 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm) /* Reset GPU part. */ ss->osd_mesh_invalid = true; if (ss->osd_topology_refiner != NULL) { - openSubdiv_deleteTopologyRefinerDescr(ss->osd_topology_refiner); + openSubdiv_deleteTopologyRefiner(ss->osd_topology_refiner); ss->osd_topology_refiner = NULL; } /* Reset CPU side. */ if (ss->osd_evaluator != NULL) { - openSubdiv_deleteEvaluatorDescr(ss->osd_evaluator); + openSubdiv_deleteEvaluator(ss->osd_evaluator); ss->osd_evaluator = NULL; } } @@ -209,10 +197,10 @@ void ccgSubSurf_checkTopologyChanged(CCGSubSurf *ss, DerivedMesh *dm) static void ccgSubSurf__updateGLMeshCoords(CCGSubSurf *ss) { BLI_assert(ss->meshIFC.numLayers == 3); - openSubdiv_osdGLMeshUpdateVertexBuffer(ss->osd_mesh, - (float *) ss->osd_coarse_coords, - 0, - ss->osd_num_coarse_coords); + ss->osd_mesh->setCoarsePositions(ss->osd_mesh, + (float *) ss->osd_coarse_coords, + 0, + ss->osd_num_coarse_coords); } bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, @@ -259,9 +247,7 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, ss->osd_mesh = openSubdiv_createOsdGLMeshFromTopologyRefiner( ss->osd_topology_refiner, - compute_type, - ss->subdivLevels); - ss->osd_topology_refiner = NULL; + compute_type); if (UNLIKELY(ss->osd_mesh == NULL)) { /* Most likely compute device is not available. */ @@ -269,13 +255,12 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, } ccgSubSurf__updateGLMeshCoords(ss); - openSubdiv_osdGLMeshRefine(ss->osd_mesh); - openSubdiv_osdGLMeshSynchronize(ss->osd_mesh); + ss->osd_mesh->refine(ss->osd_mesh); + ss->osd_mesh->synchronize(ss->osd_mesh); ss->osd_coarse_coords_invalid = false; glBindVertexArray(ss->osd_vao); - glBindBuffer(GL_ARRAY_BUFFER, - openSubdiv_getOsdGLMeshVertexBuffer(ss->osd_mesh)); + ss->osd_mesh->bindVertexBuffer(ss->osd_mesh); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); @@ -289,12 +274,12 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, } else if (ss->osd_coarse_coords_invalid) { ccgSubSurf__updateGLMeshCoords(ss); - openSubdiv_osdGLMeshRefine(ss->osd_mesh); - openSubdiv_osdGLMeshSynchronize(ss->osd_mesh); + ss->osd_mesh->refine(ss->osd_mesh); + ss->osd_mesh->synchronize(ss->osd_mesh); ss->osd_coarse_coords_invalid = false; } - openSubdiv_osdGLMeshDisplayPrepare(use_osd_glsl, active_uv_index); + ss->osd_mesh->prepareDraw(ss->osd_mesh, use_osd_glsl, active_uv_index); return true; } @@ -305,12 +290,12 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads, if (LIKELY(ss->osd_mesh != NULL)) { glBindVertexArray(ss->osd_vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, - openSubdiv_getOsdGLMeshPatchIndexBuffer(ss->osd_mesh)); + ss->osd_mesh->getPatchIndexBuffer(ss->osd_mesh)); - openSubdiv_osdGLMeshBindVertexBuffer(ss->osd_mesh); + ss->osd_mesh->bindVertexBuffer(ss->osd_mesh); glBindVertexArray(ss->osd_vao); - openSubdiv_osdGLMeshDisplay(ss->osd_mesh, fill_quads, - start_partition, num_partitions); + ss->osd_mesh->drawPatches(ss->osd_mesh, fill_quads, + start_partition, num_partitions); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -319,33 +304,21 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads, int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss) { - const OpenSubdiv_TopologyRefinerDescr *topology_refiner; if (ss->osd_topology_refiner != NULL) { - topology_refiner = ss->osd_topology_refiner; - } - else if (ss->osd_mesh != NULL) { - topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); - } - else { - return 0; + return ss->osd_topology_refiner->getNumFaces( + ss->osd_topology_refiner); } - return openSubdiv_topologyRefinerGetNumFaces(topology_refiner); + return 0; } /* Get number of vertices in base faces in a particular GL mesh. */ int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face) { - const OpenSubdiv_TopologyRefinerDescr *topology_refiner; if (ss->osd_topology_refiner != NULL) { - topology_refiner = ss->osd_topology_refiner; - } - else if (ss->osd_mesh != NULL) { - topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh); - } - else { - return 0; + return ss->osd_topology_refiner->getNumFaceVertices( + ss->osd_topology_refiner, face); } - return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face); + return 0; } void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids) @@ -453,17 +426,21 @@ void ccgSubSurf_evaluatorFVarUV(CCGSubSurf *ss, static bool opensubdiv_createEvaluator(CCGSubSurf *ss) { OpenSubdiv_Converter converter; - OpenSubdiv_TopologyRefinerDescr *topology_refiner; + OpenSubdiv_TopologyRefiner *topology_refiner; if (ss->fMap->numEntries == 0) { /* OpenSubdiv doesn't support meshes without faces. */ return false; } ccgSubSurf_converter_setup_from_ccg(ss, &converter); - topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter); + OpenSubdiv_TopologyRefinerSettings settings; + settings.level = ss->subdivLevels; + settings.is_adaptive = false; + topology_refiner = + openSubdiv_createTopologyRefinerFromConverter( + &converter, &settings); ccgSubSurf_converter_free(&converter); ss->osd_evaluator = - openSubdiv_createEvaluatorDescr(topology_refiner, - ss->subdivLevels); + openSubdiv_createEvaluatorFromTopologyRefiner(topology_refiner); if (ss->osd_evaluator == NULL) { BLI_assert(!"OpenSubdiv initialization failed, should not happen."); return false; @@ -519,11 +496,11 @@ static void opensubdiv_updateEvaluatorCoarsePositions(CCGSubSurf *ss) } } - openSubdiv_setEvaluatorCoarsePositions(ss->osd_evaluator, - (float *)positions, - 0, - num_basis_verts); - openSubdiv_refineEvaluator(ss->osd_evaluator); + ss->osd_evaluator->setCoarsePositions(ss->osd_evaluator, + (float *)positions, + 0, + num_basis_verts); + ss->osd_evaluator->refine(ss->osd_evaluator); MEM_freeN(positions); } @@ -558,11 +535,12 @@ static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss, ccgSubSurf__mapGridToFace(S, grid_u, grid_v, &face_u, &face_v); /* TODO(sergey): Need proper port. */ - openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index, - face_u, face_v, - P, - do_normals ? dPdu : NULL, - do_normals ? dPdv : NULL); + ss->osd_evaluator->evaluateLimit( + ss->osd_evaluator, osd_face_index, + face_u, face_v, + P, + do_normals ? dPdu : NULL, + do_normals ? dPdv : NULL); OSD_LOG("face=%d, corner=%d, grid_u=%f, grid_v=%f, face_u=%f, face_v=%f, P=(%f, %f, %f)\n", osd_face_index, S, grid_u, grid_v, face_u, face_v, P[0], P[1], P[2]); @@ -636,7 +614,11 @@ static void opensubdiv_evaluateQuadFaceGrids(CCGSubSurf *ss, * let's just re-evaluate for simplicity. */ /* TODO(sergey): Need proper port. */ - openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index, u, v, P, dPdu, dPdv); + ss->osd_evaluator->evaluateLimit( + ss->osd_evaluator, + osd_face_index, + u, v, + P, dPdu, dPdv); VertDataCopy(co, P, ss); if (do_normals) { cross_v3_v3v3(no, dPdu, dPdv); @@ -700,7 +682,11 @@ static void opensubdiv_evaluateNGonFaceGrids(CCGSubSurf *ss, float P[3], dPdu[3], dPdv[3]; /* TODO(sergey): Need proper port. */ - openSubdiv_evaluateLimit(ss->osd_evaluator, osd_face_index + S, u, v, P, dPdu, dPdv); + ss->osd_evaluator->evaluateLimit( + ss->osd_evaluator, + osd_face_index + S, + u, v, + P, dPdu, dPdv); OSD_LOG("face=%d, corner=%d, u=%f, v=%f, P=(%f, %f, %f)\n", osd_face_index + S, S, u, v, P[0], P[1], P[2]); @@ -838,7 +824,12 @@ void ccgSubSurf_prepareTopologyRefiner(CCGSubSurf *ss, DerivedMesh *dm) OpenSubdiv_Converter converter; ccgSubSurf_converter_setup_from_derivedmesh(ss, dm, &converter); /* TODO(sergey): Remove possibly previously allocated refiner. */ - ss->osd_topology_refiner = openSubdiv_createTopologyRefinerDescr(&converter); + OpenSubdiv_TopologyRefinerSettings settings; + settings.level = ss->subdivLevels; + settings.is_adaptive = false; + ss->osd_topology_refiner = + openSubdiv_createTopologyRefinerFromConverter( + &converter, &settings); ccgSubSurf_converter_free(&converter); } } diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index 8c1ba0c3782..219d77a6c52 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c @@ -432,35 +432,35 @@ void ccgSubSurf_converter_setup_from_derivedmesh( { ConvDMStorage *user_data; - converter->get_scheme_type = conv_dm_get_type; + converter->getSchemeType = conv_dm_get_type; - converter->get_fvar_linear_interpolation = + converter->getFVarLinearInterpolation = conv_dm_get_fvar_linear_interpolation; - converter->get_num_faces = conv_dm_get_num_faces; - converter->get_num_edges = conv_dm_get_num_edges; - converter->get_num_verts = conv_dm_get_num_verts; + converter->getNumFaces = conv_dm_get_num_faces; + converter->getNumEdges = conv_dm_get_num_edges; + converter->getNumVertices = conv_dm_get_num_verts; - converter->get_num_face_verts = conv_dm_get_num_face_verts; - converter->get_face_verts = conv_dm_get_face_verts; - converter->get_face_edges = conv_dm_get_face_edges; + converter->getNumFaceVertices = conv_dm_get_num_face_verts; + converter->getFaceVertices = conv_dm_get_face_verts; + converter->getFaceEdges = conv_dm_get_face_edges; - converter->get_edge_verts = conv_dm_get_edge_verts; - converter->get_num_edge_faces = conv_dm_get_num_edge_faces; - converter->get_edge_faces = conv_dm_get_edge_faces; - converter->get_edge_sharpness = conv_dm_get_edge_sharpness; + converter->getEdgeVertices = conv_dm_get_edge_verts; + converter->getNumEdgeFaces = conv_dm_get_num_edge_faces; + converter->getEdgeFaces = conv_dm_get_edge_faces; + converter->getEdgeSharpness = conv_dm_get_edge_sharpness; - converter->get_num_vert_edges = conv_dm_get_num_vert_edges; - converter->get_vert_edges = conv_dm_get_vert_edges; - converter->get_num_vert_faces = conv_dm_get_num_vert_faces; - converter->get_vert_faces = conv_dm_get_vert_faces; + converter->getNumVertexEdges = conv_dm_get_num_vert_edges; + converter->getVertexEdges = conv_dm_get_vert_edges; + converter->getNumVertexFaces = conv_dm_get_num_vert_faces; + converter->getVertexFaces = conv_dm_get_vert_faces; - converter->get_num_uv_layers = conv_dm_get_num_uv_layers; - converter->precalc_uv_layer = conv_dm_precalc_uv_layer; - converter->finish_uv_layer = conv_dm_finish_uv_layer; - converter->get_num_uvs = conv_dm_get_num_uvs; - converter->get_uvs = conv_dm_get_uvs; - converter->get_face_corner_uv_index = conv_dm_get_face_corner_uv_index; + converter->getNumUVLayers = conv_dm_get_num_uv_layers; + converter->precalcUVLayer = conv_dm_precalc_uv_layer; + converter->finishUVLayer = conv_dm_finish_uv_layer; + converter->getNumUVCoordinates = conv_dm_get_num_uvs; + converter->getUVCoordinates = conv_dm_get_uvs; + converter->getFaceCornerUVIndex = conv_dm_get_face_corner_uv_index; user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__); user_data->ss = ss; @@ -476,7 +476,7 @@ void ccgSubSurf_converter_setup_from_derivedmesh( user_data->uvs = NULL; user_data->face_uvs = NULL; - converter->free_user_data = conv_dm_free_user_data; + converter->freeUserData = conv_dm_free_user_data; converter->user_data = user_data; #ifdef USE_MESH_ELEMENT_MAPPING @@ -717,45 +717,45 @@ static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED( void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, OpenSubdiv_Converter *converter) { - converter->get_scheme_type = conv_ccg_get_bilinear_type; + converter->getSchemeType = conv_ccg_get_bilinear_type; - converter->get_fvar_linear_interpolation = + converter->getFVarLinearInterpolation = conv_ccg_get_fvar_linear_interpolation; - converter->get_num_faces = conv_ccg_get_num_faces; - converter->get_num_edges = conv_ccg_get_num_edges; - converter->get_num_verts = conv_ccg_get_num_verts; + converter->getNumFaces = conv_ccg_get_num_faces; + converter->getNumEdges = conv_ccg_get_num_edges; + converter->getNumVertices = conv_ccg_get_num_verts; - converter->get_num_face_verts = conv_ccg_get_num_face_verts; - converter->get_face_verts = conv_ccg_get_face_verts; - converter->get_face_edges = conv_ccg_get_face_edges; + converter->getNumFaceVertices = conv_ccg_get_num_face_verts; + converter->getFaceVertices = conv_ccg_get_face_verts; + converter->getFaceEdges = conv_ccg_get_face_edges; - converter->get_edge_verts = conv_ccg_get_edge_verts; - converter->get_num_edge_faces = conv_ccg_get_num_edge_faces; - converter->get_edge_faces = conv_ccg_get_edge_faces; - converter->get_edge_sharpness = conv_ccg_get_edge_sharpness; + converter->getEdgeVertices = conv_ccg_get_edge_verts; + converter->getNumEdgeFaces = conv_ccg_get_num_edge_faces; + converter->getEdgeFaces = conv_ccg_get_edge_faces; + converter->getEdgeSharpness = conv_ccg_get_edge_sharpness; - converter->get_num_vert_edges = conv_ccg_get_num_vert_edges; - converter->get_vert_edges = conv_ccg_get_vert_edges; - converter->get_num_vert_faces = conv_ccg_get_num_vert_faces; - converter->get_vert_faces = conv_ccg_get_vert_faces; + converter->getNumVertexEdges = conv_ccg_get_num_vert_edges; + converter->getVertexEdges = conv_ccg_get_vert_edges; + converter->getNumVertexFaces = conv_ccg_get_num_vert_faces; + converter->getVertexFaces = conv_ccg_get_vert_faces; - converter->get_num_uv_layers = conv_ccg_get_num_uv_layers; - converter->precalc_uv_layer = conv_ccg_precalc_uv_layer; - converter->finish_uv_layer = conv_ccg_finish_uv_layer; - converter->get_num_uvs = conv_ccg_get_num_uvs; - converter->get_uvs = conv_ccg_get_uvs; - converter->get_face_corner_uv_index = conv_ccg_get_face_corner_uv_index; + converter->getNumUVLayers = conv_ccg_get_num_uv_layers; + converter->precalcUVLayer = conv_ccg_precalc_uv_layer; + converter->finishUVLayer = conv_ccg_finish_uv_layer; + converter->getNumUVCoordinates = conv_ccg_get_num_uvs; + converter->getUVCoordinates = conv_ccg_get_uvs; + converter->getFaceCornerUVIndex = conv_ccg_get_face_corner_uv_index; - converter->free_user_data = NULL; + converter->freeUserData = NULL; converter->user_data = ss; } void ccgSubSurf_converter_free( struct OpenSubdiv_Converter *converter) { - if (converter->free_user_data) { - converter->free_user_data(converter); + if (converter->freeUserData) { + converter->freeUserData(converter); } } -- cgit v1.2.3 From 010e24a95c9e53f2c0bee2aa4cc8450e4346233d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 11:12:02 +0200 Subject: OpenSubdiv: Remove UV coordinates from converter Converter only defines topology, not coordinates or (face)varying data. --- intern/opensubdiv/opensubdiv_converter_capi.h | 3 --- .../blenkernel/intern/CCGSubSurf_opensubdiv_converter.c | 13 ------------- 2 files changed, 16 deletions(-) diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 1d76da4d76b..b16d6eb6c8f 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -127,9 +127,6 @@ typedef struct OpenSubdiv_Converter { // Get number of UV coordinates in the current layer (layer which was // specified in precalcUVLayer(). int (*getNumUVCoordinates)(const struct OpenSubdiv_Converter* converter); - // Get cooridnates themselves. - void (*getUVCoordinates)(const struct OpenSubdiv_Converter* converter, - float* uvs_coordinates); // For the given face index and its corner (known as loop in Blender) // get corrsponding UV coordinate index. int (*getFaceCornerUVIndex)(const struct OpenSubdiv_Converter* converter, diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c index 219d77a6c52..649b7c7fa4c 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv_converter.c @@ -389,12 +389,6 @@ static int conv_dm_get_num_uvs(const OpenSubdiv_Converter *converter) return storage->num_uvs; } -static void conv_dm_get_uvs(const OpenSubdiv_Converter *converter, float *uvs) -{ - ConvDMStorage *storage = converter->user_data; - memcpy(uvs, storage->uvs, sizeof(float) * 2 * storage->num_uvs); -} - static int conv_dm_get_face_corner_uv_index(const OpenSubdiv_Converter *converter, int face, int corner) @@ -459,7 +453,6 @@ void ccgSubSurf_converter_setup_from_derivedmesh( converter->precalcUVLayer = conv_dm_precalc_uv_layer; converter->finishUVLayer = conv_dm_finish_uv_layer; converter->getNumUVCoordinates = conv_dm_get_num_uvs; - converter->getUVCoordinates = conv_dm_get_uvs; converter->getFaceCornerUVIndex = conv_dm_get_face_corner_uv_index; user_data = MEM_mallocN(sizeof(ConvDMStorage), __func__); @@ -702,11 +695,6 @@ static int conv_ccg_get_num_uvs(const OpenSubdiv_Converter *UNUSED(converter)) return 0; } -static void conv_ccg_get_uvs(const OpenSubdiv_Converter * UNUSED(converter), - float *UNUSED(uvs)) -{ -} - static int conv_ccg_get_face_corner_uv_index(const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(face), int UNUSED(corner_)) @@ -744,7 +732,6 @@ void ccgSubSurf_converter_setup_from_ccg(CCGSubSurf *ss, converter->precalcUVLayer = conv_ccg_precalc_uv_layer; converter->finishUVLayer = conv_ccg_finish_uv_layer; converter->getNumUVCoordinates = conv_ccg_get_num_uvs; - converter->getUVCoordinates = conv_ccg_get_uvs; converter->getFaceCornerUVIndex = conv_ccg_get_face_corner_uv_index; converter->freeUserData = NULL; -- cgit v1.2.3 From d3674587b2e9a43e9dcf794a3c4c8b5eca878dfd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 12:33:32 +0200 Subject: OpenSubdiv: Remove unused file --- .../internal/opensubdiv_topology_refiner.h | 41 ---------------------- 1 file changed, 41 deletions(-) delete mode 100644 intern/opensubdiv/internal/opensubdiv_topology_refiner.h diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.h b/intern/opensubdiv/internal/opensubdiv_topology_refiner.h deleted file mode 100644 index b00f6a54201..00000000000 --- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.h +++ /dev/null @@ -1,41 +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) 2016 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_TOPOLOGY_REFINER_H__ -#define __OPENSUBDIV_TOPOLOGY_REFINER_H__ - -#include - -typedef struct OpenSubdiv_TopologyRefinerDescr { - OpenSubdiv::Far::TopologyRefiner *osd_refiner; - - /* TODO(sergey): For now only, need to find better place - * after revisiting whole OSD drawing pipeline and Blender - * integration. - */ - std::vector uvs; -} OpenSubdiv_TopologyRefinerDescr; - -#endif /* __OPENSUBDIV_TOPOLOGY_REFINER_H__ */ -- cgit v1.2.3 From 775c4eb903ef7ed23e734a2412b96d1bf2126e8f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 12:34:19 +0200 Subject: OpenSubdiv: Remove one more unused file --- intern/opensubdiv/internal/opensubdiv_gpu.cc | 788 --------------------------- 1 file changed, 788 deletions(-) delete mode 100644 intern/opensubdiv/internal/opensubdiv_gpu.cc diff --git a/intern/opensubdiv/internal/opensubdiv_gpu.cc b/intern/opensubdiv/internal/opensubdiv_gpu.cc deleted file mode 100644 index d28b48ddd18..00000000000 --- a/intern/opensubdiv/internal/opensubdiv_gpu.cc +++ /dev/null @@ -1,788 +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) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#include "opensubdiv_capi.h" - -#ifdef _MSC_VER -# include "iso646.h" -#endif - -#include -#include -#include - -#include - -#ifdef OPENSUBDIV_HAS_CUDA -# include -#endif /* OPENSUBDIV_HAS_CUDA */ - -#include -#include - -#include "MEM_guardedalloc.h" - -#include "opensubdiv_capi.h" -#include "opensubdiv_gl_mesh.h" -#include "opensubdiv_topology_refiner.h" - -using OpenSubdiv::Osd::GLMeshInterface; - -extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[]; -extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[]; -extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[]; - -/* TODO(sergey): This is bit of bad level calls :S */ -extern "C" { -void copy_m3_m3(float m1[3][3], float m2[3][3]); -void copy_m3_m4(float m1[3][3], float m2[4][4]); -void adjoint_m3_m3(float m1[3][3], float m[3][3]); -float determinant_m3_array(float m[3][3]); -bool invert_m3_m3(float m1[3][3], float m2[3][3]); -bool invert_m3(float m[3][3]); -void transpose_m3(float mat[3][3]); -} - -#define MAX_LIGHTS 8 -#define SUPPORT_COLOR_MATERIAL - -typedef struct Light { - float position[4]; - float ambient[4]; - float diffuse[4]; - float specular[4]; - float spot_direction[4]; -#ifdef SUPPORT_COLOR_MATERIAL - float constant_attenuation; - float linear_attenuation; - float quadratic_attenuation; - float spot_cutoff; - float spot_exponent; - float spot_cos_cutoff; - float pad, pad2; -#endif -} Light; - -typedef struct Lighting { - Light lights[MAX_LIGHTS]; - int num_enabled; -} Lighting; - -typedef struct Transform { - float projection_matrix[16]; - float model_view_matrix[16]; - float normal_matrix[9]; -} Transform; - -static bool g_use_osd_glsl = false; -static int g_active_uv_index = 0; - -static GLuint g_flat_fill_solid_program = 0; -static GLuint g_flat_fill_texture2d_program = 0; -static GLuint g_smooth_fill_solid_program = 0; -static GLuint g_smooth_fill_texture2d_program = 0; - -static GLuint g_flat_fill_solid_shadeless_program = 0; -static GLuint g_flat_fill_texture2d_shadeless_program = 0; -static GLuint g_smooth_fill_solid_shadeless_program = 0; -static GLuint g_smooth_fill_texture2d_shadeless_program = 0; - -static GLuint g_wireframe_program = 0; - -static GLuint g_lighting_ub = 0; -static Lighting g_lighting_data; -static Transform g_transform; - -struct OpenSubdiv_GLMeshFVarData -{ - OpenSubdiv_GLMeshFVarData() : - texture_buffer(0), offset_buffer(0) { - } - - ~OpenSubdiv_GLMeshFVarData() - { - Release(); - } - - void Release() - { - if (texture_buffer) { - glDeleteTextures(1, &texture_buffer); - } - if (offset_buffer) { - glDeleteTextures(1, &offset_buffer); - } - texture_buffer = 0; - offset_buffer = 0; - fvar_width = 0; - channel_offsets.clear(); - } - - void Create(const OpenSubdiv::Far::TopologyRefiner *refiner, - const OpenSubdiv::Far::PatchTable *patch_table, - int fvar_width, - const float *fvar_src_data) - { - Release(); - - this->fvar_width = fvar_width; - - /* Expand fvar data to per-patch array */ - const int max_level = refiner->GetMaxLevel(); - const int num_channels = patch_table->GetNumFVarChannels(); - std::vector data; - int fvar_data_offset = 0; - channel_offsets.resize(num_channels); - for (int channel = 0; channel < num_channels; ++channel) { - OpenSubdiv::Far::ConstIndexArray indices = - patch_table->GetFVarValues(channel); - - channel_offsets[channel] = data.size(); - data.reserve(data.size() + indices.size() * fvar_width); - - for (int fvert = 0; fvert < (int)indices.size(); ++fvert) { - int index = indices[fvert] * fvar_width; - for (int i = 0; i < fvar_width; ++i) { - data.push_back(fvar_src_data[fvar_data_offset + index++]); - } - } - if (refiner->IsUniform()) { - const int num_values_max = refiner->GetLevel(max_level).GetNumFVarValues(channel); - fvar_data_offset += num_values_max * fvar_width; - } else { - const int num_values_total = refiner->GetNumFVarValuesTotal(channel); - fvar_data_offset += num_values_total * fvar_width; - } - } - - GLuint buffer; - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(float), - &data[0], GL_STATIC_DRAW); - - glGenTextures(1, &texture_buffer); - glBindTexture(GL_TEXTURE_BUFFER, texture_buffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer); - - glDeleteBuffers(1, &buffer); - - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, channel_offsets.size()*sizeof(int), - &channel_offsets[0], GL_STATIC_DRAW); - - glGenTextures(1, &offset_buffer); - glBindTexture(GL_TEXTURE_BUFFER, offset_buffer); - glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer); - glBindTexture(GL_TEXTURE_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - GLuint texture_buffer; - GLuint offset_buffer; - std::vector channel_offsets; - int fvar_width; -}; - -namespace { - -GLuint compileShader(GLenum shaderType, - const char *version, - const char *define, - const char *source) -{ - const char *sources[] = { - version, - define, -#ifdef SUPPORT_COLOR_MATERIAL - "#define SUPPORT_COLOR_MATERIAL\n", -#else - "", -#endif - source, - }; - - GLuint shader = glCreateShader(shaderType); - glShaderSource(shader, 4, sources, NULL); - glCompileShader(shader); - - GLint status; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - GLchar emsg[1024]; - glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg); - fprintf(stderr, "Error compiling GLSL: %s\n", emsg); - fprintf(stderr, "Version: %s\n", version); - fprintf(stderr, "Defines: %s\n", define); - fprintf(stderr, "Source: %s\n", source); - return 0; - } - - return shader; -} - -GLuint linkProgram(const char *version, const char *define) -{ - GLuint vertexShader = compileShader(GL_VERTEX_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_vertex_glsl); - if (vertexShader == 0) { - return 0; - } - GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_geometry_glsl); - if (geometryShader == 0) { - return 0; - } - GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, - version, - define, - datatoc_gpu_shader_opensubdiv_fragment_glsl ); - if (fragmentShader == 0) { - return 0; - } - - GLuint program = glCreateProgram(); - - glAttachShader(program, vertexShader); - glAttachShader(program, geometryShader); - glAttachShader(program, fragmentShader); - - glBindAttribLocation(program, 0, "position"); - glBindAttribLocation(program, 1, "normal"); - - glLinkProgram(program); - - glDeleteShader(vertexShader); - glDeleteShader(geometryShader); - glDeleteShader(fragmentShader); - - GLint status; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if (status == GL_FALSE) { - GLchar emsg[1024]; - glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); - fprintf(stderr, "Error linking GLSL program : %s\n", emsg); - fprintf(stderr, "Defines: %s\n", define); - glDeleteProgram(program); - return 0; - } - - glUniformBlockBinding(program, - glGetUniformBlockIndex(program, "Lighting"), - 0); - - if (GLEW_VERSION_4_1) { - glProgramUniform1i(program, - glGetUniformLocation(program, "texture_buffer"), - 0); /* GL_TEXTURE0 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataOffsetBuffer"), - 30); /* GL_TEXTURE30 */ - - glProgramUniform1i(program, - glGetUniformLocation(program, "FVarDataBuffer"), - 31); /* GL_TEXTURE31 */ - } - else { - glUseProgram(program); - glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0); /* GL_TEXTURE0 */ - glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30); /* GL_TEXTURE30 */ - glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31); /* GL_TEXTURE31 */ - glUseProgram(0); - } - - return program; -} - -void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program) -{ - glUseProgram(program); - - /* Matrices */ - glUniformMatrix4fv(glGetUniformLocation(program, "modelViewMatrix"), - 1, false, - g_transform.model_view_matrix); - glUniformMatrix4fv(glGetUniformLocation(program, "projectionMatrix"), - 1, false, - g_transform.projection_matrix); - glUniformMatrix3fv(glGetUniformLocation(program, "normalMatrix"), - 1, false, - g_transform.normal_matrix); - - /* Lighting */ - glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); - glBufferSubData(GL_UNIFORM_BUFFER, - 0, sizeof(g_lighting_data), &g_lighting_data); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); - - /* Color */ - { - /* TODO: stop using glGetMaterial */ - float color[4]; - glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color); - glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color); - - glGetMaterialfv(GL_FRONT, GL_SPECULAR, color); - glUniform4fv(glGetUniformLocation(program, "specular"), 1, color); - - glGetMaterialfv(GL_FRONT, GL_SHININESS, color); - glUniform1f(glGetUniformLocation(program, "shininess"), color[0]); - } - - /* Face-vertex data */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), - gl_mesh->fvar_data->fvar_width); - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), - gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); - } else { - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } - } else { - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } -} - -} /* namespace */ - -bool openSubdiv_osdGLDisplayInit(void) -{ - static bool need_init = true; - static bool init_success = false; - - if (need_init) { - /* TODO: update OSD drawing to OpenGL 3.3 core, then remove following line */ - return false; - - const char *version = ""; - if (GLEW_VERSION_3_2) { - version = "#version 150 compatibility\n"; - } - else if (GLEW_VERSION_3_1) { - version = "#version 140\n" - "#extension GL_ARB_compatibility: enable\n"; - } - else { - version = "#version 130\n"; - /* minimum supported for OpenSubdiv */ - } - - g_flat_fill_solid_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define FLAT_SHADING\n"); - g_flat_fill_texture2d_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define USE_TEXTURE_2D\n" - "#define FLAT_SHADING\n"); - g_smooth_fill_solid_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define SMOOTH_SHADING\n"); - g_smooth_fill_texture2d_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_LIGHTING\n" - "#define USE_TEXTURE_2D\n" - "#define SMOOTH_SHADING\n"); - - g_flat_fill_solid_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define FLAT_SHADING\n"); - g_flat_fill_texture2d_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_TEXTURE_2D\n" - "#define FLAT_SHADING\n"); - g_smooth_fill_solid_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define SMOOTH_SHADING\n"); - g_smooth_fill_texture2d_shadeless_program = linkProgram( - version, - "#define USE_COLOR_MATERIAL\n" - "#define USE_TEXTURE_2D\n" - "#define SMOOTH_SHADING\n"); - - g_wireframe_program = linkProgram( - version, - "#define WIREFRAME\n"); - - glGenBuffers(1, &g_lighting_ub); - glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub); - glBufferData(GL_UNIFORM_BUFFER, - sizeof(g_lighting_data), NULL, GL_STATIC_DRAW); - - need_init = false; - init_success = g_flat_fill_solid_program != 0 && - g_flat_fill_texture2d_program != 0 && - g_smooth_fill_solid_program != 0 && - g_smooth_fill_texture2d_program != 0 && - g_wireframe_program; - } - return init_success; -} - -void openSubdiv_osdGLDisplayDeinit(void) -{ - if (g_lighting_ub != 0) { - glDeleteBuffers(1, &g_lighting_ub); - } -#define SAFE_DELETE_PROGRAM(program) \ - do { \ - if (program) { \ - glDeleteProgram(program); \ - } \ - } while (false) - - SAFE_DELETE_PROGRAM(g_flat_fill_solid_program); - SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program); - SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program); - SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program); - SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program); - SAFE_DELETE_PROGRAM(g_wireframe_program); - -#undef SAFE_DELETE_PROGRAM -} - -void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, - int active_uv_index) -{ - g_active_uv_index = active_uv_index; - g_use_osd_glsl = (use_osd_glsl != 0); - - /* Update transformation matrices. */ - glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix); - glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix); - - copy_m3_m4((float (*)[3])g_transform.normal_matrix, - (float (*)[4])g_transform.model_view_matrix); - invert_m3((float (*)[3])g_transform.normal_matrix); - transpose_m3((float (*)[3])g_transform.normal_matrix); - - /* Update OpenGL lights positions, colors etc. */ - g_lighting_data.num_enabled = 0; - for (int i = 0; i < MAX_LIGHTS; ++i) { - GLboolean enabled; - glGetBooleanv(GL_LIGHT0 + i, &enabled); - if (enabled) { - g_lighting_data.num_enabled++; - } - - /* TODO: stop using glGetLight */ - glGetLightfv(GL_LIGHT0 + i, - GL_POSITION, - g_lighting_data.lights[i].position); - glGetLightfv(GL_LIGHT0 + i, - GL_AMBIENT, - g_lighting_data.lights[i].ambient); - glGetLightfv(GL_LIGHT0 + i, - GL_DIFFUSE, - g_lighting_data.lights[i].diffuse); - glGetLightfv(GL_LIGHT0 + i, - GL_SPECULAR, - g_lighting_data.lights[i].specular); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_DIRECTION, - g_lighting_data.lights[i].spot_direction); -#ifdef SUPPORT_COLOR_MATERIAL - glGetLightfv(GL_LIGHT0 + i, - GL_CONSTANT_ATTENUATION, - &g_lighting_data.lights[i].constant_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_LINEAR_ATTENUATION, - &g_lighting_data.lights[i].linear_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_QUADRATIC_ATTENUATION, - &g_lighting_data.lights[i].quadratic_attenuation); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_CUTOFF, - &g_lighting_data.lights[i].spot_cutoff); - glGetLightfv(GL_LIGHT0 + i, - GL_SPOT_EXPONENT, - &g_lighting_data.lights[i].spot_exponent); - g_lighting_data.lights[i].spot_cos_cutoff = - cos(g_lighting_data.lights[i].spot_cutoff); -#endif - } -} - -static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, - bool fill_quads) -{ - GLint program = 0; - if (!g_use_osd_glsl) { - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - if (program) { - GLint model; - glGetIntegerv(GL_SHADE_MODEL, &model); - - GLint location = glGetUniformLocation(program, "osd_flat_shading"); - if (location != -1) { - glUniform1i(location, model == GL_FLAT); - } - - /* Face-vertex data */ - if (gl_mesh->fvar_data != NULL) { - if (gl_mesh->fvar_data->texture_buffer) { - glActiveTexture(GL_TEXTURE31); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->texture_buffer); - glActiveTexture(GL_TEXTURE0); - } - - if (gl_mesh->fvar_data->offset_buffer) { - glActiveTexture(GL_TEXTURE30); - glBindTexture(GL_TEXTURE_BUFFER, - gl_mesh->fvar_data->offset_buffer); - glActiveTexture(GL_TEXTURE0); - } - - GLint location = glGetUniformLocation(program, "osd_fvar_count"); - if (location != -1) { - glUniform1i(location, gl_mesh->fvar_data->fvar_width); - } - - location = glGetUniformLocation(program, "osd_active_uv_offset"); - if (location != -1) { - if (gl_mesh->fvar_data->channel_offsets.size() > 0 && - g_active_uv_index >= 0) - { - glUniform1i(location, - gl_mesh->fvar_data->channel_offsets[g_active_uv_index]); - } else { - glUniform1i(location, 0); - } - } - } else { - glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0); - glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0); - } - } - return program; - } - - if (fill_quads) { - int model; - GLboolean use_texture_2d; - glGetIntegerv(GL_SHADE_MODEL, &model); - glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); - - if (model == GL_FLAT) { - if (use_texture_2d) { - program = g_flat_fill_texture2d_program; - } - else { - program = g_flat_fill_solid_program; - } - } - else { - if (use_texture_2d) { - program = g_smooth_fill_texture2d_program; - } - else { - program = g_smooth_fill_solid_program; - } - } - - } - else { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - program = g_wireframe_program; - } - - bindProgram(gl_mesh, program); - - return program; -} - -static void perform_drawElements(GLuint program, - int patch_index, - int num_elements, - int start_element) -{ - if (program) { - glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), - patch_index); - } - glDrawElements(GL_LINES_ADJACENCY, - num_elements, - GL_UNSIGNED_INT, - (void *)(start_element * sizeof(unsigned int))); -} - -static void finish_patchDraw(bool fill_quads) -{ - /* TODO(sergey): Some of the stuff could be done once after the whole - * mesh is displayed. - */ - - /* Restore state. */ - if (!fill_quads) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - glBindVertexArray(0); - - if (g_use_osd_glsl) { - /* TODO(sergey): Store previously used program and roll back to it? */ - glUseProgram(0); - } -} - -static void draw_partition_patches_range(GLMeshInterface *mesh, - GLuint program, - int start_patch, - int num_patches) -{ - int traversed_patches = 0, num_remained_patches = num_patches; - const OpenSubdiv::Osd::PatchArrayVector& patches = - mesh->GetPatchTable()->GetPatchArrays(); - for (int i = 0; i < (int)patches.size(); ++i) { - const OpenSubdiv::Osd::PatchArray& patch = patches[i]; - OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); - OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); - - if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { - const int num_block_patches = patch.GetNumPatches(); - if (start_patch >= traversed_patches && - start_patch < traversed_patches + num_block_patches) - { - const int num_control_verts = desc.GetNumControlVertices(); - const int start_draw_patch = start_patch - traversed_patches; - const int num_draw_patches = std::min(num_remained_patches, - num_block_patches - start_draw_patch); - perform_drawElements(program, - i + start_draw_patch, - num_draw_patches * num_control_verts, - patch.GetIndexBase() + start_draw_patch * num_control_verts); - num_remained_patches -= num_draw_patches; - } - if (num_remained_patches == 0) { - break; - } - traversed_patches += num_block_patches; - } - } -} - -static void draw_all_patches(GLMeshInterface *mesh, - GLuint program) -{ - const OpenSubdiv::Osd::PatchArrayVector& patches = - mesh->GetPatchTable()->GetPatchArrays(); - for (int i = 0; i < (int)patches.size(); ++i) { - const OpenSubdiv::Osd::PatchArray& patch = patches[i]; - OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); - OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); - - if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { - perform_drawElements(program, - i, - patch.GetNumPatches() * desc.GetNumControlVertices(), - patch.GetIndexBase()); - } - } -} - -void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, - int fill_quads, - int start_patch, - int num_patches) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - - /* Make sure all global invariants are initialized. */ - if (!openSubdiv_osdGLDisplayInit()) { - return; - } - - /* Setup GLSL/OpenGL to draw patches in current context. */ - GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0); - - if (start_patch != -1) { - draw_partition_patches_range(mesh, - program, - start_patch, - num_patches); - } - else { - draw_all_patches(mesh, program); - } - - /* Finish patch drawing by restoring all changes to the OpenGL context. */ - finish_patchDraw(fill_quads != 0); -} - -void openSubdiv_osdGLAllocFVar(OpenSubdiv_TopologyRefinerDescr *topology_refiner, - OpenSubdiv_GLMesh *gl_mesh, - const float *fvar_data) -{ - GLMeshInterface *mesh = - (GLMeshInterface *)(gl_mesh->descriptor); - gl_mesh->fvar_data = OBJECT_GUARDED_NEW(OpenSubdiv_GLMeshFVarData); - gl_mesh->fvar_data->Create(topology_refiner->osd_refiner, - mesh->GetFarPatchTable(), - 2, - fvar_data); -} - -void openSubdiv_osdGLDestroyFVar(OpenSubdiv_GLMesh *gl_mesh) -{ - if (gl_mesh->fvar_data != NULL) { - OBJECT_GUARDED_DELETE(gl_mesh->fvar_data, OpenSubdiv_GLMeshFVarData); - } -} -- cgit v1.2.3 From e1423391621dcc72e55144541cb26b540698edba Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 12:55:39 +0200 Subject: Fix compilation with older OpenSubdiv libraries Only fixes compilation error, the functionality will be limited. Currently we don't care that much, since all the work is done in the branch anyway. Later on when we'll know which fixes we need to apply on top of latest OpenSubdiv library we will call a library upgrade. --- intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index 595df3eaa75..d593518405f 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -52,6 +53,13 @@ using OpenSubdiv::Far::StencilTable; using OpenSubdiv::Far::StencilTableFactory; using OpenSubdiv::Far::TopologyRefiner; +// TODO(sergey): Remove after official requirement bump for OSD version. +#if OPENSUBDIV_VERSION_NUMBER >= 30200 +# define OPENSUBDIV_HAS_FVAR_EVALUATION +#else +# undef OPENSUBDIV_HAS_FVAR_EVALUATION +#endif + namespace opensubdiv_capi { namespace { @@ -652,6 +660,7 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( StencilTableFactory::Create(*refiner, varying_stencil_options); // Face warying stencil. const StencilTable* face_varying_stencils = NULL; +#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION if (has_face_varying_data) { StencilTableFactory::Options face_varying_stencil_options; face_varying_stencil_options.generateOffsets = true; @@ -664,6 +673,7 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( face_varying_stencils = StencilTableFactory::Create(*refiner, face_varying_stencil_options); } +#endif // Generate bi-cubic patch table for the limit surface. // TODO(sergey): Ideally we would want to expose end-cap settings via // C-API to make it more generic. Currently it matches old Blender's @@ -694,6 +704,7 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( delete varying_stencils; varying_stencils = table; } +#ifdef OPENSUBDIV_HAS_FVAR_EVALUATION const StencilTable* local_point_face_varying_stencil_table = patch_table->GetLocalPointFaceVaryingStencilTable(); if (local_point_face_varying_stencil_table != NULL) { @@ -705,6 +716,7 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( delete face_varying_stencils; face_varying_stencils = table; } +#endif // Create OpenSubdiv's CPU side evaluator. // TODO(sergey): Make it possible to use different evaluators. opensubdiv_capi::CpuEvalOutput* eval_output = -- cgit v1.2.3 From 80795ff8976fabb210ef139f94d60a9e1080c8ce Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 16 Jul 2018 14:34:24 +0200 Subject: Buildbot: update for new VS2017 buildbot worker name. --- build_files/buildbot/slave_compile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index c43bb88b270..bf8f9f15751 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -78,7 +78,7 @@ if 'cmake' in builder: # cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE=/usr/local/cuda-hack/nvcc') elif builder.startswith('win'): - if builder.endswith('_vc2017'): + if builder.endswith('_vs2017'): if builder.startswith('win64'): cmake_options.extend(['-G', 'Visual Studio 15 2017 Win64']) elif builder.startswith('win32'): -- cgit v1.2.3 From 96b4e43e8dcdf3c051be2b52bb453c55d6afcd08 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 16 Jul 2018 09:37:24 +0200 Subject: Fix T55527: creating a Quaternion without args should result in identity quaternion Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D3487 --- source/blender/python/mathutils/mathutils_Quaternion.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 1a6fd0ee86f..48c18dd20c1 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -1100,7 +1100,8 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw { PyObject *seq = NULL; double angle = 0.0f; - float quat[QUAT_SIZE] = {0.0f, 0.0f, 0.0f, 0.0f}; + float quat[QUAT_SIZE]; + unit_qt(quat); if (kwds && PyDict_Size(kwds)) { PyErr_SetString(PyExc_TypeError, -- cgit v1.2.3 From 43f0af734e42d7e539cbb68ebf390b97016048bb Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 16 Jul 2018 09:48:52 +0200 Subject: Fix T55944: fbx export error with smoothing face ddee0931b868 added PROP_RAW_BOOLEAN case for foreach_set, but missed foreach_get Reviewed By: brecht Differential Revision: https://developer.blender.org/D3534 --- source/blender/python/intern/bpy_rna.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 80b0aa7a51b..28a6a4f7fb0 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -5047,6 +5047,9 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) case PROP_RAW_DOUBLE: item = PyFloat_FromDouble((double) ((double *)array)[i]); break; + case PROP_RAW_BOOLEAN: + item = PyBool_FromLong((long) ((bool *)array)[i]); + break; default: /* PROP_RAW_UNSET */ /* should never happen */ BLI_assert(!"Invalid array type - get"); -- cgit v1.2.3 From 20f3cbfb78b37fdc201d30be52a249cd08fa5d83 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 15:37:27 +0200 Subject: Cleanup: More clear naming in UV vertex/element mappings Also use unsigned short for loop index within a polygon for UV vertex mapping, which matches UV element mapping. --- source/blender/blenkernel/BKE_mesh_mapping.h | 12 ++++++--- source/blender/blenkernel/intern/mesh_mapping.c | 10 ++++---- source/blender/blenkernel/intern/subsurf_ccg.c | 6 ++--- source/blender/editors/mesh/editmesh_utils.c | 18 ++++++------- source/blender/editors/uvedit/uvedit_ops.c | 30 +++++++++++----------- .../blender/editors/uvedit/uvedit_smart_stitch.c | 9 ++++--- 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index b5b5443574c..aedffb17ae6 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -50,8 +50,12 @@ typedef struct UvVertMap { typedef struct UvMapVert { struct UvMapVert *next; - unsigned int f; - unsigned char tfindex, separate, flag; + unsigned int poly_index; + unsigned short loop_of_poly_index; + bool separate; + /* Zero-ed by map creation, left for use by specific areas. Is not + * initialized to anything. */ + unsigned char flag; } UvMapVert; /* UvElement stores per uv information so that we can quickly access information for a uv. @@ -63,9 +67,9 @@ typedef struct UvElement { /* Face the element belongs to */ struct BMLoop *l; /* index in loop. */ - unsigned short tfindex; + unsigned short loop_of_poly_index; /* Whether this element is the first of coincident elements */ - unsigned char separate; + bool separate; /* general use flag */ unsigned char flag; /* If generating element map with island sorting, this stores the island index */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 699d6bce2b0..953d3ff2f96 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -103,8 +103,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create( nverts = mp->totloop; for (i = 0; i < nverts; i++) { - buf->tfindex = (unsigned char)i; - buf->f = a; + buf->loop_of_poly_index = (unsigned short)i; + buf->poly_index = a; buf->separate = 0; buf->next = vmap->vert[mloop[mp->loopstart + i].v]; vmap->vert[mloop[mp->loopstart + i].v] = buf; @@ -134,19 +134,19 @@ UvVertMap *BKE_mesh_uv_vert_map_create( v->next = newvlist; newvlist = v; - uv = mloopuv[mpoly[v->f].loopstart + v->tfindex].uv; + uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index].uv; lastv = NULL; iterv = vlist; while (iterv) { next = iterv->next; - uv2 = mloopuv[mpoly[iterv->f].loopstart + iterv->tfindex].uv; + uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index].uv; sub_v2_v2v2(uvdiff, uv2, uv); if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] && - (!use_winding || winding[iterv->f] == winding[v->f])) + (!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) { if (lastv) lastv->next = next; else vlist = next; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 1f1270b85b6..dadffbf8fb4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -285,11 +285,11 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct ML for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) { if (v->separate) nv = v; - if (v->f == fi) + if (v->poly_index == fi) break; } - fverts[j] = SET_UINT_IN_POINTER(mpoly[nv->f].loopstart + nv->tfindex); + fverts[j] = SET_UINT_IN_POINTER(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index); } } @@ -337,7 +337,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) { if (v->separate) { CCGVert *ssv; - int loopid = mpoly[v->f].loopstart + v->tfindex; + int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index; CCGVertHDL vhdl = SET_INT_IN_POINTER(loopid); copy_v2_v2(uv, mloopuv[loopid].uv); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 250d8ca23c1..7a344be8e5a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -561,8 +561,8 @@ UvVertMap *BM_uv_vert_map_create( } BM_ITER_ELEM_INDEX(l, &liter, efa, BM_LOOPS_OF_FACE, i) { - buf->tfindex = i; - buf->f = a; + buf->loop_of_poly_index = i; + buf->poly_index = a; buf->separate = 0; buf->next = vmap->vert[BM_elem_index_get(l->v)]; @@ -593,10 +593,10 @@ UvVertMap *BM_uv_vert_map_create( v->next = newvlist; newvlist = v; - efa = BM_face_at_index(bm, v->f); + efa = BM_face_at_index(bm, v->poly_index); /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->tfindex); + l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->loop_of_poly_index); luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); uv = luv->uv; @@ -605,17 +605,17 @@ UvVertMap *BM_uv_vert_map_create( while (iterv) { next = iterv->next; - efa = BM_face_at_index(bm, iterv->f); + efa = BM_face_at_index(bm, iterv->poly_index); /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */ - l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex); + l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index); luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); uv2 = luv->uv; sub_v2_v2v2(uvdiff, uv2, uv); if (fabsf(uvdiff[0]) < limit[0] && fabsf(uvdiff[1]) < limit[1] && - (!use_winding || winding[iterv->f] == winding[v->f])) + (!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) { if (lastv) lastv->next = next; else vlist = next; @@ -712,7 +712,7 @@ UvElementMap *BM_uv_element_map_create( buf->l = l; buf->separate = 0; buf->island = INVALID_ISLAND; - buf->tfindex = i; + buf->loop_of_poly_index = i; buf->next = element_map->vert[BM_elem_index_get(l->v)]; element_map->vert[BM_elem_index_get(l->v)] = buf; @@ -825,7 +825,7 @@ UvElementMap *BM_uv_element_map_create( map[element - element_map->buf] = islandbufsize; islandbuf[islandbufsize].l = element->l; islandbuf[islandbufsize].separate = element->separate; - islandbuf[islandbufsize].tfindex = element->tfindex; + islandbuf[islandbufsize].loop_of_poly_index = element->loop_of_poly_index; islandbuf[islandbufsize].island = nislands; islandbufsize++; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 3aacd9b4605..375dda7dd6a 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1043,7 +1043,7 @@ static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa for (iterv = first; iterv; iterv = iterv->next) { if (iterv->separate) first = iterv; - if (iterv->f == BM_elem_index_get(efa)) + if (iterv->poly_index == BM_elem_index_get(efa)) return first; } @@ -1065,9 +1065,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, if (iterv2->separate && iterv2 != first2) break; - if (iterv1->f == iterv2->f) { + if (iterv1->poly_index == iterv2->poly_index) { /* if face already tagged, don't do this edge */ - efa = BM_face_at_index(em->bm, iterv1->f); + efa = BM_face_at_index(em->bm, iterv1->poly_index); if (BM_elem_flag_test(efa, BM_ELEM_TAG)) return false; @@ -1091,8 +1091,8 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, if (iterv2->separate && iterv2 != first2) break; - if (iterv1->f == iterv2->f) { - efa = BM_face_at_index(em->bm, iterv1->f); + if (iterv1->poly_index == iterv2->poly_index) { + efa = BM_face_at_index(em->bm, iterv1->poly_index); BM_elem_flag_enable(efa, BM_ELEM_TAG); break; } @@ -1301,16 +1301,16 @@ static void uv_select_linked( for (iterv = vlist; iterv; iterv = iterv->next) { if (iterv->separate) startv = iterv; - if (iterv->f == a) + if (iterv->poly_index == a) break; } for (iterv = startv; iterv; iterv = iterv->next) { if ((startv != iterv) && (iterv->separate)) break; - else if (!flag[iterv->f]) { - flag[iterv->f] = 1; - stack[stacksize] = iterv->f; + else if (!flag[iterv->poly_index]) { + flag[iterv->poly_index] = 1; + stack[stacksize] = iterv->poly_index; stacksize++; } } @@ -2750,7 +2750,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal( if (vlist_iter->separate) start_vlist = vlist_iter; - if (efa_index == vlist_iter->f) + if (efa_index == vlist_iter->poly_index) break; vlist_iter = vlist_iter->next; @@ -2762,12 +2762,12 @@ static void uv_select_flush_from_tag_sticky_loc_internal( if (vlist_iter != start_vlist && vlist_iter->separate) break; - if (efa_index != vlist_iter->f) { + if (efa_index != vlist_iter->poly_index) { BMLoop *l_other; - efa_vlist = BM_face_at_index(em->bm, vlist_iter->f); + efa_vlist = BM_face_at_index(em->bm, vlist_iter->poly_index); /* tf_vlist = BM_ELEM_CD_GET_VOID_P(efa_vlist, cd_poly_tex_offset); */ /* UNUSED */ - l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex); + l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index); uvedit_uv_select_set(em, scene, l_other, select, false, cd_loop_uv_offset); } @@ -4241,14 +4241,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) v1coincident = 0; separated2 = 0; - efa1 = BM_face_at_index(bm, mv1->f); + efa1 = BM_face_at_index(bm, mv1->poly_index); mvinit2 = vmap->vert[BM_elem_index_get(editedge->v2)]; for (mv2 = mvinit2; mv2; mv2 = mv2->next) { if (mv2->separate) mv2sep = mv2; - efa2 = BM_face_at_index(bm, mv2->f); + efa2 = BM_face_at_index(bm, mv2->poly_index); if (efa1 == efa2) { /* if v1 is not coincident no point in comparing */ if (v1coincident) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index e4452af4790..0b768350942 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -483,9 +483,10 @@ static void stitch_calculate_island_snapping( int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position; stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, - preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect); + preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index, + state->aspect); - add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex, + add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index, island_stitch_data[i].translation); } } @@ -901,7 +902,7 @@ static void stitch_propagate_uv_final_position( else { int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position; if (face_preview_pos != STITCH_NO_PREVIEW) { - copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex, + copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->loop_of_poly_index, final_position[index].uv); } } @@ -2013,7 +2014,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) RNA_collection_add(op->ptr, "selection", &itemptr); RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f)); - RNA_int_set(&itemptr, "element_index", element->tfindex); + RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index); } uvedit_live_unwrap_update(sima, scene, obedit); -- cgit v1.2.3 From 72d1fb993445b6233e6d905c867625586bf62bfe Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 15:58:12 +0200 Subject: Cleanup: Use const qualifier for UV vertex map --- source/blender/blenkernel/BKE_mesh_mapping.h | 6 +++--- source/blender/blenkernel/intern/mesh_mapping.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index aedffb17ae6..1005a50a214 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -104,9 +104,9 @@ typedef struct MeshElemMap { /* mapping */ UvVertMap *BKE_mesh_uv_vert_map_create( - struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv, - unsigned int totpoly, unsigned int totvert, - const float limit[2], const bool selected, const bool use_winding); + const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopUV *mloopuv, + unsigned int totpoly, unsigned int totvert, const float limit[2], + const bool selected, const bool use_winding); UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v); void BKE_mesh_uv_vert_map_free(UvVertMap *vmap); diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 953d3ff2f96..5c9849f6b74 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -55,13 +55,13 @@ * but for now this replaces it because its unused. */ UvVertMap *BKE_mesh_uv_vert_map_create( - struct MPoly *mpoly, struct MLoop *mloop, struct MLoopUV *mloopuv, + const MPoly *mpoly, const MLoop *mloop, const MLoopUV *mloopuv, unsigned int totpoly, unsigned int totvert, const float limit[2], const bool selected, const bool use_winding) { UvVertMap *vmap; UvMapVert *buf; - MPoly *mp; + const MPoly *mp; unsigned int a; int i, totuv, nverts; @@ -126,7 +126,8 @@ UvVertMap *BKE_mesh_uv_vert_map_create( for (a = 0; a < totvert; a++) { UvMapVert *newvlist = NULL, *vlist = vmap->vert[a]; UvMapVert *iterv, *v, *lastv, *next; - float *uv, *uv2, uvdiff[2]; + const float *uv, *uv2; + float uvdiff[2]; while (vlist) { v = vlist; -- cgit v1.2.3 From 1e1c858cf1bf900f0876b13f922beb0e2aeb0e8c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 16:15:57 +0200 Subject: Cleanup: Remove obscure flag which was only used for read in subsurf code Some sort of rudiment from many years ago, is never set by 2.5x code. --- source/blender/blenkernel/intern/subsurf_ccg.c | 15 +++------------ source/blender/makesdna/DNA_meshdata_types.h | 2 +- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index dadffbf8fb4..e08560cccac 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -297,7 +297,6 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, { MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); - MVert *mvert = dm->getVertArray(dm); int totvert = dm->getNumVerts(dm); int totface = dm->getNumPolys(dm); int i, seam; @@ -309,13 +308,12 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, BLI_array_declare(fverts); #endif EdgeSet *eset; - float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */ limit[0] = limit[1] = STD_UV_CONNECT_LIMIT; /* previous behavior here is without accounting for winding, however this causes stretching in * UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially - * intention is to treat merged vertices from mirror modifier as seams, see code below with ME_VERT_MERGED + * intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true); if (!vmap) @@ -332,7 +330,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, if (v->separate) break; - seam = (v != NULL) || ((mvert + i)->flag & ME_VERT_MERGED); + seam = (v != NULL); for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) { if (v->separate) { @@ -370,18 +368,11 @@ static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) { unsigned int v0 = GET_UINT_FROM_POINTER(fverts[j_next]); unsigned int v1 = GET_UINT_FROM_POINTER(fverts[j]); - MVert *mv0 = mvert + (ml[j_next].v); - MVert *mv1 = mvert + (ml[j].v); if (BLI_edgeset_add(eset, v0, v1)) { CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next); CCGEdgeHDL ehdl = SET_INT_IN_POINTER(mp->loopstart + j_next); - float crease; - - if ((mv0->flag & mv1->flag) & ME_VERT_MERGED) - crease = creaseFactor; - else - crease = ccgSubSurf_getEdgeCrease(orige); + float crease = ccgSubSurf_getEdgeCrease(orige); ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e); } diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index bda557fc59d..d1c137492de 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -401,7 +401,7 @@ enum { /* SELECT = (1 << 0), */ ME_VERT_TMP_TAG = (1 << 2), ME_HIDE = (1 << 4), - ME_VERT_MERGED = (1 << 6), +/* ME_VERT_MERGED = (1 << 6), */ ME_VERT_PBVH_UPDATE = (1 << 7), }; -- cgit v1.2.3 From e6af8758c86099790b003454195c4a748251c6a4 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 16 Jul 2018 17:32:57 +0200 Subject: Ghost: Fix memory leak happening with keyboard mapping access So far only noticed system de-initialization doesn't perform full object free. So rather harmless but yet stupid. --- intern/ghost/intern/GHOST_SystemX11.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index ac77fb3e196..3bace8fc35a 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -254,7 +254,7 @@ GHOST_SystemX11:: #endif /* WITH_X11_XINPUT */ if (m_xkb_descr) { - XkbFreeNames(m_xkb_descr, XkbKeyNamesMask, false); + XkbFreeKeyboard (m_xkb_descr, XkbAllComponentsMask, true); } XCloseDisplay(m_display); -- cgit v1.2.3 From 43593e846bbed183a54ee1dae1b76f3f8c4be9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 11 Jul 2018 19:01:12 +0200 Subject: Matcap: Fix missing pixel on preview icons --- source/blender/blenkernel/intern/studiolight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 200c50e5c23..5381d2be691 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -1037,7 +1037,7 @@ static void studiolight_matcap_preview(uint *icon_buffer, StudioLight *sl, bool if (flipped) { fx = 1.0f - fx; } - nearest_interpolation_color(ibuf, NULL, color, fx * ibuf->x, fy * ibuf->y); + nearest_interpolation_color(ibuf, NULL, color, fx * ibuf->x - 1.0f, fy * ibuf->y - 1.0f); uint alphamask = alpha_circle_mask(fx, fy, 0.5f - pixel_size, 0.5f); -- cgit v1.2.3 From 7a693626d63a52acd12e80209b634711154a2f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 15:01:44 +0200 Subject: Smoke: Port display to Workbench + object mode This does not fix the smokesim. It only port the drawing method. The Object mode engine is in charge of rendering the velocity debugging. Things left to do: - Flame rendering. - Color Ramp coloring of volume data. - View facing slicing (for now it's only doing sampling starting from the volume bounds which gives a squarish look) - Add option to enable dithering (currently on by default. --- source/blender/blenloader/intern/readfile.c | 3 + source/blender/draw/CMakeLists.txt | 4 + .../workbench/shaders/workbench_volume_frag.glsl | 181 +++++++++++++++++++++ .../workbench/shaders/workbench_volume_vert.glsl | 31 ++++ .../draw/engines/workbench/workbench_data.c | 3 + .../draw/engines/workbench/workbench_deferred.c | 32 +++- .../draw/engines/workbench/workbench_forward.c | 23 ++- .../draw/engines/workbench/workbench_private.h | 14 ++ .../draw/engines/workbench/workbench_volume.c | 152 +++++++++++++++++ source/blender/draw/intern/draw_cache.c | 53 +++++- source/blender/draw/intern/draw_cache.h | 3 +- source/blender/draw/intern/draw_common.c | 25 +++ source/blender/draw/intern/draw_common.h | 2 + source/blender/draw/modes/object_mode.c | 101 +++++++++++- .../draw/modes/shaders/volume_velocity_vert.glsl | 115 +++++++++++++ source/blender/gpu/GPU_draw.h | 2 + source/blender/gpu/intern/gpu_draw.c | 46 ++++++ source/blender/makesdna/DNA_smoke_types.h | 3 + 18 files changed, 782 insertions(+), 11 deletions(-) create mode 100644 source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl create mode 100644 source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl create mode 100644 source/blender/draw/engines/workbench/workbench_volume.c create mode 100644 source/blender/draw/modes/shaders/volume_velocity_vert.glsl diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6b356ac2e96..f7d585e6fd7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5100,6 +5100,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->domain->tex = NULL; smd->domain->tex_shadow = NULL; smd->domain->tex_flame = NULL; + smd->domain->tex_velocity_x = NULL; + smd->domain->tex_velocity_y = NULL; + smd->domain->tex_velocity_z = NULL; smd->domain->tex_wt = NULL; smd->domain->coba = newdataadr(fd, smd->domain->coba); diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2183bc26755..e4c6a372d34 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -118,6 +118,7 @@ set(SRC engines/workbench/workbench_forward.c engines/workbench/workbench_materials.c engines/workbench/workbench_studiolight.c + engines/workbench/workbench_volume.c engines/workbench/solid_mode.c engines/workbench/transparent_mode.c engines/external/external_engine.c @@ -225,6 +226,8 @@ data_to_c_simple(engines/workbench/shaders/workbench_shadow_vert.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_shadow_geom.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_shadow_debug_frag.glsl SRC) +data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC) +data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC) data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC) @@ -297,6 +300,7 @@ data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC) +data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC) list(APPEND INC ) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl new file mode 100644 index 00000000000..ba5b78f4ecf --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -0,0 +1,181 @@ + +uniform mat4 ProjectionMatrix; +uniform mat4 ModelMatrixInverse; +uniform mat4 ModelViewMatrixInverse; +uniform mat4 ModelMatrix; + +uniform sampler2D depthBuffer; +uniform sampler3D densityTexture; + +uniform int samplesLen = 256; +uniform float stepLength; /* Step length in local space. */ +uniform float densityScale; /* Simple Opacity multiplicator. */ +uniform vec4 viewvecs[3]; + +uniform float slicePosition; +uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */ + +#ifdef VOLUME_SLICE +in vec3 localPos; +#endif + +out vec4 fragColor; + +#define M_PI 3.1415926535897932 /* pi */ + +float phase_function_isotropic() +{ + return 1.0 / (4.0 * M_PI); +} + +float get_view_z_from_depth(float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + float d = 2.0 * depth - 1.0; + return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]); + } + else { + return viewvecs[0].z + depth * viewvecs[1].z; + } +} + +vec3 get_view_space_from_depth(vec2 uvcoords, float depth) +{ + if (ProjectionMatrix[3][3] == 0.0) { + return vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0) * get_view_z_from_depth(depth); + } + else { + return viewvecs[0].xyz + vec3(uvcoords, depth) * viewvecs[1].xyz; + } +} + +float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); } + +float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection) +{ + /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */ + vec3 firstplane = (vec3( 1.0) - lineorigin) / linedirection; + vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection; + vec3 furthestplane = min(firstplane, secondplane); + return max_v3(furthestplane); +} + +void volume_properties(vec3 ls_pos, out vec3 scattering, out float extinction) +{ + scattering = vec3(0.0); + extinction = 1e-8; + + vec4 density = texture(densityTexture, ls_pos * 0.5 + 0.5); + density.rgb /= density.a; + density *= densityScale; + + scattering = density.rgb; + extinction = max(1e-8, density.a); +} + +#define P(x) ((x + 0.5) * (1.0 / 16.0)) +const vec4 dither_mat[4] = vec4[4]( + vec4( P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4( P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0)) +); + +vec4 volume_integration( + vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max, float step_len) +{ + /* Start with full transmittance and no scattered light. */ + vec3 final_scattering = vec3(0.0); + float final_transmittance = 1.0; + + ivec2 tx = ivec2(gl_FragCoord.xy) % 4; + float noise = dither_mat[tx.x][tx.y]; + + float ray_len = noise * ray_inc; + for (int i = 0; i < samplesLen && ray_len < ray_max; ++i, ray_len += ray_inc) { + vec3 ls_pos = ray_ori + ray_dir * ray_len; + + vec3 Lscat; + float s_extinction; + volume_properties(ls_pos, Lscat, s_extinction); + /* Evaluate Scattering */ + float Tr = exp(-s_extinction * step_len); + /* integrate along the current step segment */ + Lscat = (Lscat - Lscat * Tr) / s_extinction; + /* accumulate and also take into account the transmittance from previous steps */ + final_scattering += final_transmittance * Lscat; + final_transmittance *= Tr; + } + + return vec4(final_scattering, 1.0 - final_transmittance); +} + +void main() +{ +#ifdef VOLUME_SLICE + /* Manual depth test. TODO remove. */ + float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + if (gl_FragCoord.z >= depth) { + discard; + } + + ivec3 volume_size = textureSize(densityTexture, 0); + float step_len; + if (sliceAxis == 0) { + step_len = float(volume_size.x); + } + else if (sliceAxis == 1) { + step_len = float(volume_size.y); + } + else { + step_len = float(volume_size.z); + } + /* FIXME Should be in world space but is in local space. */ + step_len = 1.0 / step_len; + + vec3 Lscat; + float s_extinction; + volume_properties(localPos, Lscat, s_extinction); + /* Evaluate Scattering */ + float Tr = exp(-s_extinction * step_len); + /* integrate along the current step segment */ + Lscat = (Lscat - Lscat * Tr) / s_extinction; + + fragColor = vec4(Lscat, 1.0 - Tr); + +#else + vec2 screen_uv = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0).xy); + bool is_persp = ProjectionMatrix[3][3] == 0.0; + + vec3 volume_center = ModelMatrix[3].xyz; + + float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; + float depth_end = min(depth, gl_FragCoord.z); + vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end); + vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0); + vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0); + vs_ray_dir /= abs(vs_ray_dir.z); + + vec3 ls_ray_dir = mat3(ModelViewMatrixInverse) * vs_ray_dir; + vec3 ls_ray_ori = (ModelViewMatrixInverse * vec4(vs_ray_ori, 1.0)).xyz; + vec3 ls_ray_end = (ModelViewMatrixInverse * vec4(vs_ray_end, 1.0)).xyz; + + /* TODO: Align rays to volume center so that it mimics old behaviour of slicing the volume. */ + + float dist = line_unit_box_intersect_dist(ls_ray_ori, ls_ray_dir); + if (dist > 0.0) { + ls_ray_ori = ls_ray_dir * dist + ls_ray_ori; + } + + vec3 ls_vol_isect = ls_ray_end - ls_ray_ori; + if (dot(ls_ray_dir, ls_vol_isect) < 0.0) { + /* Start is further away than the end. + * That means no volume is intersected. */ + discard; + } + + fragColor = volume_integration(ls_ray_ori, ls_ray_dir, stepLength, + length(ls_vol_isect) / length(ls_ray_dir), + length(vs_ray_dir) * stepLength); +#endif +} \ No newline at end of file diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl new file mode 100644 index 00000000000..90a22d9d02f --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_vert.glsl @@ -0,0 +1,31 @@ + +uniform mat4 ModelViewProjectionMatrix; +uniform float slicePosition; +uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */ + +in vec3 pos; + +#ifdef VOLUME_SLICE +in vec3 uvs; + +out vec3 localPos; +#endif + +void main() +{ +#ifdef VOLUME_SLICE + if (sliceAxis == 0) { + localPos = vec3(slicePosition * 2.0 - 1.0, pos.xy); + } + else if (sliceAxis == 1) { + localPos = vec3(pos.x, slicePosition * 2.0 - 1.0, pos.y); + } + else { + localPos = vec3(pos.xy, slicePosition * 2.0 - 1.0); + } + + gl_Position = ModelViewProjectionMatrix * vec4(localPos, 1.0); +#else + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +#endif +} diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 1f5a1e17277..ede1bd7fcb5 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -119,6 +119,9 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->viewvecs[1][2] = vec_far[2] - wpd->viewvecs[0][2]; } } + + wpd->volumes_do = false; + BLI_listbase_clear(&wpd->smoke_domains); } void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3]) diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 784ed861014..d17c48b0360 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -33,6 +33,7 @@ #include "BLI_rand.h" #include "BKE_node.h" +#include "BKE_modifier.h" #include "BKE_particle.h" #include "DNA_image_types.h" @@ -327,12 +328,11 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) char *cavity_frag = workbench_build_cavity_frag(); e_data.cavity_sh = DRW_shader_create_fullscreen(cavity_frag, NULL); MEM_freeN(cavity_frag); - } + workbench_volume_engine_init(); workbench_fxaa_engine_init(); workbench_taa_engine_init(vedata); - WORKBENCH_PrivateData *wpd = stl->g_data; workbench_private_data_init(wpd); @@ -370,6 +370,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx), }); + GPU_framebuffer_ensure_config(&fbl->volume_fb, { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx), + }); GPU_framebuffer_ensure_config(&fbl->effect_fb, { GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx), @@ -446,6 +450,7 @@ void workbench_deferred_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh); DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh); + workbench_volume_engine_free(); workbench_fxaa_engine_free(); workbench_taa_engine_free(); } @@ -485,7 +490,10 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) Scene *scene = draw_ctx->scene; + workbench_volume_cache_init(vedata); + select_deferred_shaders(wpd); + /* Deferred Mix Pass */ { workbench_private_data_get_light_direction(wpd, e_data.display.light_direction); @@ -636,6 +644,9 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PrivateData *wpd = stl->g_data; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + if (!DRW_object_is_renderable(ob)) return; @@ -643,13 +654,22 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) workbench_cache_populate_particles(vedata, ob); } + ModifierData *md; + if (((ob->base_flag & BASE_FROMDUPLI) == 0) && + (md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && + (((SmokeModifierData *)md)->domain != NULL)) + { + workbench_volume_cache_populate(vedata, scene, ob, md); + return; /* Do not draw solid in this case. */ + } + if (!DRW_check_object_visible_within_active_context(ob)) { return; } WORKBENCH_MaterialData *material; if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { - const DRWContextState *draw_ctx = DRW_context_state_get(); const bool is_active = (ob == draw_ctx->obact); const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0; bool is_drawn = false; @@ -860,6 +880,12 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->composite_pass); } + if (wpd->volumes_do) { + GPU_framebuffer_bind(fbl->volume_fb); + DRW_draw_pass(psl->volume_pass); + } + workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); workbench_private_data_free(wpd); + workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index e921b2ac2f7..3fb68654188 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -33,6 +33,7 @@ #include "BKE_node.h" #include "BKE_particle.h" +#include "BKE_modifier.h" #include "DNA_image_types.h" #include "DNA_mesh_types.h" @@ -284,6 +285,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) MEM_freeN(defines_texture); MEM_freeN(defines_hair); } + workbench_volume_engine_init(); workbench_fxaa_engine_init(); workbench_taa_engine_init(vedata); @@ -305,13 +307,11 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx), }); - GPU_framebuffer_ensure_config(&fbl->transparent_accum_fb, { GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx), GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx), }); - GPU_framebuffer_ensure_config(&fbl->composite_fb, { GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx), @@ -321,6 +321,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx), }); + workbench_volume_cache_init(vedata); + /* Transparency Accum */ { int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT; @@ -372,7 +374,9 @@ void workbench_forward_engine_free() DRW_SHADER_FREE_SAFE(e_data.object_outline_hair_sh); DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh); + workbench_volume_engine_free(); workbench_fxaa_engine_free(); + workbench_taa_engine_free(); } void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata)) @@ -444,6 +448,8 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) { WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PrivateData *wpd = stl->g_data; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; if (!DRW_object_is_renderable(ob)) return; @@ -452,13 +458,22 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) workbench_forward_cache_populate_particles(vedata, ob); } + ModifierData *md; + if (((ob->base_flag & BASE_FROMDUPLI) == 0) && + (md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && + (((SmokeModifierData *)md)->domain != NULL)) + { + workbench_volume_cache_populate(vedata, scene, ob, md); + return; /* Do not draw solid in this case. */ + } + if (!DRW_check_object_visible_within_active_context(ob)) { return; } WORKBENCH_MaterialData *material; if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) { - const DRWContextState *draw_ctx = DRW_context_state_get(); const bool is_active = (ob == draw_ctx->obact); const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0; bool is_drawn = false; @@ -595,6 +610,7 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) /* Composite */ GPU_framebuffer_bind(fbl->composite_fb); DRW_draw_pass(psl->composite_pass); + DRW_draw_pass(psl->volume_pass); /* Color correct and Anti aliasing */ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); @@ -604,4 +620,5 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->checker_depth_pass); workbench_private_data_free(wpd); + workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 4210e03f470..13e9686aa85 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -70,6 +70,7 @@ typedef struct WORKBENCH_FramebufferList { struct GPUFrameBuffer *effect_fb; struct GPUFrameBuffer *effect_taa_fb; struct GPUFrameBuffer *depth_buffer_fb; + struct GPUFrameBuffer *volume_fb; /* Forward render buffers */ struct GPUFrameBuffer *object_outline_fb; @@ -101,6 +102,7 @@ typedef struct WORKBENCH_PassList { struct DRWPass *composite_pass; struct DRWPass *composite_shadow_pass; struct DRWPass *effect_aa_pass; + struct DRWPass *volume_pass; /* forward rendering */ struct DRWPass *transparent_accum_pass; @@ -167,6 +169,10 @@ typedef struct WORKBENCH_PrivateData { float shadow_near_sides[2][4]; /* This is a parallelogram, so only 2 normal and distance to the edges. */ bool shadow_changed; + /* Volumes */ + bool volumes_do; + ListBase smoke_domains; + /* Ssao */ float winmat[4][4]; float viewvecs[3][4]; @@ -280,6 +286,14 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd); void workbench_private_data_free(WORKBENCH_PrivateData *wpd); void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3]); +/* workbench_volume.c */ +void workbench_volume_engine_init(void); +void workbench_volume_engine_free(void); +void workbench_volume_cache_init(WORKBENCH_Data *vedata); +void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, struct ModifierData *md); +void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd); + + extern DrawEngineType draw_engine_workbench_solid; extern DrawEngineType draw_engine_workbench_transparent; diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c new file mode 100644 index 00000000000..f28bfd01ae8 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -0,0 +1,152 @@ +/* + * Copyright 2018, Blender Foundation. + * + * 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. + * + * Contributor(s): Blender Institute + * + */ + +/** \file workbench_volumed.c + * \ingroup draw_engine + */ + +#include "workbench_private.h" + +#include "BKE_modifier.h" + +#include "DNA_modifier_types.h" +#include "DNA_object_force_types.h" +#include "DNA_smoke_types.h" + +#include "GPU_draw.h" + +static struct { + struct GPUShader *volume_sh; + struct GPUShader *volume_slice_sh; +} e_data = {NULL}; + +extern char datatoc_workbench_volume_vert_glsl[]; +extern char datatoc_workbench_volume_frag_glsl[]; + +void workbench_volume_engine_init(void) +{ + if (!e_data.volume_sh) { + e_data.volume_sh = DRW_shader_create( + datatoc_workbench_volume_vert_glsl, NULL, + datatoc_workbench_volume_frag_glsl, NULL); + e_data.volume_slice_sh = DRW_shader_create( + datatoc_workbench_volume_vert_glsl, NULL, + datatoc_workbench_volume_frag_glsl, "#define VOLUME_SLICE"); + } +} + +void workbench_volume_engine_free(void) +{ + DRW_SHADER_FREE_SAFE(e_data.volume_sh); + DRW_SHADER_FREE_SAFE(e_data.volume_slice_sh); +} + +void workbench_volume_cache_init(WORKBENCH_Data *vedata) +{ + vedata->psl->volume_pass = DRW_pass_create("Volumes", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | DRW_STATE_CULL_FRONT); +} + +void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, ModifierData *md) +{ + SmokeModifierData *smd = (SmokeModifierData *)md; + SmokeDomainSettings *sds = smd->domain; + WORKBENCH_PrivateData *wpd = vedata->stl->g_data; + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + /* Don't show smoke before simulation starts, this could be made an option in the future. */ + if (!sds->fluid || CFRA < sds->point_cache[0]->startframe) { + return; + } + + wpd->volumes_do = true; + + if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + GPU_create_smoke(smd, 0); + } + else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + GPU_create_smoke(smd, 1); + } + + if (sds->tex == NULL) { + return; + } + + if (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED && + sds->axis_slice_method == AXIS_SLICE_SINGLE) + { + float invviewmat[4][4]; + DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV); + + const int axis = (sds->slice_axis == SLICE_AXIS_AUTO) + ? axis_dominant_v3_single(invviewmat[2]) + : sds->slice_axis - 1; + + DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_slice_sh, vedata->psl->volume_pass); + DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex); + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness); + DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth); + DRW_shgroup_uniform_int_copy(grp, "sliceAxis", axis); + DRW_shgroup_state_disable(grp, DRW_STATE_CULL_FRONT); + BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd)); + + /* TODO Flame rendering */ + /* TODO COBA Rendering */ + + DRW_shgroup_call_object_add(grp, DRW_cache_quad_get(), ob); + } + else { + int max_slices = max_iii(sds->res[0], sds->res[1], sds->res[2]) * sds->slice_per_voxel; + + DRWShadingGroup *grp = DRW_shgroup_create(e_data.volume_sh, vedata->psl->volume_pass); + DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3); + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_texture(grp, "densityTexture", sds->tex); + DRW_shgroup_uniform_float_copy(grp, "densityScale", 10.0f * sds->display_thickness); + DRW_shgroup_uniform_int_copy(grp, "samplesLen", max_slices); + /* TODO FIXME : This step size is in object space but the ray itself + * is NOT unit length in object space so the required number of subdivisions + * is tricky to get. */ + DRW_shgroup_uniform_float_copy(grp, "stepLength", 8.0f / max_slices); + DRW_shgroup_state_enable(grp, DRW_STATE_CULL_FRONT); + BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(smd)); + + /* TODO Flame rendering */ + /* TODO COBA Rendering */ + + DRW_shgroup_call_object_add(grp, DRW_cache_cube_get(), ob); + } +} + +void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd) +{ + /* Free Smoke Textures after rendering */ + /* XXX This is a waste of processing and GPU bandwidth if nothing + * is updated. But the problem is since Textures are stored in the + * modifier we don't want them to take precious VRAM if the + * modifier is not used for display. We should share them for + * all viewport in a redraw at least. */ + for (LinkData *link = wpd->smoke_domains.first; link; link = link->next) { + SmokeModifierData *smd = (SmokeModifierData *)link->data; + GPU_free_smoke(smd); + } + BLI_freelistN(&wpd->smoke_domains); +} diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 1bf40673239..0d2317199fc 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -61,6 +61,7 @@ static struct DRWShapeCache { Gwn_Batch *drw_square; Gwn_Batch *drw_line; Gwn_Batch *drw_line_endpoints; + Gwn_Batch *drw_empty_cube; Gwn_Batch *drw_empty_sphere; Gwn_Batch *drw_empty_cone; Gwn_Batch *drw_arrows; @@ -341,6 +342,54 @@ Gwn_Batch *DRW_cache_cube_get(void) { 1.0f, 1.0f, 1.0f} }; + const uint indices[36] = { + 0, 1, 2, + 1, 3, 2, + 0, 4, 1, + 4, 5, 1, + 6, 5, 4, + 6, 7, 5, + 2, 7, 6, + 2, 3, 7, + 3, 1, 7, + 1, 5, 7, + 0, 2, 4, + 2, 6, 4, + }; + + /* Position Only 3D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = 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, 36); + + for (int i = 0; i < 36; ++i) { + GWN_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); + } + + SHC.drw_cube = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_cube; +} + +Gwn_Batch *DRW_cache_empty_cube_get(void) +{ + if (!SHC.drw_empty_cube) { + const GLfloat verts[8][3] = { + {-1.0f, -1.0f, -1.0f}, + {-1.0f, -1.0f, 1.0f}, + {-1.0f, 1.0f, -1.0f}, + {-1.0f, 1.0f, 1.0f}, + { 1.0f, -1.0f, -1.0f}, + { 1.0f, -1.0f, 1.0f}, + { 1.0f, 1.0f, -1.0f}, + { 1.0f, 1.0f, 1.0f} + }; + 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}; /* Position Only 3D format */ @@ -357,9 +406,9 @@ Gwn_Batch *DRW_cache_cube_get(void) GWN_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); } - SHC.drw_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); } - return SHC.drw_cube; + return SHC.drw_empty_cube; } Gwn_Batch *DRW_cache_circle_get(void) diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index e7ab847d42e..9114a4d872d 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -41,6 +41,7 @@ struct Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); struct Gwn_Batch *DRW_cache_quad_get(void); +struct Gwn_Batch *DRW_cache_cube_get(void); struct Gwn_Batch *DRW_cache_sphere_get(void); struct Gwn_Batch *DRW_cache_single_vert_get(void); struct Gwn_Batch *DRW_cache_single_line_get(void); @@ -61,7 +62,7 @@ void DRW_cache_object_face_wireframe_get( /* Empties */ struct Gwn_Batch *DRW_cache_plain_axes_get(void); struct Gwn_Batch *DRW_cache_single_arrow_get(void); -struct Gwn_Batch *DRW_cache_cube_get(void); +struct Gwn_Batch *DRW_cache_empty_cube_get(void); struct Gwn_Batch *DRW_cache_circle_get(void); struct Gwn_Batch *DRW_cache_square_get(void); struct Gwn_Batch *DRW_cache_empty_sphere_get(void); diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index a1c60be4742..df80300417e 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -162,6 +162,8 @@ extern char datatoc_animviz_mpath_lines_vert_glsl[]; extern char datatoc_animviz_mpath_lines_geom_glsl[]; extern char datatoc_animviz_mpath_points_vert_glsl[]; +extern char datatoc_volume_velocity_vert_glsl[]; + extern char datatoc_armature_axes_vert_glsl[]; extern char datatoc_armature_sphere_solid_vert_glsl[]; extern char datatoc_armature_sphere_solid_frag_glsl[]; @@ -199,6 +201,9 @@ static struct { struct GPUShader *mpath_line_sh; struct GPUShader *mpath_points_sh; + struct GPUShader *volume_velocity_needle_sh; + struct GPUShader *volume_velocity_sh; + struct GPUShader *mball_handles; } g_shaders = {NULL}; @@ -736,6 +741,26 @@ struct GPUShader *mpath_points_shader_get(void) return g_shaders.mpath_points_sh; } +struct GPUShader *volume_velocity_shader_get(bool use_needle) +{ + if (use_needle) { + if (g_shaders.volume_velocity_needle_sh == NULL) { + g_shaders.volume_velocity_needle_sh = DRW_shader_create( + datatoc_volume_velocity_vert_glsl, NULL, + datatoc_gpu_shader_flat_color_frag_glsl, "#define USE_NEEDLE"); + } + return g_shaders.volume_velocity_needle_sh; + } + else { + if (g_shaders.volume_velocity_sh == NULL) { + g_shaders.volume_velocity_sh = DRW_shader_create( + datatoc_volume_velocity_vert_glsl, NULL, + datatoc_gpu_shader_flat_color_frag_glsl, NULL); + } + return g_shaders.volume_velocity_sh; + } +} + /* ******************************************** COLOR UTILS *********************************************** */ /* TODO FINISH */ diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 6227130fb05..b4ae0600f02 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -138,6 +138,8 @@ struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass); struct GPUShader *mpath_line_shader_get(void); struct GPUShader *mpath_points_shader_get(void); +struct GPUShader *volume_velocity_shader_get(bool use_needle); + int DRW_object_wire_theme_get( struct Object *ob, struct ViewLayer *view_layer, float **r_color); float *DRW_color_background_blend_get(int theme_id); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 6c99024312c..2e41dbfd529 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -32,10 +32,12 @@ #include "DNA_curve_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_force_types.h" #include "DNA_lightprobe_types.h" #include "DNA_particle_types.h" #include "DNA_rigidbody_types.h" +#include "DNA_smoke_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -49,6 +51,7 @@ #include "BKE_global.h" #include "BKE_mball.h" #include "BKE_mesh.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_image.h" @@ -58,6 +61,7 @@ #include "GPU_shader.h" #include "GPU_texture.h" +#include "GPU_draw.h" #include "MEM_guardedalloc.h" @@ -286,6 +290,8 @@ static struct { struct GPUTexture *outlines_id_tx; struct GPUTexture *outlines_color_tx; struct GPUTexture *outlines_blur_tx; + + ListBase smoke_domains; } e_data = {NULL}; /* Engine data */ @@ -1078,7 +1084,7 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_plain_axes_get(); stl->g_data->plain_axes = shgroup_instance(psl->non_meshes, geom); - geom = DRW_cache_cube_get(); + geom = DRW_cache_empty_cube_get(); stl->g_data->cube = shgroup_instance(psl->non_meshes, geom); geom = DRW_cache_circle_get(); @@ -1156,7 +1162,7 @@ static void OBJECT_cache_init(void *vedata) stl->g_data->camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom); /* Texture Space */ - geom = DRW_cache_cube_get(); + geom = DRW_cache_empty_cube_get(); stl->g_data->texspace = shgroup_instance(psl->non_meshes, geom); } @@ -1723,6 +1729,85 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye } } +static void DRW_shgroup_volume_extra( + OBJECT_PassList *psl, OBJECT_StorageList *stl, + Object *ob, ViewLayer *view_layer, Scene *scene, ModifierData *md) +{ + SmokeModifierData *smd = (SmokeModifierData *)md; + SmokeDomainSettings *sds = smd->domain; + float *color; + float one = 1.0f; + + if (sds == NULL) { + return; + } + + DRW_object_wire_theme_get(ob, view_layer, &color); + + /* Small cube showing voxel size. */ + float voxel_cubemat[4][4] = {{0.0f}}; + voxel_cubemat[0][0] = 1.0f / (float)sds->res[0]; + voxel_cubemat[1][1] = 1.0f / (float)sds->res[1]; + voxel_cubemat[2][2] = 1.0f / (float)sds->res[2]; + voxel_cubemat[3][0] = voxel_cubemat[3][1] = voxel_cubemat[3][2] = -1.0f; + voxel_cubemat[3][3] = 1.0f; + translate_m4(voxel_cubemat, 1.0f, 1.0f, 1.0f); + mul_m4_m4m4(voxel_cubemat, ob->obmat, voxel_cubemat); + + DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, voxel_cubemat); + + /* Don't show smoke before simulation starts, this could be made an option in the future. */ + if (!sds->draw_velocity || !sds->fluid || CFRA < sds->point_cache[0]->startframe) { + return; + } + + const bool use_needle = (sds->vector_draw_type == VECTOR_DRAW_NEEDLE); + int line_count = (use_needle) ? 6 : 1; + int slice_axis = -1; + line_count *= sds->res[0] * sds->res[1] * sds->res[2]; + + if (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED && + sds->axis_slice_method == AXIS_SLICE_SINGLE) + { + float invviewmat[4][4]; + DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV); + + const int axis = (sds->slice_axis == SLICE_AXIS_AUTO) + ? axis_dominant_v3_single(invviewmat[2]) + : sds->slice_axis - 1; + slice_axis = axis; + line_count /= sds->res[axis]; + } + + GPU_create_smoke_velocity(smd); + + DRWShadingGroup *grp = DRW_shgroup_create(volume_velocity_shader_get(use_needle), psl->non_meshes); + DRW_shgroup_uniform_texture(grp, "velocityX", sds->tex_velocity_x); + DRW_shgroup_uniform_texture(grp, "velocityY", sds->tex_velocity_y); + DRW_shgroup_uniform_texture(grp, "velocityZ", sds->tex_velocity_z); + DRW_shgroup_uniform_float_copy(grp, "displaySize", sds->vector_scale); + DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth); + DRW_shgroup_uniform_int_copy(grp, "sliceAxis", slice_axis); + DRW_shgroup_call_procedural_lines_add(grp, line_count, ob->obmat); + + BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd)); +} + +static void volumes_free_smoke_textures(void) +{ + /* Free Smoke Textures after rendering */ + /* XXX This is a waste of processing and GPU bandwidth if nothing + * is updated. But the problem is since Textures are stored in the + * modifier we don't want them to take precious VRAM if the + * modifier is not used for display. We should share them for + * all viewport in a redraw at least. */ + for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) { + SmokeModifierData *smd = (SmokeModifierData *)link->data; + GPU_free_smoke(smd); + } + BLI_freelistN(&e_data.smoke_domains); +} + static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) { float *color; @@ -2142,7 +2227,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); ViewLayer *view_layer = draw_ctx->view_layer; + Scene *scene = draw_ctx->scene; View3D *v3d = draw_ctx->v3d; + ModifierData *md = NULL; int theme_id = TH_UNDEFINED; /* Handle particles first in case the emitter itself shouldn't be rendered. */ @@ -2311,6 +2398,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) DRW_shgroup_forcefield(stl, ob, view_layer); } + if (((ob->base_flag & BASE_FROMDUPLI) == 0) && + (md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && + (((SmokeModifierData *)md)->domain != NULL)) + { + DRW_shgroup_volume_extra(psl, stl, ob, view_layer, scene, md); + } + /* don't show object extras in set's */ if ((ob->base_flag & (BASE_FROM_SET | BASE_FROMDUPLI)) == 0) { @@ -2437,6 +2532,8 @@ static void OBJECT_draw_scene(void *vedata) BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN); stl->g_data->image_plane_map = NULL; } + + volumes_free_smoke_textures(); } static const DrawEngineDataSize OBJECT_data_size = DRW_VIEWPORT_DATA_SIZE(OBJECT_Data); diff --git a/source/blender/draw/modes/shaders/volume_velocity_vert.glsl b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl new file mode 100644 index 00000000000..574c434920e --- /dev/null +++ b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl @@ -0,0 +1,115 @@ + +uniform mat4 ModelViewProjectionMatrix; + +uniform sampler3D velocityX; +uniform sampler3D velocityY; +uniform sampler3D velocityZ; +uniform float displaySize = 1.0; +uniform float slicePosition; +uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */ + +flat out vec4 finalColor; + +const vec3 corners[4] = vec3[4]( + vec3(0.0, 0.2, -0.5), + vec3(-0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.0, 0.0, 0.5) +); + +const int indices[12] = int[12](0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3); + +/* Straight Port from BKE_defvert_weight_to_rgb() + * TODO port this to a color ramp. */ +vec3 weight_to_color(float weight) +{ + vec3 r_rgb = vec3(0.0); + float blend = ((weight / 2.0) + 0.5); + + if (weight <= 0.25) { /* blue->cyan */ + r_rgb.g = blend * weight * 4.0; + r_rgb.b = blend; + } + else if (weight <= 0.50) { /* cyan->green */ + r_rgb.g = blend; + r_rgb.b = blend * (1.0 - ((weight - 0.25) * 4.0)); + } + else if (weight <= 0.75) { /* green->yellow */ + r_rgb.r = blend * ((weight - 0.50) * 4.0); + r_rgb.g = blend; + } + else if (weight <= 1.0) { /* yellow->red */ + r_rgb.r = blend; + r_rgb.g = blend * (1.0 - ((weight - 0.75) * 4.0)); + } + else { + /* exceptional value, unclamped or nan, + * avoid uninitialized memory use */ + r_rgb = vec3(1.0, 0.0, 1.0); + } + + return r_rgb; +} + +mat3 rotation_from_vector(vec3 v) +{ + /* Add epsilon to avoid NaN. */ + vec3 N = normalize(v + 1e-8); + vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0); + vec3 T = normalize(cross(UpVector, N)); + vec3 B = cross(N, T); + return mat3(T, B, N); +} + +void main() +{ +#ifdef USE_NEEDLE + int cell = gl_VertexID / 12; +#else + int cell = gl_VertexID / 2; +#endif + + ivec3 volume_size = textureSize(velocityX, 0); + float voxel_size = 1.0 / float(max(max(volume_size.x, volume_size.y), volume_size.z)); + + ivec3 cell_ofs = ivec3(0); + ivec3 cell_div = volume_size; + if (sliceAxis == 0) { + cell_ofs.x = int(slicePosition * float(volume_size.x)); + cell_div.x = 1; + } + else if (sliceAxis == 1) { + cell_ofs.y = int(slicePosition * float(volume_size.y)); + cell_div.y = 1; + } + else if (sliceAxis == 2) { + cell_ofs.z = int(slicePosition * float(volume_size.z)); + cell_div.z = 1; + } + + ivec3 cell_co; + cell_co.x = cell % cell_div.x; + cell_co.y = (cell / cell_div.x) % cell_div.y; + cell_co.z = cell / (cell_div.x * cell_div.y); + cell_co += cell_ofs; + + vec3 pos = (vec3(cell_co) + 0.5) / vec3(volume_size); + pos = pos * 2.0 - 1.0; + + vec3 velocity; + velocity.x = texelFetch(velocityX, cell_co, 0).r; + velocity.y = texelFetch(velocityY, cell_co, 0).r; + velocity.z = texelFetch(velocityZ, cell_co, 0).r; + + finalColor = vec4(weight_to_color(length(velocity)), 1.0); + +#ifdef USE_NEEDLE + mat3 rot_mat = rotation_from_vector(velocity); + vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 12]]; + pos += rotated_pos * length(velocity) * displaySize * voxel_size; +#else + pos += (((gl_VertexID % 2) == 1) ? velocity : vec3(0.0)) * displaySize * voxel_size; +#endif + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +} diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index ebce83d2a5f..028756bc739 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -101,7 +101,9 @@ void GPU_free_images_old(struct Main *bmain); /* smoke drawing functions */ void GPU_free_smoke(struct SmokeModifierData *smd); +void GPU_free_smoke_velocity(struct SmokeModifierData *smd); void GPU_create_smoke(struct SmokeModifierData *smd, int highres); +void GPU_create_smoke_velocity(struct SmokeModifierData *smd); /* Delayed free of OpenGL buffers by main thread */ void GPU_free_unused_buffers(struct Main *bmain); diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7383868843d..e2c83d6fadf 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -971,6 +971,52 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) #endif // WITH_SMOKE } +void GPU_create_smoke_velocity(SmokeModifierData *smd) +{ +#ifdef WITH_SMOKE + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + SmokeDomainSettings *sds = smd->domain; + + const float *vel_x = smoke_get_velocity_x(sds->fluid); + const float *vel_y = smoke_get_velocity_y(sds->fluid); + const float *vel_z = smoke_get_velocity_z(sds->fluid); + + if (ELEM(NULL, vel_x, vel_y, vel_z)) { + return; + } + + if (!sds->tex_velocity_x) { + sds->tex_velocity_x = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_x, NULL); + sds->tex_velocity_y = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_y, NULL); + sds->tex_velocity_z = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_z, NULL); + } + } +#else // WITH_SMOKE + smd->domain->tex_velocity_x = NULL; + smd->domain->tex_velocity_y = NULL; + smd->domain->tex_velocity_z = NULL; +#endif // WITH_SMOKE +} + +/* TODO Unify with the other GPU_free_smoke. */ +void GPU_free_smoke_velocity(SmokeModifierData *smd) +{ + if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) { + if (smd->domain->tex_velocity_x) + GPU_texture_free(smd->domain->tex_velocity_x); + + if (smd->domain->tex_velocity_y) + GPU_texture_free(smd->domain->tex_velocity_y); + + if (smd->domain->tex_velocity_z) + GPU_texture_free(smd->domain->tex_velocity_z); + + smd->domain->tex_velocity_x = NULL; + smd->domain->tex_velocity_y = NULL; + smd->domain->tex_velocity_z = NULL; + } +} + static LinkNode *image_free_queue = NULL; static void gpu_queue_image_for_free(Image *ima) diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index 76b609b0c6c..443c6923ed0 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -137,6 +137,9 @@ typedef struct SmokeDomainSettings { struct GPUTexture *tex_wt; struct GPUTexture *tex_shadow; struct GPUTexture *tex_flame; + struct GPUTexture *tex_velocity_x; + struct GPUTexture *tex_velocity_y; + struct GPUTexture *tex_velocity_z; float *shadow; /* simulation data */ -- cgit v1.2.3 From eef6e1cca16468d70166330c0f64fe202d619304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 15:02:08 +0200 Subject: StudioLight: Fix codestyle --- source/blender/blenkernel/intern/studiolight.c | 42 -------------------------- 1 file changed, 42 deletions(-) diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 5381d2be691..df5cc7551aa 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -442,106 +442,64 @@ static void studiolight_calculate_spherical_harmonics_coefficient(StudioLight *s switch (sh_component) { /* L0 */ case 0: - { coef = 0.2822095f; break; - } - /* L1 */ case 1: - { coef = -0.488603f * nz * 2.0f / 3.0f; break; - } case 2: - { coef = 0.488603f * ny * 2.0f / 3.0f; break; - } case 3: - { coef = -0.488603f * nx * 2.0f / 3.0f; break; - } - /* L2 */ case 4: - { coef = 1.092548f * nx * nz * 1.0f / 4.0f; break; - } case 5: - { coef = -1.092548f * nz * ny * 1.0f / 4.0f; break; - } case 6: - { coef = 0.315392f * (3.0f * ny2 - 1.0f) * 1.0f / 4.0f; break; - } case 7: - { coef = 1.092548f * nx * ny * 1.0f / 4.0f; break; - } case 8: - { coef = 0.546274f * (nx2 - nz2) * 1.0f / 4.0f; break; - } - /* L4 */ case 9: - { coef = (2.5033429417967046f * nx * nz * (nx2 - nz2)) / -24.0f; break; - } case 10: - { coef = (-1.7701307697799304f * nz * ny * (3.0f * nx2 - nz2)) / -24.0f; break; - } case 11: - { coef = (0.9461746957575601f * nz * nx * (-1.0f + 7.0f * ny2)) / -24.0f; break; - } case 12: - { coef = (-0.6690465435572892f * nz * ny * (-3.0f + 7.0f * ny2)) / -24.0f; break; - } case 13: - { coef = ((105.0f * ny4 - 90.0f * ny2 + 9.0f) / 28.359261614f) / -24.0f; break; - } case 14: - { coef = (-0.6690465435572892f * nx * ny * (-3.0f + 7.0f * ny2)) / -24.0f; break; - } case 15: - { coef = (0.9461746957575601f * (nx2 - nz2) * (-1.0f + 7.0f * ny2)) / -24.0f; break; - } case 16: - { coef = (-1.7701307697799304f * nx * ny * (nx2 - 3.0f * nz2)) / -24.0f; break; - } case 17: - { coef = (0.6258357354491761f * (nx4 - 6.0f * nz2 * nx2 + nz4)) / -24.0f; break; - } - default: - { coef = 0.0f; - } } madd_v3_v3fl(sh, color, coef * weight); -- cgit v1.2.3 From 44a9c392290320b7ff1d439af75d073360386c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 15:02:42 +0200 Subject: Workbench: Fix use of uninitialized memory. --- source/blender/draw/engines/workbench/workbench_forward.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 3fb68654188..e0e0bdea0f5 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -247,10 +247,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) if (!stl->g_data) { /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } if (!stl->effects) { - stl->effects = MEM_mallocN(sizeof(*stl->effects), __func__); + stl->effects = MEM_callocN(sizeof(*stl->effects), __func__); workbench_effect_info_init(stl->effects); } WORKBENCH_PrivateData *wpd = stl->g_data; -- cgit v1.2.3 From 1f69ffd35b08768e8605496be4389e6bbea39ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 19:54:37 +0200 Subject: Eevee: Fix Cascaded Shadow Maps glitches There was an issue that caused the cascaded shadow map to appear glitchy when the lamp was not at the origin. --- source/blender/draw/engines/eevee/eevee_lights.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 0f0d9d281c9..431fc9fe561 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -891,7 +891,7 @@ static void eevee_shadow_cascade_setup( frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c])); /* Project into lightspace */ - mul_mat3_m4_v3(viewmat, center); + mul_m4_v3(viewmat, center); /* Snap projection center to nearest texel to cancel shimmering. */ float shadow_origin[2], shadow_texco[2]; -- cgit v1.2.3 From db374d665875af0673ab576779649e0f2ee45704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 20:07:13 +0200 Subject: DRWDebug: Add new debug functions for spheres and matrices. --- source/blender/draw/intern/DRW_render.h | 1 + source/blender/draw/intern/draw_debug.c | 74 +++++++++++++++++++++++++++++++ source/blender/draw/intern/draw_debug.h | 2 + source/blender/draw/intern/draw_manager.h | 7 +++ 4 files changed, 84 insertions(+) diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 4d1b8269494..a4a933250c9 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -55,6 +55,7 @@ #include "draw_view.h" #include "draw_manager_profiling.h" +#include "draw_debug.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/draw/intern/draw_debug.c b/source/blender/draw/intern/draw_debug.c index 0e4176f90a6..64e76a339c1 100644 --- a/source/blender/draw/intern/draw_debug.c +++ b/source/blender/draw/intern/draw_debug.c @@ -29,6 +29,8 @@ #include "DNA_object_types.h" +#include "BKE_object.h" + #include "BLI_link_utils.h" #include "GPU_immediate.h" @@ -105,6 +107,36 @@ void DRW_debug_bbox(const BoundBox *bbox, const float color[4]) DRW_debug_line_v3v3(bbox->vec[3], bbox->vec[7], color); } +void DRW_debug_m4_as_bbox(const float m[4][4], const float color[4], const bool invert) +{ + BoundBox bb; + const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f}; + float minv[4][4]; + if (invert) { + invert_m4_m4(minv, m); + } + + BKE_boundbox_init_from_minmax(&bb, min, max); + for (int i = 0; i < 8; ++i) { + mul_project_m4_v3((invert) ? minv : m, bb.vec[i]); + } + DRW_debug_bbox(&bb, color); +} + +void DRW_debug_sphere(const float center[3], const float radius, const float color[4]) +{ + float size_mat[4][4]; + DRWDebugSphere *sphere = MEM_mallocN(sizeof(DRWDebugSphere), "DRWDebugSphere"); + /* Bake all transform into a Matrix4 */ + scale_m4_fl(size_mat, radius); + copy_m4_m4(sphere->mat, g_modelmat); + translate_m4(sphere->mat, center[0], center[1], center[2]); + mul_m4_m4m4(sphere->mat, sphere->mat, size_mat); + + copy_v4_v4(sphere->color, color); + BLI_LINKS_PREPEND(DST.debug.spheres, sphere); +} + /* --------- Render --------- */ static void drw_debug_draw_lines(void) @@ -140,9 +172,51 @@ static void drw_debug_draw_lines(void) immUnbindProgram(); } +static void drw_debug_draw_spheres(void) +{ + int count = BLI_linklist_count((LinkNode *)DST.debug.spheres); + + if (count == 0) { + return; + } + + float one = 1.0f; + Gwn_VertFormat vert_format = {0}; + uint mat = GWN_vertformat_attr_add(&vert_format, "InstanceModelMatrix", GWN_COMP_F32, 16, GWN_FETCH_FLOAT); + uint col = GWN_vertformat_attr_add(&vert_format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint siz = GWN_vertformat_attr_add(&vert_format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + + Gwn_VertBuf *inst_vbo = GWN_vertbuf_create_with_format(&vert_format); + + GWN_vertbuf_data_alloc(inst_vbo, count); + + int v = 0; + while (DST.debug.spheres) { + void *next = DST.debug.spheres->next; + + GWN_vertbuf_attr_set(inst_vbo, mat, v, DST.debug.spheres->mat[0]); + GWN_vertbuf_attr_set(inst_vbo, col, v, DST.debug.spheres->color); + GWN_vertbuf_attr_set(inst_vbo, siz, v, &one); + v++; + + MEM_freeN(DST.debug.spheres); + DST.debug.spheres = next; + } + + Gwn_Batch *empty_sphere = DRW_cache_empty_sphere_get(); + + Gwn_Batch *draw_batch = GWN_batch_create(GWN_PRIM_LINES, empty_sphere->verts[0], NULL); + GWN_batch_instbuf_set(draw_batch, inst_vbo, true); + GWN_batch_program_set_builtin(draw_batch, GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); + + GWN_batch_draw(draw_batch); + GWN_batch_discard(draw_batch); +} + void drw_debug_draw(void) { drw_debug_draw_lines(); + drw_debug_draw_spheres(); } void drw_debug_init(void) diff --git a/source/blender/draw/intern/draw_debug.h b/source/blender/draw/intern/draw_debug.h index 1dab431fc88..319d2674279 100644 --- a/source/blender/draw/intern/draw_debug.h +++ b/source/blender/draw/intern/draw_debug.h @@ -34,6 +34,8 @@ void DRW_debug_modelmat(const float modelmat[4][4]); void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]); void DRW_debug_polygon_v3(const float (*v)[3], const int vert_len, const float color[4]); void DRW_debug_m4(const float m[4][4]); +void DRW_debug_m4_as_bbox(const float m[4][4], const float color[4], const bool invert); void DRW_debug_bbox(const BoundBox *bbox, const float color[4]); +void DRW_debug_sphere(const float center[3], const float radius, const float color[4]); #endif /* __DRAW_DEBUG_H__ */ diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 6eae3459c2b..d25e372c26e 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -296,6 +296,12 @@ typedef struct DRWDebugLine { float color[4]; } DRWDebugLine; +typedef struct DRWDebugSphere { + struct DRWDebugSphere *next; /* linked list */ + float mat[4][4]; + float color[4]; +} DRWDebugSphere; + /* ------------- DRAW MANAGER ------------ */ #define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */ @@ -388,6 +394,7 @@ typedef struct DRWManager { struct { /* TODO(fclem) optimize: use chunks. */ DRWDebugLine *lines; + DRWDebugSphere *spheres; } debug; } DRWManager; -- cgit v1.2.3 From d5f048f8830d2cbb47a4845a9ca0a085f242f910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jul 2018 20:08:02 +0200 Subject: Eevee: Add debug visual for Cascaded Shadow Maps --- source/blender/draw/engines/eevee/eevee_lights.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 431fc9fe561..dc9ce29a148 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -37,6 +37,8 @@ #define SHADOW_CASTER_ALLOC_CHUNK 16 +// #define DEBUG_CSM + static struct { struct GPUShader *shadow_sh; struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX]; @@ -871,13 +873,13 @@ static void eevee_shadow_cascade_setup( /* Given 8 frustum corners */ float corners[8][3] = { /* Near Cap */ - {-1.0f, -1.0f, splits_start_ndc[c]}, { 1.0f, -1.0f, splits_start_ndc[c]}, + {-1.0f, -1.0f, splits_start_ndc[c]}, {-1.0f, 1.0f, splits_start_ndc[c]}, { 1.0f, 1.0f, splits_start_ndc[c]}, /* Far Cap */ - {-1.0f, -1.0f, splits_end_ndc[c]}, { 1.0f, -1.0f, splits_end_ndc[c]}, + {-1.0f, -1.0f, splits_end_ndc[c]}, {-1.0f, 1.0f, splits_end_ndc[c]}, { 1.0f, 1.0f, splits_end_ndc[c]} }; @@ -890,6 +892,15 @@ static void eevee_shadow_cascade_setup( float center[3]; frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c])); +#ifdef DEBUG_CSM + float dbg_col[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + if (c < 3) { + dbg_col[c] = 1.0f; + } + DRW_debug_bbox((BoundBox *)&corners, dbg_col); + DRW_debug_sphere(center, sh_data->radius[c], dbg_col); +#endif + /* Project into lightspace */ mul_m4_v3(viewmat, center); @@ -919,6 +930,10 @@ static void eevee_shadow_cascade_setup( mul_m4_m4m4(sh_data->viewprojmat[c], projmat, viewmat); mul_m4_m4m4(cascade_data->shadowmat[c], texcomat, sh_data->viewprojmat[c]); + +#ifdef DEBUG_CSM + DRW_debug_m4_as_bbox(sh_data->viewprojmat[c], dbg_col, true); +#endif } ubo_data->bias = 0.05f * la->bias; -- cgit v1.2.3 From b85be88655ccc408d9545a077f33502fd583eb2e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 16 Jul 2018 22:29:26 +0200 Subject: Fix (IRC-reported) wrong usercount handling of deprecated IPO datablocks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit versionning code would unref those twice... Reported by @ßergey on IRC, thanks! --- source/blender/blenkernel/intern/ipo.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 9d8ca1e352c..fd8cb6d6d98 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1732,8 +1732,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* IPO first to take into any non-NLA'd Object Animation */ if (ob->ipo) { ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); - - id_us_min(&ob->ipo->id); + /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ ob->ipo = NULL; } @@ -1766,7 +1765,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* IPO second... */ if (ob->ipo) { ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); - id_us_min(&ob->ipo->id); + /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ ob->ipo = NULL; { -- cgit v1.2.3 From dc3b3d945386b3651bb0fb4413753297f044e535 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 17 Jul 2018 00:45:56 +0200 Subject: UI: Lamp -> Light for the object type visibility operators Spotted in a live stream by Emilton Mendoza, thanks! --- release/scripts/startup/bl_ui/space_view3d.py | 2 +- source/blender/makesrna/intern/rna_space.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 36bfe5ec65e..693bb9c4efb 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3714,7 +3714,7 @@ class VIEW3D_PT_object_type_visibility(Panel): "lattice", "empty", "camera", - "lamp", + "light", "light_probe", "speaker", ) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index df838264cb7..d7024a149a3 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3100,8 +3100,8 @@ static void rna_def_space_view3d(BlenderRNA *brna) {"show_object_viewport_empty", "show_object_select_empty"}}, {"Camera", (1 << OB_CAMERA), {"show_object_viewport_camera", "show_object_select_camera"}}, - {"Lamp", (1 << OB_LAMP), - {"show_object_viewport_lamp", "show_object_select_lamp"}}, + {"Light", (1 << OB_LAMP), + {"show_object_viewport_light", "show_object_select_light"}}, {"Speaker", (1 << OB_SPEAKER), {"show_object_viewport_speaker", "show_object_select_speaker"}}, {"Light Probe", (1 << OB_LIGHTPROBE), -- cgit v1.2.3 From 7dcc7bd5eee89ebaba7fb036bb2f2970d1532804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 17 Jul 2018 11:36:07 +0200 Subject: Object Mode: Add back object bound display --- source/blender/draw/intern/draw_cache.c | 141 ++++++++++++++++++++++++++++++++ source/blender/draw/intern/draw_cache.h | 3 + source/blender/draw/modes/object_mode.c | 108 ++++++++++++++++++++++-- 3 files changed, 243 insertions(+), 9 deletions(-) diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 0d2317199fc..707aadbc229 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -63,6 +63,9 @@ static struct DRWShapeCache { Gwn_Batch *drw_line_endpoints; Gwn_Batch *drw_empty_cube; Gwn_Batch *drw_empty_sphere; + Gwn_Batch *drw_empty_cylinder; + Gwn_Batch *drw_empty_capsule_body; + Gwn_Batch *drw_empty_capsule_cap; Gwn_Batch *drw_empty_cone; Gwn_Batch *drw_arrows; Gwn_Batch *drw_axis_names; @@ -784,6 +787,144 @@ Gwn_Batch *DRW_cache_empty_cone_get(void) #undef NSEGMENTS } +Gwn_Batch *DRW_cache_empty_cylinder_get(void) +{ +#define NSEGMENTS 12 + if (!SHC.drw_empty_cylinder) { + /* 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] = cosf(angle); + p[i][1] = sinf(angle); + } + + /* Position Only 3D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = 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, NSEGMENTS * 6); + + for (int i = 0; i < NSEGMENTS; ++i) { + float cv[2], pv[2], v[3]; + cv[0] = p[(i) % NSEGMENTS][0]; + cv[1] = p[(i) % NSEGMENTS][1]; + pv[0] = p[(i + 1) % NSEGMENTS][0]; + pv[1] = p[(i + 1) % NSEGMENTS][1]; + + /* cylinder sides */ + copy_v3_fl3(v, cv[0], cv[1], -1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6, v); + copy_v3_fl3(v, cv[0], cv[1], 1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 1, v); + + /* top ring */ + copy_v3_fl3(v, cv[0], cv[1], 1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 2, v); + copy_v3_fl3(v, pv[0], pv[1], 1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 3, v); + + /* bottom ring */ + copy_v3_fl3(v, cv[0], cv[1], -1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 4, v); + copy_v3_fl3(v, pv[0], pv[1], -1.0f); + GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 5, v); + } + + SHC.drw_empty_cylinder = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_empty_cylinder; +#undef NSEGMENTS +} + +Gwn_Batch *DRW_cache_empty_capsule_body_get(void) +{ + if (!SHC.drw_empty_capsule_body) { + const float pos[8][3] = { + { 1.0f, 0.0f, 1.0f}, + { 1.0f, 0.0f, 0.0f}, + { 0.0f, 1.0f, 1.0f}, + { 0.0f, 1.0f, 0.0f}, + {-1.0f, 0.0f, 1.0f}, + {-1.0f, 0.0f, 0.0f}, + { 0.0f, -1.0f, 1.0f}, + { 0.0f, -1.0f, 0.0f} + }; + + /* Position Only 3D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = 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, 8); + GWN_vertbuf_attr_fill(vbo, attr_id.pos, pos); + + SHC.drw_empty_capsule_body = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_empty_capsule_body; +} + +Gwn_Batch *DRW_cache_empty_capsule_cap_get(void) +{ +#define NSEGMENTS 24 /* Must be multiple of 2. */ + if (!SHC.drw_empty_capsule_cap) { + /* 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] = cosf(angle); + p[i][1] = sinf(angle); + } + + /* Position Only 3D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = 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, (NSEGMENTS * 2) * 2); + + /* Base circle */ + int vidx = 0; + for (int i = 0; i < NSEGMENTS; ++i) { + float v[3] = {0.0f, 0.0f, 0.0f}; + copy_v2_v2(v, p[(i) % NSEGMENTS]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + copy_v2_v2(v, p[(i+1) % NSEGMENTS]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + } + + for (int i = 0; i < NSEGMENTS / 2; ++i) { + float v[3] = {0.0f, 0.0f, 0.0f}; + int ci = i % NSEGMENTS; + int pi = (i + 1) % NSEGMENTS; + /* Y half circle */ + copy_v3_fl3(v, p[ci][0], 0.0f, p[ci][1]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + copy_v3_fl3(v, p[pi][0], 0.0f, p[pi][1]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + /* X half circle */ + copy_v3_fl3(v, 0.0f, p[ci][0], p[ci][1]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + copy_v3_fl3(v, 0.0f, p[pi][0], p[pi][1]); + GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + } + + SHC.drw_empty_capsule_cap = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_empty_capsule_cap; +#undef NSEGMENTS +} + Gwn_Batch *DRW_cache_arrows_get(void) { if (!SHC.drw_arrows) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 9114a4d872d..c1c80d2c5bf 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -66,7 +66,10 @@ struct Gwn_Batch *DRW_cache_empty_cube_get(void); struct Gwn_Batch *DRW_cache_circle_get(void); struct Gwn_Batch *DRW_cache_square_get(void); struct Gwn_Batch *DRW_cache_empty_sphere_get(void); +struct Gwn_Batch *DRW_cache_empty_cylinder_get(void); struct Gwn_Batch *DRW_cache_empty_cone_get(void); +struct Gwn_Batch *DRW_cache_empty_capsule_cap_get(void); +struct Gwn_Batch *DRW_cache_empty_capsule_body_get(void); struct Gwn_Batch *DRW_cache_arrows_get(void); struct Gwn_Batch *DRW_cache_axis_names_get(void); struct Gwn_Batch *DRW_cache_image_plane_get(void); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 2e41dbfd529..43400b3bac0 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -145,6 +145,9 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *cube; DRWShadingGroup *circle; DRWShadingGroup *sphere; + DRWShadingGroup *cylinder; + DRWShadingGroup *capsule_cap; + DRWShadingGroup *capsule_body; DRWShadingGroup *cone; DRWShadingGroup *single_arrow; DRWShadingGroup *single_arrow_line; @@ -1093,6 +1096,15 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_empty_sphere_get(); stl->g_data->sphere = shgroup_instance(psl->non_meshes, geom); + geom = DRW_cache_empty_cylinder_get(); + stl->g_data->cylinder = shgroup_instance(psl->non_meshes, geom); + + geom = DRW_cache_empty_capsule_cap_get(); + stl->g_data->capsule_cap = shgroup_instance(psl->non_meshes, geom); + + geom = DRW_cache_empty_capsule_body_get(); + stl->g_data->capsule_body = shgroup_instance(psl->non_meshes, geom); + geom = DRW_cache_empty_cone_get(); stl->g_data->cone = shgroup_instance(psl->non_meshes, geom); @@ -2146,6 +2158,82 @@ static void DRW_shgroup_texture_space(OBJECT_StorageList *stl, Object *ob, int t DRW_shgroup_call_dynamic_add(stl->g_data->texspace, color, &one, tmp); } +static void DRW_shgroup_bounds(OBJECT_StorageList *stl, Object *ob, int theme_id) +{ + float color[4], center[3], size[3], tmp[4][4], final_mat[4][4], one = 1.0f; + BoundBox bb_local; + + if (ob->type == OB_MBALL && !BKE_mball_is_basis(ob)) { + return; + } + + BoundBox *bb = BKE_object_boundbox_get(ob); + + if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, + OB_MBALL, OB_ARMATURE, OB_LATTICE)) + { + 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); + } + + UI_GetThemeColor4fv(theme_id, color); + BKE_boundbox_calc_center_aabb(bb, center); + BKE_boundbox_calc_size_aabb(bb, size); + + switch (ob->boundtype) { + case OB_BOUND_BOX: + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, tmp); + break; + case OB_BOUND_SPHERE: + size[0] = max_fff(size[0], size[1], size[2]); + size[1] = size[2] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &one, tmp); + break; + case OB_BOUND_CYLINDER: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cylinder, color, &one, tmp); + break; + case OB_BOUND_CONE: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + /* Cone batch has base at 0 and is pointing towards +Y. */ + swap_v3_v3(tmp[1], tmp[2]); + tmp[3][2] -= size[2]; + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cone, color, &one, tmp); + break; + case OB_BOUND_CAPSULE: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + scale_m4_fl(tmp, size[0]); + copy_v2_v2(tmp[3], center); + tmp[3][2] = center[2] + max_ff(0.0f, size[2] - size[0]); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_cap, color, &one, final_mat); + negate_v3(tmp[2]); + tmp[3][2] = center[2] - max_ff(0.0f, size[2] - size[0]); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_cap, color, &one, final_mat); + tmp[2][2] = max_ff(0.0f, size[2] * 2.0f - size[0] * 2.0f); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_body, color, &one, final_mat); + break; + } +} + static void OBJECT_cache_populate_particles(Object *ob, OBJECT_PassList *psl) { @@ -2398,17 +2486,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) DRW_shgroup_forcefield(stl, ob, view_layer); } - if (((ob->base_flag & BASE_FROMDUPLI) == 0) && - (md = modifiers_findByType(ob, eModifierType_Smoke)) && - (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && - (((SmokeModifierData *)md)->domain != NULL)) - { - DRW_shgroup_volume_extra(psl, stl, ob, view_layer, scene, md); - } - /* don't show object extras in set's */ if ((ob->base_flag & (BASE_FROM_SET | BASE_FROMDUPLI)) == 0) { - DRW_shgroup_object_center(stl, ob, view_layer, v3d); if (show_relations) { @@ -2434,6 +2513,17 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if ((ob->dtx & OB_TEXSPACE) && ELEM(ob->type, OB_MESH, OB_CURVE, OB_MBALL)) { DRW_shgroup_texture_space(stl, ob, theme_id); } + + if (ob->dtx & OB_DRAWBOUNDOX) { + DRW_shgroup_bounds(stl, ob, theme_id); + } + + if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && + (((SmokeModifierData *)md)->domain != NULL)) + { + DRW_shgroup_volume_extra(psl, stl, ob, view_layer, scene, md); + } } } -- cgit v1.2.3 From 273482749ef7e937de8a1a2c886576a9418c7f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuk=20Garda=C5=A1evi=C4=87?= Date: Tue, 17 Jul 2018 11:59:24 +0200 Subject: UI: Minor fixes to separators on menus Closes D3547 --- release/scripts/startup/bl_ui/space_view3d.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 693bb9c4efb..77198168dcf 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -642,9 +642,12 @@ class VIEW3D_MT_view_align(Menu): layout.separator() - layout.operator("view3d.view_all", text="Center Cursor and View All").center = True layout.operator("view3d.camera_to_view", text="Align Active Camera to View") layout.operator("view3d.camera_to_view_selected", text="Align Active Camera to Selected") + + layout.separator() + + layout.operator("view3d.view_all", text="Center Cursor and View All").center = True layout.operator("view3d.view_center_cursor") layout.separator() @@ -667,6 +670,8 @@ class VIEW3D_MT_view_align_selected(Menu): props.align_active = True props.type = 'BOTTOM' + layout.separator() + props = layout.operator("view3d.view_axis", text="Front") props.align_active = True props.type = 'FRONT' @@ -675,6 +680,8 @@ class VIEW3D_MT_view_align_selected(Menu): props.align_active = True props.type = 'BACK' + layout.separator() + props = layout.operator("view3d.view_axis", text="Right") props.align_active = True props.type = 'RIGHT' @@ -2655,6 +2662,9 @@ class VIEW3D_MT_edit_mesh(Menu): layout.menu("VIEW3D_MT_edit_mesh_showhide") layout.operator_menu_enum("mesh.separate", "type") layout.menu("VIEW3D_MT_edit_mesh_clean") + + layout.separator() + layout.menu("VIEW3D_MT_edit_mesh_delete") @@ -2879,14 +2889,11 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu): props.use_verts = True props.clear = True - layout.separator() - - layout.separator() - if with_freestyle: + layout.separator() + layout.operator("mesh.mark_freestyle_edge").clear = False layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True - layout.separator() class VIEW3D_MT_edit_mesh_edges(Menu): @@ -4493,9 +4500,9 @@ class VIEW3D_PT_pivot_point(Panel): col.label("Pivot Point") col.prop(toolsettings, "transform_pivot_point", expand=True) - col.separator() - if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}): + col.separator() + col.prop( toolsettings, "use_transform_pivot_point_align", -- cgit v1.2.3 From 84d4037363b325a279ef87b6b1c430be29984357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuk=20Garda=C5=A1evi=C4=87?= Date: Tue, 17 Jul 2018 12:17:42 +0200 Subject: UI: Single-column and flow layout for Scene properties See D3532 --- release/scripts/modules/rna_prop_ui.py | 17 +- .../startup/bl_ui/properties_physics_common.py | 87 +++++----- release/scripts/startup/bl_ui/properties_scene.py | 185 +++++++++++++++------ 3 files changed, 199 insertions(+), 90 deletions(-) diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index bdb0751c973..8453077be85 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -132,6 +132,11 @@ def draw(layout, context, context_member, property_type, use_edit=True): show_developer_ui = context.user_preferences.view.show_developer_ui rna_properties = {prop.identifier for prop in rna_item.bl_rna.properties if prop.is_runtime} if items else None + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + for key, val in items: if key == '_RNA_UI': @@ -143,7 +148,6 @@ def draw(layout, context, context_member, property_type, use_edit=True): if is_rna and not show_developer_ui: continue - row = layout.row() to_dict = getattr(val, "to_dict", None) to_list = getattr(val, "to_list", None) @@ -157,17 +161,20 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: val_draw = val + row = flow.row(align=True) box = row.box() if use_edit: split = box.split(percentage=0.75) - row = split.row() + row = split.row(align=True) else: - row = box.row() + row = box.row(align=True) + + row.alignment = "RIGHT" row.label(text=key, translate=False) - # explicit exception for arrays + # explicit exception for arrays. if to_dict or to_list: row.label(text=val_draw, translate=False) else: @@ -186,6 +193,8 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: row.label(text="API Defined") + del flow + class PropertyPanel: """ diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index e071de0108b..c9bde32c53d 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -97,7 +97,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): 'CONSTRAINT') # RB_TODO needs better icon -# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc +# cache-type can be 'PSYS' 'HAIR' 'SMOKE' etc. def point_cache_ui(self, context, cache, enabled, cachetype): layout = self.layout @@ -112,8 +112,8 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.operator("ptcache.add", icon='ZOOMIN', text="") col.operator("ptcache.remove", icon='ZOOMOUT', text="") - row = layout.row() if cachetype in {'PSYS', 'HAIR', 'SMOKE'}: + row = layout.row() row.prop(cache, "use_external") if cachetype == 'SMOKE': @@ -131,7 +131,9 @@ def point_cache_ui(self, context, cache, enabled, cachetype): cache_info = cache.info if cache_info: - layout.label(text=cache_info) + col = layout.column() + col.alignment = "RIGHT" + col.label(text=cache_info) else: if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}: if not bpy.data.is_saved: @@ -147,45 +149,54 @@ def point_cache_ui(self, context, cache, enabled, cachetype): col.enabled = enabled col.prop(cache, "frame_start", text="Simulation Start") col.prop(cache, "frame_end") + if cachetype not in {'SMOKE', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}: col.prop(cache, "frame_step") - if cachetype != 'SMOKE': - layout.label(text=cache.info) + cache_info = cache.info + if cachetype != 'SMOKE' and cache_info: # avoid empty space. + col = layout.column(align=True) + col.alignment = "RIGHT" + col.label(text=cache_info) can_bake = True if cachetype not in {'SMOKE', 'DYNAMIC_PAINT', 'RIGID_BODY'}: - split = layout.split() - split.enabled = enabled and bpy.data.is_saved + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + flow.enabled = enabled and bpy.data.is_saved - col = split.column() - col.prop(cache, "use_disk_cache") + flow.use_property_split = True - col = split.column() - col.active = cache.use_disk_cache - col.prop(cache, "use_library_path", "Use Lib Path") + # NOTE: TODO temporarly used until the animate properties are properly skipped. + flow.use_property_decorate = False # No animation (remove this later on) - row = layout.row() - row.enabled = enabled and bpy.data.is_saved - row.active = cache.use_disk_cache - row.label(text="Compression:") - row.prop(cache, "compression", expand=True) + col = flow.column() + col.prop(cache, "use_disk_cache") - layout.separator() + subcol = col.column() + subcol.active = cache.use_disk_cache + subcol.prop(cache, "use_library_path", "Use Lib Path") + + col = flow.column() + col.enabled = enabled and bpy.data.is_saved + col.active = cache.use_disk_cache + col.prop(cache, "compression", text="Compression", expand=True) if cache.id_data.library and not cache.use_disk_cache: can_bake = False col = layout.column(align=True) - col.label(text="Linked object baking requires Disk Cache to be enabled", icon='INFO') + col.alignment = "RIGHT" + + col.separator() + + col.label(text="Linked object baking requires Disk Cache to be enabled") else: layout.separator() - split = layout.split() - split.active = can_bake - - col = split.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + col = flow.column() + col.active = can_bake if cache.is_baked is True: col.operator("ptcache.free_bake", text="Free Bake") @@ -200,7 +211,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): sub.enabled = enabled sub.operator("ptcache.bake_from_cache", text="Current Cache to Bake") - col = split.column() + col = flow.column() col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True col.operator("ptcache.free_bake_all", text="Free All Bakes") col.operator("ptcache.bake_all", text="Update All To Frame").bake = False @@ -212,31 +223,31 @@ def effector_weights_ui(self, context, weights, weight_type): layout.prop(weights, "group") - layout.use_property_split = False - - split = layout.split() - - split.prop(weights, "gravity", slider=True) - split.prop(weights, "all", slider=True) + # NOTE: TODO temporarly used until the animate properties are properly skipped + layout.use_property_decorate = False # No animation (remove this later on) - layout.separator() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - split = layout.split() - - col = split.column() + col = flow.column() + col.prop(weights, "gravity", slider=True) + col.prop(weights, "all", slider=True) col.prop(weights, "force", slider=True) col.prop(weights, "vortex", slider=True) + + col = flow.column() col.prop(weights, "magnetic", slider=True) + col.prop(weights, "harmonic", slider=True) + col.prop(weights, "charge", slider=True) + col.prop(weights, "lennardjones", slider=True) + + col = flow.column() col.prop(weights, "wind", slider=True) col.prop(weights, "curve_guide", slider=True) col.prop(weights, "texture", slider=True) if weight_type != 'SMOKE': col.prop(weights, "smokeflow", slider=True) - col = split.column() - col.prop(weights, "harmonic", slider=True) - col.prop(weights, "charge", slider=True) - col.prop(weights, "lennardjones", slider=True) + col = flow.column() col.prop(weights, "turbulence", slider=True) col.prop(weights, "drag", slider=True) col.prop(weights, "boid", slider=True) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index d0fce0a2582..c0b8233a796 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -17,9 +17,9 @@ # ##### END GPL LICENSE BLOCK ##### # + import bpy from bpy.types import ( - Menu, Panel, UIList, ) @@ -71,6 +71,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True + scene = context.scene layout.prop(scene, "camera") @@ -92,13 +93,13 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): layout.use_property_split = True - col = layout.column() - col.prop(unit, "system") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) - col = layout.column() + col = flow.column() + col.prop(unit, "system") col.prop(unit, "system_rotation") - col = layout.column() + col = flow.column() col.enabled = unit.system != 'NONE' col.prop(unit, "scale_length") col.prop(unit, "use_separate") @@ -147,15 +148,17 @@ class SceneKeyingSetsPanel: propname = prop row = layout.row(align=True) - row.prop(item, toggle_prop, text="", icon='STYLUS_PRESSURE', toggle=True) # XXX: needs dedicated icon - subrow = row.row() + subrow = row.row(align=True) subrow.active = getattr(item, toggle_prop) + if subrow.active: subrow.prop(item, prop, text=label) else: subrow.prop(owner, propname, text=label) + row.prop(item, toggle_prop, text="", icon='STYLUS_PRESSURE', toggle=True) # XXX: needs dedicated icon + class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Keying Sets" @@ -166,6 +169,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): layout = self.layout scene = context.scene + row = layout.row() col = row.column() @@ -175,20 +179,56 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): col.operator("anim.keying_set_add", icon='ZOOMIN', text="") col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="") + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) + ks = scene.keying_sets.active if ks and ks.is_path_absolute: - row = layout.row() - - col = row.column() + col = flow.column() col.prop(ks, "bl_description") - subcol = col.column() + subcol = flow.column() subcol.operator_context = 'INVOKE_DEFAULT' subcol.operator("anim.keying_set_export", text="Export to File").filepath = "keyingset.py" - col = row.column() - col.label(text="Keyframing Settings:") - self.draw_keyframing_settings(context, col, ks, None) + +class SCENE_PT_keyframing_settings(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): + bl_label = "Keyframing Settings" + bl_parent_id = "SCENE_PT_keying_sets" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + ks = context.scene.keying_sets.active + return (ks and ks.is_path_absolute) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + scene = context.scene + ks = scene.keying_sets.active + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column(align=True) + col.alignment = "RIGHT" + col.label(text="General Override") + + self.draw_keyframing_settings(context, col, ks, None) + + ksp = ks.paths.active + if ksp: + col.separator() + + col = flow.column(align=True) + col.alignment = "RIGHT" + col.label(text="Active Set Override") + + self.draw_keyframing_settings(context, col, ks, ksp) class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): @@ -219,34 +259,40 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="") col.operator("anim.keying_set_path_remove", icon='ZOOMOUT', text="") + # TODO: 1) the template_any_ID needs to be fixed for the text alignment. + # 2) use_property_decorate has to properly skip the non animatable properties. + # Properties affected with needless draw: + # group_method, template_any_ID dropdown, use_entire_array + + layout.use_property_split = True + layout.use_property_decorate = False # No animation (remove this later on). + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=True) + ksp = ks.paths.active if ksp: - col = layout.column() - col.label(text="Target:") - col.template_any_ID(ksp, "id", "id_type") - col.template_path_builder(ksp, "data_path", ksp.id) - - row = col.row(align=True) - row.label(text="Array Target:") - row.prop(ksp, "use_entire_array", text="All Items") - if ksp.use_entire_array: - row.label(text=" ") # padding - else: - row.prop(ksp, "array_index", text="Index") + col = flow.column(align=True) + col.alignment = "RIGHT" + + col.template_any_ID(ksp, "id", "id_type", text="Target ID-Block") + + col.separator() - layout.separator() + col.template_path_builder(ksp, "data_path", ksp.id, text="Data Path") - row = layout.row() - col = row.column() - col.label(text="F-Curve Grouping:") - col.prop(ksp, "group_method", text="") + col = flow.column() + + col.prop(ksp, "use_entire_array", text="Array All Items") + + if not ksp.use_entire_array: + col.prop(ksp, "array_index", text="Index") + + col.separator() + + col.prop(ksp, "group_method", text="F-Curve Grouping") if ksp.group_method == 'NAMED': col.prop(ksp, "group") - col = row.column() - col.label(text="Keyframing Settings:") - self.draw_keyframing_settings(context, col, ks, ksp) - class SCENE_PT_color_management(SceneButtonsPanel, Panel): bl_label = "Color Management" @@ -260,16 +306,19 @@ class SCENE_PT_color_management(SceneButtonsPanel, Panel): scene = context.scene view = scene.view_settings - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(scene.display_settings, "display_device") col.separator() - col = layout.column() col.prop(view, "view_transform") + col.prop(view, "look") + + col = flow.column() col.prop(view, "exposure") col.prop(view, "gamma") - col.prop(view, "look") col.separator() @@ -314,21 +363,28 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): rd = context.scene.render ffmpeg = rd.ffmpeg - layout.prop(scene, "audio_volume") + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - col = layout.column() - col.prop(scene, "audio_distance_model") + col = flow.column() + col.prop(scene, "audio_volume") + col.separator() + + col.prop(scene, "audio_distance_model") col.prop(ffmpeg, "audio_channels") + + col.separator() + + col = flow.column() col.prop(ffmpeg, "audio_mixrate", text="Sample Rate") - layout.separator() + col.separator() - col = layout.column(align=True) + col = col.column(align=True) col.prop(scene, "audio_doppler_speed", text="Doppler Speed") col.prop(scene, "audio_doppler_factor", text="Doppler Factor") - layout.separator() + col.separator() layout.operator("sound.bake_animation") @@ -372,7 +428,6 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): layout.use_property_split = True scene = context.scene - rbw = scene.rigidbody_world if rbw is None: @@ -380,7 +435,28 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): else: layout.operator("rigidbody.world_remove") - col = layout.column() + +class SCENE_PT_rigid_body_world_settings(SceneButtonsPanel, Panel): + bl_label = "Settings" + bl_parent_id = "SCENE_PT_rigid_body_world" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + @classmethod + def poll(cls, context): + scene = context.scene + return scene and scene.rigidbody_world and (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + scene = context.scene + rbw = scene.rigidbody_world + + if rbw: + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() col.active = rbw.enabled col = col.column() @@ -389,6 +465,9 @@ class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): col = col.column() col.prop(rbw, "time_scale", text="Speed") + + col = flow.column() + col.active = rbw.enabled col.prop(rbw, "use_split_impulse") col = col.column() @@ -458,8 +537,12 @@ class SCENE_PT_simplify_viewport(SceneButtonsPanel, Panel): layout.active = rd.use_simplify - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(rd, "simplify_subdivision", text="Max Subdivision") + + col = flow.column() col.prop(rd, "simplify_child_particles", text="Max Child Particles") @@ -476,8 +559,12 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): layout.active = rd.use_simplify - col = layout.column() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) + + col = flow.column() col.prop(rd, "simplify_subdivision_render", text="Max Subdivision") + + col = flow.column() col.prop(rd, "simplify_child_particles_render", text="Max Child Particles") @@ -494,11 +581,13 @@ classes = ( SCENE_PT_unit, SCENE_PT_keying_sets, SCENE_PT_keying_set_paths, + SCENE_PT_keyframing_settings, SCENE_PT_color_management, SCENE_PT_color_management_curves, SCENE_PT_audio, SCENE_PT_physics, SCENE_PT_rigid_body_world, + SCENE_PT_rigid_body_world_settings, SCENE_PT_rigid_body_cache, SCENE_PT_rigid_body_field_weights, SCENE_PT_simplify, -- cgit v1.2.3 From 8d53b72b81212d9d87c71375d299af1dc535b487 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 17 Jul 2018 12:35:45 +0200 Subject: World: Added 'Viewport Display' panel The Properties->World tab had no Viewport Display panel. The world color itself was hidden when the 'use_node_tree' was enabled. Also renamed the World.horizon_color to World.color as it has nothing to do with the color of the horizon (old BI feature) --- intern/cycles/blender/addon/ui.py | 2 +- intern/cycles/blender/blender_shader.cpp | 2 +- release/scripts/startup/bl_ui/properties_world.py | 19 +++++++++++++++++-- source/blender/makesrna/intern/rna_world.c | 4 ++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 6e56e42f9b2..3d5ed6b9b44 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1227,7 +1227,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel): world = context.world if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'): - layout.prop(world, "horizon_color", text="Color") + layout.prop(world, "color") class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 6129565fec5..b3dfe1f6800 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1330,7 +1330,7 @@ void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all) } else if(b_world) { BackgroundNode *background = new BackgroundNode(); - background->color = get_float3(b_world.horizon_color()); + background->color = get_float3(b_world.color()); graph->add(background); ShaderNode *out = graph->output(); diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index b6ea8054b0c..ed1b17a911d 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -90,7 +90,6 @@ class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): bl_label = "Surface" - bl_context = "world" COMPAT_ENGINES = {'BLENDER_EEVEE'} @classmethod @@ -119,13 +118,29 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel): else: layout.label(text="No output node") else: - layout.prop(world, "horizon_color", text="Color") + layout.prop(world, "color") + + +class WORLD_PT_viewport_display(WorldButtonsPanel, Panel): + bl_label = "Viewport Display" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return context.world + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + world = context.world + layout.prop(world, "color") classes = ( WORLD_PT_context_world, EEVEE_WORLD_PT_surface, EEVEE_WORLD_PT_mist, + WORLD_PT_viewport_display, WORLD_PT_custom_props, ) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index ead67814f01..f4dc07cf6c3 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -207,10 +207,10 @@ void RNA_def_world(BlenderRNA *brna) rna_def_animdata_common(srna); /* colors */ - prop = RNA_def_property(srna, "horizon_color", PROP_FLOAT, PROP_COLOR); + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "horr"); RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Horizon Color", "Color at the horizon"); + RNA_def_property_ui_text(prop, "Color", "Color of the background"); /* RNA_def_property_update(prop, 0, "rna_World_update"); */ /* render-only uses this */ RNA_def_property_update(prop, 0, "rna_World_draw_update"); -- cgit v1.2.3 From efe94793c0854454517f49f833f688e0652f4ec0 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 17 Jul 2018 13:55:43 +0200 Subject: Fix T56003: Opening image files as movies in VSE crashes. metadata loading code was assuming all videos in Blender were from FFMPEG... added empty place-holders for other types too, we probably could load some metadata from pictures or AVI files too! --- source/blender/imbuf/intern/anim_movie.c | 34 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 290226acf78..9ab2ee7dd21 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -243,21 +243,35 @@ void IMB_close_anim_proxies(struct anim *anim) struct IDProperty *IMB_anim_load_metadata(struct anim *anim) { + switch (anim->curtype) { + case ANIM_FFMPEG: + { #ifdef WITH_FFMPEG - AVDictionaryEntry *entry = NULL; + AVDictionaryEntry *entry = NULL; - BLI_assert(anim->pFormatCtx != NULL); - av_log(anim->pFormatCtx, AV_LOG_DEBUG, "METADATA FETCH\n"); + BLI_assert(anim->pFormatCtx != NULL); + av_log(anim->pFormatCtx, AV_LOG_DEBUG, "METADATA FETCH\n"); - while (true) { - entry = av_dict_get(anim->pFormatCtx->metadata, "", entry, AV_DICT_IGNORE_SUFFIX); - if (entry == NULL) break; + while (true) { + entry = av_dict_get(anim->pFormatCtx->metadata, "", entry, AV_DICT_IGNORE_SUFFIX); + if (entry == NULL) break; - /* Delay creation of the property group until there is actual metadata to put in there. */ - IMB_metadata_ensure(&anim->metadata); - IMB_metadata_set_field(anim->metadata, entry->key, entry->value); - } + /* Delay creation of the property group until there is actual metadata to put in there. */ + IMB_metadata_ensure(&anim->metadata); + IMB_metadata_set_field(anim->metadata, entry->key, entry->value); + } #endif + break; + } + case ANIM_SEQUENCE: + case ANIM_AVI: + case ANIM_MOVIE: + /* TODO */ + break; + case ANIM_NONE: + default: + break; + } return anim->metadata; } -- cgit v1.2.3 From 6d8e36b72355fd8642beca9c400388e9e2906f21 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Jul 2018 12:33:47 +0200 Subject: Fix inconsistent shade smooth naming in object and edit mode. --- release/scripts/startup/bl_ui/space_view3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 77198168dcf..2c1ee3c5338 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1548,8 +1548,8 @@ class VIEW3D_MT_object(Menu): layout.separator() - layout.operator("object.shade_smooth", text="Smooth Shading") - layout.operator("object.shade_flat", text="Flat Shading") + layout.operator("object.shade_smooth") + layout.operator("object.shade_flat") layout.separator() -- cgit v1.2.3 From 117a5c0ac75a5c96dff3873bed93bd55f76192f2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Jul 2018 14:21:16 +0200 Subject: Fix Python error removing studio lights in user preferences. --- release/scripts/startup/bl_operators/wm.py | 9 ++++++--- source/blender/makesrna/intern/rna_userdef.c | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index cfbc96696d6..3f0cdfa606b 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2499,9 +2499,12 @@ class WM_OT_studiolight_uninstall(Operator): userpref = context.user_preferences for studio_light in userpref.studio_lights: if studio_light.index == self.index: - self._remove_path(pathlib.Path(studio_light.path)) - self._remove_path(pathlib.Path(studio_light.path_irr_cache)) - self._remove_path(pathlib.Path(studio_light.path_sh_cache)) + if len(studio_light.path) > 0: + self._remove_path(pathlib.Path(studio_light.path)) + if len(studio_light.path_irr_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_irr_cache)) + if len(studio_light.path_sh_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_sh_cache)) userpref.studio_lights.remove(studio_light) return {'FINISHED'} return {'CANCELLED'} diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 5557afdb33f..a54462e6b3e 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -683,7 +683,9 @@ static void rna_UserDef_studiolight_path_irr_cache_get(PointerRNA *ptr, char *va if (sl->path_irr_cache) { BLI_strncpy(value, sl->path_irr_cache, FILE_MAX); } - value[0] = 0x00; + else { + value[0] = '\0'; + } } static int rna_UserDef_studiolight_path_irr_cache_length(PointerRNA *ptr) @@ -702,7 +704,9 @@ static void rna_UserDef_studiolight_path_sh_cache_get(PointerRNA *ptr, char *val if (sl->path_sh_cache) { BLI_strncpy(value, sl->path_sh_cache, FILE_MAX); } - value[0] = 0x00; + else { + value[0] = '\0'; + } } static int rna_UserDef_studiolight_path_sh_cache_length(PointerRNA *ptr) -- cgit v1.2.3 From f8e2dba7fe429c6e514a2f12ff35addc8f474294 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Jul 2018 13:58:08 +0200 Subject: UI: move specular light settings to Lights tab in user preferences. --- release/scripts/startup/bl_ui/space_userpref.py | 111 ++++++++++++------------ source/blender/makesrna/intern/rna_userdef.c | 6 -- 2 files changed, 55 insertions(+), 62 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e2bca0b6b33..ed0389942ad 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -28,25 +28,6 @@ from bpy.app.translations import pgettext_iface as iface_ from bpy.app.translations import contexts as i18n_contexts -def opengl_light_buttons(column, light): - split = column.row() - - split.prop(light, "use", text="", icon='OUTLINER_OB_LIGHT' if light.use else 'LIGHT_DATA') - - col = split.column() - col.active = light.use - row = col.row() - row.label(text="Diffuse:") - row.prop(light, "diffuse_color", text="") - row = col.row() - row.label(text="Specular:") - row.prop(light, "specular_color", text="") - - col = split.column() - col.active = light.use - col.prop(light, "direction", text="") - - class USERPREF_HT_header(Header): bl_space_type = 'USER_PREFERENCES' @@ -550,43 +531,25 @@ class USERPREF_PT_system(Panel): col.label(text="Text Draw Options:") col.prop(system, "use_text_antialiasing") - col.separator() - - col.label(text="Textures:") - col.prop(system, "gl_texture_limit", text="Limit Size") - col.prop(system, "texture_time_out", text="Time Out") - col.prop(system, "texture_collection_rate", text="Collection Rate") - - col.separator() - - col.label(text="Images Draw Method:") - col.prop(system, "image_draw_method", text="") - - col.separator() - - col.label(text="Sequencer/Clip Editor:") - # currently disabled in the code - # col.prop(system, "prefetch_frames") - col.prop(system, "memory_cache_limit") - # 3. Column column = split.column() - column.label(text="Solid OpenGL Lights:") + column.label(text="Textures:") + column.prop(system, "gl_texture_limit", text="Limit Size") + column.prop(system, "texture_time_out", text="Time Out") + column.prop(system, "texture_collection_rate", text="Collection Rate") - split = column.split(percentage=0.1) - split.label() - split.label(text="Colors:") - split.label(text="Direction:") + column.separator() - light = system.solid_lights[0] - opengl_light_buttons(column, light) + column.label(text="Images Draw Method:") + column.prop(system, "image_draw_method", text="") - light = system.solid_lights[1] - opengl_light_buttons(column, light) + column.separator() - light = system.solid_lights[2] - opengl_light_buttons(column, light) + column.label(text="Sequencer/Clip Editor:") + # currently disabled in the code + # column.prop(system, "prefetch_frames") + column.prop(system, "memory_cache_limit") column.separator() @@ -1596,13 +1559,6 @@ class StudioLightPanelMixin(): def _get_lights(self, userpref): return [light for light in userpref.studio_lights if light.is_user_defined and light.orientation == self.sl_orientation] - def draw_header(self, context): - layout = self.layout - row = layout.row() - userpref = context.user_preferences - lights = self._get_lights(userpref) - row.label("({})".format(len(lights))) - def draw(self, context): layout = self.layout userpref = context.user_preferences @@ -1640,6 +1596,48 @@ class USERPREF_PT_studiolight_camera(Panel, StudioLightPanelMixin): sl_orientation = 'CAMERA' +class USERPREF_PT_studiolight_specular(Panel, StudioLightPanelMixin): + bl_label = "Specular Lights" + sl_orientation = 'CAMERA' + + @classmethod + def poll(cls, context): + userpref = context.user_preferences + return (userpref.active_section == 'LIGHTS') + + def opengl_light_buttons(self, column, light): + split = column.split() + + col = split.column() + col.prop(light, "use", text="Use", icon='OUTLINER_OB_LIGHT' if light.use else 'LIGHT_DATA') + + sub = col.column() + sub.active = light.use + sub.prop(light, "specular_color") + + col = split.column() + col.active = light.use + col.prop(light, "direction", text="") + + def draw(self, context): + layout = self.layout + column = layout.split() + + userpref = context.user_preferences + system = userpref.system + + light = system.solid_lights[0] + colsplit = column.split(percentage=0.85) + self.opengl_light_buttons(colsplit, light) + + light = system.solid_lights[1] + colsplit = column.split(percentage=0.85) + self.opengl_light_buttons(colsplit, light) + + light = system.solid_lights[2] + self.opengl_light_buttons(column, light) + + classes = ( USERPREF_HT_header, USERPREF_PT_tabs, @@ -1663,6 +1661,7 @@ classes = ( USERPREF_PT_studiolight_matcaps, USERPREF_PT_studiolight_world, USERPREF_PT_studiolight_camera, + USERPREF_PT_studiolight_specular, ) if __name__ == "__main__": # only for live edit. diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index a54462e6b3e..0823e8ddd9a 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -3431,12 +3431,6 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Direction", "Direction that the OpenGL light is shining"); RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update"); - prop = RNA_def_property(srna, "diffuse_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "col"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Diffuse Color", "Diffuse color of the OpenGL light"); - RNA_def_property_update(prop, 0, "rna_UserDef_viewport_lights_update"); - prop = RNA_def_property(srna, "specular_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "spec"); RNA_def_property_array(prop, 3); -- cgit v1.2.3 From 7b3a18f0aa3ed9612aca602878a8ebdf2f1250f9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 11 Jul 2018 14:20:39 +0200 Subject: Cleanup: moving shading type into View3DShading. So all shading settings are in this struct and can be reused in the OpenGL render engine. --- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/blenloader/intern/readfile.c | 7 +- source/blender/blenloader/intern/versioning_280.c | 16 +++ source/blender/draw/engines/eevee/eevee_private.h | 2 +- source/blender/draw/intern/draw_manager.c | 10 +- source/blender/draw/modes/edit_mesh_mode.c | 2 +- source/blender/draw/modes/object_mode.c | 4 +- source/blender/editors/armature/armature_select.c | 4 +- source/blender/editors/curve/editcurve_paint.c | 2 +- source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/render/render_opengl.c | 2 +- source/blender/editors/render/render_update.c | 2 +- .../editors/sculpt_paint/paint_image_proj.c | 2 +- source/blender/editors/space_view3d/drawobject.c | 10 +- source/blender/editors/space_view3d/space_view3d.c | 11 +- source/blender/editors/space_view3d/view3d_draw.c | 2 +- .../editors/space_view3d/view3d_draw_legacy.c | 6 +- source/blender/editors/space_view3d/view3d_edit.c | 18 +-- .../editors/space_view3d/view3d_gizmo_ruler.c | 2 +- source/blender/editors/space_view3d/view3d_ruler.c | 2 +- .../blender/editors/space_view3d/view3d_select.c | 4 +- source/blender/editors/space_view3d/view3d_view.c | 6 +- source/blender/editors/transform/transform.c | 4 +- source/blender/makesdna/DNA_view3d_types.h | 10 +- source/blender/makesrna/intern/rna_space.c | 138 ++++++++++----------- 25 files changed, 145 insertions(+), 125 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6a8f46badd9..3b1416d2881 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1307,7 +1307,7 @@ static bool check_rendered_viewport_visible(Main *bmain) if (area->spacetype != SPACE_VIEW3D) { continue; } - if (v3d->drawtype == OB_RENDER) { + if (v3d->shading.type == OB_RENDER) { return true; } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f7d585e6fd7..18a6198254e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6606,9 +6606,10 @@ static void direct_link_area(FileData *fd, ScrArea *area) v3d->properties_storage = NULL; /* render can be quite heavy, set to solid on load */ - if (v3d->drawtype == OB_RENDER) - v3d->drawtype = OB_SOLID; - v3d->prev_drawtype = OB_SOLID; + if (v3d->shading.type == OB_RENDER) { + v3d->shading.type = OB_SOLID; + } + v3d->shading.prev_type = OB_SOLID; if (v3d->fx_settings.dof) v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index b854438ed47..5855b9d39de 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1599,5 +1599,21 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "short", "type")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->drawtype == OB_RENDER) { + v3d->drawtype = OB_SOLID; + } + v3d->shading.type = v3d->drawtype; + v3d->shading.prev_type = OB_SOLID; + } + } + } + } + } } } diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index e2a875dca1f..1e43d6fba08 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -96,7 +96,7 @@ extern struct DrawEngineType draw_engine_eevee_type; } ((void)0) #define OVERLAY_ENABLED(v3d) ((v3d) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) -#define LOOK_DEV_MODE_ENABLED(v3d) ((v3d) && (v3d->drawtype == OB_MATERIAL)) +#define LOOK_DEV_MODE_ENABLED(v3d) ((v3d) && (v3d->shading.type == OB_MATERIAL)) #define LOOK_DEV_OVERLAY_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && OVERLAY_ENABLED(v3d) && (v3d->overlay.flag & V3D_OVERLAY_LOOK_DEV)) #define USE_SCENE_LIGHT(v3d) ((!v3d) || (!LOOK_DEV_MODE_ENABLED(v3d)) || ((LOOK_DEV_MODE_ENABLED(v3d) && (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)))) #define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && !(v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1460f9a88f2..556f02c2899 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1200,7 +1200,7 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t Object *obact = OBACT(view_layer); const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode); View3D * v3d = DST.draw_ctx.v3d; - const int drawtype = v3d->drawtype; + const int drawtype = v3d->shading.type; drw_engines_enable_from_engine(engine_type, drawtype, v3d->shading.flag); @@ -1304,7 +1304,7 @@ void DRW_draw_view(const bContext *C) ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = DEG_get_evaluated_scene(depsgraph); - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype); + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar); /* Reset before using it. */ @@ -1499,7 +1499,7 @@ void DRW_draw_render_loop( drw_state_prepare_clean_for_draw(&DST); Scene *scene = DEG_get_evaluated_scene(depsgraph); - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype); + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, NULL); } @@ -1764,7 +1764,7 @@ void DRW_draw_select_loop( DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data) { Scene *scene = DEG_get_evaluated_scene(depsgraph); - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype); + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); Object *obact = OBACT(view_layer); Object *obedit = OBEDIT_FROM_OBACT(obact); @@ -1983,7 +1983,7 @@ void DRW_draw_depth_loop( ARegion *ar, View3D *v3d) { Scene *scene = DEG_get_evaluated_scene(depsgraph); - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->drawtype); + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = ar->regiondata; diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 1e05b154974..b402494dfb5 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -365,7 +365,7 @@ static void EDIT_MESH_cache_init(void *vedata) const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (draw_ctx->v3d->drawtype < OB_MATERIAL); + (draw_ctx->v3d->shading.type < OB_MATERIAL); stl->g_data->do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0) || xray_enabled; { diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 43400b3bac0..386261b64d7 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -907,7 +907,7 @@ static void OBJECT_cache_init(void *vedata) OBJECT_PrivateData *g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (draw_ctx->v3d->drawtype < OB_MATERIAL); + (draw_ctx->v3d->shading.type < OB_MATERIAL); /* TODO : use dpi setting for enabling the second pass */ const bool do_outline_expand = false; @@ -2337,7 +2337,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) { struct Gwn_Batch *geom; const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (v3d->drawtype < OB_MATERIAL); + (v3d->shading.type < OB_MATERIAL); if (xray_enabled) { geom = DRW_cache_object_edge_detection_get(ob, NULL); } diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index ae2e7339c66..7602bccc48c 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -426,7 +426,7 @@ static EditBone *get_nearest_editbonepoint( if (use_cycle) { static int last_mval[2] = {-100, -100}; - if (vc->v3d->drawtype > OB_WIRE) { + if (vc->v3d->shading.type > OB_WIRE) { do_nearest = true; if (len_manhattan_v2v2_int(vc->mval, last_mval) < 3) { do_nearest = false; @@ -435,7 +435,7 @@ static EditBone *get_nearest_editbonepoint( copy_v2_v2_int(last_mval, vc->mval); } else { - if (vc->v3d->drawtype > OB_WIRE) { + if (vc->v3d->shading.type > OB_WIRE) { do_nearest = true; } } diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 130e3cc5475..927b8b8514d 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -1095,7 +1095,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) } else { if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) && - (v3d->drawtype > OB_WIRE)) + (v3d->shading.type > OB_WIRE)) { /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index efcf5978968..516b121031e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -523,7 +523,7 @@ void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *a void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *sa); #define V3D_IS_ZBUF(v3d) \ - (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE)) + (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->shading.type > OB_WIRE)) void ED_view3d_id_remap(struct View3D *v3d, const struct ID *old_id, struct ID *new_id); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 1b8d8cf7af2..22000bd2a03 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -355,7 +355,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (view_context) { ibuf_view = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, v3d->drawtype, + depsgraph, scene, v3d->shading.type, v3d, ar, sizex, sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, oglrender->ofs, err_out); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index e473b98b4a1..09d89e3b90f 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -144,7 +144,7 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update } else { RenderEngineType *engine_type = - ED_view3d_engine_type(scene, v3d->drawtype); + ED_view3d_engine_type(scene, v3d->shading.type); if (updated) { DRW_notify_view_update( (&(DRWUpdateContext){ diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 04329697b54..7badd30e6d0 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -5442,7 +5442,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, v3d->drawtype, + depsgraph, scene, v3d->shading.type, v3d, CTX_wm_region(C), w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, NULL, err_out); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index f48d7ef578f..a6714927249 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -121,10 +121,10 @@ int view3d_effective_drawtype(const struct View3D *v3d) { - if (v3d->drawtype == OB_RENDER) { - return v3d->prev_drawtype; + if (v3d->shading.type == OB_RENDER) { + return v3d->shading.prev_type; } - return v3d->drawtype; + return v3d->shading.type; } static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) @@ -139,10 +139,10 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return true; /* if its drawing textures with zbuf sel, then don't draw dots */ - if (dt == OB_TEXTURE && vd->drawtype == OB_TEXTURE) + if (dt == OB_TEXTURE && vd->shading.type == OB_TEXTURE) return false; - if ((vd->drawtype >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX)) + if ((vd->shading.type >= OB_SOLID) && (vd->flag2 & V3D_SOLID_TEX)) return false; return true; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 75c9b4a050f..188ee928f3c 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -293,7 +293,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) { wmWindowManager *wm = bmain->wm.first; - if (v3d->drawtype != OB_RENDER) { + if (v3d->shading.type != OB_RENDER) { ARegion *ar; for (ar = sa->regionbase.first; ar; ar = ar->next) { @@ -324,7 +324,8 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) v3d->grid = 1.0f; v3d->gridlines = 16; v3d->gridsubdiv = 10; - v3d->drawtype = OB_SOLID; + v3d->shading.type = OB_SOLID; + v3d->shading.prev_type = OB_SOLID; v3d->shading.flag = V3D_SHADING_SPECULAR_HIGHLIGHT; v3d->shading.light = V3D_LIGHTING_STUDIO; v3d->shading.shadow_intensity = 0.5f; @@ -431,8 +432,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) v3dn->lay = v3do->localvd->lay & 0xFFFFFF; } - if (v3dn->drawtype == OB_RENDER) - v3dn->drawtype = OB_SOLID; + if (v3dn->shading.type == OB_RENDER) + v3dn->shading.type = OB_SOLID; /* copy or clear inside new stuff */ @@ -1421,7 +1422,7 @@ static void space_view3d_listener( case NC_MATERIAL: switch (wmn->data) { case ND_NODES: - if (v3d->drawtype == OB_TEXTURE) + if (v3d->shading.type == OB_TEXTURE) ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 4928f6e1f28..e03fe149af6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1589,7 +1589,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( v3d.camera = camera; v3d.lay = scene->lay; - v3d.drawtype = drawtype; + v3d.shading.type = drawtype; v3d.flag2 = V3D_RENDER_OVERRIDE; if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) { diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index cc7f23e2c18..94cd4dfc73d 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -179,7 +179,7 @@ static void backdrawview3d( } /* texture paint mode sampling */ else if (obact_eval && (obact_eval->mode & OB_MODE_TEXTURE_PAINT) && - (v3d->drawtype > OB_WIRE)) + (v3d->shading.type > OB_WIRE)) { /* do nothing */ } @@ -211,7 +211,7 @@ static void backdrawview3d( #endif #if 0 /* v3d->zbuf deprecated */ - if (v3d->drawtype > OB_WIRE) v3d->zbuf = true; + if (v3d->shading.type > OB_WIRE) v3d->zbuf = true; #endif /* dithering and AA break color coding, so disable */ @@ -1033,7 +1033,7 @@ bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View bool use_border; /* test if there is a 3d view rendering */ - if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene)) + if (v3d->shading.type != OB_RENDER || !view3d_main_region_do_render_draw(scene)) return false; /* test if there is a border render */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 792a341fba4..2cc1236e5c6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4873,7 +4873,7 @@ static int toggle_shading_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (type == OB_SOLID) { - if (v3d->drawtype == OB_SOLID) { + if (v3d->shading.type == OB_SOLID) { /* Toggle X-Ray if already in solid mode. */ if (ED_operator_posemode(C) || ED_operator_editmesh(C)) { v3d->flag ^= V3D_ZBUF_SELECT; @@ -4884,24 +4884,24 @@ static int toggle_shading_exec(bContext *C, wmOperator *op) } else { /* Go to solid mode. */ - v3d->drawtype = OB_SOLID; + v3d->shading.type = OB_SOLID; } } else if (type == OB_MATERIAL) { - if (v3d->drawtype == OB_MATERIAL) { - v3d->drawtype = OB_SOLID; + if (v3d->shading.type == OB_MATERIAL) { + v3d->shading.type = OB_SOLID; } else { - v3d->drawtype = OB_MATERIAL; + v3d->shading.type = OB_MATERIAL; } } else if (type == OB_RENDER) { - if (v3d->drawtype == OB_RENDER) { - v3d->drawtype = v3d->prev_drawtype; + if (v3d->shading.type == OB_RENDER) { + v3d->shading.type = v3d->shading.prev_type; } else { - v3d->prev_drawtype = v3d->drawtype; - v3d->drawtype = OB_RENDER; + v3d->shading.prev_type = v3d->shading.type; + v3d->shading.type = OB_RENDER; } } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index db7ba040b3b..e9a8dd5ee08 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -1052,7 +1052,7 @@ static int view3d_ruler_add_invoke(bContext *C, wmOperator *UNUSED(op), const wm wmGizmoMap *gzmap = ar->gizmo_map; wmGizmoGroup *gzgroup = WM_gizmomap_group_find(gzmap, view3d_gzgt_ruler_id); - const bool use_depth = (v3d->drawtype >= OB_SOLID); + const bool use_depth = (v3d->shading.type >= OB_SOLID); /* Create new line */ RulerItem *ruler_item; diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 4617b92c780..133af8e6da7 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -911,7 +911,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) BLI_listbase_is_empty(&ruler_info->items)) { View3D *v3d = CTX_wm_view3d(C); - const bool use_depth = (v3d->drawtype >= OB_SOLID); + const bool use_depth = (v3d->shading.type >= OB_SOLID); /* Create new line */ RulerItem *ruler_item_prev = ruler_item_active_get(ruler_info); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 3175075e9c3..7da69c5b2d5 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1189,7 +1189,7 @@ static int mixed_bones_object_selectbuffer( /* define if we use solid nearest select or not */ if (use_cycle) { - if (v3d->drawtype > OB_WIRE) { + if (v3d->shading.type > OB_WIRE) { do_nearest = true; if (len_manhattan_v2v2_int(mval, last_mval) < 3) { do_nearest = false; @@ -1198,7 +1198,7 @@ static int mixed_bones_object_selectbuffer( copy_v2_v2_int(last_mval, mval); } else { - if (v3d->drawtype > OB_WIRE) { + if (v3d->shading.type > OB_WIRE) { do_nearest = true; } } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index bb0745b1998..8a4a0efad2a 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -184,7 +184,7 @@ void ED_view3d_smooth_view_ex( } /* skip smooth viewing for render engine draw */ - if (smooth_viewtx && v3d->drawtype != OB_RENDER) { + if (smooth_viewtx && v3d->shading.type != OB_RENDER) { bool changed = false; /* zero means no difference */ if (sview->camera_old != sview->camera) @@ -1003,7 +1003,7 @@ int view3d_opengl_select( * the object & bone view locking takes 'rect' into account, see: T51629. */ ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect); - if (v3d->drawtype > OB_WIRE) { + if (v3d->shading.type > OB_WIRE) { GPU_depth_test(true); } @@ -1048,7 +1048,7 @@ int view3d_opengl_select( G.f &= ~G_PICKSEL; ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL); - if (v3d->drawtype > OB_WIRE) { + if (v3d->shading.type > OB_WIRE) { GPU_depth_test(false); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c49c9a8706c..e9abdd80d20 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -6654,7 +6654,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *t if (t->spacetype == SPACE_VIEW3D) { v3d = t->sa ? t->sa->spacedata.first : NULL; rv3d = t->ar ? t->ar->regiondata : NULL; - use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); + use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->shading.type > OB_WIRE); } calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, true); @@ -6849,7 +6849,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *t if (t->spacetype == SPACE_VIEW3D) { v3d = t->sa ? t->sa->spacedata.first : NULL; rv3d = t->ar ? t->ar->regiondata : NULL; - use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); + use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE && v3d->shading.type > OB_WIRE); } calcEdgeSlide_mval_range(t, tc, sld, sv_table, loop_nr, mval, use_occlude_geometry, false); diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 8abec3474f9..fedc604f120 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -135,11 +135,14 @@ typedef struct View3DCursor { /* 3D Viewport Shading setings */ typedef struct View3DShading { + short type; /* Shading type (VIEW3D_SHADE_SOLID, ..) */ + short prev_type; /* Runtime, for toggle between rendered viewport. */ + short flag; short color_type; short light; - char pad[2]; + short pad[3]; char studio_light[256]; /* FILE_MAXFILE */ char matcap[256]; /* FILE_MAXFILE */ @@ -267,9 +270,8 @@ typedef struct View3D { float stereo3d_convergence_alpha; /* Display settings */ - short drawtype; /* Shading mode (OB_SOLID, OB_TEXTURE, ..) */ - short prev_drawtype; /* Runtime, for toggle between rendered viewport. */ - int pad5; + short drawtype DNA_DEPRECATED; + short pad5[3]; View3DShading shading; View3DOverlay overlay; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index d7024a149a3..66ff29a8c16 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -581,14 +581,6 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin DEG_on_visible_update(bmain, false); } -static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) -{ - View3D *v3d = (View3D *)(ptr->data); - ScrArea *sa = rna_area_from_space(ptr); - - ED_view3d_shade_update(bmain, v3d, sa); -} - static PointerRNA rna_SpaceView3D_region_3d_get(PointerRNA *ptr) { View3D *v3d = (View3D *)(ptr->data); @@ -685,29 +677,46 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value ED_view3d_from_m4(mat, rv3d->ofs, rv3d->viewquat, &rv3d->dist); } +static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +{ + bScreen *screen = ptr->id.data; + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (&v3d->shading == ptr->data) { + ED_view3d_shade_update(bmain, v3d, sa); + return; + } + } + } + } +} + static int rna_3DViewShading_type_get(PointerRNA *ptr) { bScreen *screen = ptr->id.data; Scene *scene = WM_windows_scene_get_from_screen(G_MAIN->wm.first, screen); RenderEngineType *type = RE_engines_find(scene->r.engine); - View3D *v3d = (View3D *)ptr->data; + View3DShading *shading = (View3DShading *)ptr->data; - if (!BKE_scene_uses_blender_eevee(scene) && v3d->drawtype == OB_RENDER) { + if (!BKE_scene_uses_blender_eevee(scene) && shading->type == OB_RENDER) { if (!(type && type->view_draw)) { return OB_MATERIAL; } } - return v3d->drawtype; + return shading->type; } static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) { - View3D *v3d = (View3D *)ptr->data; - if (value != v3d->drawtype && value == OB_RENDER) { - v3d->prev_drawtype = v3d->drawtype; + View3DShading *shading = (View3DShading *)ptr->data; + if (value != shading->type && value == OB_RENDER) { + shading->prev_type = shading->type; } - v3d->drawtype = value; + shading->type = value; } static const EnumPropertyItem *rna_3DViewShading_type_itemf( @@ -743,13 +752,13 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf( /* Shading.selected_studio_light */ static PointerRNA rna_View3DShading_selected_studio_light_get(PointerRNA *ptr) { - View3D *v3d = (View3D *)ptr->data; + View3DShading *shading = (View3DShading *)ptr->data; StudioLight *sl; - if (v3d->drawtype == OB_SOLID && v3d->shading.light == V3D_LIGHTING_MATCAP) { - sl = BKE_studiolight_find(v3d->shading.matcap, STUDIOLIGHT_FLAG_ALL); + if (shading->type == OB_SOLID && shading->light == V3D_LIGHTING_MATCAP) { + sl = BKE_studiolight_find(shading->matcap, STUDIOLIGHT_FLAG_ALL); } else { - sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_FLAG_ALL); + sl = BKE_studiolight_find(shading->studio_light, STUDIOLIGHT_FLAG_ALL); } return rna_pointer_inherit_refine(ptr, &RNA_StudioLight, sl); } @@ -757,33 +766,33 @@ static PointerRNA rna_View3DShading_selected_studio_light_get(PointerRNA *ptr) /* shading.light */ static int rna_View3DShading_light_get(PointerRNA *ptr) { - View3D *v3d = (View3D *)ptr->data; - return v3d->shading.light; + View3DShading *shading = (View3DShading *)ptr->data; + return shading->light; } static void rna_View3DShading_light_set(PointerRNA *ptr, int value) { - View3D *v3d = (View3D *)ptr->data; - if (value == V3D_LIGHTING_MATCAP && v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) { - v3d->shading.color_type = V3D_SHADING_MATERIAL_COLOR; + View3DShading *shading = (View3DShading *)ptr->data; + if (value == V3D_LIGHTING_MATCAP && shading->color_type == V3D_SHADING_TEXTURE_COLOR) { + shading->color_type = V3D_SHADING_MATERIAL_COLOR; } - v3d->shading.light = value; + shading->light = value; } static const EnumPropertyItem *rna_View3DShading_color_type_itemf( bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { - View3D *v3d = (View3D *)ptr->data; + View3DShading *shading = (View3DShading *)ptr->data; int totitem = 0; EnumPropertyItem *item = NULL; - if (v3d->drawtype == OB_SOLID) { + if (shading->type == OB_SOLID) { RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_SINGLE_COLOR); RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_MATERIAL_COLOR); RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_RANDOM_COLOR); - if (v3d->shading.light != V3D_LIGHTING_MATCAP) { + if (shading->light != V3D_LIGHTING_MATCAP) { RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_color_type_items, V3D_SHADING_TEXTURE_COLOR); } } @@ -796,15 +805,15 @@ static const EnumPropertyItem *rna_View3DShading_color_type_itemf( /* Studio light */ static int rna_View3DShading_studio_light_get(PointerRNA *ptr) { - View3D *v3d = (View3D *)ptr->data; - char *dna_storage = v3d->shading.studio_light; + View3DShading *shading = (View3DShading *)ptr->data; + char *dna_storage = shading->studio_light; int flag = STUDIOLIGHT_ORIENTATIONS_SOLID; - if (v3d->drawtype == OB_SOLID && v3d->shading.light == V3D_LIGHTING_MATCAP) { + if (shading->type == OB_SOLID && shading->light == V3D_LIGHTING_MATCAP) { flag = STUDIOLIGHT_ORIENTATION_VIEWNORMAL; - dna_storage = v3d->shading.matcap; + dna_storage = shading->matcap; } - else if (v3d->drawtype == OB_MATERIAL) { + else if (shading->type == OB_MATERIAL) { flag = STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE; } StudioLight *sl = BKE_studiolight_find(dna_storage, flag); @@ -819,15 +828,15 @@ static int rna_View3DShading_studio_light_get(PointerRNA *ptr) static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value) { - View3D *v3d = (View3D *)ptr->data; - char *dna_storage = v3d->shading.studio_light; + View3DShading *shading = (View3DShading *)ptr->data; + char *dna_storage = shading->studio_light; int flag = STUDIOLIGHT_ORIENTATIONS_SOLID; - if (v3d->drawtype == OB_SOLID && v3d->shading.light == V3D_LIGHTING_MATCAP) { + if (shading->type == OB_SOLID && shading->light == V3D_LIGHTING_MATCAP) { flag = STUDIOLIGHT_ORIENTATION_VIEWNORMAL; - dna_storage = v3d->shading.matcap; + dna_storage = shading->matcap; } - else if (v3d->drawtype == OB_MATERIAL) { + else if (shading->type == OB_MATERIAL) { flag = STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE; } StudioLight *sl = BKE_studiolight_findindex(value, flag); @@ -840,15 +849,15 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { - View3D *v3d = (View3D *)ptr->data; + View3DShading *shading = (View3DShading *)ptr->data; EnumPropertyItem *item = NULL; int totitem = 0; - if (v3d->drawtype == OB_SOLID && v3d->shading.light == V3D_LIGHTING_MATCAP) { + if (shading->type == OB_SOLID && shading->light == V3D_LIGHTING_MATCAP) { const int flags = (STUDIOLIGHT_EXTERNAL_FILE | STUDIOLIGHT_ORIENTATION_VIEWNORMAL); LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) { - int icon_id = (v3d->shading.flag & V3D_SHADING_MATCAP_FLIP_X) ? sl->icon_id_matcap_flipped: sl->icon_id_matcap; + int icon_id = (shading->flag & V3D_SHADING_MATCAP_FLIP_X) ? sl->icon_id_matcap_flipped: sl->icon_id_matcap; if ((sl->flag & flags) == flags) { EnumPropertyItem tmp = {sl->index, sl->name, icon_id, sl->name, ""}; RNA_enum_item_add(&item, &totitem, &tmp); @@ -862,12 +871,12 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf( if (sl->flag & STUDIOLIGHT_INTERNAL) { /* always show internal lights for solid */ - if (v3d->drawtype == OB_SOLID) { + if (shading->type == OB_SOLID) { show_studiolight = true; } } else { - switch (v3d->drawtype) { + switch (shading->type) { case OB_SOLID: case OB_TEXTURE: show_studiolight = ( @@ -914,11 +923,6 @@ static int rna_SpaceView3D_icon_from_show_object_viewport_get(PointerRNA *ptr) return ICON_VIS_SEL_11 + (view_value << 1) + select_value; } -static PointerRNA rna_SpaceView3D_shading_get(PointerRNA *ptr) -{ - return rna_pointer_inherit_refine(ptr, &RNA_View3DShading, ptr->data); -} - static char *rna_View3DShading_path(PointerRNA *UNUSED(ptr)) { return BLI_sprintfN("shading"); @@ -2398,13 +2402,10 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "View3DShading", NULL); - RNA_def_struct_sdna(srna, "View3D"); - RNA_def_struct_nested(brna, srna, "SpaceView3D"); RNA_def_struct_path_func(srna, "rna_View3DShading_path"); RNA_def_struct_ui_text(srna, "3D View Shading Settings", "Settings for shading in the 3D viewport"); prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "drawtype"); RNA_def_property_enum_items(prop, rna_enum_shading_type_items); RNA_def_property_enum_funcs(prop, "rna_3DViewShading_type_get", "rna_3DViewShading_type_set", "rna_3DViewShading_type_itemf"); @@ -2412,14 +2413,14 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update"); prop = RNA_def_property(srna, "light", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "shading.light"); + RNA_def_property_enum_sdna(prop, NULL, "light"); RNA_def_property_enum_items(prop, rna_enum_viewport_lighting_items); RNA_def_property_enum_funcs(prop, "rna_View3DShading_light_get", "rna_View3DShading_light_set", NULL); RNA_def_property_ui_text(prop, "Lighting", "Lighting Method for Solid/Texture Viewport Shading"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_object_outline", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_OBJECT_OUTLINE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_OBJECT_OUTLINE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Outline", "Show Object Outline"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); @@ -2432,13 +2433,13 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_cavity", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_CAVITY); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_CAVITY); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Cavity", "Show Cavity"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "cavity_ridge_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shading.cavity_ridge_factor"); + RNA_def_property_float_sdna(prop, NULL, "cavity_ridge_factor"); RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Ridge", "Factor for the ridges"); RNA_def_property_range(prop, 0.0f, 250.0f); @@ -2447,7 +2448,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "cavity_valley_factor", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shading.cavity_valley_factor"); + RNA_def_property_float_sdna(prop, NULL, "cavity_valley_factor"); RNA_def_property_float_default(prop, 1.0); RNA_def_property_ui_text(prop, "Valley", "Factor for the valleys"); RNA_def_property_range(prop, 0.0f, 250.0f); @@ -2464,7 +2465,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_define_verify_sdna(1); prop = RNA_def_property(srna, "studiolight_rotate_z", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_float_sdna(prop, NULL, "shading.studiolight_rot_z"); + RNA_def_property_float_sdna(prop, NULL, "studiolight_rot_z"); RNA_def_property_float_default(prop, 0.0); RNA_def_property_ui_text(prop, "Studiolight Rotation", "Rotation of the studiolight around the Z-Axis"); RNA_def_property_range(prop, -M_PI, M_PI); @@ -2472,33 +2473,33 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "color_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "shading.color_type"); + RNA_def_property_enum_sdna(prop, NULL, "color_type"); RNA_def_property_enum_items(prop, rna_enum_shading_color_type_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_View3DShading_color_type_itemf"); RNA_def_property_ui_text(prop, "Color", "Color Type"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "single_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "shading.single_color"); + RNA_def_property_float_sdna(prop, NULL, "single_color"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Color", "Color for single color mode"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_shadows", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_SHADOW); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SHADOW); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Shadow", "Show Shadow"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_xray", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_XRAY); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_XRAY); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "X-Ray", "Show whole scene transparent"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "xray_alpha", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shading.xray_alpha"); + RNA_def_property_float_sdna(prop, NULL, "xray_alpha"); RNA_def_property_float_default(prop, 0.5); RNA_def_property_ui_text(prop, "X-Ray Alpha", "Amount of alpha to use"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -2506,32 +2507,32 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "use_scene_lights", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_SCENE_LIGHTS); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SCENE_LIGHTS); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Scene Lights", "Render lights and light probes of the scene"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "use_scene_world", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_SCENE_WORLD); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SCENE_WORLD); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Scene World", "Use scene world for lighting"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_specular_highlight", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_SPECULAR_HIGHLIGHT); + RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SPECULAR_HIGHLIGHT); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Specular Highlights", "Render specular highlights"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "object_outline_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "shading.object_outline_color"); + RNA_def_property_float_sdna(prop, NULL, "object_outline_color"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Outline Color", "Color for object outline"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "shadow_intensity", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shading.shadow_intensity"); + RNA_def_property_float_sdna(prop, NULL, "shadow_intensity"); RNA_def_property_float_default(prop, 0.5); RNA_def_property_ui_text(prop, "Shadow Intensity", "Darkness of shadows"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -2540,7 +2541,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "studiolight_background_alpha", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, NULL, "shading.studiolight_background"); + RNA_def_property_float_sdna(prop, NULL, "studiolight_background"); RNA_def_property_float_default(prop, 0.0); RNA_def_property_ui_text(prop, "Background", "Show the studiolight in the background"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -3134,7 +3135,6 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "View3DShading"); - RNA_def_property_pointer_funcs(prop, "rna_SpaceView3D_shading_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Shading Settings", "Settings for shading in the 3D viewport"); prop = RNA_def_property(srna, "overlay", PROP_POINTER, PROP_NONE); -- cgit v1.2.3 From 43ac0f38d72a33cf6721909f3f671ac2dac6ffe3 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Tue, 17 Jul 2018 18:57:22 +0530 Subject: Fix weld incoherent normals with weld operation --- source/blender/bmesh/tools/bmesh_bevel.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index c8a82eac743..8a72ffc775f 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -4069,6 +4069,13 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv) flag_out_edge(bm, bme); } } + else if (bp->faceHash) { + BMFace *f; + BMIter fiter; + BM_ITER_ELEM(f, &fiter, bv->v, BM_FACES_OF_VERT) { + BLI_ghash_insert(bp->faceHash, f, NULL); + } + } } /* Given that the boundary is built, now make the actual BMVerts -- cgit v1.2.3 From 644fadf2f0131f8ecd73da6c994ec8a8d4b0a7d1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 11 Jul 2018 11:43:56 +0200 Subject: Render: add "OpenGL" render engine. This is intended for quick renders for previsualization, animation previews or sequencer previews. It provides the same settings as found in the 3D view Shading popover in solid display mode, but in the scene render properties. The "Workbench" engine was removed, and this name no longer appears in the user interface, it's purely an internal name. We might come up with a better name for this OpenGL engine still, but it's good to be consistent with the OpenGL Render operator name since this has a similar purpose. --- .../startup/bl_ui/properties_data_armature.py | 2 +- .../scripts/startup/bl_ui/properties_data_bone.py | 2 +- .../startup/bl_ui/properties_data_camera.py | 22 +-- .../scripts/startup/bl_ui/properties_data_curve.py | 4 +- .../startup/bl_ui/properties_data_lattice.py | 2 +- .../scripts/startup/bl_ui/properties_data_light.py | 77 +-------- .../scripts/startup/bl_ui/properties_data_mesh.py | 22 ++- .../startup/bl_ui/properties_data_metaball.py | 4 +- .../startup/bl_ui/properties_data_speaker.py | 10 +- .../scripts/startup/bl_ui/properties_material.py | 4 +- release/scripts/startup/bl_ui/properties_object.py | 2 +- .../scripts/startup/bl_ui/properties_particle.py | 90 +++++------ .../startup/bl_ui/properties_physics_cloth.py | 12 +- .../startup/bl_ui/properties_physics_common.py | 2 +- .../bl_ui/properties_physics_dynamicpaint.py | 18 +-- .../startup/bl_ui/properties_physics_field.py | 10 +- .../startup/bl_ui/properties_physics_rigidbody.py | 6 +- .../properties_physics_rigidbody_constraint.py | 2 +- .../startup/bl_ui/properties_physics_smoke.py | 16 +- .../startup/bl_ui/properties_physics_softbody.py | 14 +- release/scripts/startup/bl_ui/properties_render.py | 83 ++++++++-- release/scripts/startup/bl_ui/properties_scene.py | 30 ++-- .../scripts/startup/bl_ui/properties_texture.py | 38 ++--- .../scripts/startup/bl_ui/properties_view_layer.py | 2 +- release/scripts/startup/bl_ui/properties_world.py | 4 +- release/scripts/startup/bl_ui/space_sequencer.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 29 ++-- source/blender/blenkernel/BKE_scene.h | 1 + source/blender/blenkernel/BKE_screen.h | 3 + source/blender/blenkernel/intern/scene.c | 13 +- source/blender/blenkernel/intern/screen.c | 18 ++- source/blender/blenloader/intern/versioning_280.c | 6 + source/blender/draw/CMakeLists.txt | 1 + source/blender/draw/engines/workbench/solid_mode.c | 10 +- .../draw/engines/workbench/workbench_data.c | 42 ++--- .../draw/engines/workbench/workbench_deferred.c | 9 ++ .../draw/engines/workbench/workbench_effect_aa.c | 20 ++- .../draw/engines/workbench/workbench_effect_taa.c | 16 +- .../draw/engines/workbench/workbench_engine.c | 12 +- .../draw/engines/workbench/workbench_engine.h | 2 +- .../draw/engines/workbench/workbench_private.h | 15 +- .../draw/engines/workbench/workbench_render.c | 172 +++++++++++++++++++++ source/blender/draw/intern/DRW_render.h | 1 + source/blender/draw/intern/draw_cache.c | 30 ++++ source/blender/draw/intern/draw_cache.h | 1 + source/blender/draw/intern/draw_manager.c | 25 ++- source/blender/editors/space_view3d/space_view3d.c | 10 +- source/blender/makesdna/DNA_scene_types.h | 5 +- source/blender/makesrna/intern/rna_scene.c | 4 + source/blender/makesrna/intern/rna_space.c | 48 ++++-- 50 files changed, 655 insertions(+), 318 deletions(-) create mode 100644 source/blender/draw/engines/workbench/workbench_render.c diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index 6cfc4b6ea3f..63d80638ae2 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -328,7 +328,7 @@ class DATA_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit from class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Armature diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index cc593fbb0a2..6d364ee6539 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -402,7 +402,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 4730fc56602..f66419a7f8e 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -39,7 +39,7 @@ class CAMERA_PT_presets(PresetMenu): preset_subdir = "camera" preset_operator = "script.execute_preset" preset_add_operator = "camera.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class SAFE_AREAS_PT_presets(PresetMenu): @@ -47,13 +47,13 @@ class SAFE_AREAS_PT_presets(PresetMenu): preset_subdir = "safe_areas" preset_operator = "script.execute_preset" preset_add_operator = "safe_areas.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -70,7 +70,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -111,7 +111,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): sub = col.column(align=True) sub.prop(ccam, "longitude_min", text="Longiture Min") sub.prop(ccam, "longitude_max", text="Max") - elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE'}: + elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}: if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': @@ -133,7 +133,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -181,7 +181,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): CAMERA_PT_presets.draw_panel_header(self.layout) @@ -264,7 +264,7 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): bl_label = "Background Images" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cam = context.camera @@ -365,7 +365,7 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -398,7 +398,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): bl_label = "Safe Areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cam = context.camera @@ -417,7 +417,7 @@ class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Camera diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index c0ab9da949f..4002568fb7d 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -135,7 +135,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -459,7 +459,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Curve diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py index 40e82bc0a52..9aa8a4dee64 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -85,7 +85,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Lattice diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index a92414c0e7c..f5c985f2abe 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -36,7 +36,7 @@ class DataButtonsPanel: class DATA_PT_context_light(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -62,7 +62,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel): class DATA_PT_light(DataButtonsPanel, Panel): bl_label = "Light" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -71,38 +71,6 @@ class DATA_PT_light(DataButtonsPanel, Panel): layout.row().prop(light, "type", expand=True) - layout.use_property_split = True - - col = col.column() - col.prop(light, "color") - col.prop(light, "energy") - - if light.type in {'POINT', 'SPOT'}: - - col = col.column() - col.label(text="Falloff") - col.prop(light, "falloff_type") - col.prop(light, "distance") - col.prop(light, "shadow_soft_size") - - if light.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED': - sub = col.column(align=True) - sub.prop(light, "linear_attenuation", slider=True, text="Linear") - sub.prop(light, "quadratic_attenuation", slider=True, text="Quadratic") - - elif light.falloff_type == 'INVERSE_COEFFICIENTS': - col.label(text="Inverse Coefficients") - sub = col.column(align=True) - sub.prop(light, "constant_coefficient", text="Constant") - sub.prop(light, "linear_coefficient", text="Linear") - sub.prop(light, "quadratic_coefficient", text="Quadratic") - - if light.type == 'AREA': - col.prop(light, "distance") - - col = split.column() - col.label() - class DATA_PT_EEVEE_light(DataButtonsPanel, Panel): bl_label = "Light" @@ -234,7 +202,7 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel): class DATA_PT_area(DataButtonsPanel, Panel): bl_label = "Area Shape" - COMPAT_ENGINES = {'BLENDER_RENDER'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -258,45 +226,10 @@ class DATA_PT_area(DataButtonsPanel, Panel): sub.prop(light, "size_y", text="Size Y") -class DATA_PT_spot(DataButtonsPanel, Panel): - bl_label = "Spot Shape" - COMPAT_ENGINES = {'BLENDER_RENDER'} - - @classmethod - def poll(cls, context): - light = context.light - engine = context.engine - return (light and light.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - light = context.light - - split = layout.split() - - col = split.column() - sub = col.column() - sub.prop(light, "spot_size", text="Size") - sub.prop(light, "spot_blend", text="Blend", slider=True) - col.prop(light, "use_square") - col.prop(light, "show_cone") - - col = split.column() - - col.active = (light.shadow_method != 'BUFFER_SHADOW' or light.shadow_buffer_type != 'DEEP') - col.prop(light, "use_halo") - sub = col.column(align=True) - sub.active = light.use_halo - sub.prop(light, "halo_intensity", text="Intensity") - if light.shadow_method == 'BUFFER_SHADOW': - sub.prop(light, "halo_step", text="Step") - - class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" bl_parent_id = "DATA_PT_EEVEE_light" - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -337,7 +270,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Light diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index e8015327c1d..214852cc826 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -24,7 +24,6 @@ from rna_prop_ui import PropertyPanel class MESH_MT_vertex_group_specials(Menu): bl_label = "Vertex Group Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -48,7 +47,6 @@ class MESH_MT_vertex_group_specials(Menu): class MESH_MT_shape_key_specials(Menu): bl_label = "Shape Key Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} def draw(self, context): layout = self.layout @@ -137,7 +135,7 @@ class MeshButtonsPanel: class DATA_PT_context_mesh(MeshButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -154,7 +152,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -174,7 +172,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): class DATA_PT_texture_space(MeshButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -194,7 +192,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -241,7 +239,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -283,7 +281,7 @@ class DATA_PT_face_maps(MeshButtonsPanel, Panel): class DATA_PT_shape_keys(MeshButtonsPanel, Panel): bl_label = "Shape Keys" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -373,7 +371,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): class DATA_PT_uv_texture(MeshButtonsPanel, Panel): bl_label = "UV Maps" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -392,7 +390,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): bl_label = "Vertex Colors" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -412,7 +410,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel): class DATA_PT_customdata(MeshButtonsPanel, Panel): bl_label = "Geometry Data" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -439,7 +437,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Mesh diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index 2a61e6cda79..75015a57f5f 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -71,7 +71,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -125,7 +125,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.MetaBall diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 2a3dc4d02c1..d7c93095489 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -36,7 +36,7 @@ class DataButtonsPanel: class DATA_PT_context_speaker(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -55,7 +55,7 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): class DATA_PT_speaker(DataButtonsPanel, Panel): bl_label = "Sound" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -76,7 +76,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel): class DATA_PT_distance(DataButtonsPanel, Panel): bl_label = "Distance" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -99,7 +99,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel): class DATA_PT_cone(DataButtonsPanel, Panel): bl_label = "Cone" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -121,7 +121,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel): class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object.data" _property_type = bpy.types.Speaker diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index b601922e944..0e3e50b3497 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -73,7 +73,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "material" _property_type = bpy.types.Material @@ -82,7 +82,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): bl_label = "" bl_context = "material" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 63b708ae059..64bc8d52068 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -359,7 +359,7 @@ class OBJECT_PT_onion_skinning(OnionSkinButtonsPanel): # , Panel): # inherit fr class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "object" _property_type = bpy.types.Object diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 05538e71faf..9d891a07989 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -67,7 +67,7 @@ def particle_get_settings(context): class PARTICLE_MT_specials(Menu): bl_label = "Particle Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -88,7 +88,7 @@ class PARTICLE_PT_hair_dynamics_presets(PresetMenu): preset_subdir = "hair_dynamics" preset_operator = "script.execute_preset" preset_add_operator = "particle.hair_dynamics_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} class ParticleButtonsPanel: @@ -132,7 +132,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -235,7 +235,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): bl_label = "Emission" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -287,7 +287,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PARTICLE_PT_emission" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -325,7 +325,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): bl_label = "Hair Dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -406,7 +406,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): bl_label = "Structure" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -438,7 +438,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): bl_label = "Volume" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -470,7 +470,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): bl_label = "Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -501,7 +501,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): bl_label = "Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -550,7 +550,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -603,7 +603,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): bl_label = "Angular Velocity" bl_parent_id = "PARTICLE_PT_rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -628,7 +628,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): bl_label = "Physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -826,7 +826,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): bl_label = "Deflection" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -852,7 +852,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel): bl_label = "Forces" bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -879,7 +879,7 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): bl_label = "Integration" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -911,7 +911,7 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_label = "Boid Brain" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1015,7 +1015,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): class PARTICLE_PT_render(ParticleButtonsPanel, Panel): bl_label = "Render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1055,7 +1055,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): bl_label = "Extra" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1082,7 +1082,7 @@ class PARTICLE_PT_render_line(ParticleButtonsPanel, Panel): bl_label = "Line" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1110,7 +1110,7 @@ class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel): bl_label = "Path" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1145,7 +1145,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): bl_label = "Timing" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1177,7 +1177,7 @@ class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): bl_label = "Object" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1205,7 +1205,7 @@ class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel): bl_label = "Collection" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1237,7 +1237,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): bl_label = "Use Count" bl_parent_id = "PARTICLE_PT_render_collection" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1288,7 +1288,7 @@ class PARTICLE_PT_render_billboards_alignment(ParticleButtonsPanel, Panel): bl_label = "Billboard Alignment" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1314,7 +1314,7 @@ class PARTICLE_PT_render_billboards_tilt(ParticleButtonsPanel, Panel): bl_label = "Billboard Tilt" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1348,7 +1348,7 @@ class PARTICLE_PT_render_billboards_uv(ParticleButtonsPanel, Panel): bl_label = "Billboard UVs" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1384,7 +1384,7 @@ class PARTICLE_PT_render_trails(ParticleButtonsPanel, Panel): bl_label = "Trails" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1412,7 +1412,7 @@ class PARTICLE_PT_render_trails(ParticleButtonsPanel, Panel): class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1474,7 +1474,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): class PARTICLE_PT_children(ParticleButtonsPanel, Panel): bl_label = "Children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1530,7 +1530,7 @@ class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel): bl_label = "Parting" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1555,7 +1555,7 @@ class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel): bl_label = "Clumping" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1597,7 +1597,7 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel): bl_label = "Roughness" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1639,7 +1639,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1690,7 +1690,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): bl_label = "Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1711,7 +1711,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): bl_label = "Force Field Settings" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1727,7 +1727,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): bl_label = "Type 1" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1743,7 +1743,7 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): bl_label = "Type 2" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1760,7 +1760,7 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type1" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1775,7 +1775,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type2" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -1789,7 +1789,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): bl_label = "Vertex Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1862,7 +1862,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): bl_label = "Textures" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1894,7 +1894,7 @@ class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): bl_label = "Hair Shape" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -1921,7 +1921,7 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "particle_system.settings" _property_type = bpy.types.ParticleSettings diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 2f659af3891..7775722784b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -51,7 +51,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): CLOTH_PT_presets.draw_panel_header(self.layout) @@ -129,7 +129,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.cloth @@ -140,7 +140,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -181,7 +181,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness Scaling" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.settings @@ -215,7 +215,7 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): bl_label = "Sewing Springs" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): cloth = context.cloth.settings @@ -250,7 +250,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): cloth = context.cloth.settings diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index c9bde32c53d..bed5617c76c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -56,7 +56,7 @@ def physics_add_special(self, layout, data, name, addop, removeop, typeicon): class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): obj = context.object diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 6a66dafadf0..611f477a31b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -60,7 +60,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -129,7 +129,7 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -206,7 +206,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Output" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -300,7 +300,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Initial Color" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -337,7 +337,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Effects" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -387,7 +387,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -409,7 +409,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -463,7 +463,7 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Velocity" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -500,7 +500,7 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Waves" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 3b01015047f..1a4e24fbc0c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -38,7 +38,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_field(PhysicButtonsPanel, Panel): bl_label = "Force Fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -112,7 +112,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): bl_label = "Falloff" bl_parent_id = "PHYSICS_PT_field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -170,7 +170,7 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -199,7 +199,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): bl_label = "Particle" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -241,7 +241,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): bl_label = "Softbody" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index db59665e21d..013822793de 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -57,7 +57,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -103,7 +103,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Dynamics" bl_parent_id = 'PHYSICS_PT_rigid_body' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index aca989fd0ba..69491f36c63 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -29,7 +29,7 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py index acbaecbda4c..0a4f1c71126 100644 --- a/release/scripts/startup/bl_ui/properties_physics_smoke.py +++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py @@ -39,7 +39,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): bl_label = "Smoke" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -138,7 +138,7 @@ class PHYSICS_PT_smoke_flow_advanced(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -174,7 +174,7 @@ class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel): bl_label = "Flames" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -205,7 +205,7 @@ class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Adaptive Domain" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -240,7 +240,7 @@ class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel): bl_label = "High Resolution" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -280,7 +280,7 @@ class PHYSICS_PT_smoke_groups(PhysicButtonsPanel, Panel): bl_label = "Groups" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -309,7 +309,7 @@ class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -346,7 +346,7 @@ class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index 68db165875e..77440bdc628 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -46,7 +46,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -77,7 +77,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.soft_body @@ -88,7 +88,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Goal" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -129,7 +129,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Edges" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -180,7 +180,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collision" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): softbody = context.soft_body.settings @@ -210,7 +210,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Solver" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -244,7 +244,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index a7cfee5ed8f..b1c5edf97e7 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -21,6 +21,11 @@ import bpy from bpy.types import Menu, Panel, UIList from bl_operators.presets import PresetMenu +from .space_view3d import ( + VIEW3D_PT_shading_lighting, + VIEW3D_PT_shading_color, + VIEW3D_PT_shading_options, +) class RENDER_PT_presets(PresetMenu): @@ -79,7 +84,7 @@ class RENDER_PT_context(Panel): class RENDER_PT_dimensions(RenderButtonsPanel, Panel): bl_label = "Dimensions" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _frame_rate_args_prev = None _preset_class = None @@ -166,7 +171,7 @@ class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel): bl_label = "Time Remapping" bl_parent_id = "RENDER_PT_dimensions" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -183,7 +188,7 @@ class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel): class RENDER_PT_post_processing(RenderButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -201,7 +206,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, Panel): class RENDER_PT_stamp(RenderButtonsPanel, Panel): bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -242,7 +247,7 @@ class RENDER_PT_stamp_burn(RenderButtonsPanel, Panel): bl_label = "Burn Into Image" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): rd = context.scene.render @@ -266,7 +271,7 @@ class RENDER_PT_stamp_burn(RenderButtonsPanel, Panel): class RENDER_PT_output(RenderButtonsPanel, Panel): bl_label = "Output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -298,7 +303,7 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): class RENDER_PT_encoding(RenderButtonsPanel, Panel): bl_label = "Encoding" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): RENDER_PT_ffmpeg_presets.draw_panel_header(self.layout) @@ -395,7 +400,7 @@ class RENDER_UL_renderviews(UIList): class RENDER_PT_stereoscopy(RenderButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -777,7 +782,7 @@ class RENDER_PT_eevee_film(RenderButtonsPanel, Panel): col.prop(rd, "alpha_mode", text="Alpha") -class RENDER_PT_hair(RenderButtonsPanel, Panel): +class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): bl_label = "Hair" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_EEVEE'} @@ -798,6 +803,60 @@ class RENDER_PT_hair(RenderButtonsPanel, Panel): layout.prop(rd, "hair_subdiv") +class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): + bl_label = "Film" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + rd = context.scene.render + + layout.prop(rd, "use_antialiasing") + + layout.prop(rd, "antialiasing_samples") + layout.prop(rd, "alpha_mode") + + +class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): + bl_label = "Lighting" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_lighting.draw(self, context) + + +class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): + bl_label = "Color" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_color.draw(self, context) + + +class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): + bl_label = "Options" + COMPAT_ENGINES = {'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + VIEW3D_PT_shading_options.draw(self, context) + + classes = ( RENDER_PT_presets, RENDER_PT_ffmpeg_presets, @@ -812,7 +871,7 @@ classes = ( RENDER_PT_stamp_burn, RENDER_UL_renderviews, RENDER_PT_stereoscopy, - RENDER_PT_hair, + RENDER_PT_eevee_hair, RENDER_PT_eevee_sampling, RENDER_PT_eevee_film, RENDER_PT_eevee_shadows, @@ -824,6 +883,10 @@ classes = ( RENDER_PT_eevee_motion_blur, RENDER_PT_eevee_depth_of_field, RENDER_PT_eevee_bloom, + RENDER_PT_opengl_film, + RENDER_PT_opengl_lighting, + RENDER_PT_opengl_color, + RENDER_PT_opengl_options, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index c0b8233a796..1b21ac8fcdf 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -66,7 +66,7 @@ class SceneButtonsPanel: class SCENE_PT_scene(SceneButtonsPanel, Panel): bl_label = "Scene" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -81,7 +81,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): class SCENE_PT_unit(SceneButtonsPanel, Panel): bl_label = "Units" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header_preset(self, context): SCENE_PT_units_length_presets.draw_panel_header(self.layout) @@ -163,7 +163,7 @@ class SceneKeyingSetsPanel: class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Keying Sets" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -234,7 +234,7 @@ class SCENE_PT_keyframing_settings(SceneButtonsPanel, SceneKeyingSetsPanel, Pane class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): bl_label = "Active Keying Set" bl_parent_id = "SCENE_PT_keying_sets" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -297,7 +297,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): class SCENE_PT_color_management(SceneButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -329,7 +329,7 @@ class SCENE_PT_color_management_curves(SceneButtonsPanel, Panel): bl_label = "Use Curves" bl_parent_id = "SCENE_PT_color_management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): @@ -353,7 +353,7 @@ class SCENE_PT_color_management_curves(SceneButtonsPanel, Panel): class SCENE_PT_audio(SceneButtonsPanel, Panel): bl_label = "Audio" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -392,7 +392,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel): class SCENE_PT_physics(SceneButtonsPanel, Panel): bl_label = "Gravity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): self.layout.prop(context.scene, "use_gravity", text="") @@ -411,7 +411,7 @@ class SCENE_PT_physics(SceneButtonsPanel, Panel): class SCENE_PT_rigid_body_world(SceneButtonsPanel, Panel): bl_label = "Rigid Body World" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -479,7 +479,7 @@ class SCENE_PT_rigid_body_cache(SceneButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "SCENE_PT_rigid_body_world" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -497,7 +497,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = "SCENE_PT_rigid_body_world" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -514,7 +514,7 @@ class SCENE_PT_rigid_body_field_weights(SceneButtonsPanel, Panel): class SCENE_PT_simplify(SceneButtonsPanel, Panel): bl_label = "Simplify" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw_header(self, context): rd = context.scene.render @@ -527,7 +527,7 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): class SCENE_PT_simplify_viewport(SceneButtonsPanel, Panel): bl_label = "Viewport" bl_parent_id = "SCENE_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -549,7 +549,7 @@ class SCENE_PT_simplify_viewport(SceneButtonsPanel, Panel): class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): bl_label = "Render" bl_parent_id = "SCENE_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -569,7 +569,7 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "scene" _property_type = bpy.types.Scene diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index b3b7341a734..d937f2470b8 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -83,7 +83,7 @@ class TextureButtonsPanel: class TEXTURE_PT_preview(TextureButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -112,7 +112,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -151,7 +151,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): class TEXTURE_PT_node(TextureButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -169,7 +169,7 @@ class TEXTURE_PT_node(TextureButtonsPanel, Panel): class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): bl_label = "Mapping" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -212,7 +212,7 @@ class TextureTypePanel(TextureButtonsPanel): class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -236,7 +236,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -265,7 +265,7 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -292,7 +292,7 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -307,7 +307,7 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -325,7 +325,7 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -345,7 +345,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -475,7 +475,7 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -511,7 +511,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -547,7 +547,7 @@ class TEXTURE_PT_voronoi(TextureTypePanel, Panel): class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout @@ -567,7 +567,7 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -579,7 +579,7 @@ class TextureSlotPanel(TextureButtonsPanel): class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -657,7 +657,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -745,7 +745,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): class TEXTURE_PT_colors(TextureButtonsPanel, Panel): bl_label = "Colors" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -776,7 +776,7 @@ class TEXTURE_PT_colors(TextureButtonsPanel, Panel): class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "texture" _property_type = Texture diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index 05dc15216a2..f96bf041311 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -34,7 +34,7 @@ class ViewLayerButtonsPanel: class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): bl_label = "View Layer" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index ed1b17a911d..7395fa13d9a 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -37,7 +37,7 @@ class WorldButtonsPanel: class WORLD_PT_context_world(WorldButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): @@ -83,7 +83,7 @@ class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "world" _property_type = bpy.types.World diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 0bdfcc39ed9..5fc9be2aa5b 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1289,7 +1289,7 @@ class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsP class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "scene.sequence_editor.active_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2c1ee3c5338..e8c640721c8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3748,6 +3748,15 @@ class VIEW3D_PT_shading(Panel): bl_label = "Shading" bl_ui_units_x = 11 + @classmethod + def get_shading(cls, context): + # Get settings from 3D viewport or OpenGL render engine + view = context.space_data + if view.type == 'VIEW_3D': + return view.shading + else: + return context.scene.display.shading + def draw(self, context): pass @@ -3760,9 +3769,7 @@ class VIEW3D_PT_shading_lighting(Panel): def draw(self, context): layout = self.layout - - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) col = layout.column() split = col.split(0.9) @@ -3824,15 +3831,13 @@ class VIEW3D_PT_shading_color(Panel): @classmethod def poll(cls, context): - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) return shading.type == 'SOLID' def draw(self, context): layout = self.layout - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) layout.row().prop(shading, "color_type", expand=True) @@ -3848,15 +3853,13 @@ class VIEW3D_PT_shading_options(Panel): @classmethod def poll(cls, context): - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) return shading.type == 'SOLID' def draw(self, context): layout = self.layout - view = context.space_data - shading = view.shading + shading = VIEW3D_PT_shading.get_shading(context) col = layout.column() @@ -3909,7 +3912,9 @@ class VIEW3D_PT_shading_options(Panel): if not shading.light == 'MATCAP': col.prop(shading, "show_specular_highlight") - col.prop(view, "show_world") + view = context.space_data + if view.type == 'VIEW_3D': + col.prop(view, "show_world") class VIEW3D_PT_shading_options_shadow(Panel): diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 270ab60c02b..adccfda8e25 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -156,6 +156,7 @@ bool BKE_scene_use_shading_nodes_custom(struct Scene *scene); bool BKE_scene_use_spherical_stereo(struct Scene *scene); bool BKE_scene_uses_blender_eevee(const struct Scene *scene); +bool BKE_scene_uses_blender_opengl(const struct Scene *scene); bool BKE_scene_uses_cycles(const struct Scene *scene); void BKE_scene_disable_color_management(struct Scene *scene); diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 60981c6e76e..c74170becb4 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -45,6 +45,7 @@ struct ScrVert; struct SpaceType; struct TransformOrientation; struct View3D; +struct View3DShading; struct bContext; struct bContextDataResult; struct bScreen; @@ -355,6 +356,8 @@ bool BKE_screen_is_used(const struct bScreen *screen) ATTR_WARN_UNUSED_RESULT AT float BKE_screen_view3d_zoom_to_fac(float camzoom); float BKE_screen_view3d_zoom_from_fac(float zoomfac); +void BKE_screen_view3d_shading_init(struct View3DShading *shading); + /* screen */ void BKE_screen_free(struct bScreen *sc); void BKE_screen_area_map_free(struct ScrAreaMap *area_map) ATTR_NONNULL(); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 3b1416d2881..f99a30b75d0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -113,7 +113,7 @@ #include "bmesh.h" const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; -const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH"; +const char *RE_engine_id_BLENDER_OPENGL = "BLENDER_OPENGL"; const char *RE_engine_id_CYCLES = "CYCLES"; void free_avicodecdata(AviCodecData *acd) @@ -361,6 +361,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) curvemapping_copy_data(&sce_copy->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve); + /* viewport display settings */ + sce_copy->display = sce->display; + /* tool settings */ sce_copy->toolsettings = BKE_toolsettings_copy(sce->toolsettings, 0); @@ -820,6 +823,9 @@ void BKE_scene_init(Scene *sce) sce->display.matcap_ssao_attenuation = 1.0f; sce->display.matcap_ssao_samples = 16; + /* OpenGL Render. */ + BKE_screen_view3d_shading_init(&sce->display.shading); + /* SceneEEVEE */ sce->eevee.gi_diffuse_bounces = 3; sce->eevee.gi_cubemap_resolution = 512; @@ -1541,6 +1547,11 @@ bool BKE_scene_uses_blender_eevee(const Scene *scene) return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE); } +bool BKE_scene_uses_blender_opengl(const Scene *scene) +{ + return STREQ(scene->r.engine, RE_engine_id_BLENDER_OPENGL); +} + bool BKE_scene_uses_cycles(const Scene *scene) { return STREQ(scene->r.engine, RE_engine_id_CYCLES); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 448b97c63b3..f8d926a13ed 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -45,9 +45,10 @@ #include "DNA_view3d_types.h" #include "DNA_workspace_types.h" +#include "BLI_math_vector.h" #include "BLI_listbase.h" -#include "BLI_utildefines.h" #include "BLI_rect.h" +#include "BLI_utildefines.h" #include "BKE_icons.h" #include "BKE_idprop.h" @@ -855,6 +856,21 @@ void BKE_screen_view3d_scene_sync(bScreen *sc, Scene *scene) } } +void BKE_screen_view3d_shading_init(View3DShading *shading) +{ + memset(shading, 0, sizeof(*shading)); + + shading->type = OB_SOLID; + shading->prev_type = OB_SOLID; + shading->flag = V3D_SHADING_SPECULAR_HIGHLIGHT; + shading->light = V3D_LIGHTING_STUDIO; + shading->shadow_intensity = 0.5f; + shading->xray_alpha = 0.5f; + shading->cavity_valley_factor = 1.0f; + shading->cavity_ridge_factor = 1.0f; + copy_v3_fl(shading->single_color, 0.8f); +} + /* magic zoom calculation, no idea what * it signifies, if you find out, tell me! -zr */ diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 5855b9d39de..d1ed166ba89 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1615,5 +1615,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "SceneDisplay", "View3DShading", "shading")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + BKE_screen_view3d_shading_init(&scene->display.shading); + } + } } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index e4c6a372d34..6ec7b03501b 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -117,6 +117,7 @@ set(SRC engines/workbench/workbench_effect_taa.c engines/workbench/workbench_forward.c engines/workbench/workbench_materials.c + engines/workbench/workbench_render.c engines/workbench/workbench_studiolight.c engines/workbench/workbench_volume.c engines/workbench/solid_mode.c diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c index b28263d48cf..5c64cebd981 100644 --- a/source/blender/draw/engines/workbench/solid_mode.c +++ b/source/blender/draw/engines/workbench/solid_mode.c @@ -30,6 +30,8 @@ #include "GPU_shader.h" +#include "RE_pipeline.h" + #include "workbench_private.h" /* Functions */ @@ -69,6 +71,7 @@ static void workbench_solid_draw_scene(void *vedata) { WORKBENCH_Data *data = vedata; workbench_deferred_draw_scene(data); + workbench_deferred_draw_finish(data); } static void workbench_solid_engine_free(void) @@ -82,6 +85,11 @@ static void workbench_solid_view_update(void *vedata) workbench_taa_view_updated(data); } +static void workbench_render_to_image(void *vedata, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect) +{ + workbench_render(vedata, engine, render_layer, rect); +} + static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data); DrawEngineType draw_engine_workbench_solid = { @@ -97,5 +105,5 @@ DrawEngineType draw_engine_workbench_solid = { &workbench_solid_draw_scene, &workbench_solid_view_update, NULL, - NULL, + &workbench_render_to_image, }; diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index ede1bd7fcb5..07df067f324 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -19,37 +19,37 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->user_preferences = &U; View3D *v3d = draw_ctx->v3d; - if (v3d) { + if (!v3d) { + wpd->shading = scene->display.shading; + } + else if (v3d->shading.type == OB_RENDER && + BKE_scene_uses_blender_opengl(scene)) + { + wpd->shading = scene->display.shading; + } + else { wpd->shading = v3d->shading; - if (wpd->shading.light == V3D_LIGHTING_MATCAP) { - wpd->studio_light = BKE_studiolight_find( - wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); - } - else { - wpd->studio_light = BKE_studiolight_find( - wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); - } + } + + if (wpd->shading.light == V3D_LIGHTING_MATCAP) { + wpd->studio_light = BKE_studiolight_find( + wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); } else { - memset(&wpd->shading, 0, sizeof(wpd->shading)); - wpd->shading.light = V3D_LIGHTING_STUDIO; - wpd->shading.shadow_intensity = 0.5; - copy_v3_fl(wpd->shading.single_color, 0.8f); - wpd->studio_light = BKE_studiolight_find_first(STUDIOLIGHT_INTERNAL); + wpd->studio_light = BKE_studiolight_find( + wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); } wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity; WORKBENCH_UBO_World *wd = &wpd->world_data; wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0; - wd->background_alpha = 1.0f; + wd->background_alpha = (v3d || scene->r.alphamode == R_ADDSKY) ? 1.0f : 0.0f; - if ((v3d->flag3 & V3D_SHOW_WORLD) && - (scene->world != NULL)) - { + if (!v3d || ((v3d->flag3 & V3D_SHOW_WORLD) && (scene->world != NULL))) { copy_v3_v3(wd->background_color_low, &scene->world->horr); copy_v3_v3(wd->background_color_high, &scene->world->horr); } - else { + else if (v3d) { UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low); UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high); @@ -58,6 +58,10 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high); srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low); } + else { + zero_v3(wd->background_color_low); + zero_v3(wd->background_color_high); + } studiolight_update_world(wpd->studio_light, wd); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index d17c48b0360..0ad755049b1 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -842,6 +842,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + /* TODO. */ if (TAA_ENABLED(wpd)) { workbench_taa_draw_scene_start(vedata); } @@ -885,7 +886,15 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->volume_pass); } + /* TODO */ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); +} + +void workbench_deferred_draw_finish(WORKBENCH_Data *vedata) +{ + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; + workbench_private_data_free(wpd); workbench_volume_smoke_textures_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c index f1d5d5d6078..66f1de7f9fc 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_aa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -45,6 +45,18 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) } } +static void workspace_aa_draw_transform(GPUTexture *tx) +{ + if (DRW_state_is_image_render()) { + /* Linear result for render. */ + DRW_transform_none(tx); + } + else { + /* Display space result for viewport. */ + DRW_transform_to_display(tx); + } +} + void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) { WORKBENCH_StorageList *stl = vedata->stl; @@ -56,7 +68,7 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (FXAA_ENABLED(wpd)) { GPU_framebuffer_bind(fbl->effect_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -69,11 +81,11 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) */ if (effect_info->jitter_index == 1) { GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); } else { GPU_framebuffer_bind(fbl->effect_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -81,6 +93,6 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) } else { GPU_framebuffer_bind(dfbl->color_only_fb); - DRW_transform_to_display(tx); + workspace_aa_draw_transform(tx); } } diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c index fbeccc19660..403338d55c4 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_taa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c @@ -93,15 +93,19 @@ int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; int result = 1; if (TAA_ENABLED(wpd)) { - if (IN_RANGE_INCL( + if (DRW_state_is_image_render()) { + const Scene *scene = DRW_context_state_get()->scene; + result = (scene->r.mode & R_OSA) ? scene->r.osa : 1; + } + else if (IN_RANGE_INCL( wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_TAA8, GPU_VIEWPORT_QUALITY_TAA16)) { result = 8; } else if (IN_RANGE_INCL( - wpd->user_preferences->gpu_viewport_quality, - GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32)) + wpd->user_preferences->gpu_viewport_quality, + GPU_VIEWPORT_QUALITY_TAA16, GPU_VIEWPORT_QUALITY_TAA32)) { result = 16; } @@ -276,10 +280,12 @@ void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata) GPU_framebuffer_blit(dfbl->color_only_fb, 0, fbl->effect_taa_fb, 0, GPU_COLOR_BIT); - DRW_viewport_matrix_override_unset_all(); + if (!DRW_state_is_image_render()) { + DRW_viewport_matrix_override_unset_all(); + } copy_m4_m4(effect_info->last_mat, effect_info->curr_mat); - if (effect_info->jitter_index != 0) { + if (effect_info->jitter_index != 0 && !DRW_state_is_image_render()) { DRW_viewport_request_redraw(); } } diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 26ae1c289c8..642c5820895 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -29,16 +29,16 @@ #include "DRW_render.h" #include "workbench_engine.h" -/* Shaders */ - -#define WORKBENCH_ENGINE "BLENDER_WORKBENCH" +#include "workbench_private.h" +#define OPENGL_ENGINE "BLENDER_OPENGL" /* Note: currently unused, we may want to register so we can see this when debugging the view. */ -RenderEngineType DRW_engine_viewport_workbench_type = { +RenderEngineType DRW_engine_viewport_opengl_type = { NULL, NULL, - WORKBENCH_ENGINE, N_("Workbench"), RE_INTERNAL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + OPENGL_ENGINE, N_("OpenGL"), RE_INTERNAL, + NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, + &workbench_render_update_passes, &draw_engine_workbench_solid, {NULL, NULL, NULL} }; diff --git a/source/blender/draw/engines/workbench/workbench_engine.h b/source/blender/draw/engines/workbench/workbench_engine.h index a7f168db093..24f68cacd21 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.h +++ b/source/blender/draw/engines/workbench/workbench_engine.h @@ -28,6 +28,6 @@ extern DrawEngineType draw_engine_workbench_solid; extern DrawEngineType draw_engine_workbench_transparent; -extern RenderEngineType DRW_engine_viewport_workbench_type; +extern RenderEngineType DRW_engine_viewport_opengl_type; #endif /* __WORKBENCH_ENGINE_H__ */ diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 13e9686aa85..99d1b7060fd 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -36,6 +36,7 @@ #include "DRW_render.h" +#include "workbench_engine.h" #define WORKBENCH_ENGINE "BLENDER_WORKBENCH" #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895 @@ -51,7 +52,7 @@ #define CAVITY_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_CAVITY) #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) -#define IS_NAVIGATING(wpd) (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING) +#define IS_NAVIGATING(wpd) ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING)) #define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && (IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || ((wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8) && IS_NAVIGATING(wpd)))) #define TAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd)) #define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd))) @@ -61,6 +62,11 @@ #define NORMAL_ENCODING_ENABLED() (true) +struct RenderEngine; +struct RenderLayer; +struct rcti; + + typedef struct WORKBENCH_FramebufferList { /* Deferred render buffers */ struct GPUFrameBuffer *prepass_fb; @@ -231,6 +237,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata); void workbench_deferred_engine_free(void); void workbench_deferred_draw_background(WORKBENCH_Data *vedata); void workbench_deferred_draw_scene(WORKBENCH_Data *vedata); +void workbench_deferred_draw_finish(WORKBENCH_Data *vedata); void workbench_deferred_cache_init(WORKBENCH_Data *vedata); void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob); void workbench_deferred_cache_finish(WORKBENCH_Data *vedata); @@ -293,8 +300,8 @@ void workbench_volume_cache_init(WORKBENCH_Data *vedata); void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, struct ModifierData *md); void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd); - -extern DrawEngineType draw_engine_workbench_solid; -extern DrawEngineType draw_engine_workbench_transparent; +/* workbench_render.c */ +void workbench_render(WORKBENCH_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect); +void workbench_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer); #endif diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c new file mode 100644 index 00000000000..1b25d4c875c --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -0,0 +1,172 @@ +/* + * Copyright 2016, Blender Foundation. + * + * 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. + * + * Contributor(s): Blender Institute + * + */ + +/** \file workbench_render.c + * \ingroup draw_engine + * + * Render functions for final render output. + */ + +#include "BLI_rect.h" + +#include "BKE_report.h" + +#include "DRW_render.h" + +#include "GPU_shader.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "RE_pipeline.h" + +#include "workbench_private.h" + +static void workbench_render_cache( + void *vedata, struct Object *ob, + struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +{ + workbench_deferred_solid_cache_populate(vedata, ob); +} + +static void workbench_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph) +{ + /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */ + Scene *scene = DEG_get_evaluated_scene(depsgraph); + struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); + float frame = BKE_scene_frame_get(scene); + + /* Set the persective, view and window matrix. */ + float winmat[4][4], wininv[4][4]; + float viewmat[4][4], viewinv[4][4]; + float persmat[4][4], persinv[4][4]; + + RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat); + RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv); + + invert_m4_m4(viewmat, viewinv); + mul_m4_m4m4(persmat, winmat, viewmat); + invert_m4_m4(persinv, persmat); + invert_m4_m4(wininv, winmat); + + DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN); + DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV); + DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); +} + +static bool workbench_render_framebuffers_init(void) +{ + /* For image render, allocate own buffers because we don't have a viewport. */ + const float *viewport_size = DRW_viewport_size_get(); + const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; + + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + dtxl->color = GPU_texture_create_2D(size[0], size[1], GPU_RGBA8, NULL, NULL); + dtxl->depth = GPU_texture_create_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); + + if (!(dtxl->depth && dtxl->color)) { + return false; + } + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + + GPU_framebuffer_ensure_config(&dfbl->default_fb, { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_TEXTURE(dtxl->color) + }); + + GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_NONE + }); + + GPU_framebuffer_ensure_config(&dfbl->color_only_fb, { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color) + }); + + bool ok = true; + ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); + + return ok; +} + +static void workbench_render_framebuffers_finish(void) +{ +} + +void workbench_render(WORKBENCH_Data *data, RenderEngine *engine, RenderLayer *render_layer, const rcti *rect) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + + Depsgraph *depsgraph = draw_ctx->depsgraph; + workbench_render_matrices_init(engine, depsgraph); + + if (!workbench_render_framebuffers_init()) { + RE_engine_report(engine, RPT_ERROR, "Failed to allocate OpenGL buffers"); + return; + } + + /* Init engine. */ + workbench_deferred_engine_init(data); + + /* Init objects. */ + workbench_deferred_cache_init(data); + DRW_render_object_iter(data, engine, depsgraph, workbench_render_cache); + workbench_deferred_cache_finish(data); + DRW_render_instance_buffer_finish(); + + /* Draw. */ + int num_samples = workbench_taa_calculate_num_iterations(data); + for (int sample = 0; sample < num_samples; sample++) { + if (RE_engine_test_break(engine)) { + break; + } + + workbench_deferred_draw_background(data); + workbench_deferred_draw_scene(data); + } + + workbench_deferred_draw_finish(data); + + /* Write render output. */ + const char *viewname = RE_GetActiveRenderView(engine->re); + RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname); + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + GPU_framebuffer_bind(dfbl->color_only_fb); + GPU_framebuffer_read_color(dfbl->color_only_fb, + rect->xmin, rect->ymin, + BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), + 4, 0, rp->rect); + + workbench_render_framebuffers_finish(); +} + +void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) +{ + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); +} diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index a4a933250c9..16a17f4f21d 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -226,6 +226,7 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } while (0) void DRW_transform_to_display(struct GPUTexture *tex); +void DRW_transform_none(struct GPUTexture *tex); void DRW_multisamples_resolve( struct GPUTexture *src_depth, struct GPUTexture *src_color); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 707aadbc229..d23b9e693ce 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -51,6 +51,7 @@ static struct DRWShapeCache { Gwn_Batch *drw_cursor; Gwn_Batch *drw_cursor_only_circle; Gwn_Batch *drw_fullscreen_quad; + Gwn_Batch *drw_fullscreen_quad_texcoord; Gwn_Batch *drw_quad; Gwn_Batch *drw_sphere; Gwn_Batch *drw_screenspace_circle; @@ -287,6 +288,35 @@ Gwn_Batch *DRW_cache_fullscreen_quad_get(void) return SHC.drw_fullscreen_quad; } +Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void) +{ + if (!SHC.drw_fullscreen_quad_texcoord) { + /* Use a triangle instead of a real quad */ + /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */ + float pos[3][2] = {{-1.0f, -1.0f}, { 3.0f, -1.0f}, {-1.0f, 3.0f}}; + float texCoord[3][2] = {{ 0.0f, 0.0f}, { 2.0f, 0.0f}, { 0.0f, 2.0f}}; + + /* Position Only 2D format */ + static Gwn_VertFormat format = { 0 }; + static struct { uint pos, texCoord; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.texCoord = GWN_vertformat_attr_add(&format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + } + + Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(vbo, 3); + + for (int i = 0; i < 3; ++i) { + GWN_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); + GWN_vertbuf_attr_set(vbo, attr_id.texCoord, i, texCoord[i]); + } + + SHC.drw_fullscreen_quad_texcoord = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + } + return SHC.drw_fullscreen_quad_texcoord; +} + /* Just a regular quad with 4 vertices. */ Gwn_Batch *DRW_cache_quad_get(void) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index c1c80d2c5bf..07c8a571256 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -40,6 +40,7 @@ struct Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); +struct Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void); struct Gwn_Batch *DRW_cache_quad_get(void); struct Gwn_Batch *DRW_cache_cube_get(void); struct Gwn_Batch *DRW_cache_sphere_get(void); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 556f02c2899..58ce9dd5218 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -283,6 +283,29 @@ void DRW_transform_to_display(GPUTexture *tex) } } +/* Draw texture to framebuffer without any color transforms */ +void DRW_transform_none(GPUTexture *tex) +{ + /* Draw as texture for final render (without immediate mode). */ + Gwn_Batch *geom = DRW_cache_fullscreen_quad_texcoord_get(); + GWN_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); + + GPU_texture_bind(tex, 0); + + const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + GWN_batch_uniform_4fv(geom, "color", white); + + float mat[4][4]; + unit_m4(mat); + GWN_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); + + GWN_batch_program_use_begin(geom); + GWN_batch_draw_range_ex(geom, 0, 0, false); + GWN_batch_program_use_end(geom); + + GPU_texture_unbind(tex); +} + /** \} */ @@ -2217,8 +2240,8 @@ void DRW_engine_register(DrawEngineType *draw_engine_type) void DRW_engines_register(void) { + RE_engines_register(&DRW_engine_viewport_opengl_type); RE_engines_register(&DRW_engine_viewport_eevee_type); - RE_engines_register(&DRW_engine_viewport_workbench_type); DRW_engine_register(&draw_engine_workbench_solid); DRW_engine_register(&draw_engine_workbench_transparent); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 188ee928f3c..71bdd2e20c2 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -324,15 +324,7 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) v3d->grid = 1.0f; v3d->gridlines = 16; v3d->gridsubdiv = 10; - v3d->shading.type = OB_SOLID; - v3d->shading.prev_type = OB_SOLID; - v3d->shading.flag = V3D_SHADING_SPECULAR_HIGHLIGHT; - v3d->shading.light = V3D_LIGHTING_STUDIO; - v3d->shading.shadow_intensity = 0.5f; - v3d->shading.xray_alpha = 0.5f; - v3d->shading.cavity_valley_factor = 1.0f; - v3d->shading.cavity_ridge_factor = 1.0f; - copy_v3_fl(v3d->shading.single_color, 0.8f); + BKE_screen_view3d_shading_init(&v3d->shading); v3d->overlay.wireframe_threshold = 0.5f; v3d->overlay.bone_select_alpha = 0.5f; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 0c4c0a00f1a..16c8d8875c7 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1381,6 +1381,9 @@ typedef struct SceneDisplay { float matcap_ssao_attenuation; int matcap_ssao_samples; int pad; + + /* OpenGL render engine settings. */ + View3DShading shading; } SceneDisplay; typedef struct SceneEEVEE { @@ -1707,7 +1710,7 @@ enum { /* RenderData.engine (scene.c) */ extern const char *RE_engine_id_BLENDER_EEVEE; -extern const char *RE_engine_id_BLENDER_WORKBENCH; +extern const char *RE_engine_id_BLENDER_OPENGL; extern const char *RE_engine_id_CYCLES; /* **************** SCENE ********************* */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f8d6757c601..339d3841b30 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5753,6 +5753,10 @@ static void rna_def_scene_display(BlenderRNA *brna) RNA_def_property_int_default(prop, 16); RNA_def_property_ui_text(prop, "Samples", "Number of samples"); RNA_def_property_range(prop, 1, 500); + + /* OpenGL render engine settings. */ + prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Shading Settings", "Shading settings for OpenGL render engine"); } static void rna_def_scene_eevee(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 66ff29a8c16..e670d3c31a5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -679,8 +679,12 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - bScreen *screen = ptr->id.data; + ID *id = ptr->id.data; + if (GS(id->name) == ID_SCE) { + return; + } + bScreen *screen = ptr->id.data; for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { @@ -694,20 +698,40 @@ static void rna_3DViewShading_type_update(Main *bmain, Scene *UNUSED(scene), Poi } } +static Scene *rna_3DViewShading_scene(PointerRNA *ptr) +{ + /* Get scene, depends if using 3D view or OpenGL render settings. */ + ID *id = ptr->id.data; + if (GS(id->name) == ID_SCE) { + return (Scene *)id; + } + else { + bScreen *screen = ptr->id.data; + return WM_windows_scene_get_from_screen(G_MAIN->wm.first, screen); + } +} + static int rna_3DViewShading_type_get(PointerRNA *ptr) { - bScreen *screen = ptr->id.data; - Scene *scene = WM_windows_scene_get_from_screen(G_MAIN->wm.first, screen); + /* Available shading types depend on render engine. */ + Scene *scene = rna_3DViewShading_scene(ptr); RenderEngineType *type = RE_engines_find(scene->r.engine); View3DShading *shading = (View3DShading *)ptr->data; - if (!BKE_scene_uses_blender_eevee(scene) && shading->type == OB_RENDER) { - if (!(type && type->view_draw)) { + if (BKE_scene_uses_blender_eevee(scene)) { + return shading->type; + } + else if (BKE_scene_uses_blender_opengl(scene)) { + return (shading->type == OB_MATERIAL) ? OB_RENDER : shading->type; + } + else { + if (shading->type == OB_RENDER && !(type && type->view_draw)) { return OB_MATERIAL; } + else { + return shading->type; + } } - - return shading->type; } static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) @@ -720,11 +744,10 @@ static void rna_3DViewShading_type_set(PointerRNA *ptr, int value) } static const EnumPropertyItem *rna_3DViewShading_type_itemf( - bContext *C, PointerRNA *UNUSED(ptr), + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) { - wmWindow *win = CTX_wm_window(C); - Scene *scene = WM_window_get_active_scene(win); + Scene *scene = rna_3DViewShading_scene(ptr); RenderEngineType *type = RE_engines_find(scene->r.engine); EnumPropertyItem *item = NULL; @@ -736,6 +759,9 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf( RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL); RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER); } + else if (BKE_scene_uses_blender_opengl(scene)) { + RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER); + } else { RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL); if (type && type->view_draw) { @@ -2401,6 +2427,8 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + /* Note these settings are used for both 3D viewport and the OpenGL render + * engine in the scene, so can't assume to always be part of a screen. */ srna = RNA_def_struct(brna, "View3DShading", NULL); RNA_def_struct_path_func(srna, "rna_View3DShading_path"); RNA_def_struct_ui_text(srna, "3D View Shading Settings", "Settings for shading in the 3D viewport"); -- cgit v1.2.3 From 41045478ab7fd3efc989952bfd7a83c5cbb88dbc Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Tue, 17 Jul 2018 14:44:47 -0600 Subject: make.bat: remove msvc2013 support. --- build_files/windows/autodetect_msvc.cmd | 5 +-- build_files/windows/check_libraries.cmd | 1 - build_files/windows/detect_msvc2013.cmd | 3 -- build_files/windows/detect_msvc_classic.cmd | 69 ----------------------------- build_files/windows/parse_arguments.cmd | 2 - build_files/windows/show_help.cmd | 8 ++-- 6 files changed, 5 insertions(+), 83 deletions(-) delete mode 100644 build_files/windows/detect_msvc2013.cmd delete mode 100644 build_files/windows/detect_msvc_classic.cmd diff --git a/build_files/windows/autodetect_msvc.cmd b/build_files/windows/autodetect_msvc.cmd index 6fce3829e7b..77dc005cd18 100644 --- a/build_files/windows/autodetect_msvc.cmd +++ b/build_files/windows/autodetect_msvc.cmd @@ -1,14 +1,11 @@ echo No explicit msvc version requested, autodetecting version. -call "%~dp0\detect_msvc2013.cmd" +call "%~dp0\detect_msvc2017.cmd" if %ERRORLEVEL% EQU 0 goto DetectionComplete call "%~dp0\detect_msvc2015.cmd" if %ERRORLEVEL% EQU 0 goto DetectionComplete -call "%~dp0\detect_msvc2017.cmd" -if %ERRORLEVEL% EQU 0 goto DetectionComplete - echo Compiler Detection failed. Use verbose switch for more information. exit /b 1 diff --git a/build_files/windows/check_libraries.cmd b/build_files/windows/check_libraries.cmd index c8aad7c9adb..6ad1d1749c3 100644 --- a/build_files/windows/check_libraries.cmd +++ b/build_files/windows/check_libraries.cmd @@ -1,4 +1,3 @@ -if "%BUILD_VS_YEAR%"=="2013" set BUILD_VS_LIBDIRPOST=vc12 if "%BUILD_VS_YEAR%"=="2015" set BUILD_VS_LIBDIRPOST=vc14 if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc14 diff --git a/build_files/windows/detect_msvc2013.cmd b/build_files/windows/detect_msvc2013.cmd deleted file mode 100644 index 5688d31c4b6..00000000000 --- a/build_files/windows/detect_msvc2013.cmd +++ /dev/null @@ -1,3 +0,0 @@ -set BUILD_VS_VER=12 -set BUILD_VS_YEAR=2013 -call "%~dp0\detect_msvc_classic.cmd" \ No newline at end of file diff --git a/build_files/windows/detect_msvc_classic.cmd b/build_files/windows/detect_msvc_classic.cmd deleted file mode 100644 index 61bfcf92ddf..00000000000 --- a/build_files/windows/detect_msvc_classic.cmd +++ /dev/null @@ -1,69 +0,0 @@ -if NOT "%verbose%" == "" ( - echo Detecting msvc %BUILD_VS_YEAR% -) -set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC" -for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C -if DEFINED MSVC_VC_DIR ( - if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% on Win64 detected at "%MSVC_VC_DIR%" - ) - goto msvc_detect_finally -) - -REM Check 32 bits -set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC" -for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C -if DEFINED MSVC_VC_DIR ( - if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% on Win32 detected at "%MSVC_VC_DIR%" - ) - goto msvc_detect_finally -) -if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% not found. -) -goto FAIL -:msvc_detect_finally -set VCVARS=%MSVC_VC_DIR%\vcvarsall.bat -if not exist "%VCVARS%" ( - echo "%VCVARS%" not found. - goto FAIL -) - -call "%vcvars%" %BUILD_ARCH% - -rem try msbuild -msbuild /version > NUL -if errorlevel 1 ( - if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% msbuild not found - ) - goto FAIL -) - -if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% msbuild found -) - -REM try the c++ compiler -cl 2> NUL 1>&2 -if errorlevel 1 ( - if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler not found - ) - goto FAIL -) - -if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler found -) -goto DetectionComplete - -:FAIL -exit /b 1 - -:DetectionComplete -if NOT "%verbose%" == "" ( - echo Visual Studio %BUILD_VS_YEAR% Detected successfuly -) -exit /b 0 diff --git a/build_files/windows/parse_arguments.cmd b/build_files/windows/parse_arguments.cmd index 8a6d743978d..e8caddaf4ea 100644 --- a/build_files/windows/parse_arguments.cmd +++ b/build_files/windows/parse_arguments.cmd @@ -59,8 +59,6 @@ if NOT "%1" == "" ( set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools ) else if "%1" == "2015" ( set BUILD_VS_YEAR=2015 - ) else if "%1" == "2013" ( - set BUILD_VS_YEAR=2013 ) else if "%1" == "packagename" ( set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2" shift /1 diff --git a/build_files/windows/show_help.cmd b/build_files/windows/show_help.cmd index 2b297120f4b..694b28c88ed 100644 --- a/build_files/windows/show_help.cmd +++ b/build_files/windows/show_help.cmd @@ -22,13 +22,13 @@ echo - packagename [newname] ^(override default cpack package name^) echo - buildir [newdir] ^(override default build folder^) echo - x86 ^(override host auto-detect and build 32 bit code^) echo - x64 ^(override host auto-detect and build 64 bit code^) -echo - 2013 ^(build with visual studio 2013^) -echo. -echo Experimental options -echo - 2015 ^(build with visual studio 2015^) echo - 2017 ^(build with visual studio 2017^) echo - 2017pre ^(build with visual studio 2017 pre-release^) echo - 2017b ^(build with visual studio 2017 Build Tools^) + +echo. +echo Experimental options +echo - 2015 ^(build with visual studio 2015^) echo - clang ^(enable building with clang^) echo - asan ^(enable asan when building with clang^) echo - ninja ^(enable building with ninja instead of msbuild^) -- cgit v1.2.3 From 6329629bb9eab86a989367a148154a7ebfa074df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 17 Jul 2018 14:46:44 +0200 Subject: GWN: Port to GPU module: codestyle & licence --- intern/gawain/gawain/gwn_attr_binding.h | 47 +- intern/gawain/gawain/gwn_attr_binding_private.h | 43 +- intern/gawain/gawain/gwn_batch.h | 126 +++-- intern/gawain/gawain/gwn_batch_private.h | 44 +- intern/gawain/gawain/gwn_buffer_id.h | 51 +- intern/gawain/gawain/gwn_common.h | 48 +- intern/gawain/gawain/gwn_context.h | 49 +- intern/gawain/gawain/gwn_element.h | 87 +-- intern/gawain/gawain/gwn_imm_util.h | 58 +- intern/gawain/gawain/gwn_immediate.h | 150 +++--- intern/gawain/gawain/gwn_primitive.h | 47 +- intern/gawain/gawain/gwn_primitive_private.h | 43 +- intern/gawain/gawain/gwn_shader_interface.h | 103 ++-- intern/gawain/gawain/gwn_vertex_array_id.h | 55 +- intern/gawain/gawain/gwn_vertex_buffer.h | 143 ++--- intern/gawain/gawain/gwn_vertex_format.h | 73 ++- intern/gawain/gawain/gwn_vertex_format_private.h | 47 +- intern/gawain/src/gwn_attr_binding.c | 77 +-- intern/gawain/src/gwn_batch.c | 507 +++++++++--------- intern/gawain/src/gwn_buffer_id.cpp | 71 ++- intern/gawain/src/gwn_element.c | 265 ++++----- intern/gawain/src/gwn_imm_util.c | 72 ++- intern/gawain/src/gwn_immediate.c | 650 ++++++++++------------- intern/gawain/src/gwn_primitive.c | 65 ++- intern/gawain/src/gwn_shader_interface.c | 323 ++++++----- intern/gawain/src/gwn_vertex_array_id.cpp | 160 +++--- intern/gawain/src/gwn_vertex_buffer.c | 222 ++++---- intern/gawain/src/gwn_vertex_format.c | 233 ++++---- 28 files changed, 2155 insertions(+), 1704 deletions(-) diff --git a/intern/gawain/gawain/gwn_attr_binding.h b/intern/gawain/gawain/gwn_attr_binding.h index a209e1c4f0f..8030e86ea92 100644 --- a/intern/gawain/gawain/gwn_attr_binding.h +++ b/intern/gawain/gawain/gwn_attr_binding.h @@ -1,19 +1,42 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain vertex attribute binding -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_attr_binding.h + * \ingroup gpu + * + * Gawain vertex attribute binding + */ -#pragma once +#ifndef __GWN_ATTR_BINDING_H__ +#define __GWN_ATTR_BINDING_H__ #include "gwn_common.h" typedef struct Gwn_AttrBinding { - uint64_t loc_bits; // store 4 bits for each of the 16 attribs - uint16_t enabled_bits; // 1 bit for each attrib + uint64_t loc_bits; /* store 4 bits for each of the 16 attribs */ + uint16_t enabled_bits; /* 1 bit for each attrib */ } Gwn_AttrBinding; + +#endif /* __GWN_ATTR_BINDING_H__ */ diff --git a/intern/gawain/gawain/gwn_attr_binding_private.h b/intern/gawain/gawain/gwn_attr_binding_private.h index 300945d464b..cead1896ec7 100644 --- a/intern/gawain/gawain/gwn_attr_binding_private.h +++ b/intern/gawain/gawain/gwn_attr_binding_private.h @@ -1,15 +1,36 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain vertex attribute binding -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_attr_binding_private.h + * \ingroup gpu + * + * Gawain vertex attribute binding + */ -#pragma once +#ifndef __GWN_ATTR_BINDING_PRIVATE_H__ +#define __GWN_ATTR_BINDING_PRIVATE_H__ #include "gwn_vertex_format.h" #include "gwn_shader_interface.h" @@ -18,3 +39,5 @@ void AttribBinding_clear(Gwn_AttrBinding*); void get_attrib_locations(const Gwn_VertFormat*, Gwn_AttrBinding*, const Gwn_ShaderInterface*); unsigned read_attrib_location(const Gwn_AttrBinding*, unsigned a_idx); + +#endif /* __GWN_ATTR_BINDING_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_batch.h b/intern/gawain/gawain/gwn_batch.h index 734df3c91b6..a7a54502cc0 100644 --- a/intern/gawain/gawain/gwn_batch.h +++ b/intern/gawain/gawain/gwn_batch.h @@ -1,15 +1,37 @@ - -// Gawain geometry batch -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_batch.h + * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. + */ + +#ifndef __GWN_BATCH_H__ +#define __GWN_BATCH_H__ #include "gwn_vertex_buffer.h" #include "gwn_element.h" @@ -27,43 +49,43 @@ typedef enum { #define GWN_BATCH_VAO_DYN_ALLOC_COUNT 16 typedef struct Gwn_Batch { - // geometry - Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; // verts[0] is required, others can be NULL - Gwn_VertBuf* inst; // instance attribs - Gwn_IndexBuf* elem; // NULL if element list not needed + /* geometry */ + Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ + Gwn_VertBuf* inst; /* instance attribs */ + Gwn_IndexBuf* elem; /* NULL if element list not needed */ uint32_t gl_prim_type; - // cached values (avoid dereferencing later) + /* cached values (avoid dereferencing later) */ uint32_t vao_id; uint32_t program; const struct Gwn_ShaderInterface* interface; - // book-keeping - unsigned owns_flag; - struct Gwn_Context *context; // used to free all vaos. this implies all vaos were created under the same context. + /* book-keeping */ + uint owns_flag; + struct Gwn_Context *context; /* used to free all vaos. this implies all vaos were created under the same context. */ Gwn_BatchPhase phase; bool program_in_use; - // Vao management: remembers all geometry state (vertex attrib bindings & element buffer) - // for each shader interface. Start with a static number of vaos and fallback to dynamic count - // if necessary. Once a batch goes dynamic it does not go back. + /* Vao management: remembers all geometry state (vertex attrib bindings & element buffer) + * for each shader interface. Start with a static number of vaos and fallback to dynamic count + * if necessary. Once a batch goes dynamic it does not go back. */ bool is_dynamic_vao_count; union { - // Static handle count + /* Static handle count */ struct { const struct Gwn_ShaderInterface* interfaces[GWN_BATCH_VAO_STATIC_LEN]; uint32_t vao_ids[GWN_BATCH_VAO_STATIC_LEN]; } static_vaos; - // Dynamic handle count + /* Dynamic handle count */ struct { - unsigned count; + uint count; const struct Gwn_ShaderInterface** interfaces; uint32_t* vao_ids; } dynamic_vaos; }; - // XXX This is the only solution if we want to have some data structure using - // batches as key to identify nodes. We must destroy these nodes with this callback. + /* XXX This is the only solution if we want to have some data structure using + * batches as key to identify nodes. We must destroy these nodes with this callback. */ void (*free_callback)(struct Gwn_Batch*, void*); void* callback_data; } Gwn_Batch; @@ -75,8 +97,8 @@ enum { GWN_BATCH_OWNS_INDEX = (1 << 31), }; -Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag); -void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag); +Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); +void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src); #define GWN_batch_create(prim, verts, elem) \ @@ -84,11 +106,11 @@ Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src); #define GWN_batch_init(batch, prim, verts, elem) \ GWN_batch_init_ex(batch, prim, verts, elem, 0) -void GWN_batch_discard(Gwn_Batch*); // verts & elem are not discarded +void GWN_batch_discard(Gwn_Batch*); /* verts & elem are not discarded */ void GWN_batch_callback_free_set(Gwn_Batch*, void (*callback)(Gwn_Batch*, void*), void*); -void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); // Instancing +void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); /* Instancing */ int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); @@ -97,10 +119,10 @@ int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); void GWN_batch_program_set_no_use(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); void GWN_batch_program_set(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); -// Entire batch draws with one shader program, but can be redrawn later with another program. -// Vertex shader's inputs must be compatible with the batch's vertex format. +/* Entire batch draws with one shader program, but can be redrawn later with another program. */ +/* Vertex shader's inputs must be compatible with the batch's vertex format. */ -void GWN_batch_program_use_begin(Gwn_Batch*); // call before Batch_Uniform (temp hack?) +void GWN_batch_program_use_begin(Gwn_Batch*); /* call before Batch_Uniform (temp hack?) */ void GWN_batch_program_use_end(Gwn_Batch*); void GWN_batch_uniform_1ui(Gwn_Batch*, const char* name, int value); @@ -119,44 +141,44 @@ void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4] void GWN_batch_draw(Gwn_Batch*); -// This does not bind/unbind shader and does not call GPU_matrix_bind() +/* This does not bind/unbind shader and does not call GPU_matrix_bind() */ void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance); -// Does not even need batch +/* Does not even need batch */ void GWN_draw_primitive(Gwn_PrimType, int v_count); -#if 0 // future plans +#if 0 /* future plans */ -// Can multiple batches share a Gwn_VertBuf? Use ref count? +/* Can multiple batches share a Gwn_VertBuf? Use ref count? */ -// We often need a batch with its own data, to be created and discarded together. -// WithOwn variants reduce number of system allocations. +/* We often need a batch with its own data, to be created and discarded together. */ +/* WithOwn variants reduce number of system allocations. */ typedef struct BatchWithOwnVertexBuffer { Gwn_Batch batch; - Gwn_VertBuf verts; // link batch.verts to this + Gwn_VertBuf verts; /* link batch.verts to this */ } BatchWithOwnVertexBuffer; typedef struct BatchWithOwnElementList { Gwn_Batch batch; - Gwn_IndexBuf elem; // link batch.elem to this + Gwn_IndexBuf elem; /* link batch.elem to this */ } BatchWithOwnElementList; typedef struct BatchWithOwnVertexBufferAndElementList { Gwn_Batch batch; - Gwn_IndexBuf elem; // link batch.elem to this - Gwn_VertBuf verts; // link batch.verts to this + Gwn_IndexBuf elem; /* link batch.elem to this */ + Gwn_VertBuf verts; /* link batch.verts to this */ } BatchWithOwnVertexBufferAndElementList; -Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, unsigned v_len, Gwn_IndexBuf*); -Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, unsigned prim_len); -Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, unsigned v_len, unsigned prim_len); -// verts: shared, own -// elem: none, shared, own +Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, uint v_len, Gwn_IndexBuf*); +Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, uint prim_len); +Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, uint v_len, uint prim_len); +/* verts: shared, own */ +/* elem: none, shared, own */ Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStuff); -#endif // future plans +#endif /* future plans */ /* Macros */ @@ -167,3 +189,5 @@ Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStu batch = NULL; \ } \ } while (0) + +#endif /* __GWN_BATCH_H__ */ diff --git a/intern/gawain/gawain/gwn_batch_private.h b/intern/gawain/gawain/gwn_batch_private.h index 6503429c237..e7d42ff0249 100644 --- a/intern/gawain/gawain/gwn_batch_private.h +++ b/intern/gawain/gawain/gwn_batch_private.h @@ -1,15 +1,37 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain context -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2018 Mike Erwin, Clément Foucault -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_batch_private.h + * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. + */ -#pragma once +#ifndef __GWN_BATCH_PRIVATE_H__ +#define __GWN_BATCH_PRIVATE_H__ #ifdef __cplusplus extern "C" { @@ -28,3 +50,5 @@ void gwn_context_remove_batch(Gwn_Context*, Gwn_Batch*); #ifdef __cplusplus } #endif + +#endif /* __GWN_BATCH_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_buffer_id.h b/intern/gawain/gawain/gwn_buffer_id.h index 6f51ca6905d..0c2537a5d5a 100644 --- a/intern/gawain/gawain/gwn_buffer_id.h +++ b/intern/gawain/gawain/gwn_buffer_id.h @@ -1,20 +1,41 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain buffer IDs -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_buffer_id.h + * \ingroup gpu + * + * Gawain buffer IDs + */ -#pragma once +#ifndef __GWN_BUFFER_ID_H__ +#define __GWN_BUFFER_ID_H__ -// Manage GL buffer IDs in a thread-safe way -// Use these instead of glGenBuffers & its friends -// - alloc must be called from main thread -// - free can be called from any thread +/* Manage GL buffer IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from main thread + * - free can be called from any thread */ #ifdef __cplusplus extern "C" { @@ -28,3 +49,5 @@ void GWN_buf_id_free(GLuint buffer_id); #ifdef __cplusplus } #endif + +#endif /* __GWN_BUFFER_ID_H__ */ diff --git a/intern/gawain/gawain/gwn_common.h b/intern/gawain/gawain/gwn_common.h index 6a56543da40..2587e8670a9 100644 --- a/intern/gawain/gawain/gwn_common.h +++ b/intern/gawain/gawain/gwn_common.h @@ -1,22 +1,41 @@ - -// Gawain common #defines and #includes -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_common.h + * \ingroup gpu + */ + +#ifndef __GWN_COMMON_H__ +#define __GWN_COMMON_H__ #define PROGRAM_NO_OPTI 0 #if defined(NDEBUG) #define TRUST_NO_ONE 0 #else - // strict error checking, enabled for debug builds during early development + /* strict error checking, enabled for debug builds during early development */ #define TRUST_NO_ONE 1 #endif @@ -24,6 +43,7 @@ #include #endif +#include #include #include @@ -37,3 +57,5 @@ #else # define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) #endif + +#endif /* __GWN_COMMON_H__ */ diff --git a/intern/gawain/gawain/gwn_context.h b/intern/gawain/gawain/gwn_context.h index 3addce762b3..7784fc30562 100644 --- a/intern/gawain/gawain/gwn_context.h +++ b/intern/gawain/gawain/gwn_context.h @@ -1,17 +1,36 @@ - -// Gawain context -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2018 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once - -// This interface allow Gawain to manage VAOs for mutiple context and threads. +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_context.h + * \ingroup gpu + * + * This interface allow Gawain to manage VAOs for mutiple context and threads. + */ + +#ifndef __GWN_CONTEXT_H__ +#define __GWN_CONTEXT_H__ #ifdef __cplusplus extern "C" { @@ -32,3 +51,5 @@ Gwn_Context* GWN_context_active_get(void); #ifdef __cplusplus } #endif + +#endif /* __GWN_CONTEXT_H__ */ diff --git a/intern/gawain/gawain/gwn_element.h b/intern/gawain/gawain/gwn_element.h index 53a54cdfd76..2d5b6bb692b 100644 --- a/intern/gawain/gawain/gwn_element.h +++ b/intern/gawain/gawain/gwn_element.h @@ -1,15 +1,36 @@ - -// Gawain element list (AKA index buffer) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_element.h + * \ingroup gpu + * + * Gawain element list (AKA index buffer) + */ + +#ifndef __GWN_ELEMENT_H__ +#define __GWN_ELEMENT_H__ #include "gwn_primitive.h" @@ -18,50 +39,50 @@ #define GWN_PRIM_RESTART 0xFFFFFFFF typedef enum { - GWN_INDEX_U8, // GL has this, Vulkan does not + GWN_INDEX_U8, /* GL has this, Vulkan does not */ GWN_INDEX_U16, GWN_INDEX_U32 } Gwn_IndexBufType; typedef struct Gwn_IndexBuf { - unsigned index_len; + uint index_len; #if GWN_TRACK_INDEX_RANGE Gwn_IndexBufType index_type; uint32_t gl_index_type; - unsigned min_index; - unsigned max_index; - unsigned base_index; + uint min_index; + uint max_index; + uint base_index; #endif - uint32_t vbo_id; // 0 indicates not yet sent to VRAM + uint32_t vbo_id; /* 0 indicates not yet sent to VRAM */ bool use_prim_restart; } Gwn_IndexBuf; void GWN_indexbuf_use(Gwn_IndexBuf*); -unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf*); +uint GWN_indexbuf_size_get(const Gwn_IndexBuf*); typedef struct Gwn_IndexBufBuilder { - unsigned max_allowed_index; - unsigned max_index_len; - unsigned index_len; + uint max_allowed_index; + uint max_index_len; + uint index_len; Gwn_PrimType prim_type; - unsigned* data; + uint* data; bool use_prim_restart; } Gwn_IndexBufBuilder; -// supports all primitive types. -void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, unsigned index_len, unsigned vertex_len, bool use_prim_restart); +/* supports all primitive types. */ +void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, uint index_len, uint vertex_len, bool use_prim_restart); -// supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS. -void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, unsigned prim_len, unsigned vertex_len); +/* supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS. */ +void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, uint prim_len, uint vertex_len); -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, unsigned v); +void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, uint v); void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder*); -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, unsigned v); -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2); -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2, unsigned v3); -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, unsigned v1, unsigned v2, unsigned v3, unsigned v4); +void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, uint v); +void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, uint v1, uint v2); +void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3); +void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder*); void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder*, Gwn_IndexBuf*); @@ -77,3 +98,5 @@ void GWN_indexbuf_discard(Gwn_IndexBuf*); elem = NULL; \ } \ } while (0) + +#endif /* __GWN_ELEMENT_H__ */ diff --git a/intern/gawain/gawain/gwn_imm_util.h b/intern/gawain/gawain/gwn_imm_util.h index 5d17ec50669..e512d071dca 100644 --- a/intern/gawain/gawain/gwn_imm_util.h +++ b/intern/gawain/gawain/gwn_imm_util.h @@ -1,22 +1,46 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain immediate mode drawing utilities -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_imm_util.h + * \ingroup gpu + * + * Gawain element list (AKA index buffer) + */ -#pragma once +#ifndef __GWN_IMM_UTIL_H__ +#define __GWN_IMM_UTIL_H__ +#include -// Draw 2D rectangles (replaces glRect functions) -// caller is reponsible for vertex format & shader -void immRectf(unsigned pos, float x1, float y1, float x2, float y2); -void immRecti(unsigned pos, int x1, int y1, int x2, int y2); +/* Draw 2D rectangles (replaces glRect functions) */ +/* caller is reponsible for vertex format & shader */ +void immRectf(uint pos, float x1, float y1, float x2, float y2); +void immRecti(uint pos, int x1, int y1, int x2, int y2); -// Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS. -void immRectf_fast_with_color(unsigned pos, unsigned col, float x1, float y1, float x2, float y2, const float color[4]); -void immRecti_fast_with_color(unsigned pos, unsigned col, int x1, int y1, int x2, int y2, const float color[4]); +/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS. */ +void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]); +void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]); + +#endif /* __GWN_IMM_UTIL_H__ */ diff --git a/intern/gawain/gawain/gwn_immediate.h b/intern/gawain/gawain/gwn_immediate.h index c3ea2b911a0..8231942d735 100644 --- a/intern/gawain/gawain/gwn_immediate.h +++ b/intern/gawain/gawain/gwn_immediate.h @@ -1,88 +1,101 @@ - -// Gawain immediate mode work-alike -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_immediate.h + * \ingroup gpu + * + * Gawain immediate mode work-alike + */ + +#ifndef __GWN_IMMEDIATE_H__ +#define __GWN_IMMEDIATE_H__ #include "gwn_vertex_format.h" #include "gwn_primitive.h" #include "gwn_shader_interface.h" - -#define IMM_BATCH_COMBO 1 - - -Gwn_VertFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib - -void immBindProgram(uint32_t program, const Gwn_ShaderInterface*); // every immBegin must have a program bound first -void immUnbindProgram(void); // call after your last immEnd, or before binding another program - -void immBegin(Gwn_PrimType, unsigned vertex_len); // must supply exactly vertex_len vertices -void immBeginAtMost(Gwn_PrimType, unsigned max_vertex_len); // can supply fewer vertices -void immEnd(void); // finishes and draws - -#if IMM_BATCH_COMBO #include "gwn_batch.h" -// immBegin a batch, then use standard immFunctions as usual. -// immEnd will finalize the batch instead of drawing. -// Then you can draw it as many times as you like! Partially replaces the need for display lists. -Gwn_Batch* immBeginBatch(Gwn_PrimType, unsigned vertex_len); -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, unsigned vertex_len); -#endif +Gwn_VertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ + +void immBindProgram(uint32_t program, const Gwn_ShaderInterface*); /* every immBegin must have a program bound first. */ +void immUnbindProgram(void); /* call after your last immEnd, or before binding another program. */ -// provide attribute values that can change per vertex -// first vertex after immBegin must have all its attributes specified -// skipped attributes will continue using the previous value for that attrib_id -void immAttrib1f(unsigned attrib_id, float x); -void immAttrib2f(unsigned attrib_id, float x, float y); -void immAttrib3f(unsigned attrib_id, float x, float y, float z); -void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w); +void immBegin(Gwn_PrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ +void immBeginAtMost(Gwn_PrimType, uint max_vertex_len); /* can supply fewer vertices. */ +void immEnd(void); /* finishes and draws. */ -void immAttrib2i(unsigned attrib_id, int x, int y); +/* ImmBegin a batch, then use standard immFunctions as usual. */ +/* ImmEnd will finalize the batch instead of drawing. */ +/* Then you can draw it as many times as you like! Partially replaces the need for display lists. */ +Gwn_Batch* immBeginBatch(Gwn_PrimType, uint vertex_len); +Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, uint vertex_len); -void immAttrib1u(unsigned attrib_id, unsigned x); +/* Provide attribute values that can change per vertex. */ +/* First vertex after immBegin must have all its attributes specified. */ +/* Skipped attributes will continue using the previous value for that attrib_id. */ +void immAttrib1f(uint attrib_id, float x); +void immAttrib2f(uint attrib_id, float x, float y); +void immAttrib3f(uint attrib_id, float x, float y, float z); +void immAttrib4f(uint attrib_id, float x, float y, float z, float w); -void immAttrib2s(unsigned attrib_id, short x, short y); +void immAttrib2i(uint attrib_id, int x, int y); -void immAttrib2fv(unsigned attrib_id, const float data[2]); -void immAttrib3fv(unsigned attrib_id, const float data[3]); -void immAttrib4fv(unsigned attrib_id, const float data[4]); +void immAttrib1u(uint attrib_id, uint x); -void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b); -void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a); +void immAttrib2s(uint attrib_id, short x, short y); -void immAttrib3ubv(unsigned attrib_id, const unsigned char data[4]); -void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4]); +void immAttrib2fv(uint attrib_id, const float data[2]); +void immAttrib3fv(uint attrib_id, const float data[3]); +void immAttrib4fv(uint attrib_id, const float data[4]); -// explicitly skip an attribute -// this advanced option kills automatic value copying for this attrib_id -void immSkipAttrib(unsigned attrib_id); +void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b); +void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a); +void immAttrib3ubv(uint attrib_id, const unsigned char data[4]); +void immAttrib4ubv(uint attrib_id, const unsigned char data[4]); -// provide one last attribute value & end the current vertex -// this is most often used for 2D or 3D position (similar to glVertex) -void immVertex2f(unsigned attrib_id, float x, float y); -void immVertex3f(unsigned attrib_id, float x, float y, float z); -void immVertex4f(unsigned attrib_id, float x, float y, float z, float w); +/* Explicitly skip an attribute. */ +/* This advanced option kills automatic value copying for this attrib_id. */ +void immSkipAttrib(uint attrib_id); -void immVertex2i(unsigned attrib_id, int x, int y); +/* Provide one last attribute value & end the current vertex. */ +/* This is most often used for 2D or 3D position (similar to glVertex). */ +void immVertex2f(uint attrib_id, float x, float y); +void immVertex3f(uint attrib_id, float x, float y, float z); +void immVertex4f(uint attrib_id, float x, float y, float z, float w); -void immVertex2s(unsigned attrib_id, short x, short y); +void immVertex2i(uint attrib_id, int x, int y); -void immVertex2fv(unsigned attrib_id, const float data[2]); -void immVertex3fv(unsigned attrib_id, const float data[3]); +void immVertex2s(uint attrib_id, short x, short y); -void immVertex2iv(unsigned attrib_id, const int data[2]); +void immVertex2fv(uint attrib_id, const float data[2]); +void immVertex3fv(uint attrib_id, const float data[3]); +void immVertex2iv(uint attrib_id, const int data[2]); -// provide uniform values that don't change for the entire draw call +/* Provide uniform values that don't change for the entire draw call. */ void immUniform1i(const char* name, int x); void immUniform4iv(const char* name, const int data[4]); void immUniform1f(const char* name, float x); @@ -96,9 +109,8 @@ void immUniform4fv(const char* name, const float data[4]); void immUniformArray4fv(const char* bare_name, const float *data, int count); void immUniformMatrix4fv(const char* name, const float data[4][4]); - -// convenience functions for setting "uniform vec4 color" -// the rgb functions have implicit alpha = 1.0 +/* Convenience functions for setting "uniform vec4 color". */ +/* The rgb functions have implicit alpha = 1.0. */ void immUniformColor4f(float r, float g, float b, float a); void immUniformColor4fv(const float rgba[4]); void immUniformColor3f(float r, float g, float b); @@ -111,10 +123,10 @@ void immUniformColor3ubv(const unsigned char rgb[3]); void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a); void immUniformColor4ubv(const unsigned char rgba[4]); - -// these are called by the system -- not part of drawing API - +/* These are called by the system -- not part of drawing API. */ void immInit(void); void immActivate(void); void immDeactivate(void); void immDestroy(void); + +#endif /* __GWN_IMMEDIATE_H__ */ diff --git a/intern/gawain/gawain/gwn_primitive.h b/intern/gawain/gawain/gwn_primitive.h index 3359b3582bb..346f77441d3 100644 --- a/intern/gawain/gawain/gwn_primitive.h +++ b/intern/gawain/gawain/gwn_primitive.h @@ -1,15 +1,36 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain geometric primitives -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_primitive.h + * \ingroup gpu + * + * Gawain geometric primitives + */ -#pragma once +#ifndef __GWN_PRIMITIVE_H__ +#define __GWN_PRIMITIVE_H__ #include "gwn_common.h" @@ -18,7 +39,7 @@ typedef enum { GWN_PRIM_LINES, GWN_PRIM_TRIS, GWN_PRIM_LINE_STRIP, - GWN_PRIM_LINE_LOOP, // GL has this, Vulkan does not + GWN_PRIM_LINE_LOOP, /* GL has this, Vulkan does not */ GWN_PRIM_TRI_STRIP, GWN_PRIM_TRI_FAN, @@ -29,7 +50,7 @@ typedef enum { GWN_PRIM_NONE } Gwn_PrimType; -// what types of primitives does each shader expect? +/* what types of primitives does each shader expect? */ typedef enum { GWN_PRIM_CLASS_NONE = 0, GWN_PRIM_CLASS_POINT = (1 << 0), @@ -40,3 +61,5 @@ typedef enum { Gwn_PrimClass GWN_primtype_class(Gwn_PrimType); bool GWN_primtype_belongs_to_class(Gwn_PrimType, Gwn_PrimClass); + +#endif /* __GWN_PRIMITIVE_H__ */ diff --git a/intern/gawain/gawain/gwn_primitive_private.h b/intern/gawain/gawain/gwn_primitive_private.h index d959cd89852..6d3f1e20da7 100644 --- a/intern/gawain/gawain/gwn_primitive_private.h +++ b/intern/gawain/gawain/gwn_primitive_private.h @@ -1,14 +1,37 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain geometric primitives (private interface for use inside Gawain) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_primitive_private.h + * \ingroup gpu + * + * Gawain geometric primitives + */ -#pragma once +#ifndef __GWN_PRIMITIVE_PRIVATE_H__ +#define __GWN_PRIMITIVE_PRIVATE_H__ GLenum convert_prim_type_to_gl(Gwn_PrimType); + +#endif /* __GWN_PRIMITIVE_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h index b27b12c18d8..4b20719b329 100644 --- a/intern/gawain/gawain/gwn_shader_interface.h +++ b/intern/gawain/gawain/gwn_shader_interface.h @@ -1,55 +1,76 @@ - -// Gawain shader interface (C --> GLSL) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_shader_interface.h + * \ingroup gpu + * + * Gawain shader interface (C --> GLSL) + */ + +#ifndef __GWN_SHADER_INTERFACE_H__ +#define __GWN_SHADER_INTERFACE_H__ #include "gwn_common.h" typedef enum { - GWN_UNIFORM_NONE = 0, // uninitialized/unknown + GWN_UNIFORM_NONE = 0, /* uninitialized/unknown */ - GWN_UNIFORM_MODEL, // mat4 ModelMatrix - GWN_UNIFORM_VIEW, // mat4 ViewMatrix - GWN_UNIFORM_MODELVIEW, // mat4 ModelViewMatrix - GWN_UNIFORM_PROJECTION, // mat4 ProjectionMatrix - GWN_UNIFORM_VIEWPROJECTION, // mat4 ViewProjectionMatrix - GWN_UNIFORM_MVP, // mat4 ModelViewProjectionMatrix + GWN_UNIFORM_MODEL, /* mat4 ModelMatrix */ + GWN_UNIFORM_VIEW, /* mat4 ViewMatrix */ + GWN_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */ + GWN_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */ + GWN_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */ + GWN_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */ - GWN_UNIFORM_MODEL_INV, // mat4 ModelMatrixInverse - GWN_UNIFORM_VIEW_INV, // mat4 ViewMatrixInverse - GWN_UNIFORM_MODELVIEW_INV, // mat4 ModelViewMatrixInverse - GWN_UNIFORM_PROJECTION_INV, // mat4 ProjectionMatrixInverse - GWN_UNIFORM_VIEWPROJECTION_INV, // mat4 ViewProjectionMatrixInverse + GWN_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */ + GWN_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */ + GWN_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */ + GWN_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */ + GWN_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */ - GWN_UNIFORM_NORMAL, // mat3 NormalMatrix - GWN_UNIFORM_WORLDNORMAL, // mat3 WorldNormalMatrix - GWN_UNIFORM_CAMERATEXCO, // vec4 CameraTexCoFactors - GWN_UNIFORM_ORCO, // vec3 OrcoTexCoFactors[] + GWN_UNIFORM_NORMAL, /* mat3 NormalMatrix */ + GWN_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */ + GWN_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */ + GWN_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */ - GWN_UNIFORM_COLOR, // vec4 color - GWN_UNIFORM_EYE, // vec3 eye - GWN_UNIFORM_CALLID, // int callId + GWN_UNIFORM_COLOR, /* vec4 color */ + GWN_UNIFORM_EYE, /* vec3 eye */ + GWN_UNIFORM_CALLID, /* int callId */ - GWN_UNIFORM_CUSTOM, // custom uniform, not one of the above built-ins + GWN_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */ - GWN_NUM_UNIFORMS, // Special value, denotes number of builtin uniforms. + GWN_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ } Gwn_UniformBuiltin; typedef struct Gwn_ShaderInput { struct Gwn_ShaderInput* next; uint32_t name_offset; - unsigned name_hash; - Gwn_UniformBuiltin builtin_type; // only for uniform inputs - uint32_t gl_type; // only for attrib inputs - int32_t size; // only for attrib inputs + uint name_hash; + Gwn_UniformBuiltin builtin_type; /* only for uniform inputs */ + uint32_t gl_type; /* only for attrib inputs */ + int32_t size; /* only for attrib inputs */ int32_t location; } Gwn_ShaderInput; @@ -64,8 +85,8 @@ typedef struct Gwn_ShaderInterface { Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS]; char* name_buffer; - struct Gwn_Batch** batches; // references to batches using this interface - unsigned batches_len; + struct Gwn_Batch** batches; /* references to batches using this interface */ + uint batches_len; } Gwn_ShaderInterface; Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program_id); @@ -76,6 +97,8 @@ const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInter const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name); const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name); -// keep track of batches using this interface +/* keep track of batches using this interface */ void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); + +#endif /* __GWN_SHADER_INTERFACE_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_array_id.h b/intern/gawain/gawain/gwn_vertex_array_id.h index 1c093d428ce..6ba26612b4e 100644 --- a/intern/gawain/gawain/gwn_vertex_array_id.h +++ b/intern/gawain/gawain/gwn_vertex_array_id.h @@ -1,22 +1,41 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain buffer IDs -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2018 Mike Erwin, Clément Foucault -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_vertex_array_id.h + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ -#pragma once - -// Manage GL vertex array IDs in a thread-safe way -// Use these instead of glGenBuffers & its friends -// - alloc must be called from a thread that is bound -// to the context that will be used for drawing with -// this vao. -// - free can be called from any thread +#ifndef __GWN_VERTEX_ARRAY_ID_H__ +#define __GWN_VERTEX_ARRAY_ID_H__ #ifdef __cplusplus extern "C" { @@ -32,3 +51,5 @@ void GWN_vao_free(GLuint vao_id, Gwn_Context*); #ifdef __cplusplus } #endif + +#endif /* __GWN_VERTEX_ARRAY_ID_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h index 0eac4838e65..84ea12f86d1 100644 --- a/intern/gawain/gawain/gwn_vertex_buffer.h +++ b/intern/gawain/gawain/gwn_vertex_buffer.h @@ -1,42 +1,63 @@ - -// Gawain vertex buffer -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. - -#pragma once +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_buffer.h + * \ingroup gpu + * + * Gawain vertex buffer + */ + +#ifndef __GWN_VERTEX_BUFFER_H__ +#define __GWN_VERTEX_BUFFER_H__ #include "gwn_vertex_format.h" #define VRAM_USAGE 1 -// How to create a Gwn_VertBuf: -// 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts) -// 2) GWN_vertformat_attr_add(verts->format, ...) -// 3) GWN_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format -// 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer) +/* How to create a Gwn_VertBuf: */ +/* 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts) */ +/* 2) GWN_vertformat_attr_add(verts->format, ...) */ +/* 3) GWN_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format */ +/* 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ -// Is Gwn_VertBuf always used as part of a Gwn_Batch? +/* Is Gwn_VertBuf always used as part of a Gwn_Batch? */ typedef enum { - // can be extended to support more types + /* can be extended to support more types */ GWN_USAGE_STREAM, - GWN_USAGE_STATIC, // do not keep data in memory + GWN_USAGE_STATIC, /* do not keep data in memory */ GWN_USAGE_DYNAMIC } Gwn_UsageType; typedef struct Gwn_VertBuf { Gwn_VertFormat format; - unsigned vertex_len; /* number of verts we want to draw */ - unsigned vertex_alloc; /* number of verts data */ + uint vertex_len; /* number of verts we want to draw */ + uint vertex_alloc; /* number of verts data */ bool dirty; - unsigned char* data; // NULL indicates data in VRAM (unmapped) - uint32_t vbo_id; // 0 indicates not yet allocated - Gwn_UsageType usage; // usage hint for GL optimisation + unsigned char* data; /* NULL indicates data in VRAM (unmapped) */ + uint32_t vbo_id; /* 0 indicates not yet allocated */ + Gwn_UsageType usage; /* usage hint for GL optimisation */ } Gwn_VertBuf; Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType); @@ -53,73 +74,71 @@ void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf*, const Gwn_VertFormat*, Gwn_Us #define GWN_vertbuf_init_with_format(verts, format) \ GWN_vertbuf_init_with_format_ex(verts, format, GWN_USAGE_STATIC) -unsigned GWN_vertbuf_size_get(const Gwn_VertBuf*); -void GWN_vertbuf_data_alloc(Gwn_VertBuf*, unsigned v_len); -void GWN_vertbuf_data_resize(Gwn_VertBuf*, unsigned v_len); -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, unsigned v_len); +uint GWN_vertbuf_size_get(const Gwn_VertBuf*); +void GWN_vertbuf_data_alloc(Gwn_VertBuf*, uint v_len); +void GWN_vertbuf_data_resize(Gwn_VertBuf*, uint v_len); +void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, uint v_len); -// The most important set_attrib variant is the untyped one. Get it right first. -// It takes a void* so the app developer is responsible for matching their app data types -// to the vertex attribute's type and component count. They're in control of both, so this -// should not be a problem. +/* The most important set_attrib variant is the untyped one. Get it right first. */ +/* It takes a void* so the app developer is responsible for matching their app data types */ +/* to the vertex attribute's type and component count. They're in control of both, so this */ +/* should not be a problem. */ -void GWN_vertbuf_attr_set(Gwn_VertBuf*, unsigned a_idx, unsigned v_idx, const void* data); -void GWN_vertbuf_attr_fill(Gwn_VertBuf*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, unsigned a_idx, unsigned stride, const void* data); +void GWN_vertbuf_attr_set(Gwn_VertBuf*, uint a_idx, uint v_idx, const void* data); +void GWN_vertbuf_attr_fill(Gwn_VertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ +void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, uint a_idx, uint stride, const void* data); -// For low level access only +/* For low level access only */ typedef struct Gwn_VertBufRaw { - unsigned size; - unsigned stride; + uint size; + uint stride; unsigned char* data; unsigned char* data_init; #if TRUST_NO_ONE - // Only for overflow check + /* Only for overflow check */ unsigned char* _data_end; #endif } Gwn_VertBufRaw; GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) - { +{ unsigned char* data = a->data; a->data += a->stride; #if TRUST_NO_ONE assert(data < a->_data_end); #endif return (void *)data; - } +} -GWN_INLINE unsigned GWN_vertbuf_raw_used(Gwn_VertBufRaw *a) - { +GWN_INLINE uint GWN_vertbuf_raw_used(Gwn_VertBufRaw *a) +{ return ((a->data - a->data_init) / a->stride); - } - -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, unsigned a_idx, Gwn_VertBufRaw *access); - -// TODO: decide whether to keep the functions below -// doesn't immediate mode satisfy these needs? +} -// void setAttrib1f(unsigned a_idx, unsigned v_idx, float x); -// void setAttrib2f(unsigned a_idx, unsigned v_idx, float x, float y); -// void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z); -// void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w); -// -// void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); -// void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); - -void GWN_vertbuf_use(Gwn_VertBuf*); +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, uint a_idx, Gwn_VertBufRaw *access); +/* TODO: decide whether to keep the functions below */ +/* doesn't immediate mode satisfy these needs? */ -// Metrics +/* void setAttrib1f(uint a_idx, uint v_idx, float x); */ +/* void setAttrib2f(uint a_idx, unsigned v_idx, float x, float y); */ +/* void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z); */ +/* void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w); */ -unsigned GWN_vertbuf_get_memory_usage(void); +/* void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); */ +/* void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); */ +void GWN_vertbuf_use(Gwn_VertBuf*); -// Macros +/* Metrics */ +uint GWN_vertbuf_get_memory_usage(void); +/* Macros */ #define GWN_VERTBUF_DISCARD_SAFE(verts) do { \ if (verts != NULL) { \ GWN_vertbuf_discard(verts); \ verts = NULL; \ } \ } while (0) + +#endif /* __GWN_VERTEX_BUFFER_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h index a4593e4615b..1197a8ef842 100644 --- a/intern/gawain/gawain/gwn_vertex_format.h +++ b/intern/gawain/gawain/gwn_vertex_format.h @@ -1,15 +1,36 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain vertex format -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_vertex_format.h + * \ingroup gpu + * + * Gawain vertex format + */ -#pragma once +#ifndef __GWN_VERTEX_FORMAT_H__ +#define __GWN_VERTEX_FORMAT_H__ #include "gwn_common.h" @@ -34,45 +55,47 @@ typedef enum { typedef enum { GWN_FETCH_FLOAT, GWN_FETCH_INT, - GWN_FETCH_INT_TO_FLOAT_UNIT, // 127 (ubyte) -> 0.5 (and so on for other int types) - GWN_FETCH_INT_TO_FLOAT // 127 (any int type) -> 127.0 + GWN_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ + GWN_FETCH_INT_TO_FLOAT /* 127 (any int type) -> 127.0 */ } Gwn_VertFetchMode; typedef struct Gwn_VertAttr { Gwn_VertFetchMode fetch_mode; Gwn_VertCompType comp_type; - unsigned gl_comp_type; - unsigned comp_len; // 1 to 4 or 8 or 12 or 16 - unsigned sz; // size in bytes, 1 to 64 - unsigned offset; // from beginning of vertex, in bytes - unsigned name_len; // up to GWN_VERT_ATTR_MAX_NAMES + uint gl_comp_type; + uint comp_len; /* 1 to 4 or 8 or 12 or 16 */ + uint sz; /* size in bytes, 1 to 64 */ + uint offset; /* from beginning of vertex, in bytes */ + uint name_len; /* up to GWN_VERT_ATTR_MAX_NAMES */ const char* name[GWN_VERT_ATTR_MAX_NAMES]; } Gwn_VertAttr; typedef struct Gwn_VertFormat { - unsigned attr_len; // 0 to 16 (GWN_VERT_ATTR_MAX_LEN) - unsigned name_len; // total count of active vertex attrib - unsigned stride; // stride in bytes, 1 to 256 - unsigned name_offset; + uint attr_len; /* 0 to 16 (GWN_VERT_ATTR_MAX_LEN) */ + uint name_len; /* total count of active vertex attrib */ + uint stride; /* stride in bytes, 1 to 256 */ + uint name_offset; bool packed; char names[GWN_VERT_ATTR_NAMES_BUF_LEN]; - Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; // TODO: variable-size attribs array + Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ } Gwn_VertFormat; void GWN_vertformat_clear(Gwn_VertFormat*); void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src); -unsigned GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, unsigned comp_len, Gwn_VertFetchMode); +uint GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, uint comp_len, Gwn_VertFetchMode); void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias); -// format conversion +/* format conversion */ typedef struct Gwn_PackedNormal { int x : 10; int y : 10; int z : 10; - int w : 2; // 0 by default, can manually set to { -2, -1, 0, 1 } + int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ } Gwn_PackedNormal; Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]); Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]); + +#endif /* __GWN_VERTEX_FORMAT_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_format_private.h b/intern/gawain/gawain/gwn_vertex_format_private.h index 90cd8412e53..3cae9969fd8 100644 --- a/intern/gawain/gawain/gwn_vertex_format_private.h +++ b/intern/gawain/gawain/gwn_vertex_format_private.h @@ -1,16 +1,39 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain vertex format (private interface for use inside Gawain) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016-2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/gwn_vertex_format_private.h + * \ingroup gpu + * + * Gawain vertex format + */ -#pragma once +#ifndef __GWN_VERTEX_FORMAT_PRIVATE_H__ +#define __GWN_VERTEX_FORMAT_PRIVATE_H__ void VertexFormat_pack(Gwn_VertFormat*); -unsigned padding(unsigned offset, unsigned alignment); -unsigned vertex_buffer_size(const Gwn_VertFormat*, unsigned vertex_len); +uint padding(uint offset, uint alignment); +uint vertex_buffer_size(const Gwn_VertFormat*, uint vertex_len); + +#endif /* __GWN_VERTEX_FORMAT_PRIVATE_H__ */ diff --git a/intern/gawain/src/gwn_attr_binding.c b/intern/gawain/src/gwn_attr_binding.c index c702a0ae99d..727aceb0140 100644 --- a/intern/gawain/src/gwn_attr_binding.c +++ b/intern/gawain/src/gwn_attr_binding.c @@ -1,70 +1,85 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain vertex attribute binding -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/intern/gwn_attr_binding.c + * \ingroup gpu + * + * Gawain vertex attribute binding + */ #include "gwn_attr_binding.h" #include "gwn_attr_binding_private.h" #include +#include #if GWN_VERT_ATTR_MAX_LEN != 16 #error "attrib binding code assumes GWN_VERT_ATTR_MAX_LEN = 16" #endif void AttribBinding_clear(Gwn_AttrBinding* binding) - { +{ binding->loc_bits = 0; binding->enabled_bits = 0; - } +} -unsigned read_attrib_location(const Gwn_AttrBinding* binding, unsigned a_idx) - { +uint read_attrib_location(const Gwn_AttrBinding* binding, uint a_idx) +{ #if TRUST_NO_ONE assert(a_idx < GWN_VERT_ATTR_MAX_LEN); assert(binding->enabled_bits & (1 << a_idx)); #endif - return (binding->loc_bits >> (4 * a_idx)) & 0xF; - } +} -static void write_attrib_location(Gwn_AttrBinding* binding, unsigned a_idx, unsigned location) - { +static void write_attrib_location(Gwn_AttrBinding* binding, uint a_idx, uint location) +{ #if TRUST_NO_ONE assert(a_idx < GWN_VERT_ATTR_MAX_LEN); assert(location < GWN_VERT_ATTR_MAX_LEN); #endif - - const unsigned shift = 4 * a_idx; + const uint shift = 4 * a_idx; const uint64_t mask = ((uint64_t)0xF) << shift; - // overwrite this attrib's previous location + /* overwrite this attrib's previous location */ binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift); - // mark this attrib as enabled + /* mark this attrib as enabled */ binding->enabled_bits |= 1 << a_idx; - } +} void get_attrib_locations(const Gwn_VertFormat* format, Gwn_AttrBinding* binding, const Gwn_ShaderInterface* shaderface) - { +{ AttribBinding_clear(binding); - for (unsigned a_idx = 0; a_idx < format->attr_len; ++a_idx) - { + for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) { const Gwn_VertAttr* a = format->attribs + a_idx; - for (unsigned n_idx = 0; n_idx < a->name_len; ++n_idx) - { + for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { const Gwn_ShaderInput* input = GWN_shaderinterface_attr(shaderface, a->name[n_idx]); - #if TRUST_NO_ONE assert(input != NULL); - // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program + /* TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program */ #endif - write_attrib_location(binding, a_idx, input->location); - } } } +} diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c index 4979d93b15e..5daf0e87aec 100644 --- a/intern/gawain/src/gwn_batch.c +++ b/intern/gawain/src/gwn_batch.c @@ -1,13 +1,34 @@ - -// Gawain geometry batch -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_batch.c + * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. + */ #include "gwn_batch.h" #include "gwn_batch_private.h" @@ -17,72 +38,68 @@ #include #include -// necessary functions from matrix API +/* necessary functions from matrix API */ extern void GPU_matrix_bind(const Gwn_ShaderInterface* shaderface); -static void batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first); +static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first); void gwn_batch_vao_cache_clear(Gwn_Batch* batch) - { - if (batch->context == NULL) +{ + if (batch->context == NULL) { return; - - if (batch->is_dynamic_vao_count) - { - for (int i = 0; i < batch->dynamic_vaos.count; ++i) - { - if (batch->dynamic_vaos.vao_ids[i]) + } + if (batch->is_dynamic_vao_count) { + for (int i = 0; i < batch->dynamic_vaos.count; ++i) { + if (batch->dynamic_vaos.vao_ids[i]) { GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); - if (batch->dynamic_vaos.interfaces[i]) + } + if (batch->dynamic_vaos.interfaces[i]) { GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); } + } free(batch->dynamic_vaos.interfaces); free(batch->dynamic_vaos.vao_ids); - } - else - { - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) - { - if (batch->static_vaos.vao_ids[i]) + } + else { + for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + if (batch->static_vaos.vao_ids[i]) { GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); - if (batch->static_vaos.interfaces[i]) + } + if (batch->static_vaos.interfaces[i]) { GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->static_vaos.interfaces[i], batch); } } - + } batch->is_dynamic_vao_count = false; - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) - { + for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { batch->static_vaos.vao_ids[i] = 0; batch->static_vaos.interfaces[i] = NULL; - } - + } gwn_context_remove_batch(batch->context, batch); batch->context = NULL; - } +} Gwn_Batch* GWN_batch_create_ex( Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, - unsigned owns_flag) - { + uint owns_flag) +{ Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch)); - GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag); - return batch; - } +} void GWN_batch_init_ex( Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, - unsigned owns_flag) - { + uint owns_flag) +{ #if TRUST_NO_ONE assert(verts != NULL); #endif batch->verts[0] = verts; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) + for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { batch->verts[v] = NULL; + } batch->inst = NULL; batch->elem = elem; batch->gl_prim_type = convert_prim_type_to_gl(prim_type); @@ -90,184 +107,175 @@ void GWN_batch_init_ex( batch->is_dynamic_vao_count = false; batch->owns_flag = owns_flag; batch->free_callback = NULL; - } +} -// This will share the VBOs with the new batch +/* This will share the VBOs with the new batch. */ Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src) - { +{ Gwn_Batch* batch = GWN_batch_create_ex(GWN_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); batch->gl_prim_type = batch_src->gl_prim_type; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) + for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { batch->verts[v] = batch_src->verts[v]; - - return batch; } + return batch; +} void GWN_batch_discard(Gwn_Batch* batch) - { - if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) +{ + if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) { GWN_indexbuf_discard(batch->elem); - - if (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES) + } + if (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES) { GWN_vertbuf_discard(batch->inst); - - if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) - { - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) - { - if (batch->verts[v] == NULL) + } + if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) { + for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + if (batch->verts[v] == NULL) { break; - if (batch->owns_flag & (1 << v)) + } + if (batch->owns_flag & (1 << v)) { GWN_vertbuf_discard(batch->verts[v]); } } - + } gwn_batch_vao_cache_clear(batch); - if (batch->free_callback) + if (batch->free_callback) { batch->free_callback(batch, batch->callback_data); - - free(batch); } + free(batch); +} void GWN_batch_callback_free_set(Gwn_Batch* batch, void (*callback)(Gwn_Batch*, void*), void* user_data) - { +{ batch->free_callback = callback; batch->callback_data = user_data; - } +} void GWN_batch_instbuf_set(Gwn_Batch* batch, Gwn_VertBuf* inst, bool own_vbo) - { +{ #if TRUST_NO_ONE assert(inst != NULL); #endif - // redo the bindings + /* redo the bindings */ gwn_batch_vao_cache_clear(batch); - if (batch->inst != NULL && (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES)) + if (batch->inst != NULL && (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES)) { GWN_vertbuf_discard(batch->inst); - + } batch->inst = inst; - if (own_vbo) + if (own_vbo) { batch->owns_flag |= GWN_BATCH_OWNS_INSTANCES; - else + } + else { batch->owns_flag &= ~GWN_BATCH_OWNS_INSTANCES; } +} +/* Returns the index of verts in the batch. */ int GWN_batch_vertbuf_add_ex( Gwn_Batch* batch, Gwn_VertBuf* verts, bool own_vbo) - { - // redo the bindings +{ + /* redo the bindings */ gwn_batch_vao_cache_clear(batch); - for (unsigned v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) - { - if (batch->verts[v] == NULL) - { + for (uint v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + if (batch->verts[v] == NULL) { #if TRUST_NO_ONE - // for now all VertexBuffers must have same vertex_len + /* for now all VertexBuffers must have same vertex_len */ assert(verts->vertex_len == batch->verts[0]->vertex_len); - // in the near future we will enable instanced attribs which have their own vertex_len #endif batch->verts[v] = verts; - // TODO: mark dirty so we can keep attrib bindings up-to-date + /* TODO: mark dirty so we can keep attrib bindings up-to-date */ if (own_vbo) batch->owns_flag |= (1 << v); return v; - } } + } - // we only make it this far if there is no room for another Gwn_VertBuf + /* we only make it this far if there is no room for another Gwn_VertBuf */ #if TRUST_NO_ONE assert(false); #endif return -1; - } +} static GLuint batch_vao_get(Gwn_Batch *batch) - { - // Search through cache - if (batch->is_dynamic_vao_count) - { +{ + /* Search through cache */ + if (batch->is_dynamic_vao_count) { for (int i = 0; i < batch->dynamic_vaos.count; ++i) if (batch->dynamic_vaos.interfaces[i] == batch->interface) return batch->dynamic_vaos.vao_ids[i]; - } - else - { + } + else { for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) if (batch->static_vaos.interfaces[i] == batch->interface) return batch->static_vaos.vao_ids[i]; - } + } - // Set context of this batch. - // It will be bound to it until gwn_batch_vao_cache_clear is called. - // Until then it can only be drawn with this context. - if (batch->context == NULL) - { + /* Set context of this batch. + * It will be bound to it until gwn_batch_vao_cache_clear is called. + * Until then it can only be drawn with this context. */ + if (batch->context == NULL) { batch->context = GWN_context_active_get(); gwn_context_add_batch(batch->context, batch); - } + } #if TRUST_NO_ONE - else // Make sure you are not trying to draw this batch in another context. + else { + /* Make sure you are not trying to draw this batch in another context. */ assert(batch->context == GWN_context_active_get()); + } #endif - // Cache miss, time to add a new entry! + /* Cache miss, time to add a new entry! */ GLuint new_vao = 0; - if (!batch->is_dynamic_vao_count) - { - int i; // find first unused slot - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) + if (!batch->is_dynamic_vao_count) { + int i; /* find first unused slot */ + for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) if (batch->static_vaos.vao_ids[i] == 0) break; - if (i < GWN_BATCH_VAO_STATIC_LEN) - { + if (i < GWN_BATCH_VAO_STATIC_LEN) { batch->static_vaos.interfaces[i] = batch->interface; batch->static_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); - } - else - { - // Not enough place switch to dynamic. + } + else { + /* Not enough place switch to dynamic. */ batch->is_dynamic_vao_count = true; - // Erase previous entries, they will be added back if drawn again. - for (int j = 0; j < GWN_BATCH_VAO_STATIC_LEN; ++j) - { + /* Erase previous entries, they will be added back if drawn again. */ + for (int j = 0; j < GWN_BATCH_VAO_STATIC_LEN; ++j) { GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface*)batch->static_vaos.interfaces[j], batch); GWN_vao_free(batch->static_vaos.vao_ids[j], batch->context); - } - // Init dynamic arrays and let the branch below set the values. + } + /* Init dynamic arrays and let the branch below set the values. */ batch->dynamic_vaos.count = GWN_BATCH_VAO_DYN_ALLOC_COUNT; batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(Gwn_ShaderInterface*)); batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); - } } + } - if (batch->is_dynamic_vao_count) - { - int i; // find first unused slot + if (batch->is_dynamic_vao_count) { + int i; /* find first unused slot */ for (i = 0; i < batch->dynamic_vaos.count; ++i) if (batch->dynamic_vaos.vao_ids[i] == 0) break; - if (i == batch->dynamic_vaos.count) - { - // Not enough place, realloc the array. + if (i == batch->dynamic_vaos.count) { + /* Not enough place, realloc the array. */ i = batch->dynamic_vaos.count; batch->dynamic_vaos.count += GWN_BATCH_VAO_DYN_ALLOC_COUNT; batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(Gwn_ShaderInterface*) * batch->dynamic_vaos.count); batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(Gwn_ShaderInterface*) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); - } - + } batch->dynamic_vaos.interfaces[i] = batch->interface; batch->dynamic_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); - } + } GWN_shaderinterface_add_batch_ref((Gwn_ShaderInterface*)batch->interface, batch); @@ -275,105 +283,94 @@ static GLuint batch_vao_get(Gwn_Batch *batch) assert(new_vao != 0); #endif - // We just got a fresh VAO we need to initialize it. + /* We just got a fresh VAO we need to initialize it. */ glBindVertexArray(new_vao); batch_update_program_bindings(batch, 0); glBindVertexArray(0); return new_vao; - } +} void GWN_batch_program_set_no_use(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) - { +{ #if TRUST_NO_ONE assert(glIsProgram(shaderface->program)); assert(batch->program_in_use == 0); #endif - batch->interface = shaderface; batch->program = program; batch->vao_id = batch_vao_get(batch); - } +} void GWN_batch_program_set(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) - { +{ GWN_batch_program_set_no_use(batch, program, shaderface); - GWN_batch_program_use_begin(batch); // hack! to make Batch_Uniform* simpler - } + GWN_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ +} void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* interface) - { - if (batch->is_dynamic_vao_count) - { - for (int i = 0; i < batch->dynamic_vaos.count; ++i) - { - if (batch->dynamic_vaos.interfaces[i] == interface) - { +{ + if (batch->is_dynamic_vao_count) { + for (int i = 0; i < batch->dynamic_vaos.count; ++i) { + if (batch->dynamic_vaos.interfaces[i] == interface) { GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); batch->dynamic_vaos.vao_ids[i] = 0; batch->dynamic_vaos.interfaces[i] = NULL; - break; // cannot have duplicates - } + break; /* cannot have duplicates */ } } - else - { + } + else { int i; - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) - { - if (batch->static_vaos.interfaces[i] == interface) - { + for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + if (batch->static_vaos.interfaces[i] == interface) { GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); batch->static_vaos.vao_ids[i] = 0; batch->static_vaos.interfaces[i] = NULL; - break; // cannot have duplicates - } + break; /* cannot have duplicates */ } } } +} -static void create_bindings(Gwn_VertBuf* verts, const Gwn_ShaderInterface* interface, unsigned int v_first, const bool use_instancing) - { +static void create_bindings( + Gwn_VertBuf* verts, const Gwn_ShaderInterface* interface, + uint v_first, const bool use_instancing) +{ const Gwn_VertFormat* format = &verts->format; - const unsigned attr_len = format->attr_len; - const unsigned stride = format->stride; + const uint attr_len = format->attr_len; + const uint stride = format->stride; GWN_vertbuf_use(verts); - for (unsigned a_idx = 0; a_idx < attr_len; ++a_idx) - { + for (uint a_idx = 0; a_idx < attr_len; ++a_idx) { const Gwn_VertAttr* a = format->attribs + a_idx; - const GLvoid* pointer = (const GLubyte*)0 + a->offset + v_first * stride; - for (unsigned n_idx = 0; n_idx < a->name_len; ++n_idx) - { + for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { const Gwn_ShaderInput* input = GWN_shaderinterface_attr(interface, a->name[n_idx]); if (input == NULL) continue; - if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) - { + if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { #if TRUST_NO_ONE assert(a->fetch_mode == GWN_FETCH_FLOAT); assert(a->gl_comp_type == GL_FLOAT); #endif - for (int i = 0; i < a->comp_len / 4; ++i) - { + for (int i = 0; i < a->comp_len / 4; ++i) { glEnableVertexAttribArray(input->location + i); glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0); glVertexAttribPointer(input->location + i, 4, a->gl_comp_type, GL_FALSE, stride, (const GLubyte*)pointer + i * 16); - } } + } else { glEnableVertexAttribArray(input->location); glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0); - switch (a->fetch_mode) - { + switch (a->fetch_mode) { case GWN_FETCH_FLOAT: case GWN_FETCH_INT_TO_FLOAT: glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); @@ -383,47 +380,47 @@ static void create_bindings(Gwn_VertBuf* verts, const Gwn_ShaderInterface* inter break; case GWN_FETCH_INT: glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer); - } + break; } } } } +} -static void batch_update_program_bindings(Gwn_Batch* batch, unsigned int v_first) - { - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) +static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first) +{ + for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false); - - if (batch->inst) + } + if (batch->inst) { create_bindings(batch->inst, batch->interface, v_first, true); - - if (batch->elem) + } + if (batch->elem) { GWN_indexbuf_use(batch->elem); } +} void GWN_batch_program_use_begin(Gwn_Batch* batch) - { - // NOTE: use_program & done_using_program are fragile, depend on staying in sync with - // the GL context's active program. use_program doesn't mark other programs as "not used". - // TODO: make not fragile (somehow) +{ + /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with + * the GL context's active program. use_program doesn't mark other programs as "not used". */ + /* TODO: make not fragile (somehow) */ - if (!batch->program_in_use) - { + if (!batch->program_in_use) { glUseProgram(batch->program); batch->program_in_use = true; - } } +} void GWN_batch_program_use_end(Gwn_Batch* batch) - { - if (batch->program_in_use) - { +{ + if (batch->program_in_use) { #if PROGRAM_NO_OPTI glUseProgram(0); #endif batch->program_in_use = false; - } } +} #if TRUST_NO_ONE #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); assert(uniform); @@ -432,82 +429,82 @@ void GWN_batch_program_use_end(Gwn_Batch* batch) #endif void GWN_batch_uniform_1ui(Gwn_Batch* batch, const char* name, int value) - { +{ GET_UNIFORM glUniform1ui(uniform->location, value); - } +} void GWN_batch_uniform_1i(Gwn_Batch* batch, const char* name, int value) - { +{ GET_UNIFORM glUniform1i(uniform->location, value); - } +} void GWN_batch_uniform_1b(Gwn_Batch* batch, const char* name, bool value) - { +{ GET_UNIFORM glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE); - } +} void GWN_batch_uniform_2f(Gwn_Batch* batch, const char* name, float x, float y) - { +{ GET_UNIFORM glUniform2f(uniform->location, x, y); - } +} void GWN_batch_uniform_3f(Gwn_Batch* batch, const char* name, float x, float y, float z) - { +{ GET_UNIFORM glUniform3f(uniform->location, x, y, z); - } +} void GWN_batch_uniform_4f(Gwn_Batch* batch, const char* name, float x, float y, float z, float w) - { +{ GET_UNIFORM glUniform4f(uniform->location, x, y, z, w); - } +} void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x) - { +{ GET_UNIFORM glUniform1f(uniform->location, x); - } +} void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2]) - { +{ GET_UNIFORM glUniform2fv(uniform->location, 1, data); - } +} void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3]) - { +{ GET_UNIFORM glUniform3fv(uniform->location, 1, data); - } +} void GWN_batch_uniform_4fv(Gwn_Batch* batch, const char* name, const float data[4]) - { +{ GET_UNIFORM glUniform4fv(uniform->location, 1, data); - } +} void GWN_batch_uniform_2fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) - { +{ GET_UNIFORM glUniform2fv(uniform->location, len, data); - } +} void GWN_batch_uniform_4fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) - { +{ GET_UNIFORM glUniform4fv(uniform->location, len, data); - } +} void GWN_batch_uniform_mat4(Gwn_Batch* batch, const char* name, const float data[4][4]) - { +{ GET_UNIFORM glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); - } +} static void primitive_restart_enable(const Gwn_IndexBuf *el) { @@ -531,7 +528,7 @@ static void primitive_restart_disable(void) } void GWN_batch_draw(Gwn_Batch* batch) - { +{ #if TRUST_NO_ONE assert(batch->phase == GWN_BATCH_READY_TO_DRAW); assert(batch->verts[0]->vbo_id != 0); @@ -542,91 +539,107 @@ void GWN_batch_draw(Gwn_Batch* batch) GWN_batch_draw_range_ex(batch, 0, 0, false); GWN_batch_program_use_end(batch); - } +} void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool force_instance) - { +{ #if TRUST_NO_ONE assert(!(force_instance && (batch->inst == NULL)) || v_count > 0); // we cannot infer length if force_instance #endif const bool do_instance = (force_instance || batch->inst); // If using offset drawing, use the default VAO and redo bindings. - if (v_first != 0 && (do_instance || batch->elem)) - { + if (v_first != 0 && (do_instance || batch->elem)) { glBindVertexArray(GWN_vao_default()); batch_update_program_bindings(batch, v_first); - } - else + } + else { glBindVertexArray(batch->vao_id); + } - if (do_instance) - { - // Infer length if vertex count is not given - if (v_count == 0) + if (do_instance) { + /* Infer length if vertex count is not given */ + if (v_count == 0) { v_count = batch->inst->vertex_len; + } - if (batch->elem) - { + if (batch->elem) { const Gwn_IndexBuf* el = batch->elem; - if (el->use_prim_restart) + if (el->use_prim_restart) { primitive_restart_enable(el); - + } #if GWN_TRACK_INDEX_RANGE - glDrawElementsInstancedBaseVertex(batch->gl_prim_type, el->index_len, el->gl_index_type, 0, v_count, el->base_index); + glDrawElementsInstancedBaseVertex(batch->gl_prim_type, + el->index_len, + el->gl_index_type, + 0, + v_count, + el->base_index); #else glDrawElementsInstanced(batch->gl_prim_type, el->index_len, GL_UNSIGNED_INT, 0, v_count); #endif - if (el->use_prim_restart) + if (el->use_prim_restart) { primitive_restart_disable(); } - else + } + else { glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_len, v_count); } - else - { - // Infer length if vertex count is not given - if (v_count == 0) + } + else { + /* Infer length if vertex count is not given */ + if (v_count == 0) { v_count = (batch->elem) ? batch->elem->index_len : batch->verts[0]->vertex_len; + } - if (batch->elem) - { + if (batch->elem) { const Gwn_IndexBuf* el = batch->elem; - if (el->use_prim_restart) + if (el->use_prim_restart) { primitive_restart_enable(el); + } #if GWN_TRACK_INDEX_RANGE - if (el->base_index) - glDrawRangeElementsBaseVertex(batch->gl_prim_type, el->min_index, el->max_index, v_count, el->gl_index_type, 0, el->base_index); - else + if (el->base_index) { + glDrawRangeElementsBaseVertex(batch->gl_prim_type, + el->min_index, + el->max_index, + v_count, + el->gl_index_type, + 0, + el->base_index); + } + else { glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, v_count, el->gl_index_type, 0); + } #else glDrawElements(batch->gl_prim_type, v_count, GL_UNSIGNED_INT, 0); #endif - if (el->use_prim_restart) + if (el->use_prim_restart) { primitive_restart_disable(); } - else + } + else { glDrawArrays(batch->gl_prim_type, v_first, v_count); } + } - // Performance hog if you are drawing with the same vao multiple time. - // Only activate for debugging. + /* Performance hog if you are drawing with the same vao multiple time. + * Only activate for debugging. */ // glBindVertexArray(0); - } +} -// just draw some vertices and let shader place them where we want. +/* just draw some vertices and let shader place them where we want. */ void GWN_draw_primitive(Gwn_PrimType prim_type, int v_count) { - // we cannot draw without vao ... annoying ... + /* we cannot draw without vao ... annoying ... */ glBindVertexArray(GWN_vao_default()); GLenum type = convert_prim_type_to_gl(prim_type); glDrawArrays(type, 0, v_count); - // Performance hog if you are drawing with the same vao multiple time. - // Only activate for debugging. + /* Performance hog if you are drawing with the same vao multiple time. + * Only activate for debugging.*/ // glBindVertexArray(0); } diff --git a/intern/gawain/src/gwn_buffer_id.cpp b/intern/gawain/src/gwn_buffer_id.cpp index 13473f1f28d..2c267682f65 100644 --- a/intern/gawain/src/gwn_buffer_id.cpp +++ b/intern/gawain/src/gwn_buffer_id.cpp @@ -1,13 +1,33 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain buffer IDs -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.#include "buffer_id.h" +/** \file blender/gpu/intern/gwn_buffer_id.cpp + * \ingroup gpu + * + * Gawain buffer IDs + */ #include "gwn_buffer_id.h" #include @@ -24,47 +44,46 @@ static std::vector orphaned_buffer_ids; static std::mutex orphan_mutex; extern "C" { -extern int BLI_thread_is_main(void); // Blender-specific function +extern int BLI_thread_is_main(void); /* Blender-specific function */ } static bool thread_is_main() - { - // "main" here means the GL context's thread +{ + /* "main" here means the GL context's thread */ return BLI_thread_is_main(); - } +} GLuint GWN_buf_id_alloc() - { - // delete orphaned IDs +{ + /* delete orphaned IDs */ orphan_mutex.lock(); - if (!orphaned_buffer_ids.empty()) - { - const auto orphaned_buffer_len = (unsigned)orphaned_buffer_ids.size(); + if (!orphaned_buffer_ids.empty()) { + const auto orphaned_buffer_len = (uint)orphaned_buffer_ids.size(); #if ORPHAN_DEBUG printf("deleting %u orphaned VBO%s\n", orphaned_buffer_len, orphaned_buffer_len == 1 ? "" : "s"); #endif glDeleteBuffers(orphaned_buffer_len, orphaned_buffer_ids.data()); orphaned_buffer_ids.clear(); - } + } orphan_mutex.unlock(); GLuint new_buffer_id = 0; glGenBuffers(1, &new_buffer_id); return new_buffer_id; - } +} void GWN_buf_id_free(GLuint buffer_id) - { - if (thread_is_main()) +{ + if (thread_is_main()) { glDeleteBuffers(1, &buffer_id); - else - { - // add this ID to the orphaned list + } + else { + /* add this ID to the orphaned list */ orphan_mutex.lock(); #if ORPHAN_DEBUG printf("orphaning VBO %u\n", buffer_id); #endif orphaned_buffer_ids.emplace_back(buffer_id); orphan_mutex.unlock(); - } } +} diff --git a/intern/gawain/src/gwn_element.c b/intern/gawain/src/gwn_element.c index 257338fe089..a8c99f20860 100644 --- a/intern/gawain/src/gwn_element.c +++ b/intern/gawain/src/gwn_element.c @@ -1,13 +1,33 @@ - -// Gawain element list (AKA index buffer) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_element.c + * \ingroup gpu + * + * Gawain element list (AKA index buffer) + */ #include "gwn_element.h" #include "gwn_buffer_id.h" @@ -16,44 +36,45 @@ #define KEEP_SINGLE_COPY 1 static GLenum convert_index_type_to_gl(Gwn_IndexBufType type) - { +{ static const GLenum table[] = { - [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, // GL has this, Vulkan does not + [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ [GWN_INDEX_U16] = GL_UNSIGNED_SHORT, [GWN_INDEX_U32] = GL_UNSIGNED_INT - }; + }; return table[type]; - } +} -unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) - { +uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) +{ #if GWN_TRACK_INDEX_RANGE - static const unsigned table[] = { - [GWN_INDEX_U8] = sizeof(GLubyte), // GL has this, Vulkan does not + static const uint table[] = { + [GWN_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ [GWN_INDEX_U16] = sizeof(GLushort), [GWN_INDEX_U32] = sizeof(GLuint) - }; + }; return elem->index_len * table[elem->index_type]; #else return elem->index_len * sizeof(GLuint); #endif - } +} -void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, unsigned index_len, unsigned vertex_len, bool use_prim_restart) - { +void GWN_indexbuf_init_ex( + Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, + uint index_len, uint vertex_len, bool use_prim_restart) +{ builder->use_prim_restart = use_prim_restart; builder->max_allowed_index = vertex_len - 1; builder->max_index_len = index_len; builder->index_len = 0; // start empty builder->prim_type = prim_type; - builder->data = calloc(builder->max_index_len, sizeof(unsigned)); - } + builder->data = calloc(builder->max_index_len, sizeof(uint)); +} -void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, unsigned prim_len, unsigned vertex_len) - { - unsigned verts_per_prim = 0; - switch (prim_type) - { +void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uint prim_len, uint vertex_len) +{ + uint verts_per_prim = 0; + switch (prim_type) { case GWN_PRIM_POINTS: verts_per_prim = 1; break; @@ -71,234 +92,216 @@ void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uns assert(false); #endif return; - } + } GWN_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); - } +} -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, unsigned v) - { +void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v) +{ #if TRUST_NO_ONE assert(builder->data != NULL); assert(builder->index_len < builder->max_index_len); assert(v <= builder->max_allowed_index); #endif - builder->data[builder->index_len++] = v; - } +} void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder* builder) - { +{ #if TRUST_NO_ONE assert(builder->data != NULL); assert(builder->index_len < builder->max_index_len); assert(builder->use_prim_restart); #endif - builder->data[builder->index_len++] = GWN_PRIM_RESTART; - } +} -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, unsigned v) - { +void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, uint v) +{ #if TRUST_NO_ONE assert(builder->prim_type == GWN_PRIM_POINTS); #endif - GWN_indexbuf_add_generic_vert(builder, v); - } +} -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2) - { +void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2) +{ #if TRUST_NO_ONE assert(builder->prim_type == GWN_PRIM_LINES); assert(v1 != v2); #endif - GWN_indexbuf_add_generic_vert(builder, v1); GWN_indexbuf_add_generic_vert(builder, v2); - } +} -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2, unsigned v3) - { +void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3) +{ #if TRUST_NO_ONE assert(builder->prim_type == GWN_PRIM_TRIS); assert(v1 != v2 && v2 != v3 && v3 != v1); #endif - GWN_indexbuf_add_generic_vert(builder, v1); GWN_indexbuf_add_generic_vert(builder, v2); GWN_indexbuf_add_generic_vert(builder, v3); - } +} -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, unsigned v1, unsigned v2, unsigned v3, unsigned v4) - { +void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) +{ #if TRUST_NO_ONE assert(builder->prim_type == GWN_PRIM_LINES_ADJ); assert(v2 != v3); /* only the line need diff indices */ #endif - GWN_indexbuf_add_generic_vert(builder, v1); GWN_indexbuf_add_generic_vert(builder, v2); GWN_indexbuf_add_generic_vert(builder, v3); GWN_indexbuf_add_generic_vert(builder, v4); - } +} #if GWN_TRACK_INDEX_RANGE -// Everything remains 32 bit while building to keep things simple. -// Find min/max after, then convert to smallest index type possible. +/* Everything remains 32 bit while building to keep things simple. + * Find min/max after, then convert to smallest index type possible. */ -static unsigned index_range(const unsigned values[], unsigned value_len, unsigned* min_out, unsigned* max_out) - { - if (value_len == 0) - { +static uint index_range(const uint values[], uint value_len, uint* min_out, uint* max_out) +{ + if (value_len == 0) { *min_out = 0; *max_out = 0; return 0; - } - unsigned min_value = values[0]; - unsigned max_value = values[0]; - for (unsigned i = 1; i < value_len; ++i) - { - const unsigned value = values[i]; + } + uint min_value = values[0]; + uint max_value = values[0]; + for (uint i = 1; i < value_len; ++i) { + const uint value = values[i]; if (value == GWN_PRIM_RESTART) continue; else if (value < min_value) min_value = value; else if (value > max_value) max_value = value; - } + } *min_out = min_value; *max_out = max_value; return max_value - min_value; - } +} static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) - { - const unsigned *values = builder->data; - const unsigned index_len = elem->index_len; +{ + const uint *values = builder->data; + const uint index_len = elem->index_len; - // data will never be *larger* than builder->data... - // converting in place to avoid extra allocation + /* data will never be *larger* than builder->data... + * converting in place to avoid extra allocation */ GLubyte *data = (GLubyte *)builder->data; - if (elem->max_index > 0xFF) - { - const unsigned base = elem->min_index; - + if (elem->max_index > 0xFF) { + const uint base = elem->min_index; elem->base_index = base; elem->min_index = 0; elem->max_index -= base; - - for (unsigned i = 0; i < index_len; ++i) + for (uint i = 0; i < index_len; ++i) { data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); } - else - { + } + else { elem->base_index = 0; - - for (unsigned i = 0; i < index_len; ++i) + for (uint i = 0; i < index_len; ++i) { data[i] = (GLubyte)(values[i]); } } +} static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) - { - const unsigned *values = builder->data; - const unsigned index_len = elem->index_len; +{ + const uint *values = builder->data; + const uint index_len = elem->index_len; - // data will never be *larger* than builder->data... - // converting in place to avoid extra allocation + /* data will never be *larger* than builder->data... + * converting in place to avoid extra allocation */ GLushort *data = (GLushort *)builder->data; - if (elem->max_index > 0xFFFF) - { - const unsigned base = elem->min_index; - + if (elem->max_index > 0xFFFF) { + const uint base = elem->min_index; elem->base_index = base; elem->min_index = 0; elem->max_index -= base; - - for (unsigned i = 0; i < index_len; ++i) + for (uint i = 0; i < index_len; ++i) { data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); } - else - { + } + else { elem->base_index = 0; - - for (unsigned i = 0; i < index_len; ++i) + for (uint i = 0; i < index_len; ++i) { data[i] = (GLushort)(values[i]); } } +} -#endif // GWN_TRACK_INDEX_RANGE +#endif /* GWN_TRACK_INDEX_RANGE */ Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder* builder) - { +{ Gwn_IndexBuf* elem = calloc(1, sizeof(Gwn_IndexBuf)); GWN_indexbuf_build_in_place(builder, elem); return elem; - } +} void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* elem) - { +{ #if TRUST_NO_ONE assert(builder->data != NULL); #endif - elem->index_len = builder->index_len; elem->use_prim_restart = builder->use_prim_restart; #if GWN_TRACK_INDEX_RANGE - unsigned range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); + uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); - // count the primitive restart index. - if (elem->use_prim_restart) + /* count the primitive restart index. */ + if (elem->use_prim_restart) { range += 1; + } - if (range <= 0xFF) - { + if (range <= 0xFF) { elem->index_type = GWN_INDEX_U8; squeeze_indices_byte(builder, elem); - } - else if (range <= 0xFFFF) - { + } + else if (range <= 0xFFFF) { elem->index_type = GWN_INDEX_U16; squeeze_indices_short(builder, elem); - } - else - { + } + else { elem->index_type = GWN_INDEX_U32; elem->base_index = 0; - } - + } elem->gl_index_type = convert_index_type_to_gl(elem->index_type); #endif - if (elem->vbo_id == 0) + if (elem->vbo_id == 0) { elem->vbo_id = GWN_buf_id_alloc(); - - // send data to GPU - // GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, - // so we use the GL_ARRAY_BUFFER here to create a buffer without - // interfering in the VAO state. + } + /* send data to GPU */ + /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, + * so we use the GL_ARRAY_BUFFER here to create a buffer without + * interfering in the VAO state. */ glBindBuffer(GL_ARRAY_BUFFER, elem->vbo_id); glBufferData(GL_ARRAY_BUFFER, GWN_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); - // discard builder (one-time use) + /* discard builder (one-time use) */ free(builder->data); builder->data = NULL; - // other fields are safe to leave - } + /* other fields are safe to leave */ +} void GWN_indexbuf_use(Gwn_IndexBuf* elem) - { +{ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id); - } +} void GWN_indexbuf_discard(Gwn_IndexBuf* elem) - { - if (elem->vbo_id) +{ + if (elem->vbo_id) { GWN_buf_id_free(elem->vbo_id); - - free(elem); } + free(elem); +} diff --git a/intern/gawain/src/gwn_imm_util.c b/intern/gawain/src/gwn_imm_util.c index a8d2b05c8a3..cdf55c3dfc4 100644 --- a/intern/gawain/src/gwn_imm_util.c +++ b/intern/gawain/src/gwn_imm_util.c @@ -1,40 +1,60 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain immediate mode drawing utilities -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/intern/gwn_imm_util.c + * \ingroup gpu + * + * Gawain immediate mode drawing utilities + */ #include "gwn_imm_util.h" #include "gwn_immediate.h" +#include - -void immRectf(unsigned pos, float x1, float y1, float x2, float y2) - { +void immRectf(uint pos, float x1, float y1, float x2, float y2) +{ immBegin(GWN_PRIM_TRI_FAN, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x2, y1); immVertex2f(pos, x2, y2); immVertex2f(pos, x1, y2); immEnd(); - } +} -void immRecti(unsigned pos, int x1, int y1, int x2, int y2) - { +void immRecti(uint pos, int x1, int y1, int x2, int y2) +{ immBegin(GWN_PRIM_TRI_FAN, 4); immVertex2i(pos, x1, y1); immVertex2i(pos, x2, y1); immVertex2i(pos, x2, y2); immVertex2i(pos, x1, y2); immEnd(); - } +} -void immRectf_fast_with_color(unsigned pos, unsigned col, float x1, float y1, float x2, float y2, const float color[4]) - { +void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]) +{ immAttrib4fv(col, color); immVertex2f(pos, x1, y1); immAttrib4fv(col, color); @@ -48,10 +68,10 @@ void immRectf_fast_with_color(unsigned pos, unsigned col, float x1, float y1, fl immVertex2f(pos, x2, y2); immAttrib4fv(col, color); immVertex2f(pos, x1, y2); - } +} -void immRecti_fast_with_color(unsigned pos, unsigned col, int x1, int y1, int x2, int y2, const float color[4]) - { +void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]) +{ immAttrib4fv(col, color); immVertex2i(pos, x1, y1); immAttrib4fv(col, color); @@ -65,16 +85,16 @@ void immRecti_fast_with_color(unsigned pos, unsigned col, int x1, int y1, int x2 immVertex2i(pos, x2, y2); immAttrib4fv(col, color); immVertex2i(pos, x1, y2); - } +} -#if 0 // more complete version in case we want that +#if 0 /* more complete version in case we want that */ void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4]) - { +{ Gwn_VertFormat *format = immVertexFormat(); - unsigned pos = add_attrib(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = add_attrib(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); immRecti(pos, x1, y1, x2, y2); immUnbindProgram(); - } +} #endif diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c index f6760b0e9da..442aa85ece4 100644 --- a/intern/gawain/src/gwn_immediate.c +++ b/intern/gawain/src/gwn_immediate.c @@ -1,13 +1,33 @@ - -// Gawain immediate mode work-alike -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_immediate.c + * \ingroup gpu + * + * Gawain immediate mode work-alike + */ #include "gwn_immediate.h" #include "gwn_buffer_id.h" @@ -17,33 +37,32 @@ #include "gwn_vertex_array_id.h" #include "gwn_primitive_private.h" #include +#include -// necessary functions from matrix API +/* necessary functions from matrix API */ extern void GPU_matrix_bind(const Gwn_ShaderInterface*); extern bool GPU_matrix_dirty_get(void); typedef struct { - // TODO: organize this struct by frequency of change (run-time) + /* TODO: organize this struct by frequency of change (run-time) */ -#if IMM_BATCH_COMBO Gwn_Batch* batch; -#endif Gwn_Context* context; - // current draw call + /* current draw call */ GLubyte* buffer_data; - unsigned buffer_offset; - unsigned buffer_bytes_mapped; - unsigned vertex_len; + uint buffer_offset; + uint buffer_bytes_mapped; + uint vertex_len; bool strict_vertex_len; Gwn_PrimType prim_type; Gwn_VertFormat vertex_format; - // current vertex - unsigned vertex_idx; + /* current vertex */ + uint vertex_idx; GLubyte* vertex_data; - uint16_t unassigned_attrib_bits; // which attributes of current vertex have not been given values? + uint16_t unassigned_attrib_bits; /* which attributes of current vertex have not been given values? */ GLuint vbo_id; GLuint vao_id; @@ -51,21 +70,20 @@ typedef struct { GLuint bound_program; const Gwn_ShaderInterface* shader_interface; Gwn_AttrBinding attrib_binding; - uint16_t prev_enabled_attrib_bits; // <-- only affects this VAO, so we're ok + uint16_t prev_enabled_attrib_bits; /* <-- only affects this VAO, so we're ok */ } Immediate; -// size of internal buffer -- make this adjustable? +/* size of internal buffer -- make this adjustable? */ #define IMM_BUFFER_SIZE (4 * 1024 * 1024) static bool initialized = false; static Immediate imm; void immInit(void) - { +{ #if TRUST_NO_ONE assert(!initialized); #endif - memset(&imm, 0, sizeof(Immediate)); imm.vbo_id = GWN_buf_id_alloc(); @@ -77,45 +95,45 @@ void immInit(void) glBindBuffer(GL_ARRAY_BUFFER, 0); initialized = true; - } +} void immActivate(void) - { +{ #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); // make sure we're not between a Begin/End pair + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ assert(imm.vao_id == 0); #endif imm.vao_id = GWN_vao_alloc(); imm.context = GWN_context_active_get(); - } +} void immDeactivate(void) - { +{ #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); // make sure we're not between a Begin/End pair + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ assert(imm.vao_id != 0); #endif GWN_vao_free(imm.vao_id, imm.context); imm.vao_id = 0; imm.prev_enabled_attrib_bits = 0; - } +} void immDestroy(void) - { +{ GWN_buf_id_free(imm.vbo_id); initialized = false; - } +} Gwn_VertFormat* immVertexFormat(void) - { +{ GWN_vertformat_clear(&imm.vertex_format); return &imm.vertex_format; - } +} void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) - { +{ #if TRUST_NO_ONE assert(imm.bound_program == 0); assert(glIsProgram(program)); @@ -130,10 +148,10 @@ void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) glUseProgram(program); get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface); GPU_matrix_bind(shaderface); - } +} void immUnbindProgram(void) - { +{ #if TRUST_NO_ONE assert(imm.bound_program != 0); #endif @@ -141,17 +159,17 @@ void immUnbindProgram(void) glUseProgram(0); #endif imm.bound_program = 0; - } +} #if TRUST_NO_ONE -static bool vertex_count_makes_sense_for_primitive(unsigned vertex_len, Gwn_PrimType prim_type) - { - // does vertex_len make sense for this primitive type? - if (vertex_len == 0) +static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType prim_type) +{ + /* does vertex_len make sense for this primitive type? */ + if (vertex_len == 0) { return false; + } - switch (prim_type) - { + switch (prim_type) { case GWN_PRIM_POINTS: return true; case GWN_PRIM_LINES: @@ -168,25 +186,24 @@ static bool vertex_count_makes_sense_for_primitive(unsigned vertex_len, Gwn_Prim return vertex_len >= 3; default: return false; - } } +} #endif -void immBegin(Gwn_PrimType prim_type, unsigned vertex_len) - { +void immBegin(Gwn_PrimType prim_type, uint vertex_len) +{ #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); // make sure we haven't already begun + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); #endif - imm.prim_type = prim_type; imm.vertex_len = vertex_len; imm.vertex_idx = 0; imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - // how many bytes do we need for this draw call? - const unsigned bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); + /* how many bytes do we need for this draw call? */ + const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); #if TRUST_NO_ONE assert(bytes_needed <= IMM_BUFFER_SIZE); @@ -194,41 +211,22 @@ void immBegin(Gwn_PrimType prim_type, unsigned vertex_len) glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); - // does the current buffer have enough room? - const unsigned available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; - // ensure vertex data is aligned - const unsigned pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); // might waste a little space, but it's safe - if ((bytes_needed + pre_padding) <= available_bytes) + /* does the current buffer have enough room? */ + const uint available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; + /* ensure vertex data is aligned */ + const uint pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); /* might waste a little space, but it's safe */ + if ((bytes_needed + pre_padding) <= available_bytes) { imm.buffer_offset += pre_padding; - else - { - // orphan this buffer & start with a fresh one -#if 1 - // this method works on all platforms, old & new + } + else { + /* orphan this buffer & start with a fresh one */ + /* this method works on all platforms, old & new */ glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); -#else - // TODO: use other (more recent) methods after thorough testing - if (GLEW_VERSION_4_3 || GLEW_ARB_invalidate_subdata) - glInvalidateBufferData(imm.vbo_id); - else - { - // glitches! -// glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, GL_MAP_INVALIDATE_BUFFER_BIT); - - // works -// glMapBufferRange(GL_ARRAY_BUFFER, 0, IMM_BUFFER_SIZE, -// GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); -// glUnmapBuffer(GL_ARRAY_BUFFER); - - // also works - glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); - } -#endif imm.buffer_offset = 0; - } + } -// printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); +/* printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */ imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)); @@ -239,28 +237,26 @@ void immBegin(Gwn_PrimType prim_type, unsigned vertex_len) imm.buffer_bytes_mapped = bytes_needed; imm.vertex_data = imm.buffer_data; - } +} -void immBeginAtMost(Gwn_PrimType prim_type, unsigned vertex_len) - { +void immBeginAtMost(Gwn_PrimType prim_type, uint vertex_len) +{ #if TRUST_NO_ONE assert(vertex_len > 0); #endif imm.strict_vertex_len = false; immBegin(prim_type, vertex_len); - } +} -#if IMM_BATCH_COMBO -Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, unsigned vertex_len) - { +Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, uint vertex_len) +{ #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); // make sure we haven't already begun + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); #endif - imm.prim_type = prim_type; imm.vertex_len = vertex_len; imm.vertex_idx = 0; @@ -276,59 +272,47 @@ Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, unsigned vertex_len) imm.batch->phase = GWN_BATCH_BUILDING; return imm.batch; - } +} -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType prim_type, unsigned vertex_len) - { +Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType prim_type, uint vertex_len) +{ imm.strict_vertex_len = false; return immBeginBatch(prim_type, vertex_len); - } - -#endif // IMM_BATCH_COMBO +} static void immDrawSetup(void) - { - // set up VAO -- can be done during Begin or End really +{ + /* set up VAO -- can be done during Begin or End really */ glBindVertexArray(imm.vao_id); - // enable/disable vertex attribs as needed - if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits) - { - for (unsigned loc = 0; loc < GWN_VERT_ATTR_MAX_LEN; ++loc) - { + /* enable/disable vertex attribs as needed */ + if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits) { + for (uint loc = 0; loc < GWN_VERT_ATTR_MAX_LEN; ++loc) { bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc); bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc); - if (is_enabled && !was_enabled) - { -// printf("enabling attrib %u\n", loc); + if (is_enabled && !was_enabled) { glEnableVertexAttribArray(loc); - } - else if (was_enabled && !is_enabled) - { -// printf("disabling attrib %u\n", loc); + } + else if (was_enabled && !is_enabled) { glDisableVertexAttribArray(loc); - } } + } imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits; - } + } - const unsigned stride = imm.vertex_format.stride; + const uint stride = imm.vertex_format.stride; - for (unsigned a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) - { + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; - const unsigned offset = imm.buffer_offset + a->offset; + const uint offset = imm.buffer_offset + a->offset; const GLvoid* pointer = (const GLubyte*)0 + offset; - const unsigned loc = read_attrib_location(&imm.attrib_binding, a_idx); - -// printf("specifying attrib %u '%s' with offset %u, stride %u\n", loc, a->name, offset, stride); + const uint loc = read_attrib_location(&imm.attrib_binding, a_idx); - switch (a->fetch_mode) - { + switch (a->fetch_mode) { case GWN_FETCH_FLOAT: case GWN_FETCH_INT_TO_FLOAT: glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); @@ -338,414 +322,372 @@ static void immDrawSetup(void) break; case GWN_FETCH_INT: glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); - } } + } - if (GPU_matrix_dirty_get()) + if (GPU_matrix_dirty_get()) { GPU_matrix_bind(imm.shader_interface); } +} void immEnd(void) - { +{ #if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - unsigned buffer_bytes_used; - if (imm.strict_vertex_len) - { + uint buffer_bytes_used; + if (imm.strict_vertex_len) { #if TRUST_NO_ONE - assert(imm.vertex_idx == imm.vertex_len); // with all vertices defined + assert(imm.vertex_idx == imm.vertex_len); /* with all vertices defined */ #endif buffer_bytes_used = imm.buffer_bytes_mapped; - } - else - { + } + else { #if TRUST_NO_ONE assert(imm.vertex_idx <= imm.vertex_len); #endif - // printf("used %u of %u verts,", imm.vertex_idx, imm.vertex_len); - if (imm.vertex_idx == imm.vertex_len) - { + if (imm.vertex_idx == imm.vertex_len) { buffer_bytes_used = imm.buffer_bytes_mapped; - } - else - { + } + else { #if TRUST_NO_ONE assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type)); #endif imm.vertex_len = imm.vertex_idx; buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_len); - // unused buffer bytes are available to the next immBegin - // printf(" %u of %u bytes\n", buffer_bytes_used, imm.buffer_bytes_mapped); - } - - // tell OpenGL what range was modified so it doesn't copy the whole mapped range - // printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1); - glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used); + /* unused buffer bytes are available to the next immBegin */ } + /* tell OpenGL what range was modified so it doesn't copy the whole mapped range */ + glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used); + } -#if IMM_BATCH_COMBO - if (imm.batch) - { - if (buffer_bytes_used != imm.buffer_bytes_mapped) - { + if (imm.batch) { + if (buffer_bytes_used != imm.buffer_bytes_mapped) { GWN_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); - // TODO: resize only if vertex count is much smaller - } - + /* TODO: resize only if vertex count is much smaller */ + } GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); imm.batch->phase = GWN_BATCH_READY_TO_DRAW; - imm.batch = NULL; // don't free, batch belongs to caller - } - else -#endif - { + imm.batch = NULL; /* don't free, batch belongs to caller */ + } + else { glUnmapBuffer(GL_ARRAY_BUFFER); - - if (imm.vertex_len > 0) - { + if (imm.vertex_len > 0) { immDrawSetup(); glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_len); - } - + } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - - // prep for next immBegin + /* prep for next immBegin */ imm.buffer_offset += buffer_bytes_used; - } + } - // prep for next immBegin + /* prep for next immBegin */ imm.prim_type = GWN_PRIM_NONE; imm.strict_vertex_len = true; - } +} -static void setAttribValueBit(unsigned attrib_id) - { +static void setAttribValueBit(uint attrib_id) +{ uint16_t mask = 1 << attrib_id; - #if TRUST_NO_ONE - assert(imm.unassigned_attrib_bits & mask); // not already set + assert(imm.unassigned_attrib_bits & mask); /* not already set */ #endif - imm.unassigned_attrib_bits &= ~mask; - } +} -// --- generic attribute functions --- +/* --- generic attribute functions --- */ -void immAttrib1f(unsigned attrib_id, float x) - { +void immAttrib1f(uint attrib_id, float x) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_F32); assert(attrib->comp_len == 1); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); float* data = (float*)(imm.vertex_data + attrib->offset); -// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; - } +} -void immAttrib2f(unsigned attrib_id, float x, float y) - { +void immAttrib2f(uint attrib_id, float x, float y) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_F32); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); float* data = (float*)(imm.vertex_data + attrib->offset); -// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; data[1] = y; - } +} -void immAttrib3f(unsigned attrib_id, float x, float y, float z) - { +void immAttrib3f(uint attrib_id, float x, float y, float z) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_F32); assert(attrib->comp_len == 3); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); float* data = (float*)(imm.vertex_data + attrib->offset); -// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; data[1] = y; data[2] = z; - } +} -void immAttrib4f(unsigned attrib_id, float x, float y, float z, float w) - { +void immAttrib4f(uint attrib_id, float x, float y, float z, float w) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_F32); assert(attrib->comp_len == 4); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); float* data = (float*)(imm.vertex_data + attrib->offset); -// printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; data[1] = y; data[2] = z; data[3] = w; - } +} -void immAttrib1u(unsigned attrib_id, unsigned x) - { +void immAttrib1u(uint attrib_id, uint x) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_U32); assert(attrib->comp_len == 1); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); - unsigned* data = (unsigned*)(imm.vertex_data + attrib->offset); + uint* data = (uint*)(imm.vertex_data + attrib->offset); data[0] = x; - } +} -void immAttrib2i(unsigned attrib_id, int x, int y) - { +void immAttrib2i(uint attrib_id, int x, int y) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_I32); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); int* data = (int*)(imm.vertex_data + attrib->offset); data[0] = x; data[1] = y; - } +} -void immAttrib2s(unsigned attrib_id, short x, short y) - { +void immAttrib2s(uint attrib_id, short x, short y) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_I16); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); short* data = (short*)(imm.vertex_data + attrib->offset); data[0] = x; data[1] = y; - } +} -void immAttrib2fv(unsigned attrib_id, const float data[2]) - { +void immAttrib2fv(uint attrib_id, const float data[2]) +{ immAttrib2f(attrib_id, data[0], data[1]); - } +} -void immAttrib3fv(unsigned attrib_id, const float data[3]) - { +void immAttrib3fv(uint attrib_id, const float data[3]) +{ immAttrib3f(attrib_id, data[0], data[1], data[2]); - } +} -void immAttrib4fv(unsigned attrib_id, const float data[4]) - { +void immAttrib4fv(uint attrib_id, const float data[4]) +{ immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]); - } +} -void immAttrib3ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b) - { +void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_U8); assert(attrib->comp_len == 3); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); GLubyte* data = imm.vertex_data + attrib->offset; -// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ data[0] = r; data[1] = g; data[2] = b; - } +} -void immAttrib4ub(unsigned attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) - { +void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; - #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GWN_COMP_U8); assert(attrib->comp_len == 4); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); GLubyte* data = imm.vertex_data + attrib->offset; -// printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); +/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ data[0] = r; data[1] = g; data[2] = b; data[3] = a; - } +} -void immAttrib3ubv(unsigned attrib_id, const unsigned char data[3]) - { +void immAttrib3ubv(uint attrib_id, const unsigned char data[3]) +{ immAttrib3ub(attrib_id, data[0], data[1], data[2]); - } +} -void immAttrib4ubv(unsigned attrib_id, const unsigned char data[4]) - { +void immAttrib4ubv(uint attrib_id, const unsigned char data[4]) +{ immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]); - } +} -void immSkipAttrib(unsigned attrib_id) - { +void immSkipAttrib(uint attrib_id) +{ #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif - setAttribValueBit(attrib_id); - } +} -static void immEndVertex(void) // and move on to the next vertex - { +static void immEndVertex(void) /* and move on to the next vertex */ +{ #if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); // make sure we're between a Begin/End pair + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ assert(imm.vertex_idx < imm.vertex_len); #endif - // have all attribs been assigned values? - // if not, copy value from previous vertex - if (imm.unassigned_attrib_bits) - { + /* have all attribs been assigned values? + * if not, copy value from previous vertex */ + if (imm.unassigned_attrib_bits) { #if TRUST_NO_ONE - assert(imm.vertex_idx > 0); // first vertex must have all attribs specified + assert(imm.vertex_idx > 0); /* first vertex must have all attribs specified */ #endif - - for (unsigned a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) - { - if ((imm.unassigned_attrib_bits >> a_idx) & 1) - { + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { + if ((imm.unassigned_attrib_bits >> a_idx) & 1) { const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; -// printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); +/* printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); */ GLubyte* data = imm.vertex_data + a->offset; memcpy(data, data - imm.vertex_format.stride, a->sz); - // TODO: consolidate copy of adjacent attributes - } + /* TODO: consolidate copy of adjacent attributes */ } } + } imm.vertex_idx++; imm.vertex_data += imm.vertex_format.stride; imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - } +} -void immVertex2f(unsigned attrib_id, float x, float y) - { +void immVertex2f(uint attrib_id, float x, float y) +{ immAttrib2f(attrib_id, x, y); immEndVertex(); - } +} -void immVertex3f(unsigned attrib_id, float x, float y, float z) - { +void immVertex3f(uint attrib_id, float x, float y, float z) +{ immAttrib3f(attrib_id, x, y, z); immEndVertex(); - } +} -void immVertex4f(unsigned attrib_id, float x, float y, float z, float w) - { +void immVertex4f(uint attrib_id, float x, float y, float z, float w) +{ immAttrib4f(attrib_id, x, y, z, w); immEndVertex(); - } +} -void immVertex2i(unsigned attrib_id, int x, int y) - { +void immVertex2i(uint attrib_id, int x, int y) +{ immAttrib2i(attrib_id, x, y); immEndVertex(); - } +} -void immVertex2s(unsigned attrib_id, short x, short y) - { +void immVertex2s(uint attrib_id, short x, short y) +{ immAttrib2s(attrib_id, x, y); immEndVertex(); - } +} -void immVertex2fv(unsigned attrib_id, const float data[2]) - { +void immVertex2fv(uint attrib_id, const float data[2]) +{ immAttrib2f(attrib_id, data[0], data[1]); immEndVertex(); - } +} -void immVertex3fv(unsigned attrib_id, const float data[3]) - { +void immVertex3fv(uint attrib_id, const float data[3]) +{ immAttrib3f(attrib_id, data[0], data[1], data[2]); immEndVertex(); - } +} -void immVertex2iv(unsigned attrib_id, const int data[2]) - { +void immVertex2iv(uint attrib_id, const int data[2]) +{ immAttrib2i(attrib_id, data[0], data[1]); immEndVertex(); - } +} -// --- generic uniform functions --- +/* --- generic uniform functions --- */ #if 0 #if TRUST_NO_ONE @@ -754,49 +696,49 @@ void immVertex2iv(unsigned attrib_id, const int data[2]) #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); #endif #else - // NOTE: It is possible to have uniform fully optimized out from the shader. - // In this case we can't assert failure or allow NULL-pointer dereference. - // TODO(sergey): How can we detect existing-but-optimized-out uniform but still - // catch typos in uniform names passed to immUniform*() functions? + /* NOTE: It is possible to have uniform fully optimized out from the shader. + * In this case we can't assert failure or allow NULL-pointer dereference. + * TODO(sergey): How can we detect existing-but-optimized-out uniform but still + * catch typos in uniform names passed to immUniform*() functions? */ #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; #endif void immUniform1f(const char* name, float x) - { +{ GET_UNIFORM glUniform1f(uniform->location, x); - } +} void immUniform2f(const char* name, float x, float y) - { +{ GET_UNIFORM glUniform2f(uniform->location, x, y); - } +} void immUniform2fv(const char* name, const float data[2]) - { +{ GET_UNIFORM glUniform2fv(uniform->location, 1, data); - } +} void immUniform3f(const char* name, float x, float y, float z) - { +{ GET_UNIFORM glUniform3f(uniform->location, x, y, z); - } +} void immUniform3fv(const char* name, const float data[3]) - { +{ GET_UNIFORM glUniform3fv(uniform->location, 1, data); - } +} -// can increase this limit or move to another file +/* can increase this limit or move to another file */ #define MAX_UNIFORM_NAME_LEN 60 void immUniformArray3fv(const char* bare_name, const float *data, int count) - { - // look up "name[0]" when given "name" +{ + /* look up "name[0]" when given "name" */ const size_t len = strlen(bare_name); #if TRUST_NO_ONE assert(len <= MAX_UNIFORM_NAME_LEN); @@ -810,23 +752,23 @@ void immUniformArray3fv(const char* bare_name, const float *data, int count) GET_UNIFORM glUniform3fv(uniform->location, count, data); - } +} void immUniform4f(const char* name, float x, float y, float z, float w) - { +{ GET_UNIFORM glUniform4f(uniform->location, x, y, z, w); - } +} void immUniform4fv(const char* name, const float data[4]) - { +{ GET_UNIFORM glUniform4fv(uniform->location, 1, data); - } +} void immUniformArray4fv(const char* bare_name, const float *data, int count) - { - // look up "name[0]" when given "name" +{ + /* look up "name[0]" when given "name" */ const size_t len = strlen(bare_name); #if TRUST_NO_ONE assert(len <= MAX_UNIFORM_NAME_LEN); @@ -840,84 +782,82 @@ void immUniformArray4fv(const char* bare_name, const float *data, int count) GET_UNIFORM glUniform4fv(uniform->location, count, data); - } +} void immUniformMatrix4fv(const char* name, const float data[4][4]) - { +{ GET_UNIFORM glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data); - } +} void immUniform1i(const char* name, int x) - { +{ GET_UNIFORM glUniform1i(uniform->location, x); - } +} void immUniform4iv(const char* name, const int data[4]) - { +{ GET_UNIFORM glUniform4iv(uniform->location, 1, data); - } +} -// --- convenience functions for setting "uniform vec4 color" --- +/* --- convenience functions for setting "uniform vec4 color" --- */ void immUniformColor4f(float r, float g, float b, float a) - { +{ const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform_builtin(imm.shader_interface, GWN_UNIFORM_COLOR); - #if TRUST_NO_ONE assert(uniform != NULL); #endif - glUniform4f(uniform->location, r, g, b, a); - } +} void immUniformColor4fv(const float rgba[4]) - { +{ immUniformColor4f(rgba[0], rgba[1], rgba[2], rgba[3]); - } +} void immUniformColor3f(float r, float g, float b) - { +{ immUniformColor4f(r, g, b, 1.0f); - } +} void immUniformColor3fv(const float rgb[3]) - { +{ immUniformColor4f(rgb[0], rgb[1], rgb[2], 1.0f); - } +} void immUniformColor3fvAlpha(const float rgb[3], float a) - { +{ immUniformColor4f(rgb[0], rgb[1], rgb[2], a); - } +} -// TODO: v-- treat as sRGB? --v +/* TODO: v-- treat as sRGB? --v */ void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b) - { +{ const float scale = 1.0f / 255.0f; immUniformColor4f(scale * r, scale * g, scale * b, 1.0f); - } +} void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) - { +{ const float scale = 1.0f / 255.0f; immUniformColor4f(scale * r, scale * g, scale * b, scale * a); - } +} void immUniformColor3ubv(const unsigned char rgb[3]) - { +{ immUniformColor3ub(rgb[0], rgb[1], rgb[2]); - } +} void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char alpha) - { +{ immUniformColor4ub(rgb[0], rgb[1], rgb[2], alpha); - } +} void immUniformColor4ubv(const unsigned char rgba[4]) - { +{ immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]); - } +} diff --git a/intern/gawain/src/gwn_primitive.c b/intern/gawain/src/gwn_primitive.c index c2638bcc8c8..bec638a4972 100644 --- a/intern/gawain/src/gwn_primitive.c +++ b/intern/gawain/src/gwn_primitive.c @@ -1,21 +1,40 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ -// Gawain geometric primitives -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +/** \file blender/gpu/intern/gwn_primitive.c + * \ingroup gpu + * + * Gawain geometric primitives + */ #include "gwn_primitive.h" #include "gwn_primitive_private.h" Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type) - { - static const Gwn_PrimClass classes[] = - { +{ + static const Gwn_PrimClass classes[] = { [GWN_PRIM_POINTS] = GWN_PRIM_CLASS_POINT, [GWN_PRIM_LINES] = GWN_PRIM_CLASS_LINE, [GWN_PRIM_LINE_STRIP] = GWN_PRIM_CLASS_LINE, @@ -29,27 +48,25 @@ Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type) [GWN_PRIM_TRIS_ADJ] = GWN_PRIM_CLASS_SURFACE, [GWN_PRIM_NONE] = GWN_PRIM_CLASS_NONE - }; + }; return classes[prim_type]; - } +} bool GWN_primtype_belongs_to_class(Gwn_PrimType prim_type, Gwn_PrimClass prim_class) - { - if (prim_class == GWN_PRIM_CLASS_NONE && prim_type == GWN_PRIM_NONE) +{ + if (prim_class == GWN_PRIM_CLASS_NONE && prim_type == GWN_PRIM_NONE) { return true; - - return prim_class & GWN_primtype_class(prim_type); } + return prim_class & GWN_primtype_class(prim_type); +} GLenum convert_prim_type_to_gl(Gwn_PrimType prim_type) - { +{ #if TRUST_NO_ONE assert(prim_type != GWN_PRIM_NONE); #endif - - static const GLenum table[] = - { + static const GLenum table[] = { [GWN_PRIM_POINTS] = GL_POINTS, [GWN_PRIM_LINES] = GL_LINES, [GWN_PRIM_LINE_STRIP] = GL_LINE_STRIP, @@ -61,7 +78,7 @@ GLenum convert_prim_type_to_gl(Gwn_PrimType prim_type) [GWN_PRIM_LINES_ADJ] = GL_LINES_ADJACENCY, [GWN_PRIM_LINE_STRIP_ADJ] = GL_LINE_STRIP_ADJACENCY, [GWN_PRIM_TRIS_ADJ] = GL_TRIANGLES_ADJACENCY, - }; + }; return table[prim_type]; - } +} diff --git a/intern/gawain/src/gwn_shader_interface.c b/intern/gawain/src/gwn_shader_interface.c index d18af234fb0..997d5215d5b 100644 --- a/intern/gawain/src/gwn_shader_interface.c +++ b/intern/gawain/src/gwn_shader_interface.c @@ -1,13 +1,33 @@ - -// Gawain shader interface (C --> GLSL) -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2017 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_shader_interface.c + * \ingroup gpu + * + * Gawain shader interface (C --> GLSL) + */ #include "gwn_batch_private.h" #include "gwn_shader_interface.h" @@ -23,9 +43,8 @@ #endif static const char* BuiltinUniform_name(Gwn_UniformBuiltin u) - { - static const char* names[] = - { +{ + static const char* names[] = { [GWN_UNIFORM_NONE] = NULL, [GWN_UNIFORM_MODEL] = "ModelMatrix", @@ -52,154 +71,142 @@ static const char* BuiltinUniform_name(Gwn_UniformBuiltin u) [GWN_UNIFORM_CUSTOM] = NULL, [GWN_NUM_UNIFORMS] = NULL, - }; + }; return names[u]; - } +} GWN_INLINE bool match(const char* a, const char* b) - { +{ return strcmp(a, b) == 0; - } +} -GWN_INLINE unsigned hash_string(const char *str) - { - unsigned i = 0, c; - - while ((c = *str++)) - { +GWN_INLINE uint hash_string(const char *str) +{ + uint i = 0, c; + while ((c = *str++)) { i = i * 37 + c; - } - - return i; } + return i; +} GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* input, const char* name, uint32_t name_len) - { +{ input->name_offset = shaderface->name_buffer_offset; input->name_hash = hash_string(name); - shaderface->name_buffer_offset += name_len + 1; // include NULL terminator - } + shaderface->name_buffer_offset += name_len + 1; /* include NULL terminator */ +} GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input, Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) - { - const unsigned bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; +{ + const uint bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; input->next = buckets[bucket_index]; buckets[bucket_index] = input; - } +} GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], const char *name_buffer, const char *name) - { - const unsigned name_hash = hash_string(name); - const unsigned bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; +{ + const uint name_hash = hash_string(name); + const uint bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; const Gwn_ShaderInput* input = buckets[bucket_index]; - if (input == NULL) - { - // Requested uniform is not found at all. - return NULL; - } - // Optimization bit: if there is no hash collision detected when constructing shader interface - // it means we can only request the single possible uniform. Surely, it's possible we request - // uniform which causes hash collision, but that will be detected in debug builds. - if (input->next == NULL) - { - if (name_hash == input->name_hash) - { + if (input == NULL) { + /* Requested uniform is not found at all. */ + return NULL; + } + /* Optimization bit: if there is no hash collision detected when constructing shader interface + * it means we can only request the single possible uniform. Surely, it's possible we request + * uniform which causes hash collision, but that will be detected in debug builds. */ + if (input->next == NULL) { + if (name_hash == input->name_hash) { #if TRUST_NO_ONE - assert(match(name_buffer + input->name_offset, name)); + assert(match(name_buffer + input->name_offset, name)); #endif - return input; - } - return NULL; + return input; } - // Work through possible collisions. + return NULL; + } + /* Work through possible collisions. */ const Gwn_ShaderInput* next = input; - while (next != NULL) - { + while (next != NULL) { input = next; next = input->next; - - if (input->name_hash != name_hash) - { + if (input->name_hash != name_hash) { continue; - } - if (match(name_buffer + input->name_offset, name)) - { + } + if (match(name_buffer + input->name_offset, name)) { return input; - } } - return NULL; // not found } + return NULL; /* not found */ +} GWN_INLINE void buckets_free(Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) - { - for (unsigned bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) - { +{ + for (uint bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { Gwn_ShaderInput *input = buckets[bucket_index]; - while (input != NULL) - { + while (input != NULL) { Gwn_ShaderInput *input_next = input->next; free(input); input = input_next; - } } } +} static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name) - { - // TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types +{ + /* TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types */ - // detect built-in uniforms (name must match) - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) - { + /* detect built-in uniforms (name must match) */ + for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { const char* builtin_name = BuiltinUniform_name(u); - if (match(name, builtin_name)) - { + if (match(name, builtin_name)) { input->builtin_type = u; return true; - } } - + } input->builtin_type = GWN_UNIFORM_CUSTOM; return false; - } +} static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const char* name) - { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); +{ + Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); - input->location = glGetUniformLocation(shaderface->program, name); + input->location = glGetUniformLocation(shaderface->program, name); - unsigned name_len = strlen(name); - shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); // include NULL terminator - char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; - strcpy(name_buffer, name); + uint name_len = strlen(name); + shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ + char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; + strcpy(name_buffer, name); - set_input_name(shaderface, input, name, name_len); - setup_builtin_uniform(input, name); - - shader_input_to_bucket(input, shaderface->uniform_buckets); - if (input->builtin_type != GWN_UNIFORM_NONE && - input->builtin_type != GWN_UNIFORM_CUSTOM) - { - shaderface->builtin_uniforms[input->builtin_type] = input; - } + set_input_name(shaderface, input, name, name_len); + setup_builtin_uniform(input, name); + + shader_input_to_bucket(input, shaderface->uniform_buckets); + if (input->builtin_type != GWN_UNIFORM_NONE && + input->builtin_type != GWN_UNIFORM_CUSTOM) + { + shaderface->builtin_uniforms[input->builtin_type] = input; + } #if DEBUG_SHADER_INTERFACE - printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, shaderface->program, name, input->location); + printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, + shaderface->program, + name, + input->location); #endif - return input; - } + return input; +} Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) - { +{ Gwn_ShaderInterface* shaderface = calloc(1, sizeof(Gwn_ShaderInterface)); shaderface->program = program; #if DEBUG_SHADER_INTERFACE - printf("%s {\n", __func__); // enter function + printf("%s {\n", __func__); /* enter function */ printf("Gwn_ShaderInterface %p, program %d\n", shaderface, program); #endif @@ -214,9 +221,8 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) const uint32_t name_buffer_len = attr_len * max_attrib_name_len + ubo_len * max_ubo_name_len; shaderface->name_buffer = malloc(name_buffer_len); - // Attributes - for (uint32_t i = 0; i < attr_len; ++i) - { + /* Attributes */ + for (uint32_t i = 0; i < attr_len; ++i) { Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char* name = shaderface->name_buffer + shaderface->name_buffer_offset; @@ -224,14 +230,13 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name); - // remove "[0]" from array name - if (name[name_len-1] == ']') - { + /* remove "[0]" from array name */ + if (name[name_len-1] == ']') { name[name_len-3] = '\0'; name_len -= 3; - } + } - // TODO: reject DOUBLE gl_types + /* TODO: reject DOUBLE gl_types */ input->location = glGetAttribLocation(program, name); @@ -242,11 +247,9 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) #if DEBUG_SHADER_INTERFACE printf("attrib[%u] '%s' at location %d\n", i, name, input->location); #endif - } - - // Uniform Blocks - for (uint32_t i = 0; i < ubo_len; ++i) - { + } + /* Uniform Blocks */ + for (uint32_t i = 0; i < ubo_len; ++i) { Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char* name = shaderface->name_buffer + shaderface->name_buffer_offset; @@ -263,100 +266,96 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) #if DEBUG_SHADER_INTERFACE printf("ubo '%s' at location %d\n", name, input->location); #endif - } - - // Builtin Uniforms - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) - { + } + /* Builtin Uniforms */ + for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { const char* builtin_name = BuiltinUniform_name(u); - if (glGetUniformLocation(program, builtin_name) != -1) + if (glGetUniformLocation(program, builtin_name) != -1) { add_uniform((Gwn_ShaderInterface*)shaderface, builtin_name); } - - // Batches ref buffer + } + /* Batches ref buffer */ shaderface->batches_len = GWN_SHADERINTERFACE_REF_ALLOC_COUNT; shaderface->batches = calloc(shaderface->batches_len, sizeof(Gwn_Batch*)); return shaderface; - } +} void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) - { - // Free memory used by buckets and has entries. +{ + /* Free memory used by buckets and has entries. */ buckets_free(shaderface->uniform_buckets); buckets_free(shaderface->attrib_buckets); buckets_free(shaderface->ubo_buckets); - // Free memory used by name_buffer. + /* Free memory used by name_buffer. */ free(shaderface->name_buffer); - // Remove this interface from all linked Batches vao cache. - for (int i = 0; i < shaderface->batches_len; ++i) - if (shaderface->batches[i] != NULL) + /* Remove this interface from all linked Batches vao cache. */ + for (int i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] != NULL) { gwn_batch_remove_interface_ref(shaderface->batches[i], shaderface); - + } + } free(shaderface->batches); - // Free memory used by shader interface by its self. + /* Free memory used by shader interface by its self. */ free(shaderface); - } +} const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name) - { - // TODO: Warn if we find a matching builtin, since these can be looked up much quicker. +{ + /* TODO: Warn if we find a matching builtin, since these can be looked up much quicker. */ const Gwn_ShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); - - // If input is not found add it so it's found next time. - if (input == NULL) + /* If input is not found add it so it's found next time. */ + if (input == NULL) { input = add_uniform((Gwn_ShaderInterface*)shaderface, name); - - return (input->location != -1) ? input : NULL; } + return (input->location != -1) ? input : NULL; +} -const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin) - { +const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin( + const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin) +{ #if TRUST_NO_ONE assert(builtin != GWN_UNIFORM_NONE); assert(builtin != GWN_UNIFORM_CUSTOM); assert(builtin != GWN_NUM_UNIFORMS); #endif return shaderface->builtin_uniforms[builtin]; - } +} const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name) - { +{ return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name); - } +} const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name) - { +{ return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name); - } +} void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) - { - int i; // find first unused slot - for (i = 0; i < shaderface->batches_len; ++i) - if (shaderface->batches[i] == NULL) +{ + int i; /* find first unused slot */ + for (i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] == NULL) { break; - - if (i == shaderface->batches_len) - { - // Not enough place, realloc the array. + } + } + if (i == shaderface->batches_len) { + /* Not enough place, realloc the array. */ i = shaderface->batches_len; shaderface->batches_len += GWN_SHADERINTERFACE_REF_ALLOC_COUNT; shaderface->batches = realloc(shaderface->batches, sizeof(Gwn_Batch*) * shaderface->batches_len); memset(shaderface->batches + i, 0, sizeof(Gwn_Batch*) * GWN_SHADERINTERFACE_REF_ALLOC_COUNT); - } - - shaderface->batches[i] = batch; } + shaderface->batches[i] = batch; +} void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) - { - for (int i = 0; i < shaderface->batches_len; ++i) - { - if (shaderface->batches[i] == batch) - { +{ + for (int i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] == batch) { shaderface->batches[i] = NULL; - break; // cannot have duplicates - } + break; /* cannot have duplicates */ } } +} diff --git a/intern/gawain/src/gwn_vertex_array_id.cpp b/intern/gawain/src/gwn_vertex_array_id.cpp index 70294565e6a..04470bf6844 100644 --- a/intern/gawain/src/gwn_vertex_array_id.cpp +++ b/intern/gawain/src/gwn_vertex_array_id.cpp @@ -1,13 +1,38 @@ - -// Gawain vertex array IDs -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin, Clément Foucault -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.#include "buffer_id.h" +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_array_id.cpp + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ #include "gwn_batch_private.h" #include "gwn_vertex_array_id.h" @@ -21,30 +46,28 @@ #if TRUST_NO_ONE #if 0 extern "C" { -extern int BLI_thread_is_main(void); // Blender-specific function +extern int BLI_thread_is_main(void); /* Blender-specific function */ } -static bool thread_is_main() - { - // "main" here means the GL context's thread +static bool thread_is_main() { + /* "main" here means the GL context's thread */ return BLI_thread_is_main(); - } +} #endif #endif struct Gwn_Context { GLuint default_vao; - std::unordered_set batches; // Batches that have VAOs from this context + std::unordered_set batches; /* Batches that have VAOs from this context */ std::vector orphaned_vertarray_ids; - std::mutex orphans_mutex; // todo: try spinlock instead + std::mutex orphans_mutex; /* todo: try spinlock instead */ #if TRUST_NO_ONE - pthread_t thread; // Thread on which this context is active. + pthread_t thread; /* Thread on which this context is active. */ bool thread_is_used; - Gwn_Context() - { + Gwn_Context() { thread_is_used = false; - } + } #endif }; @@ -56,119 +79,118 @@ static thread_local Gwn_Context* active_ctx = NULL; #endif static void clear_orphans(Gwn_Context* ctx) - { +{ ctx->orphans_mutex.lock(); - if (!ctx->orphaned_vertarray_ids.empty()) - { - unsigned orphan_len = (unsigned)ctx->orphaned_vertarray_ids.size(); + if (!ctx->orphaned_vertarray_ids.empty()) { + uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size(); glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data()); ctx->orphaned_vertarray_ids.clear(); - } - ctx->orphans_mutex.unlock(); } + ctx->orphans_mutex.unlock(); +} Gwn_Context* GWN_context_create(void) - { +{ #if TRUST_NO_ONE - // assert(thread_is_main()); + /* assert(thread_is_main()); */ #endif Gwn_Context* ctx = new Gwn_Context; glGenVertexArrays(1, &ctx->default_vao); GWN_context_active_set(ctx); return ctx; - } +} -// to be called after GWN_context_active_set(ctx_to_destroy) +/* to be called after GWN_context_active_set(ctx_to_destroy) */ void GWN_context_discard(Gwn_Context* ctx) - { +{ #if TRUST_NO_ONE - // Make sure no other thread has locked it. + /* Make sure no other thread has locked it. */ assert(ctx == active_ctx); assert(pthread_equal(pthread_self(), ctx->thread)); assert(ctx->orphaned_vertarray_ids.empty()); #endif - // delete remaining vaos - while (!ctx->batches.empty()) - { - // this removes the array entry + /* delete remaining vaos */ + while (!ctx->batches.empty()) { + /* this removes the array entry */ gwn_batch_vao_cache_clear(*ctx->batches.begin()); - } + } glDeleteVertexArrays(1, &ctx->default_vao); delete ctx; active_ctx = NULL; - } +} -// ctx can be NULL +/* ctx can be NULL */ void GWN_context_active_set(Gwn_Context* ctx) - { +{ #if TRUST_NO_ONE - if (active_ctx) + if (active_ctx) { active_ctx->thread_is_used = false; - // Make sure no other context is already bound to this thread. - if (ctx) - { - // Make sure no other thread has locked it. + } + /* Make sure no other context is already bound to this thread. */ + if (ctx) { + /* Make sure no other thread has locked it. */ assert(ctx->thread_is_used == false); ctx->thread = pthread_self(); ctx->thread_is_used = true; - } + } #endif - if (ctx) + if (ctx) { clear_orphans(ctx); - active_ctx = ctx; } + active_ctx = ctx; +} Gwn_Context* GWN_context_active_get(void) - { +{ return active_ctx; - } +} GLuint GWN_vao_default(void) - { +{ #if TRUST_NO_ONE - assert(active_ctx); // need at least an active context - assert(pthread_equal(pthread_self(), active_ctx->thread)); // context has been activated by another thread! + assert(active_ctx); /* need at least an active context */ + assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ #endif return active_ctx->default_vao; - } +} GLuint GWN_vao_alloc(void) - { +{ #if TRUST_NO_ONE - assert(active_ctx); // need at least an active context - assert(pthread_equal(pthread_self(), active_ctx->thread)); // context has been activated by another thread! + assert(active_ctx); /* need at least an active context */ + assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ #endif clear_orphans(active_ctx); GLuint new_vao_id = 0; glGenVertexArrays(1, &new_vao_id); return new_vao_id; - } +} -// this can be called from multiple thread +/* this can be called from multiple thread */ void GWN_vao_free(GLuint vao_id, Gwn_Context* ctx) - { +{ #if TRUST_NO_ONE assert(ctx); #endif - if (ctx == active_ctx) + if (ctx == active_ctx) { glDeleteVertexArrays(1, &vao_id); - else - { + } + else { ctx->orphans_mutex.lock(); ctx->orphaned_vertarray_ids.emplace_back(vao_id); ctx->orphans_mutex.unlock(); - } } +} void gwn_context_add_batch(Gwn_Context* ctx, Gwn_Batch* batch) - { +{ ctx->batches.emplace(batch); - } +} void gwn_context_remove_batch(Gwn_Context* ctx, Gwn_Batch* batch) - { +{ ctx->orphans_mutex.lock(); ctx->batches.erase(batch); ctx->orphans_mutex.unlock(); - } +} diff --git a/intern/gawain/src/gwn_vertex_buffer.c b/intern/gawain/src/gwn_vertex_buffer.c index a372c62bd0a..c3440b25da2 100644 --- a/intern/gawain/src/gwn_vertex_buffer.c +++ b/intern/gawain/src/gwn_vertex_buffer.c @@ -1,13 +1,33 @@ - -// Gawain vertex buffer -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_vertex_buffer.c + * \ingroup gpu + * + * Gawain vertex buffer + */ #include "gwn_vertex_buffer.h" #include "gwn_buffer_id.h" @@ -17,141 +37,137 @@ #define KEEP_SINGLE_COPY 1 -static unsigned vbo_memory_usage; +static uint vbo_memory_usage; static GLenum convert_usage_type_to_gl(Gwn_UsageType type) - { +{ static const GLenum table[] = { [GWN_USAGE_STREAM] = GL_STREAM_DRAW, [GWN_USAGE_STATIC] = GL_STATIC_DRAW, [GWN_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW - }; + }; return table[type]; - } +} Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType usage) - { +{ Gwn_VertBuf* verts = malloc(sizeof(Gwn_VertBuf)); GWN_vertbuf_init(verts, usage); return verts; - } +} Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat* format, Gwn_UsageType usage) - { +{ Gwn_VertBuf* verts = GWN_vertbuf_create(usage); GWN_vertformat_copy(&verts->format, format); - if (!format->packed) + if (!format->packed) { VertexFormat_pack(&verts->format); + } return verts; - // this function might seem redundant, but there is potential for memory savings here... - // TODO: implement those memory savings - } + /* this function might seem redundant, but there is potential for memory savings here... */ + /* TODO: implement those memory savings */ +} void GWN_vertbuf_init(Gwn_VertBuf* verts, Gwn_UsageType usage) - { +{ memset(verts, 0, sizeof(Gwn_VertBuf)); verts->usage = usage; verts->dirty = true; - } +} void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf* verts, const Gwn_VertFormat* format, Gwn_UsageType usage) - { +{ GWN_vertbuf_init(verts, usage); GWN_vertformat_copy(&verts->format, format); - if (!format->packed) + if (!format->packed) { VertexFormat_pack(&verts->format); } +} void GWN_vertbuf_discard(Gwn_VertBuf* verts) - { - if (verts->vbo_id) - { +{ + if (verts->vbo_id) { GWN_buf_id_free(verts->vbo_id); #if VRAM_USAGE vbo_memory_usage -= GWN_vertbuf_size_get(verts); #endif - } - - if (verts->data) + } + if (verts->data) { free(verts->data); - - free(verts); } + free(verts); +} -unsigned GWN_vertbuf_size_get(const Gwn_VertBuf* verts) - { +uint GWN_vertbuf_size_get(const Gwn_VertBuf* verts) +{ return vertex_buffer_size(&verts->format, verts->vertex_len); - } +} -// create a new allocation, discarding any existing data -void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, unsigned v_len) - { +/* create a new allocation, discarding any existing data */ +void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) +{ Gwn_VertFormat* format = &verts->format; - if (!format->packed) + if (!format->packed) { VertexFormat_pack(format); - + } #if TRUST_NO_ONE - // catch any unnecessary use + /* catch any unnecessary use */ assert(verts->vertex_alloc != v_len || verts->data == NULL); #endif - - // only create the buffer the 1st time - if (verts->vbo_id == 0) + /* only create the buffer the 1st time */ + if (verts->vbo_id == 0) { verts->vbo_id = GWN_buf_id_alloc(); - - // discard previous data if any - if (verts->data) + } + /* discard previous data if any */ + if (verts->data) { free(verts->data); - + } #if VRAM_USAGE - unsigned new_size = vertex_buffer_size(&verts->format, v_len); + uint new_size = vertex_buffer_size(&verts->format, v_len); vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); #endif - verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; verts->data = malloc(sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); - } +} -// resize buffer keeping existing data -void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, unsigned v_len) - { +/* resize buffer keeping existing data */ +void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, uint v_len) +{ #if TRUST_NO_ONE assert(verts->data != NULL); assert(verts->vertex_alloc != v_len); #endif #if VRAM_USAGE - unsigned new_size = vertex_buffer_size(&verts->format, v_len); + uint new_size = vertex_buffer_size(&verts->format, v_len); vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); #endif - verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; verts->data = realloc(verts->data, sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); - } +} -// set vertex count but does not change allocation -// only this many verts will be uploaded to the GPU and rendered -// this is usefull for streaming data -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, unsigned v_len) - { +/* Set vertex count but does not change allocation. + * Only this many verts will be uploaded to the GPU and rendered. + * This is usefull for streaming data. */ +void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, uint v_len) +{ #if TRUST_NO_ONE - assert(verts->data != NULL); // only for dynamic data + assert(verts->data != NULL); /* only for dynamic data */ assert(v_len <= verts->vertex_alloc); #endif #if VRAM_USAGE - unsigned new_size = vertex_buffer_size(&verts->format, v_len); + uint new_size = vertex_buffer_size(&verts->format, v_len); vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); #endif - verts->vertex_len = v_len; - } +} -void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, unsigned a_idx, unsigned v_idx, const void* data) - { +void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, uint a_idx, uint v_idx, const void* data) +{ const Gwn_VertFormat* format = &verts->format; const Gwn_VertAttr* a = format->attribs + a_idx; @@ -160,27 +176,25 @@ void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, unsigned a_idx, unsigned v_idx, co assert(v_idx < verts->vertex_alloc); assert(verts->data != NULL); #endif - verts->dirty = true; memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz); - } +} -void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, unsigned a_idx, const void* data) - { +void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, uint a_idx, const void* data) +{ const Gwn_VertFormat* format = &verts->format; const Gwn_VertAttr* a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); #endif - - const unsigned stride = a->sz; // tightly packed input data + const uint stride = a->sz; /* tightly packed input data */ GWN_vertbuf_attr_fill_stride(verts, a_idx, stride, data); - } +} -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, unsigned a_idx, unsigned stride, const void* data) - { +void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, uint a_idx, uint stride, const void* data) +{ const Gwn_VertFormat* format = &verts->format; const Gwn_VertAttr* a = format->attribs + a_idx; @@ -188,25 +202,23 @@ void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, unsigned a_idx, unsigned s assert(a_idx < format->attr_len); assert(verts->data != NULL); #endif - verts->dirty = true; - const unsigned vertex_len = verts->vertex_len; + const uint vertex_len = verts->vertex_len; - if (format->attr_len == 1 && stride == format->stride) - { - // we can copy it all at once + if (format->attr_len == 1 && stride == format->stride) { + /* we can copy it all at once */ memcpy(verts->data, data, vertex_len * a->sz); - } - else - { - // we must copy it per vertex - for (unsigned v = 0; v < vertex_len; ++v) + } + else { + /* we must copy it per vertex */ + for (uint v = 0; v < vertex_len; ++v) { memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz); } } +} -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, unsigned a_idx, Gwn_VertBufRaw *access) - { +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, uint a_idx, Gwn_VertBufRaw *access) +{ const Gwn_VertFormat* format = &verts->format; const Gwn_VertAttr* a = format->attribs + a_idx; @@ -224,35 +236,33 @@ void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, unsigned a_idx, Gwn_VertB #if TRUST_NO_ONE access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride); #endif - } +} static void VertBuffer_upload_data(Gwn_VertBuf* verts) - { - unsigned buffer_sz = GWN_vertbuf_size_get(verts); +{ + uint buffer_sz = GWN_vertbuf_size_get(verts); - // orphan the vbo to avoid sync + /* orphan the vbo to avoid sync */ glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); - // upload data + /* upload data */ glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); - if (verts->usage == GWN_USAGE_STATIC) - { + if (verts->usage == GWN_USAGE_STATIC) { free(verts->data); verts->data = NULL; - } - - verts->dirty = false; } + verts->dirty = false; +} void GWN_vertbuf_use(Gwn_VertBuf* verts) - { +{ glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); - - if (verts->dirty) + if (verts->dirty) { VertBuffer_upload_data(verts); } +} -unsigned GWN_vertbuf_get_memory_usage(void) - { +uint GWN_vertbuf_get_memory_usage(void) +{ return vbo_memory_usage; - } +} diff --git a/intern/gawain/src/gwn_vertex_format.c b/intern/gawain/src/gwn_vertex_format.c index 122de12ec6e..41179ae21eb 100644 --- a/intern/gawain/src/gwn_vertex_format.c +++ b/intern/gawain/src/gwn_vertex_format.c @@ -1,13 +1,33 @@ - -// Gawain vertex format -// -// This code is part of the Gawain library, with modifications -// specific to integration with Blender. -// -// Copyright 2016 Mike Erwin -// -// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of -// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_vertex_format.c + * \ingroup gpu + * + * Gawain vertex format + */ #include "gwn_vertex_format.h" #include "gwn_vertex_format_private.h" @@ -21,7 +41,7 @@ #endif void GWN_vertformat_clear(Gwn_VertFormat* format) - { +{ #if TRUST_NO_ONE memset(format, 0, sizeof(Gwn_VertFormat)); #else @@ -30,23 +50,26 @@ void GWN_vertformat_clear(Gwn_VertFormat* format) format->name_offset = 0; format->name_len = 0; - for (unsigned i = 0; i < GWN_VERT_ATTR_MAX_LEN; i++) + for (unsigned i = 0; i < GWN_VERT_ATTR_MAX_LEN; i++) { format->attribs[i].name_len = 0; -#endif } +#endif +} void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src) - { - // copy regular struct fields +{ + /* copy regular struct fields */ memcpy(dest, src, sizeof(Gwn_VertFormat)); - for (unsigned i = 0; i < dest->attr_len; i++) - for (unsigned j = 0; j < dest->attribs[i].name_len; j++) + for (unsigned i = 0; i < dest->attr_len; i++) { + for (unsigned j = 0; j < dest->attribs[i].name_len; j++) { dest->attribs[i].name[j] = (char *)dest + (src->attribs[i].name[j] - ((char *)src)); + } } +} static GLenum convert_comp_type_to_gl(Gwn_VertCompType type) - { +{ static const GLenum table[] = { [GWN_COMP_I8] = GL_BYTE, [GWN_COMP_U8] = GL_UNSIGNED_BYTE, @@ -58,105 +81,101 @@ static GLenum convert_comp_type_to_gl(Gwn_VertCompType type) [GWN_COMP_F32] = GL_FLOAT, [GWN_COMP_I10] = GL_INT_2_10_10_10_REV - }; + }; return table[type]; - } +} static unsigned comp_sz(Gwn_VertCompType type) - { +{ #if TRUST_NO_ONE - assert(type <= GWN_COMP_F32); // other types have irregular sizes (not bytes) + assert(type <= GWN_COMP_F32); /* other types have irregular sizes (not bytes) */ #endif - const GLubyte sizes[] = {1,1,2,2,4,4,4}; return sizes[type]; - } +} static unsigned attrib_sz(const Gwn_VertAttr *a) - { - if (a->comp_type == GWN_COMP_I10) - return 4; // always packed as 10_10_10_2 - - return a->comp_len * comp_sz(a->comp_type); +{ + if (a->comp_type == GWN_COMP_I10) { + return 4; /* always packed as 10_10_10_2 */ } + return a->comp_len * comp_sz(a->comp_type); +} static unsigned attrib_align(const Gwn_VertAttr *a) - { - if (a->comp_type == GWN_COMP_I10) - return 4; // always packed as 10_10_10_2 - +{ + if (a->comp_type == GWN_COMP_I10) { + return 4; /* always packed as 10_10_10_2 */ + } unsigned c = comp_sz(a->comp_type); - if (a->comp_len == 3 && c <= 2) - return 4 * c; // AMD HW can't fetch these well, so pad it out (other vendors too?) - else - return c; // most fetches are ok if components are naturally aligned + if (a->comp_len == 3 && c <= 2) { + return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */ + } + else { + return c; /* most fetches are ok if components are naturally aligned */ } +} unsigned vertex_buffer_size(const Gwn_VertFormat* format, unsigned vertex_len) - { +{ #if TRUST_NO_ONE assert(format->packed && format->stride > 0); #endif - return format->stride * vertex_len; - } +} static const char* copy_attrib_name(Gwn_VertFormat* format, const char* name) - { - // strncpy does 110% of what we need; let's do exactly 100% +{ + /* strncpy does 110% of what we need; let's do exactly 100% */ char* name_copy = format->names + format->name_offset; unsigned available = GWN_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; bool terminated = false; - for (unsigned i = 0; i < available; ++i) - { + for (unsigned i = 0; i < available; ++i) { const char c = name[i]; name_copy[i] = c; - if (c == '\0') - { + if (c == '\0') { terminated = true; format->name_offset += (i + 1); break; - } } - + } #if TRUST_NO_ONE assert(terminated); assert(format->name_offset <= GWN_VERT_ATTR_NAMES_BUF_LEN); #else (void)terminated; #endif - return name_copy; - } +} unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_VertCompType comp_type, unsigned comp_len, Gwn_VertFetchMode fetch_mode) - { +{ #if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); // there's room for more - assert(format->attr_len < GWN_VERT_ATTR_MAX_LEN); // there's room for more - assert(!format->packed); // packed means frozen/locked + assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(format->attr_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(!format->packed); /* packed means frozen/locked */ assert((comp_len >= 1 && comp_len <= 4) || comp_len == 8 || comp_len == 12 || comp_len == 16); - switch (comp_type) - { + + switch (comp_type) { case GWN_COMP_F32: - // float type can only kept as float + /* float type can only kept as float */ assert(fetch_mode == GWN_FETCH_FLOAT); break; case GWN_COMP_I10: - // 10_10_10 format intended for normals (xyz) or colors (rgb) - // extra component packed.w can be manually set to { -2, -1, 0, 1 } + /* 10_10_10 format intended for normals (xyz) or colors (rgb) + * extra component packed.w can be manually set to { -2, -1, 0, 1 } */ assert(comp_len == 3 || comp_len == 4); - assert(fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT); // not strictly required, may relax later + assert(fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT); /* not strictly required, may relax later */ break; default: - // integer types can be kept as int or converted/normalized to float + /* integer types can be kept as int or converted/normalized to float */ assert(fetch_mode != GWN_FETCH_FLOAT); - // only support float matrices (see Batch_update_program_bindings) + /* only support float matrices (see Batch_update_program_bindings) */ assert(comp_len != 8 && comp_len != 12 && comp_len != 16); - } + } #endif - format->name_len++; // multiname support + format->name_len++; /* multiname support */ const unsigned attrib_id = format->attr_len++; Gwn_VertAttr* attrib = format->attribs + attrib_id; @@ -164,53 +183,53 @@ unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_V attrib->name[attrib->name_len++] = copy_attrib_name(format, name); attrib->comp_type = comp_type; attrib->gl_comp_type = convert_comp_type_to_gl(comp_type); - attrib->comp_len = (comp_type == GWN_COMP_I10) ? 4 : comp_len; // system needs 10_10_10_2 to be 4 or BGRA + attrib->comp_len = (comp_type == GWN_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ attrib->sz = attrib_sz(attrib); - attrib->offset = 0; // offsets & stride are calculated later (during pack) + attrib->offset = 0; /* offsets & stride are calculated later (during pack) */ attrib->fetch_mode = fetch_mode; return attrib_id; - } +} void GWN_vertformat_alias_add(Gwn_VertFormat* format, const char* alias) - { +{ Gwn_VertAttr* attrib = format->attribs + (format->attr_len - 1); #if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); // there's room for more + assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ assert(attrib->name_len < GWN_VERT_ATTR_MAX_NAMES); #endif - format->name_len++; // multiname support + format->name_len++; /* multiname support */ attrib->name[attrib->name_len++] = copy_attrib_name(format, alias); - } +} unsigned padding(unsigned offset, unsigned alignment) - { +{ const unsigned mod = offset % alignment; return (mod == 0) ? 0 : (alignment - mod); - } +} #if PACK_DEBUG static void show_pack(unsigned a_idx, unsigned sz, unsigned pad) - { +{ const char c = 'A' + a_idx; - for (unsigned i = 0; i < pad; ++i) + for (unsigned i = 0; i < pad; ++i) { putchar('-'); - for (unsigned i = 0; i < sz; ++i) + } + for (unsigned i = 0; i < sz; ++i) { putchar(c); } +} #endif void VertexFormat_pack(Gwn_VertFormat* format) - { - // for now, attributes are packed in the order they were added, - // making sure each attrib is naturally aligned (add padding where necessary) - - // later we can implement more efficient packing w/ reordering - // (keep attrib ID order, adjust their offsets to reorder in buffer) +{ + /* For now, attributes are packed in the order they were added, + * making sure each attrib is naturally aligned (add padding where necessary) + * Later we can implement more efficient packing w/ reordering + * (keep attrib ID order, adjust their offsets to reorder in buffer). */ - // TODO: - // realloc just enough to hold the final combo string. And just enough to - // hold used attribs, not all 16. + /* TODO: realloc just enough to hold the final combo string. And just enough to + * hold used attribs, not all 16. */ Gwn_VertAttr* a0 = format->attribs + 0; a0->offset = 0; @@ -220,8 +239,7 @@ void VertexFormat_pack(Gwn_VertFormat* format) show_pack(0, a0->sz, 0); #endif - for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) - { + for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) { Gwn_VertAttr* a = format->attribs + a_idx; unsigned mid_padding = padding(offset, attrib_align(a)); offset += mid_padding; @@ -231,7 +249,7 @@ void VertexFormat_pack(Gwn_VertFormat* format) #if PACK_DEBUG show_pack(a_idx, a->sz, mid_padding); #endif - } + } unsigned end_padding = padding(offset, attrib_align(a0)); @@ -239,53 +257,54 @@ void VertexFormat_pack(Gwn_VertFormat* format) show_pack(0, 0, end_padding); putchar('\n'); #endif - format->stride = offset + end_padding; format->packed = true; - } +} -// OpenGL ES packs in a different order as desktop GL but component conversion is the same. -// Of the code here, only struct Gwn_PackedNormal needs to change. +/* OpenGL ES packs in a different order as desktop GL but component conversion is the same. + * Of the code here, only struct Gwn_PackedNormal needs to change. */ #define SIGNED_INT_10_MAX 511 #define SIGNED_INT_10_MIN -512 static int clampi(int x, int min_allowed, int max_allowed) - { +{ #if TRUST_NO_ONE assert(min_allowed <= max_allowed); #endif - - if (x < min_allowed) + if (x < min_allowed) { return min_allowed; - else if (x > max_allowed) + } + else if (x > max_allowed) { return max_allowed; - else + } + else { return x; } +} static int quantize(float x) - { +{ int qx = x * 511.0f; return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX); - } +} static int convert_i16(short x) - { - // 16-bit signed --> 10-bit signed +{ + /* 16-bit signed --> 10-bit signed */ + /* TODO: round? */ return x >> 6; - // TODO: round? - } +} Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]) - { +{ Gwn_PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) }; return n; - } +} Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]) - { +{ Gwn_PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) }; return n; - } +} -- cgit v1.2.3 From 247ad2034de2c33a6d9cb7d3b6f1ef7ffa5b859d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 17 Jul 2018 21:11:23 +0200 Subject: GWN: Port to GPU module: Move files to GPU This does not include all the struct and type renaming. Only files were renamed. gwn_batch.c/h was fusioned with GPU_batch.c/h gwn_immediate.c/h was fusioned with GPU_immediate.c/h gwn_imm_util.c/h was fusioned with GPU_immediate_util.c/h --- intern/CMakeLists.txt | 1 - intern/gawain/CMakeLists.txt | 50 -- intern/gawain/gawain/gwn_attr_binding.h | 42 - intern/gawain/gawain/gwn_attr_binding_private.h | 43 - intern/gawain/gawain/gwn_batch.h | 193 ----- intern/gawain/gawain/gwn_batch_private.h | 54 -- intern/gawain/gawain/gwn_buffer_id.h | 53 -- intern/gawain/gawain/gwn_common.h | 61 -- intern/gawain/gawain/gwn_context.h | 55 -- intern/gawain/gawain/gwn_element.h | 102 --- intern/gawain/gawain/gwn_imm_util.h | 46 -- intern/gawain/gawain/gwn_immediate.h | 132 ---- intern/gawain/gawain/gwn_primitive.h | 65 -- intern/gawain/gawain/gwn_primitive_private.h | 37 - intern/gawain/gawain/gwn_shader_interface.h | 104 --- intern/gawain/gawain/gwn_vertex_array_id.h | 55 -- intern/gawain/gawain/gwn_vertex_buffer.h | 144 ---- intern/gawain/gawain/gwn_vertex_format.h | 101 --- intern/gawain/gawain/gwn_vertex_format_private.h | 39 - intern/gawain/src/gwn_attr_binding.c | 85 -- intern/gawain/src/gwn_batch.c | 645 --------------- intern/gawain/src/gwn_buffer_id.cpp | 89 --- intern/gawain/src/gwn_element.c | 307 -------- intern/gawain/src/gwn_imm_util.c | 100 --- intern/gawain/src/gwn_immediate.c | 863 --------------------- intern/gawain/src/gwn_primitive.c | 84 -- intern/gawain/src/gwn_shader_interface.c | 361 --------- intern/gawain/src/gwn_vertex_array_id.cpp | 196 ----- intern/gawain/src/gwn_vertex_buffer.c | 268 ------- intern/gawain/src/gwn_vertex_format.c | 310 -------- intern/opencolorio/CMakeLists.txt | 2 +- intern/opencolorio/ocio_impl_glsl.cc | 2 +- .../blender/blenfont/intern/blf_internal_types.h | 2 +- .../blender/draw/engines/eevee/eevee_lightcache.c | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/draw/intern/draw_manager.h | 1 + source/blender/gpu/CMakeLists.txt | 22 +- source/blender/gpu/GPU_attr_binding.h | 42 + source/blender/gpu/GPU_batch.h | 182 ++++- source/blender/gpu/GPU_buffer_id.h | 53 ++ source/blender/gpu/GPU_common.h | 61 ++ source/blender/gpu/GPU_context.h | 55 ++ source/blender/gpu/GPU_element.h | 102 +++ source/blender/gpu/GPU_immediate.h | 112 ++- source/blender/gpu/GPU_immediate_util.h | 9 + source/blender/gpu/GPU_primitive.h | 65 ++ source/blender/gpu/GPU_shader_interface.h | 104 +++ source/blender/gpu/GPU_vertex_array_id.h | 55 ++ source/blender/gpu/GPU_vertex_buffer.h | 144 ++++ source/blender/gpu/GPU_vertex_format.h | 101 +++ source/blender/gpu/intern/gpu_attr_binding.c | 85 ++ .../blender/gpu/intern/gpu_attr_binding_private.h | 43 + source/blender/gpu/intern/gpu_batch.c | 637 ++++++++++++++- source/blender/gpu/intern/gpu_batch_private.h | 53 ++ source/blender/gpu/intern/gpu_buffer_id.cpp | 90 +++ source/blender/gpu/intern/gpu_element.c | 308 ++++++++ source/blender/gpu/intern/gpu_immediate.c | 849 +++++++++++++++++++- source/blender/gpu/intern/gpu_immediate_util.c | 70 +- source/blender/gpu/intern/gpu_matrix.c | 2 +- source/blender/gpu/intern/gpu_primitive.c | 84 ++ source/blender/gpu/intern/gpu_primitive_private.h | 37 + source/blender/gpu/intern/gpu_shader_interface.c | 361 +++++++++ source/blender/gpu/intern/gpu_shader_private.h | 2 +- source/blender/gpu/intern/gpu_vertex_array_id.cpp | 196 +++++ source/blender/gpu/intern/gpu_vertex_buffer.c | 268 +++++++ source/blender/gpu/intern/gpu_vertex_format.c | 310 ++++++++ .../blender/gpu/intern/gpu_vertex_format_private.h | 39 + source/blender/python/gawain/gwn_py_api.c | 4 +- source/blender/python/gawain/gwn_py_types.c | 4 +- source/blender/render/CMakeLists.txt | 1 + source/blender/render/intern/source/pipeline.c | 2 +- source/blender/windowmanager/intern/wm_playanim.c | 2 +- source/blender/windowmanager/intern/wm_window.c | 3 +- 73 files changed, 4501 insertions(+), 4752 deletions(-) delete mode 100644 intern/gawain/CMakeLists.txt delete mode 100644 intern/gawain/gawain/gwn_attr_binding.h delete mode 100644 intern/gawain/gawain/gwn_attr_binding_private.h delete mode 100644 intern/gawain/gawain/gwn_batch.h delete mode 100644 intern/gawain/gawain/gwn_batch_private.h delete mode 100644 intern/gawain/gawain/gwn_buffer_id.h delete mode 100644 intern/gawain/gawain/gwn_common.h delete mode 100644 intern/gawain/gawain/gwn_context.h delete mode 100644 intern/gawain/gawain/gwn_element.h delete mode 100644 intern/gawain/gawain/gwn_imm_util.h delete mode 100644 intern/gawain/gawain/gwn_immediate.h delete mode 100644 intern/gawain/gawain/gwn_primitive.h delete mode 100644 intern/gawain/gawain/gwn_primitive_private.h delete mode 100644 intern/gawain/gawain/gwn_shader_interface.h delete mode 100644 intern/gawain/gawain/gwn_vertex_array_id.h delete mode 100644 intern/gawain/gawain/gwn_vertex_buffer.h delete mode 100644 intern/gawain/gawain/gwn_vertex_format.h delete mode 100644 intern/gawain/gawain/gwn_vertex_format_private.h delete mode 100644 intern/gawain/src/gwn_attr_binding.c delete mode 100644 intern/gawain/src/gwn_batch.c delete mode 100644 intern/gawain/src/gwn_buffer_id.cpp delete mode 100644 intern/gawain/src/gwn_element.c delete mode 100644 intern/gawain/src/gwn_imm_util.c delete mode 100644 intern/gawain/src/gwn_immediate.c delete mode 100644 intern/gawain/src/gwn_primitive.c delete mode 100644 intern/gawain/src/gwn_shader_interface.c delete mode 100644 intern/gawain/src/gwn_vertex_array_id.cpp delete mode 100644 intern/gawain/src/gwn_vertex_buffer.c delete mode 100644 intern/gawain/src/gwn_vertex_format.c create mode 100644 source/blender/gpu/GPU_attr_binding.h create mode 100644 source/blender/gpu/GPU_buffer_id.h create mode 100644 source/blender/gpu/GPU_common.h create mode 100644 source/blender/gpu/GPU_context.h create mode 100644 source/blender/gpu/GPU_element.h create mode 100644 source/blender/gpu/GPU_primitive.h create mode 100644 source/blender/gpu/GPU_shader_interface.h create mode 100644 source/blender/gpu/GPU_vertex_array_id.h create mode 100644 source/blender/gpu/GPU_vertex_buffer.h create mode 100644 source/blender/gpu/GPU_vertex_format.h create mode 100644 source/blender/gpu/intern/gpu_attr_binding.c create mode 100644 source/blender/gpu/intern/gpu_attr_binding_private.h create mode 100644 source/blender/gpu/intern/gpu_batch_private.h create mode 100644 source/blender/gpu/intern/gpu_buffer_id.cpp create mode 100644 source/blender/gpu/intern/gpu_element.c create mode 100644 source/blender/gpu/intern/gpu_primitive.c create mode 100644 source/blender/gpu/intern/gpu_primitive_private.h create mode 100644 source/blender/gpu/intern/gpu_shader_interface.c create mode 100644 source/blender/gpu/intern/gpu_vertex_array_id.cpp create mode 100644 source/blender/gpu/intern/gpu_vertex_buffer.c create mode 100644 source/blender/gpu/intern/gpu_vertex_format.c create mode 100644 source/blender/gpu/intern/gpu_vertex_format_private.h diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 1a050892836..1459100d415 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -34,7 +34,6 @@ add_subdirectory(opencolorio) add_subdirectory(mikktspace) add_subdirectory(glew-mx) add_subdirectory(eigen) -add_subdirectory(gawain) if(WITH_AUDASPACE) add_subdirectory(audaspace) diff --git a/intern/gawain/CMakeLists.txt b/intern/gawain/CMakeLists.txt deleted file mode 100644 index 7ebd3ee7622..00000000000 --- a/intern/gawain/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# WITH_OPENGL limits the visibility of the opengl headers to just gawain and bg_gpu, -# to more easily highlight codepadths in other libraries that need to be refactored, -# bf_intern_gawain is allowed to have opengl regardless of this option. - -if(NOT WITH_OPENGL) - add_definitions(-DWITH_OPENGL) -endif() - -set(INC - gawain -) - -set(INC_SYS - ${GLEW_INCLUDE_PATH} -) - -set(SRC - src/gwn_attr_binding.c - src/gwn_batch.c - src/gwn_element.c - src/gwn_buffer_id.cpp - src/gwn_immediate.c - src/gwn_imm_util.c - src/gwn_primitive.c - src/gwn_shader_interface.c - src/gwn_vertex_array_id.cpp - src/gwn_vertex_buffer.c - src/gwn_vertex_format.c - - gawain/gwn_attr_binding.h - gawain/gwn_attr_binding_private.h - gawain/gwn_batch.h - gawain/gwn_batch_private.h - gawain/gwn_buffer_id.h - gawain/gwn_common.h - gawain/gwn_element.h - gawain/gwn_imm_util.h - gawain/gwn_immediate.h - gawain/gwn_primitive.h - gawain/gwn_primitive_private.h - gawain/gwn_shader_interface.h - gawain/gwn_vertex_array_id.h - gawain/gwn_vertex_buffer.h - gawain/gwn_vertex_format.h - gawain/gwn_vertex_format_private.h -) - -add_definitions(${GL_DEFINITIONS}) - -blender_add_lib(bf_intern_gawain "${SRC}" "${INC}" "${INC_SYS}") diff --git a/intern/gawain/gawain/gwn_attr_binding.h b/intern/gawain/gawain/gwn_attr_binding.h deleted file mode 100644 index 8030e86ea92..00000000000 --- a/intern/gawain/gawain/gwn_attr_binding.h +++ /dev/null @@ -1,42 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_attr_binding.h - * \ingroup gpu - * - * Gawain vertex attribute binding - */ - -#ifndef __GWN_ATTR_BINDING_H__ -#define __GWN_ATTR_BINDING_H__ - -#include "gwn_common.h" - -typedef struct Gwn_AttrBinding { - uint64_t loc_bits; /* store 4 bits for each of the 16 attribs */ - uint16_t enabled_bits; /* 1 bit for each attrib */ -} Gwn_AttrBinding; - -#endif /* __GWN_ATTR_BINDING_H__ */ diff --git a/intern/gawain/gawain/gwn_attr_binding_private.h b/intern/gawain/gawain/gwn_attr_binding_private.h deleted file mode 100644 index cead1896ec7..00000000000 --- a/intern/gawain/gawain/gwn_attr_binding_private.h +++ /dev/null @@ -1,43 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_attr_binding_private.h - * \ingroup gpu - * - * Gawain vertex attribute binding - */ - -#ifndef __GWN_ATTR_BINDING_PRIVATE_H__ -#define __GWN_ATTR_BINDING_PRIVATE_H__ - -#include "gwn_vertex_format.h" -#include "gwn_shader_interface.h" - -void AttribBinding_clear(Gwn_AttrBinding*); - -void get_attrib_locations(const Gwn_VertFormat*, Gwn_AttrBinding*, const Gwn_ShaderInterface*); -unsigned read_attrib_location(const Gwn_AttrBinding*, unsigned a_idx); - -#endif /* __GWN_ATTR_BINDING_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_batch.h b/intern/gawain/gawain/gwn_batch.h deleted file mode 100644 index a7a54502cc0..00000000000 --- a/intern/gawain/gawain/gwn_batch.h +++ /dev/null @@ -1,193 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_batch.h - * \ingroup gpu - * - * Gawain geometry batch - * Contains VAOs + VBOs + Shader representing a drawable entity. - */ - -#ifndef __GWN_BATCH_H__ -#define __GWN_BATCH_H__ - -#include "gwn_vertex_buffer.h" -#include "gwn_element.h" -#include "gwn_shader_interface.h" - -typedef enum { - GWN_BATCH_READY_TO_FORMAT, - GWN_BATCH_READY_TO_BUILD, - GWN_BATCH_BUILDING, - GWN_BATCH_READY_TO_DRAW -} Gwn_BatchPhase; - -#define GWN_BATCH_VBO_MAX_LEN 3 -#define GWN_BATCH_VAO_STATIC_LEN 3 -#define GWN_BATCH_VAO_DYN_ALLOC_COUNT 16 - -typedef struct Gwn_Batch { - /* geometry */ - Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ - Gwn_VertBuf* inst; /* instance attribs */ - Gwn_IndexBuf* elem; /* NULL if element list not needed */ - uint32_t gl_prim_type; - - /* cached values (avoid dereferencing later) */ - uint32_t vao_id; - uint32_t program; - const struct Gwn_ShaderInterface* interface; - - /* book-keeping */ - uint owns_flag; - struct Gwn_Context *context; /* used to free all vaos. this implies all vaos were created under the same context. */ - Gwn_BatchPhase phase; - bool program_in_use; - - /* Vao management: remembers all geometry state (vertex attrib bindings & element buffer) - * for each shader interface. Start with a static number of vaos and fallback to dynamic count - * if necessary. Once a batch goes dynamic it does not go back. */ - bool is_dynamic_vao_count; - union { - /* Static handle count */ - struct { - const struct Gwn_ShaderInterface* interfaces[GWN_BATCH_VAO_STATIC_LEN]; - uint32_t vao_ids[GWN_BATCH_VAO_STATIC_LEN]; - } static_vaos; - /* Dynamic handle count */ - struct { - uint count; - const struct Gwn_ShaderInterface** interfaces; - uint32_t* vao_ids; - } dynamic_vaos; - }; - - /* XXX This is the only solution if we want to have some data structure using - * batches as key to identify nodes. We must destroy these nodes with this callback. */ - void (*free_callback)(struct Gwn_Batch*, void*); - void* callback_data; -} Gwn_Batch; - -enum { - GWN_BATCH_OWNS_VBO = (1 << 0), - /* each vbo index gets bit-shifted */ - GWN_BATCH_OWNS_INSTANCES = (1 << 30), - GWN_BATCH_OWNS_INDEX = (1 << 31), -}; - -Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); -void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); -Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src); - -#define GWN_batch_create(prim, verts, elem) \ - GWN_batch_create_ex(prim, verts, elem, 0) -#define GWN_batch_init(batch, prim, verts, elem) \ - GWN_batch_init_ex(batch, prim, verts, elem, 0) - -void GWN_batch_discard(Gwn_Batch*); /* verts & elem are not discarded */ - -void GWN_batch_callback_free_set(Gwn_Batch*, void (*callback)(Gwn_Batch*, void*), void*); - -void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); /* Instancing */ - -int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); - -#define GWN_batch_vertbuf_add(batch, verts) \ - GWN_batch_vertbuf_add_ex(batch, verts, false) - -void GWN_batch_program_set_no_use(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); -void GWN_batch_program_set(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); -/* Entire batch draws with one shader program, but can be redrawn later with another program. */ -/* Vertex shader's inputs must be compatible with the batch's vertex format. */ - -void GWN_batch_program_use_begin(Gwn_Batch*); /* call before Batch_Uniform (temp hack?) */ -void GWN_batch_program_use_end(Gwn_Batch*); - -void GWN_batch_uniform_1ui(Gwn_Batch*, const char* name, int value); -void GWN_batch_uniform_1i(Gwn_Batch*, const char* name, int value); -void GWN_batch_uniform_1b(Gwn_Batch*, const char* name, bool value); -void GWN_batch_uniform_1f(Gwn_Batch*, const char* name, float value); -void GWN_batch_uniform_2f(Gwn_Batch*, const char* name, float x, float y); -void GWN_batch_uniform_3f(Gwn_Batch*, const char* name, float x, float y, float z); -void GWN_batch_uniform_4f(Gwn_Batch*, const char* name, float x, float y, float z, float w); -void GWN_batch_uniform_2fv(Gwn_Batch*, const char* name, const float data[2]); -void GWN_batch_uniform_3fv(Gwn_Batch*, const char* name, const float data[3]); -void GWN_batch_uniform_4fv(Gwn_Batch*, const char* name, const float data[4]); -void GWN_batch_uniform_2fv_array(Gwn_Batch*, const char* name, int len, const float *data); -void GWN_batch_uniform_4fv_array(Gwn_Batch*, const char* name, int len, const float *data); -void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4]); - -void GWN_batch_draw(Gwn_Batch*); - -/* This does not bind/unbind shader and does not call GPU_matrix_bind() */ -void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance); - -/* Does not even need batch */ -void GWN_draw_primitive(Gwn_PrimType, int v_count); - -#if 0 /* future plans */ - -/* Can multiple batches share a Gwn_VertBuf? Use ref count? */ - - -/* We often need a batch with its own data, to be created and discarded together. */ -/* WithOwn variants reduce number of system allocations. */ - -typedef struct BatchWithOwnVertexBuffer { - Gwn_Batch batch; - Gwn_VertBuf verts; /* link batch.verts to this */ -} BatchWithOwnVertexBuffer; - -typedef struct BatchWithOwnElementList { - Gwn_Batch batch; - Gwn_IndexBuf elem; /* link batch.elem to this */ -} BatchWithOwnElementList; - -typedef struct BatchWithOwnVertexBufferAndElementList { - Gwn_Batch batch; - Gwn_IndexBuf elem; /* link batch.elem to this */ - Gwn_VertBuf verts; /* link batch.verts to this */ -} BatchWithOwnVertexBufferAndElementList; - -Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, uint v_len, Gwn_IndexBuf*); -Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, uint prim_len); -Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, uint v_len, uint prim_len); -/* verts: shared, own */ -/* elem: none, shared, own */ -Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStuff); - -#endif /* future plans */ - - -/* Macros */ - -#define GWN_BATCH_DISCARD_SAFE(batch) do { \ - if (batch != NULL) { \ - GWN_batch_discard(batch); \ - batch = NULL; \ - } \ -} while (0) - -#endif /* __GWN_BATCH_H__ */ diff --git a/intern/gawain/gawain/gwn_batch_private.h b/intern/gawain/gawain/gwn_batch_private.h deleted file mode 100644 index e7d42ff0249..00000000000 --- a/intern/gawain/gawain/gwn_batch_private.h +++ /dev/null @@ -1,54 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_batch_private.h - * \ingroup gpu - * - * Gawain geometry batch - * Contains VAOs + VBOs + Shader representing a drawable entity. - */ - -#ifndef __GWN_BATCH_PRIVATE_H__ -#define __GWN_BATCH_PRIVATE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gwn_batch.h" -#include "gwn_context.h" -#include "gwn_shader_interface.h" - -void gwn_batch_remove_interface_ref(Gwn_Batch*, const Gwn_ShaderInterface*); -void gwn_batch_vao_cache_clear(Gwn_Batch*); - -void gwn_context_add_batch(Gwn_Context*, Gwn_Batch*); -void gwn_context_remove_batch(Gwn_Context*, Gwn_Batch*); - -#ifdef __cplusplus -} -#endif - -#endif /* __GWN_BATCH_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_buffer_id.h b/intern/gawain/gawain/gwn_buffer_id.h deleted file mode 100644 index 0c2537a5d5a..00000000000 --- a/intern/gawain/gawain/gwn_buffer_id.h +++ /dev/null @@ -1,53 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_buffer_id.h - * \ingroup gpu - * - * Gawain buffer IDs - */ - -#ifndef __GWN_BUFFER_ID_H__ -#define __GWN_BUFFER_ID_H__ - -/* Manage GL buffer IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from main thread - * - free can be called from any thread */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gwn_common.h" - -GLuint GWN_buf_id_alloc(void); -void GWN_buf_id_free(GLuint buffer_id); - -#ifdef __cplusplus -} -#endif - -#endif /* __GWN_BUFFER_ID_H__ */ diff --git a/intern/gawain/gawain/gwn_common.h b/intern/gawain/gawain/gwn_common.h deleted file mode 100644 index 2587e8670a9..00000000000 --- a/intern/gawain/gawain/gwn_common.h +++ /dev/null @@ -1,61 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_common.h - * \ingroup gpu - */ - -#ifndef __GWN_COMMON_H__ -#define __GWN_COMMON_H__ - -#define PROGRAM_NO_OPTI 0 - -#if defined(NDEBUG) - #define TRUST_NO_ONE 0 -#else - /* strict error checking, enabled for debug builds during early development */ - #define TRUST_NO_ONE 1 -#endif - -#if defined(WITH_OPENGL) - #include -#endif - -#include -#include -#include - -#if TRUST_NO_ONE - #include -#endif - -/* GWN_INLINE */ -#if defined(_MSC_VER) -# define GWN_INLINE static __forceinline -#else -# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) -#endif - -#endif /* __GWN_COMMON_H__ */ diff --git a/intern/gawain/gawain/gwn_context.h b/intern/gawain/gawain/gwn_context.h deleted file mode 100644 index 7784fc30562..00000000000 --- a/intern/gawain/gawain/gwn_context.h +++ /dev/null @@ -1,55 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_context.h - * \ingroup gpu - * - * This interface allow Gawain to manage VAOs for mutiple context and threads. - */ - -#ifndef __GWN_CONTEXT_H__ -#define __GWN_CONTEXT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gwn_common.h" -#include "gwn_batch.h" -#include "gwn_shader_interface.h" - -typedef struct Gwn_Context Gwn_Context; - -Gwn_Context* GWN_context_create(void); -void GWN_context_discard(Gwn_Context*); - -void GWN_context_active_set(Gwn_Context*); -Gwn_Context* GWN_context_active_get(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __GWN_CONTEXT_H__ */ diff --git a/intern/gawain/gawain/gwn_element.h b/intern/gawain/gawain/gwn_element.h deleted file mode 100644 index 2d5b6bb692b..00000000000 --- a/intern/gawain/gawain/gwn_element.h +++ /dev/null @@ -1,102 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_element.h - * \ingroup gpu - * - * Gawain element list (AKA index buffer) - */ - -#ifndef __GWN_ELEMENT_H__ -#define __GWN_ELEMENT_H__ - -#include "gwn_primitive.h" - -#define GWN_TRACK_INDEX_RANGE 1 - -#define GWN_PRIM_RESTART 0xFFFFFFFF - -typedef enum { - GWN_INDEX_U8, /* GL has this, Vulkan does not */ - GWN_INDEX_U16, - GWN_INDEX_U32 -} Gwn_IndexBufType; - -typedef struct Gwn_IndexBuf { - uint index_len; -#if GWN_TRACK_INDEX_RANGE - Gwn_IndexBufType index_type; - uint32_t gl_index_type; - uint min_index; - uint max_index; - uint base_index; -#endif - uint32_t vbo_id; /* 0 indicates not yet sent to VRAM */ - bool use_prim_restart; -} Gwn_IndexBuf; - -void GWN_indexbuf_use(Gwn_IndexBuf*); -uint GWN_indexbuf_size_get(const Gwn_IndexBuf*); - -typedef struct Gwn_IndexBufBuilder { - uint max_allowed_index; - uint max_index_len; - uint index_len; - Gwn_PrimType prim_type; - uint* data; - bool use_prim_restart; -} Gwn_IndexBufBuilder; - - -/* supports all primitive types. */ -void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, uint index_len, uint vertex_len, bool use_prim_restart); - -/* supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS. */ -void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, uint prim_len, uint vertex_len); - -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, uint v); -void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder*); - -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, uint v); -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, uint v1, uint v2); -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3); -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); - -Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder*); -void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder*, Gwn_IndexBuf*); - -void GWN_indexbuf_discard(Gwn_IndexBuf*); - - -/* Macros */ - -#define GWN_INDEXBUF_DISCARD_SAFE(elem) do { \ - if (elem != NULL) { \ - GWN_indexbuf_discard(elem); \ - elem = NULL; \ - } \ -} while (0) - -#endif /* __GWN_ELEMENT_H__ */ diff --git a/intern/gawain/gawain/gwn_imm_util.h b/intern/gawain/gawain/gwn_imm_util.h deleted file mode 100644 index e512d071dca..00000000000 --- a/intern/gawain/gawain/gwn_imm_util.h +++ /dev/null @@ -1,46 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_imm_util.h - * \ingroup gpu - * - * Gawain element list (AKA index buffer) - */ - -#ifndef __GWN_IMM_UTIL_H__ -#define __GWN_IMM_UTIL_H__ - -#include - -/* Draw 2D rectangles (replaces glRect functions) */ -/* caller is reponsible for vertex format & shader */ -void immRectf(uint pos, float x1, float y1, float x2, float y2); -void immRecti(uint pos, int x1, int y1, int x2, int y2); - -/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS. */ -void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]); -void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]); - -#endif /* __GWN_IMM_UTIL_H__ */ diff --git a/intern/gawain/gawain/gwn_immediate.h b/intern/gawain/gawain/gwn_immediate.h deleted file mode 100644 index 8231942d735..00000000000 --- a/intern/gawain/gawain/gwn_immediate.h +++ /dev/null @@ -1,132 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_immediate.h - * \ingroup gpu - * - * Gawain immediate mode work-alike - */ - -#ifndef __GWN_IMMEDIATE_H__ -#define __GWN_IMMEDIATE_H__ - -#include "gwn_vertex_format.h" -#include "gwn_primitive.h" -#include "gwn_shader_interface.h" -#include "gwn_batch.h" - -Gwn_VertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ - -void immBindProgram(uint32_t program, const Gwn_ShaderInterface*); /* every immBegin must have a program bound first. */ -void immUnbindProgram(void); /* call after your last immEnd, or before binding another program. */ - -void immBegin(Gwn_PrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ -void immBeginAtMost(Gwn_PrimType, uint max_vertex_len); /* can supply fewer vertices. */ -void immEnd(void); /* finishes and draws. */ - -/* ImmBegin a batch, then use standard immFunctions as usual. */ -/* ImmEnd will finalize the batch instead of drawing. */ -/* Then you can draw it as many times as you like! Partially replaces the need for display lists. */ -Gwn_Batch* immBeginBatch(Gwn_PrimType, uint vertex_len); -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, uint vertex_len); - -/* Provide attribute values that can change per vertex. */ -/* First vertex after immBegin must have all its attributes specified. */ -/* Skipped attributes will continue using the previous value for that attrib_id. */ -void immAttrib1f(uint attrib_id, float x); -void immAttrib2f(uint attrib_id, float x, float y); -void immAttrib3f(uint attrib_id, float x, float y, float z); -void immAttrib4f(uint attrib_id, float x, float y, float z, float w); - -void immAttrib2i(uint attrib_id, int x, int y); - -void immAttrib1u(uint attrib_id, uint x); - -void immAttrib2s(uint attrib_id, short x, short y); - -void immAttrib2fv(uint attrib_id, const float data[2]); -void immAttrib3fv(uint attrib_id, const float data[3]); -void immAttrib4fv(uint attrib_id, const float data[4]); - -void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b); -void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a); - -void immAttrib3ubv(uint attrib_id, const unsigned char data[4]); -void immAttrib4ubv(uint attrib_id, const unsigned char data[4]); - -/* Explicitly skip an attribute. */ -/* This advanced option kills automatic value copying for this attrib_id. */ -void immSkipAttrib(uint attrib_id); - -/* Provide one last attribute value & end the current vertex. */ -/* This is most often used for 2D or 3D position (similar to glVertex). */ -void immVertex2f(uint attrib_id, float x, float y); -void immVertex3f(uint attrib_id, float x, float y, float z); -void immVertex4f(uint attrib_id, float x, float y, float z, float w); - -void immVertex2i(uint attrib_id, int x, int y); - -void immVertex2s(uint attrib_id, short x, short y); - -void immVertex2fv(uint attrib_id, const float data[2]); -void immVertex3fv(uint attrib_id, const float data[3]); - -void immVertex2iv(uint attrib_id, const int data[2]); - -/* Provide uniform values that don't change for the entire draw call. */ -void immUniform1i(const char* name, int x); -void immUniform4iv(const char* name, const int data[4]); -void immUniform1f(const char* name, float x); -void immUniform2f(const char* name, float x, float y); -void immUniform2fv(const char* name, const float data[2]); -void immUniform3f(const char* name, float x, float y, float z); -void immUniform3fv(const char* name, const float data[3]); -void immUniformArray3fv(const char* name, const float *data, int count); -void immUniform4f(const char* name, float x, float y, float z, float w); -void immUniform4fv(const char* name, const float data[4]); -void immUniformArray4fv(const char* bare_name, const float *data, int count); -void immUniformMatrix4fv(const char* name, const float data[4][4]); - -/* Convenience functions for setting "uniform vec4 color". */ -/* The rgb functions have implicit alpha = 1.0. */ -void immUniformColor4f(float r, float g, float b, float a); -void immUniformColor4fv(const float rgba[4]); -void immUniformColor3f(float r, float g, float b); -void immUniformColor3fv(const float rgb[3]); -void immUniformColor3fvAlpha(const float rgb[3], float a); - -void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b); -void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); -void immUniformColor3ubv(const unsigned char rgb[3]); -void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a); -void immUniformColor4ubv(const unsigned char rgba[4]); - -/* These are called by the system -- not part of drawing API. */ -void immInit(void); -void immActivate(void); -void immDeactivate(void); -void immDestroy(void); - -#endif /* __GWN_IMMEDIATE_H__ */ diff --git a/intern/gawain/gawain/gwn_primitive.h b/intern/gawain/gawain/gwn_primitive.h deleted file mode 100644 index 346f77441d3..00000000000 --- a/intern/gawain/gawain/gwn_primitive.h +++ /dev/null @@ -1,65 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_primitive.h - * \ingroup gpu - * - * Gawain geometric primitives - */ - -#ifndef __GWN_PRIMITIVE_H__ -#define __GWN_PRIMITIVE_H__ - -#include "gwn_common.h" - -typedef enum { - GWN_PRIM_POINTS, - GWN_PRIM_LINES, - GWN_PRIM_TRIS, - GWN_PRIM_LINE_STRIP, - GWN_PRIM_LINE_LOOP, /* GL has this, Vulkan does not */ - GWN_PRIM_TRI_STRIP, - GWN_PRIM_TRI_FAN, - - GWN_PRIM_LINES_ADJ, - GWN_PRIM_TRIS_ADJ, - GWN_PRIM_LINE_STRIP_ADJ, - - GWN_PRIM_NONE -} Gwn_PrimType; - -/* what types of primitives does each shader expect? */ -typedef enum { - GWN_PRIM_CLASS_NONE = 0, - GWN_PRIM_CLASS_POINT = (1 << 0), - GWN_PRIM_CLASS_LINE = (1 << 1), - GWN_PRIM_CLASS_SURFACE = (1 << 2), - GWN_PRIM_CLASS_ANY = GWN_PRIM_CLASS_POINT | GWN_PRIM_CLASS_LINE | GWN_PRIM_CLASS_SURFACE -} Gwn_PrimClass; - -Gwn_PrimClass GWN_primtype_class(Gwn_PrimType); -bool GWN_primtype_belongs_to_class(Gwn_PrimType, Gwn_PrimClass); - -#endif /* __GWN_PRIMITIVE_H__ */ diff --git a/intern/gawain/gawain/gwn_primitive_private.h b/intern/gawain/gawain/gwn_primitive_private.h deleted file mode 100644 index 6d3f1e20da7..00000000000 --- a/intern/gawain/gawain/gwn_primitive_private.h +++ /dev/null @@ -1,37 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_primitive_private.h - * \ingroup gpu - * - * Gawain geometric primitives - */ - -#ifndef __GWN_PRIMITIVE_PRIVATE_H__ -#define __GWN_PRIMITIVE_PRIVATE_H__ - -GLenum convert_prim_type_to_gl(Gwn_PrimType); - -#endif /* __GWN_PRIMITIVE_PRIVATE_H__ */ diff --git a/intern/gawain/gawain/gwn_shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h deleted file mode 100644 index 4b20719b329..00000000000 --- a/intern/gawain/gawain/gwn_shader_interface.h +++ /dev/null @@ -1,104 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_shader_interface.h - * \ingroup gpu - * - * Gawain shader interface (C --> GLSL) - */ - -#ifndef __GWN_SHADER_INTERFACE_H__ -#define __GWN_SHADER_INTERFACE_H__ - -#include "gwn_common.h" - -typedef enum { - GWN_UNIFORM_NONE = 0, /* uninitialized/unknown */ - - GWN_UNIFORM_MODEL, /* mat4 ModelMatrix */ - GWN_UNIFORM_VIEW, /* mat4 ViewMatrix */ - GWN_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */ - GWN_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */ - GWN_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */ - GWN_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */ - - GWN_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */ - GWN_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */ - GWN_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */ - GWN_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */ - GWN_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */ - - GWN_UNIFORM_NORMAL, /* mat3 NormalMatrix */ - GWN_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */ - GWN_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */ - GWN_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */ - - GWN_UNIFORM_COLOR, /* vec4 color */ - GWN_UNIFORM_EYE, /* vec3 eye */ - GWN_UNIFORM_CALLID, /* int callId */ - - GWN_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */ - - GWN_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ -} Gwn_UniformBuiltin; - -typedef struct Gwn_ShaderInput { - struct Gwn_ShaderInput* next; - uint32_t name_offset; - uint name_hash; - Gwn_UniformBuiltin builtin_type; /* only for uniform inputs */ - uint32_t gl_type; /* only for attrib inputs */ - int32_t size; /* only for attrib inputs */ - int32_t location; -} Gwn_ShaderInput; - -#define GWN_NUM_SHADERINTERFACE_BUCKETS 257 -#define GWN_SHADERINTERFACE_REF_ALLOC_COUNT 16 - -typedef struct Gwn_ShaderInterface { - int32_t program; - uint32_t name_buffer_offset; - Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS]; - char* name_buffer; - struct Gwn_Batch** batches; /* references to batches using this interface */ - uint batches_len; -} Gwn_ShaderInterface; - -Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program_id); -void GWN_shaderinterface_discard(Gwn_ShaderInterface*); - -const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface*, const char* name); -const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface*, Gwn_UniformBuiltin); -const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name); -const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name); - -/* keep track of batches using this interface */ -void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); -void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); - -#endif /* __GWN_SHADER_INTERFACE_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_array_id.h b/intern/gawain/gawain/gwn_vertex_array_id.h deleted file mode 100644 index 6ba26612b4e..00000000000 --- a/intern/gawain/gawain/gwn_vertex_array_id.h +++ /dev/null @@ -1,55 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_vertex_array_id.h - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#ifndef __GWN_VERTEX_ARRAY_ID_H__ -#define __GWN_VERTEX_ARRAY_ID_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gwn_common.h" -#include "gwn_context.h" - -GLuint GWN_vao_default(void); -GLuint GWN_vao_alloc(void); -void GWN_vao_free(GLuint vao_id, Gwn_Context*); - -#ifdef __cplusplus -} -#endif - -#endif /* __GWN_VERTEX_ARRAY_ID_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h deleted file mode 100644 index 84ea12f86d1..00000000000 --- a/intern/gawain/gawain/gwn_vertex_buffer.h +++ /dev/null @@ -1,144 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_vertex_buffer.h - * \ingroup gpu - * - * Gawain vertex buffer - */ - -#ifndef __GWN_VERTEX_BUFFER_H__ -#define __GWN_VERTEX_BUFFER_H__ - -#include "gwn_vertex_format.h" - -#define VRAM_USAGE 1 -/* How to create a Gwn_VertBuf: */ -/* 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts) */ -/* 2) GWN_vertformat_attr_add(verts->format, ...) */ -/* 3) GWN_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format */ -/* 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ - -/* Is Gwn_VertBuf always used as part of a Gwn_Batch? */ - -typedef enum { - /* can be extended to support more types */ - GWN_USAGE_STREAM, - GWN_USAGE_STATIC, /* do not keep data in memory */ - GWN_USAGE_DYNAMIC -} Gwn_UsageType; - -typedef struct Gwn_VertBuf { - Gwn_VertFormat format; - uint vertex_len; /* number of verts we want to draw */ - uint vertex_alloc; /* number of verts data */ - bool dirty; - unsigned char* data; /* NULL indicates data in VRAM (unmapped) */ - uint32_t vbo_id; /* 0 indicates not yet allocated */ - Gwn_UsageType usage; /* usage hint for GL optimisation */ -} Gwn_VertBuf; - -Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType); -Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat*, Gwn_UsageType); - -#define GWN_vertbuf_create_with_format(format) \ - GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_STATIC) - -void GWN_vertbuf_discard(Gwn_VertBuf*); - -void GWN_vertbuf_init(Gwn_VertBuf*, Gwn_UsageType); -void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf*, const Gwn_VertFormat*, Gwn_UsageType); - -#define GWN_vertbuf_init_with_format(verts, format) \ - GWN_vertbuf_init_with_format_ex(verts, format, GWN_USAGE_STATIC) - -uint GWN_vertbuf_size_get(const Gwn_VertBuf*); -void GWN_vertbuf_data_alloc(Gwn_VertBuf*, uint v_len); -void GWN_vertbuf_data_resize(Gwn_VertBuf*, uint v_len); -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, uint v_len); - -/* The most important set_attrib variant is the untyped one. Get it right first. */ -/* It takes a void* so the app developer is responsible for matching their app data types */ -/* to the vertex attribute's type and component count. They're in control of both, so this */ -/* should not be a problem. */ - -void GWN_vertbuf_attr_set(Gwn_VertBuf*, uint a_idx, uint v_idx, const void* data); -void GWN_vertbuf_attr_fill(Gwn_VertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, uint a_idx, uint stride, const void* data); - -/* For low level access only */ -typedef struct Gwn_VertBufRaw { - uint size; - uint stride; - unsigned char* data; - unsigned char* data_init; -#if TRUST_NO_ONE - /* Only for overflow check */ - unsigned char* _data_end; -#endif -} Gwn_VertBufRaw; - -GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) -{ - unsigned char* data = a->data; - a->data += a->stride; -#if TRUST_NO_ONE - assert(data < a->_data_end); -#endif - return (void *)data; -} - -GWN_INLINE uint GWN_vertbuf_raw_used(Gwn_VertBufRaw *a) -{ - return ((a->data - a->data_init) / a->stride); -} - -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, uint a_idx, Gwn_VertBufRaw *access); - -/* TODO: decide whether to keep the functions below */ -/* doesn't immediate mode satisfy these needs? */ - -/* void setAttrib1f(uint a_idx, uint v_idx, float x); */ -/* void setAttrib2f(uint a_idx, unsigned v_idx, float x, float y); */ -/* void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z); */ -/* void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w); */ - -/* void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); */ -/* void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); */ - -void GWN_vertbuf_use(Gwn_VertBuf*); - -/* Metrics */ -uint GWN_vertbuf_get_memory_usage(void); - -/* Macros */ -#define GWN_VERTBUF_DISCARD_SAFE(verts) do { \ - if (verts != NULL) { \ - GWN_vertbuf_discard(verts); \ - verts = NULL; \ - } \ -} while (0) - -#endif /* __GWN_VERTEX_BUFFER_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h deleted file mode 100644 index 1197a8ef842..00000000000 --- a/intern/gawain/gawain/gwn_vertex_format.h +++ /dev/null @@ -1,101 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_vertex_format.h - * \ingroup gpu - * - * Gawain vertex format - */ - -#ifndef __GWN_VERTEX_FORMAT_H__ -#define __GWN_VERTEX_FORMAT_H__ - -#include "gwn_common.h" - -#define GWN_VERT_ATTR_MAX_LEN 16 -#define GWN_VERT_ATTR_MAX_NAMES 3 -#define GWN_VERT_ATTR_NAME_AVERAGE_LEN 11 -#define GWN_VERT_ATTR_NAMES_BUF_LEN ((GWN_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GWN_VERT_ATTR_MAX_LEN) - -typedef enum { - GWN_COMP_I8, - GWN_COMP_U8, - GWN_COMP_I16, - GWN_COMP_U16, - GWN_COMP_I32, - GWN_COMP_U32, - - GWN_COMP_F32, - - GWN_COMP_I10 -} Gwn_VertCompType; - -typedef enum { - GWN_FETCH_FLOAT, - GWN_FETCH_INT, - GWN_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ - GWN_FETCH_INT_TO_FLOAT /* 127 (any int type) -> 127.0 */ -} Gwn_VertFetchMode; - -typedef struct Gwn_VertAttr { - Gwn_VertFetchMode fetch_mode; - Gwn_VertCompType comp_type; - uint gl_comp_type; - uint comp_len; /* 1 to 4 or 8 or 12 or 16 */ - uint sz; /* size in bytes, 1 to 64 */ - uint offset; /* from beginning of vertex, in bytes */ - uint name_len; /* up to GWN_VERT_ATTR_MAX_NAMES */ - const char* name[GWN_VERT_ATTR_MAX_NAMES]; -} Gwn_VertAttr; - -typedef struct Gwn_VertFormat { - uint attr_len; /* 0 to 16 (GWN_VERT_ATTR_MAX_LEN) */ - uint name_len; /* total count of active vertex attrib */ - uint stride; /* stride in bytes, 1 to 256 */ - uint name_offset; - bool packed; - char names[GWN_VERT_ATTR_NAMES_BUF_LEN]; - Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ -} Gwn_VertFormat; - -void GWN_vertformat_clear(Gwn_VertFormat*); -void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src); - -uint GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, uint comp_len, Gwn_VertFetchMode); -void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias); - -/* format conversion */ - -typedef struct Gwn_PackedNormal { - int x : 10; - int y : 10; - int z : 10; - int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ -} Gwn_PackedNormal; - -Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]); -Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]); - -#endif /* __GWN_VERTEX_FORMAT_H__ */ diff --git a/intern/gawain/gawain/gwn_vertex_format_private.h b/intern/gawain/gawain/gwn_vertex_format_private.h deleted file mode 100644 index 3cae9969fd8..00000000000 --- a/intern/gawain/gawain/gwn_vertex_format_private.h +++ /dev/null @@ -1,39 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_vertex_format_private.h - * \ingroup gpu - * - * Gawain vertex format - */ - -#ifndef __GWN_VERTEX_FORMAT_PRIVATE_H__ -#define __GWN_VERTEX_FORMAT_PRIVATE_H__ - -void VertexFormat_pack(Gwn_VertFormat*); -uint padding(uint offset, uint alignment); -uint vertex_buffer_size(const Gwn_VertFormat*, uint vertex_len); - -#endif /* __GWN_VERTEX_FORMAT_PRIVATE_H__ */ diff --git a/intern/gawain/src/gwn_attr_binding.c b/intern/gawain/src/gwn_attr_binding.c deleted file mode 100644 index 727aceb0140..00000000000 --- a/intern/gawain/src/gwn_attr_binding.c +++ /dev/null @@ -1,85 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_attr_binding.c - * \ingroup gpu - * - * Gawain vertex attribute binding - */ - -#include "gwn_attr_binding.h" -#include "gwn_attr_binding_private.h" -#include -#include - -#if GWN_VERT_ATTR_MAX_LEN != 16 - #error "attrib binding code assumes GWN_VERT_ATTR_MAX_LEN = 16" -#endif - -void AttribBinding_clear(Gwn_AttrBinding* binding) -{ - binding->loc_bits = 0; - binding->enabled_bits = 0; -} - -uint read_attrib_location(const Gwn_AttrBinding* binding, uint a_idx) -{ -#if TRUST_NO_ONE - assert(a_idx < GWN_VERT_ATTR_MAX_LEN); - assert(binding->enabled_bits & (1 << a_idx)); -#endif - return (binding->loc_bits >> (4 * a_idx)) & 0xF; -} - -static void write_attrib_location(Gwn_AttrBinding* binding, uint a_idx, uint location) -{ -#if TRUST_NO_ONE - assert(a_idx < GWN_VERT_ATTR_MAX_LEN); - assert(location < GWN_VERT_ATTR_MAX_LEN); -#endif - const uint shift = 4 * a_idx; - const uint64_t mask = ((uint64_t)0xF) << shift; - /* overwrite this attrib's previous location */ - binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift); - /* mark this attrib as enabled */ - binding->enabled_bits |= 1 << a_idx; -} - -void get_attrib_locations(const Gwn_VertFormat* format, Gwn_AttrBinding* binding, const Gwn_ShaderInterface* shaderface) -{ - AttribBinding_clear(binding); - - for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) { - const Gwn_VertAttr* a = format->attribs + a_idx; - for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const Gwn_ShaderInput* input = GWN_shaderinterface_attr(shaderface, a->name[n_idx]); -#if TRUST_NO_ONE - assert(input != NULL); - /* TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program */ -#endif - write_attrib_location(binding, a_idx, input->location); - } - } -} diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c deleted file mode 100644 index 5daf0e87aec..00000000000 --- a/intern/gawain/src/gwn_batch.c +++ /dev/null @@ -1,645 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_batch.c - * \ingroup gpu - * - * Gawain geometry batch - * Contains VAOs + VBOs + Shader representing a drawable entity. - */ - -#include "gwn_batch.h" -#include "gwn_batch_private.h" -#include "gwn_buffer_id.h" -#include "gwn_vertex_array_id.h" -#include "gwn_primitive_private.h" -#include -#include - -/* necessary functions from matrix API */ -extern void GPU_matrix_bind(const Gwn_ShaderInterface* shaderface); - -static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first); - -void gwn_batch_vao_cache_clear(Gwn_Batch* batch) -{ - if (batch->context == NULL) { - return; - } - if (batch->is_dynamic_vao_count) { - for (int i = 0; i < batch->dynamic_vaos.count; ++i) { - if (batch->dynamic_vaos.vao_ids[i]) { - GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); - } - if (batch->dynamic_vaos.interfaces[i]) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); - } - } - free(batch->dynamic_vaos.interfaces); - free(batch->dynamic_vaos.vao_ids); - } - else { - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { - if (batch->static_vaos.vao_ids[i]) { - GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); - } - if (batch->static_vaos.interfaces[i]) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->static_vaos.interfaces[i], batch); - } - } - } - batch->is_dynamic_vao_count = false; - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { - batch->static_vaos.vao_ids[i] = 0; - batch->static_vaos.interfaces[i] = NULL; - } - gwn_context_remove_batch(batch->context, batch); - batch->context = NULL; -} - -Gwn_Batch* GWN_batch_create_ex( - Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, - uint owns_flag) -{ - Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch)); - GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag); - return batch; -} - -void GWN_batch_init_ex( - Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, - uint owns_flag) -{ -#if TRUST_NO_ONE - assert(verts != NULL); -#endif - - batch->verts[0] = verts; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { - batch->verts[v] = NULL; - } - batch->inst = NULL; - batch->elem = elem; - batch->gl_prim_type = convert_prim_type_to_gl(prim_type); - batch->phase = GWN_BATCH_READY_TO_DRAW; - batch->is_dynamic_vao_count = false; - batch->owns_flag = owns_flag; - batch->free_callback = NULL; -} - -/* This will share the VBOs with the new batch. */ -Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src) -{ - Gwn_Batch* batch = GWN_batch_create_ex(GWN_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); - - batch->gl_prim_type = batch_src->gl_prim_type; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { - batch->verts[v] = batch_src->verts[v]; - } - return batch; -} - -void GWN_batch_discard(Gwn_Batch* batch) -{ - if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) { - GWN_indexbuf_discard(batch->elem); - } - if (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES) { - GWN_vertbuf_discard(batch->inst); - } - if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) { - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { - if (batch->verts[v] == NULL) { - break; - } - if (batch->owns_flag & (1 << v)) { - GWN_vertbuf_discard(batch->verts[v]); - } - } - } - gwn_batch_vao_cache_clear(batch); - - if (batch->free_callback) { - batch->free_callback(batch, batch->callback_data); - } - free(batch); -} - -void GWN_batch_callback_free_set(Gwn_Batch* batch, void (*callback)(Gwn_Batch*, void*), void* user_data) -{ - batch->free_callback = callback; - batch->callback_data = user_data; -} - -void GWN_batch_instbuf_set(Gwn_Batch* batch, Gwn_VertBuf* inst, bool own_vbo) -{ -#if TRUST_NO_ONE - assert(inst != NULL); -#endif - /* redo the bindings */ - gwn_batch_vao_cache_clear(batch); - - if (batch->inst != NULL && (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES)) { - GWN_vertbuf_discard(batch->inst); - } - batch->inst = inst; - - if (own_vbo) { - batch->owns_flag |= GWN_BATCH_OWNS_INSTANCES; - } - else { - batch->owns_flag &= ~GWN_BATCH_OWNS_INSTANCES; - } -} - -/* Returns the index of verts in the batch. */ -int GWN_batch_vertbuf_add_ex( - Gwn_Batch* batch, Gwn_VertBuf* verts, - bool own_vbo) -{ - /* redo the bindings */ - gwn_batch_vao_cache_clear(batch); - - for (uint v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { - if (batch->verts[v] == NULL) { -#if TRUST_NO_ONE - /* for now all VertexBuffers must have same vertex_len */ - assert(verts->vertex_len == batch->verts[0]->vertex_len); -#endif - batch->verts[v] = verts; - /* TODO: mark dirty so we can keep attrib bindings up-to-date */ - if (own_vbo) - batch->owns_flag |= (1 << v); - return v; - } - } - - /* we only make it this far if there is no room for another Gwn_VertBuf */ -#if TRUST_NO_ONE - assert(false); -#endif - return -1; -} - -static GLuint batch_vao_get(Gwn_Batch *batch) -{ - /* Search through cache */ - if (batch->is_dynamic_vao_count) { - for (int i = 0; i < batch->dynamic_vaos.count; ++i) - if (batch->dynamic_vaos.interfaces[i] == batch->interface) - return batch->dynamic_vaos.vao_ids[i]; - } - else { - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) - if (batch->static_vaos.interfaces[i] == batch->interface) - return batch->static_vaos.vao_ids[i]; - } - - /* Set context of this batch. - * It will be bound to it until gwn_batch_vao_cache_clear is called. - * Until then it can only be drawn with this context. */ - if (batch->context == NULL) { - batch->context = GWN_context_active_get(); - gwn_context_add_batch(batch->context, batch); - } -#if TRUST_NO_ONE - else { - /* Make sure you are not trying to draw this batch in another context. */ - assert(batch->context == GWN_context_active_get()); - } -#endif - - /* Cache miss, time to add a new entry! */ - GLuint new_vao = 0; - if (!batch->is_dynamic_vao_count) { - int i; /* find first unused slot */ - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) - if (batch->static_vaos.vao_ids[i] == 0) - break; - - if (i < GWN_BATCH_VAO_STATIC_LEN) { - batch->static_vaos.interfaces[i] = batch->interface; - batch->static_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); - } - else { - /* Not enough place switch to dynamic. */ - batch->is_dynamic_vao_count = true; - /* Erase previous entries, they will be added back if drawn again. */ - for (int j = 0; j < GWN_BATCH_VAO_STATIC_LEN; ++j) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface*)batch->static_vaos.interfaces[j], batch); - GWN_vao_free(batch->static_vaos.vao_ids[j], batch->context); - } - /* Init dynamic arrays and let the branch below set the values. */ - batch->dynamic_vaos.count = GWN_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(Gwn_ShaderInterface*)); - batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); - } - } - - if (batch->is_dynamic_vao_count) { - int i; /* find first unused slot */ - for (i = 0; i < batch->dynamic_vaos.count; ++i) - if (batch->dynamic_vaos.vao_ids[i] == 0) - break; - - if (i == batch->dynamic_vaos.count) { - /* Not enough place, realloc the array. */ - i = batch->dynamic_vaos.count; - batch->dynamic_vaos.count += GWN_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(Gwn_ShaderInterface*) * batch->dynamic_vaos.count); - batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); - memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(Gwn_ShaderInterface*) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); - memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); - } - batch->dynamic_vaos.interfaces[i] = batch->interface; - batch->dynamic_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); - } - - GWN_shaderinterface_add_batch_ref((Gwn_ShaderInterface*)batch->interface, batch); - -#if TRUST_NO_ONE - assert(new_vao != 0); -#endif - - /* We just got a fresh VAO we need to initialize it. */ - glBindVertexArray(new_vao); - batch_update_program_bindings(batch, 0); - glBindVertexArray(0); - - return new_vao; -} - -void GWN_batch_program_set_no_use(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) -{ -#if TRUST_NO_ONE - assert(glIsProgram(shaderface->program)); - assert(batch->program_in_use == 0); -#endif - batch->interface = shaderface; - batch->program = program; - batch->vao_id = batch_vao_get(batch); -} - -void GWN_batch_program_set(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) -{ - GWN_batch_program_set_no_use(batch, program, shaderface); - GWN_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ -} - -void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* interface) -{ - if (batch->is_dynamic_vao_count) { - for (int i = 0; i < batch->dynamic_vaos.count; ++i) { - if (batch->dynamic_vaos.interfaces[i] == interface) { - GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); - batch->dynamic_vaos.vao_ids[i] = 0; - batch->dynamic_vaos.interfaces[i] = NULL; - break; /* cannot have duplicates */ - } - } - } - else { - int i; - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { - if (batch->static_vaos.interfaces[i] == interface) { - GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); - batch->static_vaos.vao_ids[i] = 0; - batch->static_vaos.interfaces[i] = NULL; - break; /* cannot have duplicates */ - } - } - } -} - -static void create_bindings( - Gwn_VertBuf* verts, const Gwn_ShaderInterface* interface, - uint v_first, const bool use_instancing) -{ - const Gwn_VertFormat* format = &verts->format; - - const uint attr_len = format->attr_len; - const uint stride = format->stride; - - GWN_vertbuf_use(verts); - - for (uint a_idx = 0; a_idx < attr_len; ++a_idx) { - const Gwn_VertAttr* a = format->attribs + a_idx; - const GLvoid* pointer = (const GLubyte*)0 + a->offset + v_first * stride; - - for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const Gwn_ShaderInput* input = GWN_shaderinterface_attr(interface, a->name[n_idx]); - - if (input == NULL) continue; - - if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { -#if TRUST_NO_ONE - assert(a->fetch_mode == GWN_FETCH_FLOAT); - assert(a->gl_comp_type == GL_FLOAT); -#endif - for (int i = 0; i < a->comp_len / 4; ++i) { - glEnableVertexAttribArray(input->location + i); - glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0); - glVertexAttribPointer(input->location + i, 4, a->gl_comp_type, GL_FALSE, stride, - (const GLubyte*)pointer + i * 16); - } - } - else - { - glEnableVertexAttribArray(input->location); - glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0); - - switch (a->fetch_mode) { - case GWN_FETCH_FLOAT: - case GWN_FETCH_INT_TO_FLOAT: - glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); - break; - case GWN_FETCH_INT_TO_FLOAT_UNIT: - glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); - break; - case GWN_FETCH_INT: - glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer); - break; - } - } - } - } -} - -static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first) -{ - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { - create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false); - } - if (batch->inst) { - create_bindings(batch->inst, batch->interface, v_first, true); - } - if (batch->elem) { - GWN_indexbuf_use(batch->elem); - } -} - -void GWN_batch_program_use_begin(Gwn_Batch* batch) -{ - /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with - * the GL context's active program. use_program doesn't mark other programs as "not used". */ - /* TODO: make not fragile (somehow) */ - - if (!batch->program_in_use) { - glUseProgram(batch->program); - batch->program_in_use = true; - } -} - -void GWN_batch_program_use_end(Gwn_Batch* batch) -{ - if (batch->program_in_use) { -#if PROGRAM_NO_OPTI - glUseProgram(0); -#endif - batch->program_in_use = false; - } -} - -#if TRUST_NO_ONE - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); assert(uniform); -#else - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); -#endif - -void GWN_batch_uniform_1ui(Gwn_Batch* batch, const char* name, int value) -{ - GET_UNIFORM - glUniform1ui(uniform->location, value); -} - -void GWN_batch_uniform_1i(Gwn_Batch* batch, const char* name, int value) -{ - GET_UNIFORM - glUniform1i(uniform->location, value); -} - -void GWN_batch_uniform_1b(Gwn_Batch* batch, const char* name, bool value) -{ - GET_UNIFORM - glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE); -} - -void GWN_batch_uniform_2f(Gwn_Batch* batch, const char* name, float x, float y) -{ - GET_UNIFORM - glUniform2f(uniform->location, x, y); -} - -void GWN_batch_uniform_3f(Gwn_Batch* batch, const char* name, float x, float y, float z) -{ - GET_UNIFORM - glUniform3f(uniform->location, x, y, z); -} - -void GWN_batch_uniform_4f(Gwn_Batch* batch, const char* name, float x, float y, float z, float w) -{ - GET_UNIFORM - glUniform4f(uniform->location, x, y, z, w); -} - -void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x) -{ - GET_UNIFORM - glUniform1f(uniform->location, x); -} - -void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2]) -{ - GET_UNIFORM - glUniform2fv(uniform->location, 1, data); -} - -void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3]) -{ - GET_UNIFORM - glUniform3fv(uniform->location, 1, data); -} - -void GWN_batch_uniform_4fv(Gwn_Batch* batch, const char* name, const float data[4]) -{ - GET_UNIFORM - glUniform4fv(uniform->location, 1, data); -} - -void GWN_batch_uniform_2fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) -{ - GET_UNIFORM - glUniform2fv(uniform->location, len, data); -} - -void GWN_batch_uniform_4fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) -{ - GET_UNIFORM - glUniform4fv(uniform->location, len, data); -} - -void GWN_batch_uniform_mat4(Gwn_Batch* batch, const char* name, const float data[4][4]) -{ - GET_UNIFORM - glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); -} - -static void primitive_restart_enable(const Gwn_IndexBuf *el) -{ - // TODO(fclem) Replace by GL_PRIMITIVE_RESTART_FIXED_INDEX when we have ogl 4.3 - glEnable(GL_PRIMITIVE_RESTART); - GLuint restart_index = (GLuint)0xFFFFFFFF; - -#if GWN_TRACK_INDEX_RANGE - if (el->index_type == GWN_INDEX_U8) - restart_index = (GLuint)0xFF; - else if (el->index_type == GWN_INDEX_U16) - restart_index = (GLuint)0xFFFF; -#endif - - glPrimitiveRestartIndex(restart_index); -} - -static void primitive_restart_disable(void) -{ - glDisable(GL_PRIMITIVE_RESTART); -} - -void GWN_batch_draw(Gwn_Batch* batch) -{ -#if TRUST_NO_ONE - assert(batch->phase == GWN_BATCH_READY_TO_DRAW); - assert(batch->verts[0]->vbo_id != 0); -#endif - GWN_batch_program_use_begin(batch); - GPU_matrix_bind(batch->interface); // external call. - - GWN_batch_draw_range_ex(batch, 0, 0, false); - - GWN_batch_program_use_end(batch); -} - -void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool force_instance) -{ -#if TRUST_NO_ONE - assert(!(force_instance && (batch->inst == NULL)) || v_count > 0); // we cannot infer length if force_instance -#endif - const bool do_instance = (force_instance || batch->inst); - - // If using offset drawing, use the default VAO and redo bindings. - if (v_first != 0 && (do_instance || batch->elem)) { - glBindVertexArray(GWN_vao_default()); - batch_update_program_bindings(batch, v_first); - } - else { - glBindVertexArray(batch->vao_id); - } - - if (do_instance) { - /* Infer length if vertex count is not given */ - if (v_count == 0) { - v_count = batch->inst->vertex_len; - } - - if (batch->elem) { - const Gwn_IndexBuf* el = batch->elem; - - if (el->use_prim_restart) { - primitive_restart_enable(el); - } -#if GWN_TRACK_INDEX_RANGE - glDrawElementsInstancedBaseVertex(batch->gl_prim_type, - el->index_len, - el->gl_index_type, - 0, - v_count, - el->base_index); -#else - glDrawElementsInstanced(batch->gl_prim_type, el->index_len, GL_UNSIGNED_INT, 0, v_count); -#endif - if (el->use_prim_restart) { - primitive_restart_disable(); - } - } - else { - glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_len, v_count); - } - } - else { - /* Infer length if vertex count is not given */ - if (v_count == 0) { - v_count = (batch->elem) ? batch->elem->index_len : batch->verts[0]->vertex_len; - } - - if (batch->elem) { - const Gwn_IndexBuf* el = batch->elem; - - if (el->use_prim_restart) { - primitive_restart_enable(el); - } - -#if GWN_TRACK_INDEX_RANGE - if (el->base_index) { - glDrawRangeElementsBaseVertex(batch->gl_prim_type, - el->min_index, - el->max_index, - v_count, - el->gl_index_type, - 0, - el->base_index); - } - else { - glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, v_count, el->gl_index_type, 0); - } -#else - glDrawElements(batch->gl_prim_type, v_count, GL_UNSIGNED_INT, 0); -#endif - if (el->use_prim_restart) { - primitive_restart_disable(); - } - } - else { - glDrawArrays(batch->gl_prim_type, v_first, v_count); - } - } - - /* Performance hog if you are drawing with the same vao multiple time. - * Only activate for debugging. */ - // glBindVertexArray(0); -} - -/* just draw some vertices and let shader place them where we want. */ -void GWN_draw_primitive(Gwn_PrimType prim_type, int v_count) - { - /* we cannot draw without vao ... annoying ... */ - glBindVertexArray(GWN_vao_default()); - - GLenum type = convert_prim_type_to_gl(prim_type); - glDrawArrays(type, 0, v_count); - - /* Performance hog if you are drawing with the same vao multiple time. - * Only activate for debugging.*/ - // glBindVertexArray(0); - } diff --git a/intern/gawain/src/gwn_buffer_id.cpp b/intern/gawain/src/gwn_buffer_id.cpp deleted file mode 100644 index 2c267682f65..00000000000 --- a/intern/gawain/src/gwn_buffer_id.cpp +++ /dev/null @@ -1,89 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_buffer_id.cpp - * \ingroup gpu - * - * Gawain buffer IDs - */ - -#include "gwn_buffer_id.h" -#include -#include - -#define ORPHAN_DEBUG 0 - -#if ORPHAN_DEBUG - #include -#endif - -static std::vector orphaned_buffer_ids; - -static std::mutex orphan_mutex; - -extern "C" { -extern int BLI_thread_is_main(void); /* Blender-specific function */ -} - -static bool thread_is_main() -{ - /* "main" here means the GL context's thread */ - return BLI_thread_is_main(); -} - -GLuint GWN_buf_id_alloc() -{ - /* delete orphaned IDs */ - orphan_mutex.lock(); - if (!orphaned_buffer_ids.empty()) { - const auto orphaned_buffer_len = (uint)orphaned_buffer_ids.size(); -#if ORPHAN_DEBUG - printf("deleting %u orphaned VBO%s\n", orphaned_buffer_len, orphaned_buffer_len == 1 ? "" : "s"); -#endif - glDeleteBuffers(orphaned_buffer_len, orphaned_buffer_ids.data()); - orphaned_buffer_ids.clear(); - } - orphan_mutex.unlock(); - - GLuint new_buffer_id = 0; - glGenBuffers(1, &new_buffer_id); - return new_buffer_id; -} - -void GWN_buf_id_free(GLuint buffer_id) -{ - if (thread_is_main()) { - glDeleteBuffers(1, &buffer_id); - } - else { - /* add this ID to the orphaned list */ - orphan_mutex.lock(); -#if ORPHAN_DEBUG - printf("orphaning VBO %u\n", buffer_id); -#endif - orphaned_buffer_ids.emplace_back(buffer_id); - orphan_mutex.unlock(); - } -} diff --git a/intern/gawain/src/gwn_element.c b/intern/gawain/src/gwn_element.c deleted file mode 100644 index a8c99f20860..00000000000 --- a/intern/gawain/src/gwn_element.c +++ /dev/null @@ -1,307 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_element.c - * \ingroup gpu - * - * Gawain element list (AKA index buffer) - */ - -#include "gwn_element.h" -#include "gwn_buffer_id.h" -#include - -#define KEEP_SINGLE_COPY 1 - -static GLenum convert_index_type_to_gl(Gwn_IndexBufType type) -{ - static const GLenum table[] = { - [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ - [GWN_INDEX_U16] = GL_UNSIGNED_SHORT, - [GWN_INDEX_U32] = GL_UNSIGNED_INT - }; - return table[type]; -} - -uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) -{ -#if GWN_TRACK_INDEX_RANGE - static const uint table[] = { - [GWN_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ - [GWN_INDEX_U16] = sizeof(GLushort), - [GWN_INDEX_U32] = sizeof(GLuint) - }; - return elem->index_len * table[elem->index_type]; -#else - return elem->index_len * sizeof(GLuint); -#endif -} - -void GWN_indexbuf_init_ex( - Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, - uint index_len, uint vertex_len, bool use_prim_restart) -{ - builder->use_prim_restart = use_prim_restart; - builder->max_allowed_index = vertex_len - 1; - builder->max_index_len = index_len; - builder->index_len = 0; // start empty - builder->prim_type = prim_type; - builder->data = calloc(builder->max_index_len, sizeof(uint)); -} - -void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uint prim_len, uint vertex_len) -{ - uint verts_per_prim = 0; - switch (prim_type) { - case GWN_PRIM_POINTS: - verts_per_prim = 1; - break; - case GWN_PRIM_LINES: - verts_per_prim = 2; - break; - case GWN_PRIM_TRIS: - verts_per_prim = 3; - break; - case GWN_PRIM_LINES_ADJ: - verts_per_prim = 4; - break; - default: -#if TRUST_NO_ONE - assert(false); -#endif - return; - } - - GWN_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); -} - -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v) -{ -#if TRUST_NO_ONE - assert(builder->data != NULL); - assert(builder->index_len < builder->max_index_len); - assert(v <= builder->max_allowed_index); -#endif - builder->data[builder->index_len++] = v; -} - -void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder* builder) -{ -#if TRUST_NO_ONE - assert(builder->data != NULL); - assert(builder->index_len < builder->max_index_len); - assert(builder->use_prim_restart); -#endif - builder->data[builder->index_len++] = GWN_PRIM_RESTART; -} - -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, uint v) -{ -#if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_POINTS); -#endif - GWN_indexbuf_add_generic_vert(builder, v); -} - -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2) -{ -#if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_LINES); - assert(v1 != v2); -#endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); -} - -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3) -{ -#if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_TRIS); - assert(v1 != v2 && v2 != v3 && v3 != v1); -#endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); - GWN_indexbuf_add_generic_vert(builder, v3); -} - -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) -{ -#if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_LINES_ADJ); - assert(v2 != v3); /* only the line need diff indices */ -#endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); - GWN_indexbuf_add_generic_vert(builder, v3); - GWN_indexbuf_add_generic_vert(builder, v4); -} - -#if GWN_TRACK_INDEX_RANGE -/* Everything remains 32 bit while building to keep things simple. - * Find min/max after, then convert to smallest index type possible. */ - -static uint index_range(const uint values[], uint value_len, uint* min_out, uint* max_out) -{ - if (value_len == 0) { - *min_out = 0; - *max_out = 0; - return 0; - } - uint min_value = values[0]; - uint max_value = values[0]; - for (uint i = 1; i < value_len; ++i) { - const uint value = values[i]; - if (value == GWN_PRIM_RESTART) - continue; - else if (value < min_value) - min_value = value; - else if (value > max_value) - max_value = value; - } - *min_out = min_value; - *max_out = max_value; - return max_value - min_value; -} - -static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) -{ - const uint *values = builder->data; - const uint index_len = elem->index_len; - - /* data will never be *larger* than builder->data... - * converting in place to avoid extra allocation */ - GLubyte *data = (GLubyte *)builder->data; - - if (elem->max_index > 0xFF) { - const uint base = elem->min_index; - elem->base_index = base; - elem->min_index = 0; - elem->max_index -= base; - for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); - } - } - else { - elem->base_index = 0; - for (uint i = 0; i < index_len; ++i) { - data[i] = (GLubyte)(values[i]); - } - } -} - -static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) -{ - const uint *values = builder->data; - const uint index_len = elem->index_len; - - /* data will never be *larger* than builder->data... - * converting in place to avoid extra allocation */ - GLushort *data = (GLushort *)builder->data; - - if (elem->max_index > 0xFFFF) { - const uint base = elem->min_index; - elem->base_index = base; - elem->min_index = 0; - elem->max_index -= base; - for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); - } - } - else { - elem->base_index = 0; - for (uint i = 0; i < index_len; ++i) { - data[i] = (GLushort)(values[i]); - } - } -} - -#endif /* GWN_TRACK_INDEX_RANGE */ - -Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder* builder) -{ - Gwn_IndexBuf* elem = calloc(1, sizeof(Gwn_IndexBuf)); - GWN_indexbuf_build_in_place(builder, elem); - return elem; -} - -void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* elem) -{ -#if TRUST_NO_ONE - assert(builder->data != NULL); -#endif - elem->index_len = builder->index_len; - elem->use_prim_restart = builder->use_prim_restart; - -#if GWN_TRACK_INDEX_RANGE - uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); - - /* count the primitive restart index. */ - if (elem->use_prim_restart) { - range += 1; - } - - if (range <= 0xFF) { - elem->index_type = GWN_INDEX_U8; - squeeze_indices_byte(builder, elem); - } - else if (range <= 0xFFFF) { - elem->index_type = GWN_INDEX_U16; - squeeze_indices_short(builder, elem); - } - else { - elem->index_type = GWN_INDEX_U32; - elem->base_index = 0; - } - elem->gl_index_type = convert_index_type_to_gl(elem->index_type); -#endif - - if (elem->vbo_id == 0) { - elem->vbo_id = GWN_buf_id_alloc(); - } - /* send data to GPU */ - /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, - * so we use the GL_ARRAY_BUFFER here to create a buffer without - * interfering in the VAO state. */ - glBindBuffer(GL_ARRAY_BUFFER, elem->vbo_id); - glBufferData(GL_ARRAY_BUFFER, GWN_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); - - /* discard builder (one-time use) */ - free(builder->data); - builder->data = NULL; - /* other fields are safe to leave */ -} - -void GWN_indexbuf_use(Gwn_IndexBuf* elem) -{ - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id); -} - -void GWN_indexbuf_discard(Gwn_IndexBuf* elem) -{ - if (elem->vbo_id) { - GWN_buf_id_free(elem->vbo_id); - } - free(elem); -} diff --git a/intern/gawain/src/gwn_imm_util.c b/intern/gawain/src/gwn_imm_util.c deleted file mode 100644 index cdf55c3dfc4..00000000000 --- a/intern/gawain/src/gwn_imm_util.c +++ /dev/null @@ -1,100 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_imm_util.c - * \ingroup gpu - * - * Gawain immediate mode drawing utilities - */ - -#include "gwn_imm_util.h" -#include "gwn_immediate.h" -#include - -void immRectf(uint pos, float x1, float y1, float x2, float y2) -{ - immBegin(GWN_PRIM_TRI_FAN, 4); - immVertex2f(pos, x1, y1); - immVertex2f(pos, x2, y1); - immVertex2f(pos, x2, y2); - immVertex2f(pos, x1, y2); - immEnd(); -} - -void immRecti(uint pos, int x1, int y1, int x2, int y2) -{ - immBegin(GWN_PRIM_TRI_FAN, 4); - immVertex2i(pos, x1, y1); - immVertex2i(pos, x2, y1); - immVertex2i(pos, x2, y2); - immVertex2i(pos, x1, y2); - immEnd(); -} - -void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]) -{ - immAttrib4fv(col, color); - immVertex2f(pos, x1, y1); - immAttrib4fv(col, color); - immVertex2f(pos, x2, y1); - immAttrib4fv(col, color); - immVertex2f(pos, x2, y2); - - immAttrib4fv(col, color); - immVertex2f(pos, x1, y1); - immAttrib4fv(col, color); - immVertex2f(pos, x2, y2); - immAttrib4fv(col, color); - immVertex2f(pos, x1, y2); -} - -void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]) -{ - immAttrib4fv(col, color); - immVertex2i(pos, x1, y1); - immAttrib4fv(col, color); - immVertex2i(pos, x2, y1); - immAttrib4fv(col, color); - immVertex2i(pos, x2, y2); - - immAttrib4fv(col, color); - immVertex2i(pos, x1, y1); - immAttrib4fv(col, color); - immVertex2i(pos, x2, y2); - immAttrib4fv(col, color); - immVertex2i(pos, x1, y2); -} - -#if 0 /* more complete version in case we want that */ -void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4]) -{ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = add_attrib(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4fv(color); - immRecti(pos, x1, y1, x2, y2); - immUnbindProgram(); -} -#endif diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c deleted file mode 100644 index 442aa85ece4..00000000000 --- a/intern/gawain/src/gwn_immediate.c +++ /dev/null @@ -1,863 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_immediate.c - * \ingroup gpu - * - * Gawain immediate mode work-alike - */ - -#include "gwn_immediate.h" -#include "gwn_buffer_id.h" -#include "gwn_attr_binding.h" -#include "gwn_attr_binding_private.h" -#include "gwn_vertex_format_private.h" -#include "gwn_vertex_array_id.h" -#include "gwn_primitive_private.h" -#include -#include - -/* necessary functions from matrix API */ -extern void GPU_matrix_bind(const Gwn_ShaderInterface*); -extern bool GPU_matrix_dirty_get(void); - -typedef struct { - /* TODO: organize this struct by frequency of change (run-time) */ - - Gwn_Batch* batch; - Gwn_Context* context; - - /* current draw call */ - GLubyte* buffer_data; - uint buffer_offset; - uint buffer_bytes_mapped; - uint vertex_len; - bool strict_vertex_len; - Gwn_PrimType prim_type; - - Gwn_VertFormat vertex_format; - - /* current vertex */ - uint vertex_idx; - GLubyte* vertex_data; - uint16_t unassigned_attrib_bits; /* which attributes of current vertex have not been given values? */ - - GLuint vbo_id; - GLuint vao_id; - - GLuint bound_program; - const Gwn_ShaderInterface* shader_interface; - Gwn_AttrBinding attrib_binding; - uint16_t prev_enabled_attrib_bits; /* <-- only affects this VAO, so we're ok */ -} Immediate; - -/* size of internal buffer -- make this adjustable? */ -#define IMM_BUFFER_SIZE (4 * 1024 * 1024) - -static bool initialized = false; -static Immediate imm; - -void immInit(void) -{ -#if TRUST_NO_ONE - assert(!initialized); -#endif - memset(&imm, 0, sizeof(Immediate)); - - imm.vbo_id = GWN_buf_id_alloc(); - glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); - glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); - - imm.prim_type = GWN_PRIM_NONE; - imm.strict_vertex_len = true; - - glBindBuffer(GL_ARRAY_BUFFER, 0); - initialized = true; -} - -void immActivate(void) -{ -#if TRUST_NO_ONE - assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ - assert(imm.vao_id == 0); -#endif - imm.vao_id = GWN_vao_alloc(); - imm.context = GWN_context_active_get(); -} - -void immDeactivate(void) -{ -#if TRUST_NO_ONE - assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ - assert(imm.vao_id != 0); -#endif - GWN_vao_free(imm.vao_id, imm.context); - imm.vao_id = 0; - imm.prev_enabled_attrib_bits = 0; -} - -void immDestroy(void) -{ - GWN_buf_id_free(imm.vbo_id); - initialized = false; -} - -Gwn_VertFormat* immVertexFormat(void) -{ - GWN_vertformat_clear(&imm.vertex_format); - return &imm.vertex_format; -} - -void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) -{ -#if TRUST_NO_ONE - assert(imm.bound_program == 0); - assert(glIsProgram(program)); -#endif - - imm.bound_program = program; - imm.shader_interface = shaderface; - - if (!imm.vertex_format.packed) - VertexFormat_pack(&imm.vertex_format); - - glUseProgram(program); - get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface); - GPU_matrix_bind(shaderface); -} - -void immUnbindProgram(void) -{ -#if TRUST_NO_ONE - assert(imm.bound_program != 0); -#endif -#if PROGRAM_NO_OPTI - glUseProgram(0); -#endif - imm.bound_program = 0; -} - -#if TRUST_NO_ONE -static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType prim_type) -{ - /* does vertex_len make sense for this primitive type? */ - if (vertex_len == 0) { - return false; - } - - switch (prim_type) { - case GWN_PRIM_POINTS: - return true; - case GWN_PRIM_LINES: - return vertex_len % 2 == 0; - case GWN_PRIM_LINE_STRIP: - case GWN_PRIM_LINE_LOOP: - return vertex_len >= 2; - case GWN_PRIM_LINE_STRIP_ADJ: - return vertex_len >= 4; - case GWN_PRIM_TRIS: - return vertex_len % 3 == 0; - case GWN_PRIM_TRI_STRIP: - case GWN_PRIM_TRI_FAN: - return vertex_len >= 3; - default: - return false; - } -} -#endif - -void immBegin(Gwn_PrimType prim_type, uint vertex_len) -{ -#if TRUST_NO_ONE - assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ - assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); -#endif - imm.prim_type = prim_type; - imm.vertex_len = vertex_len; - imm.vertex_idx = 0; - imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - - /* how many bytes do we need for this draw call? */ - const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); - -#if TRUST_NO_ONE - assert(bytes_needed <= IMM_BUFFER_SIZE); -#endif - - glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); - - /* does the current buffer have enough room? */ - const uint available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; - /* ensure vertex data is aligned */ - const uint pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); /* might waste a little space, but it's safe */ - if ((bytes_needed + pre_padding) <= available_bytes) { - imm.buffer_offset += pre_padding; - } - else { - /* orphan this buffer & start with a fresh one */ - /* this method works on all platforms, old & new */ - glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); - - imm.buffer_offset = 0; - } - -/* printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */ - - imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed, - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)); - -#if TRUST_NO_ONE - assert(imm.buffer_data != NULL); -#endif - - imm.buffer_bytes_mapped = bytes_needed; - imm.vertex_data = imm.buffer_data; -} - -void immBeginAtMost(Gwn_PrimType prim_type, uint vertex_len) -{ -#if TRUST_NO_ONE - assert(vertex_len > 0); -#endif - - imm.strict_vertex_len = false; - immBegin(prim_type, vertex_len); -} - - -Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, uint vertex_len) -{ -#if TRUST_NO_ONE - assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ - assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); -#endif - imm.prim_type = prim_type; - imm.vertex_len = vertex_len; - imm.vertex_idx = 0; - imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - - Gwn_VertBuf* verts = GWN_vertbuf_create_with_format(&imm.vertex_format); - GWN_vertbuf_data_alloc(verts, vertex_len); - - imm.buffer_bytes_mapped = GWN_vertbuf_size_get(verts); - imm.vertex_data = verts->data; - - imm.batch = GWN_batch_create_ex(prim_type, verts, NULL, GWN_BATCH_OWNS_VBO); - imm.batch->phase = GWN_BATCH_BUILDING; - - return imm.batch; -} - -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType prim_type, uint vertex_len) -{ - imm.strict_vertex_len = false; - return immBeginBatch(prim_type, vertex_len); -} - -static void immDrawSetup(void) -{ - /* set up VAO -- can be done during Begin or End really */ - glBindVertexArray(imm.vao_id); - - /* enable/disable vertex attribs as needed */ - if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits) { - for (uint loc = 0; loc < GWN_VERT_ATTR_MAX_LEN; ++loc) { - bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc); - bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc); - - if (is_enabled && !was_enabled) { - glEnableVertexAttribArray(loc); - } - else if (was_enabled && !is_enabled) { - glDisableVertexAttribArray(loc); - } - } - - imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits; - } - - const uint stride = imm.vertex_format.stride; - - for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { - const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; - - const uint offset = imm.buffer_offset + a->offset; - const GLvoid* pointer = (const GLubyte*)0 + offset; - - const uint loc = read_attrib_location(&imm.attrib_binding, a_idx); - - switch (a->fetch_mode) { - case GWN_FETCH_FLOAT: - case GWN_FETCH_INT_TO_FLOAT: - glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); - break; - case GWN_FETCH_INT_TO_FLOAT_UNIT: - glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); - break; - case GWN_FETCH_INT: - glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); - } - } - - if (GPU_matrix_dirty_get()) { - GPU_matrix_bind(imm.shader_interface); - } -} - -void immEnd(void) -{ -#if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - - uint buffer_bytes_used; - if (imm.strict_vertex_len) { -#if TRUST_NO_ONE - assert(imm.vertex_idx == imm.vertex_len); /* with all vertices defined */ -#endif - buffer_bytes_used = imm.buffer_bytes_mapped; - } - else { -#if TRUST_NO_ONE - assert(imm.vertex_idx <= imm.vertex_len); -#endif - if (imm.vertex_idx == imm.vertex_len) { - buffer_bytes_used = imm.buffer_bytes_mapped; - } - else { -#if TRUST_NO_ONE - assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type)); -#endif - imm.vertex_len = imm.vertex_idx; - buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_len); - /* unused buffer bytes are available to the next immBegin */ - } - /* tell OpenGL what range was modified so it doesn't copy the whole mapped range */ - glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used); - } - - if (imm.batch) { - if (buffer_bytes_used != imm.buffer_bytes_mapped) { - GWN_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); - /* TODO: resize only if vertex count is much smaller */ - } - GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); - imm.batch->phase = GWN_BATCH_READY_TO_DRAW; - imm.batch = NULL; /* don't free, batch belongs to caller */ - } - else { - glUnmapBuffer(GL_ARRAY_BUFFER); - if (imm.vertex_len > 0) { - immDrawSetup(); - glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_len); - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - /* prep for next immBegin */ - imm.buffer_offset += buffer_bytes_used; - } - - /* prep for next immBegin */ - imm.prim_type = GWN_PRIM_NONE; - imm.strict_vertex_len = true; -} - -static void setAttribValueBit(uint attrib_id) -{ - uint16_t mask = 1 << attrib_id; -#if TRUST_NO_ONE - assert(imm.unassigned_attrib_bits & mask); /* not already set */ -#endif - imm.unassigned_attrib_bits &= ~mask; -} - - -/* --- generic attribute functions --- */ - -void immAttrib1f(uint attrib_id, float x) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); - assert(attrib->comp_len == 1); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - float* data = (float*)(imm.vertex_data + attrib->offset); -/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ - - data[0] = x; -} - -void immAttrib2f(uint attrib_id, float x, float y) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); - assert(attrib->comp_len == 2); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - float* data = (float*)(imm.vertex_data + attrib->offset); -/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ - - data[0] = x; - data[1] = y; -} - -void immAttrib3f(uint attrib_id, float x, float y, float z) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); - assert(attrib->comp_len == 3); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - float* data = (float*)(imm.vertex_data + attrib->offset); -/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ - - data[0] = x; - data[1] = y; - data[2] = z; -} - -void immAttrib4f(uint attrib_id, float x, float y, float z, float w) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); - assert(attrib->comp_len == 4); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - float* data = (float*)(imm.vertex_data + attrib->offset); -/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ - - data[0] = x; - data[1] = y; - data[2] = z; - data[3] = w; -} - -void immAttrib1u(uint attrib_id, uint x) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U32); - assert(attrib->comp_len == 1); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - uint* data = (uint*)(imm.vertex_data + attrib->offset); - - data[0] = x; -} - -void immAttrib2i(uint attrib_id, int x, int y) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_I32); - assert(attrib->comp_len == 2); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - int* data = (int*)(imm.vertex_data + attrib->offset); - - data[0] = x; - data[1] = y; -} - -void immAttrib2s(uint attrib_id, short x, short y) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_I16); - assert(attrib->comp_len == 2); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - short* data = (short*)(imm.vertex_data + attrib->offset); - - data[0] = x; - data[1] = y; -} - -void immAttrib2fv(uint attrib_id, const float data[2]) -{ - immAttrib2f(attrib_id, data[0], data[1]); -} - -void immAttrib3fv(uint attrib_id, const float data[3]) -{ - immAttrib3f(attrib_id, data[0], data[1], data[2]); -} - -void immAttrib4fv(uint attrib_id, const float data[4]) -{ - immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]); -} - -void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U8); - assert(attrib->comp_len == 3); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - GLubyte* data = imm.vertex_data + attrib->offset; -/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ - - data[0] = r; - data[1] = g; - data[2] = b; -} - -void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U8); - assert(attrib->comp_len == 4); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); - - GLubyte* data = imm.vertex_data + attrib->offset; -/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ - - data[0] = r; - data[1] = g; - data[2] = b; - data[3] = a; -} - -void immAttrib3ubv(uint attrib_id, const unsigned char data[3]) -{ - immAttrib3ub(attrib_id, data[0], data[1], data[2]); -} - -void immAttrib4ubv(uint attrib_id, const unsigned char data[4]) -{ - immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]); -} - -void immSkipAttrib(uint attrib_id) -{ -#if TRUST_NO_ONE - assert(attrib_id < imm.vertex_format.attr_len); - assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ -#endif - setAttribValueBit(attrib_id); -} - -static void immEndVertex(void) /* and move on to the next vertex */ -{ -#if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ - assert(imm.vertex_idx < imm.vertex_len); -#endif - - /* have all attribs been assigned values? - * if not, copy value from previous vertex */ - if (imm.unassigned_attrib_bits) { -#if TRUST_NO_ONE - assert(imm.vertex_idx > 0); /* first vertex must have all attribs specified */ -#endif - for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { - if ((imm.unassigned_attrib_bits >> a_idx) & 1) { - const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; - -/* printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); */ - - GLubyte* data = imm.vertex_data + a->offset; - memcpy(data, data - imm.vertex_format.stride, a->sz); - /* TODO: consolidate copy of adjacent attributes */ - } - } - } - - imm.vertex_idx++; - imm.vertex_data += imm.vertex_format.stride; - imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; -} - -void immVertex2f(uint attrib_id, float x, float y) -{ - immAttrib2f(attrib_id, x, y); - immEndVertex(); -} - -void immVertex3f(uint attrib_id, float x, float y, float z) -{ - immAttrib3f(attrib_id, x, y, z); - immEndVertex(); -} - -void immVertex4f(uint attrib_id, float x, float y, float z, float w) -{ - immAttrib4f(attrib_id, x, y, z, w); - immEndVertex(); -} - -void immVertex2i(uint attrib_id, int x, int y) -{ - immAttrib2i(attrib_id, x, y); - immEndVertex(); -} - -void immVertex2s(uint attrib_id, short x, short y) -{ - immAttrib2s(attrib_id, x, y); - immEndVertex(); -} - -void immVertex2fv(uint attrib_id, const float data[2]) -{ - immAttrib2f(attrib_id, data[0], data[1]); - immEndVertex(); -} - -void immVertex3fv(uint attrib_id, const float data[3]) -{ - immAttrib3f(attrib_id, data[0], data[1], data[2]); - immEndVertex(); -} - -void immVertex2iv(uint attrib_id, const int data[2]) -{ - immAttrib2i(attrib_id, data[0], data[1]); - immEndVertex(); -} - - -/* --- generic uniform functions --- */ - -#if 0 - #if TRUST_NO_ONE - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); - #else - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); - #endif -#else - /* NOTE: It is possible to have uniform fully optimized out from the shader. - * In this case we can't assert failure or allow NULL-pointer dereference. - * TODO(sergey): How can we detect existing-but-optimized-out uniform but still - * catch typos in uniform names passed to immUniform*() functions? */ - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; -#endif - -void immUniform1f(const char* name, float x) -{ - GET_UNIFORM - glUniform1f(uniform->location, x); -} - -void immUniform2f(const char* name, float x, float y) -{ - GET_UNIFORM - glUniform2f(uniform->location, x, y); -} - -void immUniform2fv(const char* name, const float data[2]) -{ - GET_UNIFORM - glUniform2fv(uniform->location, 1, data); -} - -void immUniform3f(const char* name, float x, float y, float z) -{ - GET_UNIFORM - glUniform3f(uniform->location, x, y, z); -} - -void immUniform3fv(const char* name, const float data[3]) -{ - GET_UNIFORM - glUniform3fv(uniform->location, 1, data); -} - -/* can increase this limit or move to another file */ -#define MAX_UNIFORM_NAME_LEN 60 - -void immUniformArray3fv(const char* bare_name, const float *data, int count) -{ - /* look up "name[0]" when given "name" */ - const size_t len = strlen(bare_name); -#if TRUST_NO_ONE - assert(len <= MAX_UNIFORM_NAME_LEN); -#endif - char name[MAX_UNIFORM_NAME_LEN]; - strcpy(name, bare_name); - name[len + 0] = '['; - name[len + 1] = '0'; - name[len + 2] = ']'; - name[len + 3] = '\0'; - - GET_UNIFORM - glUniform3fv(uniform->location, count, data); -} - -void immUniform4f(const char* name, float x, float y, float z, float w) -{ - GET_UNIFORM - glUniform4f(uniform->location, x, y, z, w); -} - -void immUniform4fv(const char* name, const float data[4]) -{ - GET_UNIFORM - glUniform4fv(uniform->location, 1, data); -} - -void immUniformArray4fv(const char* bare_name, const float *data, int count) -{ - /* look up "name[0]" when given "name" */ - const size_t len = strlen(bare_name); -#if TRUST_NO_ONE - assert(len <= MAX_UNIFORM_NAME_LEN); -#endif - char name[MAX_UNIFORM_NAME_LEN]; - strcpy(name, bare_name); - name[len + 0] = '['; - name[len + 1] = '0'; - name[len + 2] = ']'; - name[len + 3] = '\0'; - - GET_UNIFORM - glUniform4fv(uniform->location, count, data); -} - -void immUniformMatrix4fv(const char* name, const float data[4][4]) -{ - GET_UNIFORM - glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data); -} - -void immUniform1i(const char* name, int x) -{ - GET_UNIFORM - glUniform1i(uniform->location, x); -} - -void immUniform4iv(const char* name, const int data[4]) -{ - GET_UNIFORM - glUniform4iv(uniform->location, 1, data); -} - -/* --- convenience functions for setting "uniform vec4 color" --- */ - -void immUniformColor4f(float r, float g, float b, float a) -{ - const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform_builtin(imm.shader_interface, GWN_UNIFORM_COLOR); -#if TRUST_NO_ONE - assert(uniform != NULL); -#endif - glUniform4f(uniform->location, r, g, b, a); -} - -void immUniformColor4fv(const float rgba[4]) -{ - immUniformColor4f(rgba[0], rgba[1], rgba[2], rgba[3]); -} - -void immUniformColor3f(float r, float g, float b) -{ - immUniformColor4f(r, g, b, 1.0f); -} - -void immUniformColor3fv(const float rgb[3]) -{ - immUniformColor4f(rgb[0], rgb[1], rgb[2], 1.0f); -} - -void immUniformColor3fvAlpha(const float rgb[3], float a) -{ - immUniformColor4f(rgb[0], rgb[1], rgb[2], a); -} - -/* TODO: v-- treat as sRGB? --v */ - -void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b) -{ - const float scale = 1.0f / 255.0f; - immUniformColor4f(scale * r, scale * g, scale * b, 1.0f); -} - -void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) -{ - const float scale = 1.0f / 255.0f; - immUniformColor4f(scale * r, scale * g, scale * b, scale * a); -} - -void immUniformColor3ubv(const unsigned char rgb[3]) -{ - immUniformColor3ub(rgb[0], rgb[1], rgb[2]); -} - -void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char alpha) -{ - immUniformColor4ub(rgb[0], rgb[1], rgb[2], alpha); -} - -void immUniformColor4ubv(const unsigned char rgba[4]) -{ - immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]); -} diff --git a/intern/gawain/src/gwn_primitive.c b/intern/gawain/src/gwn_primitive.c deleted file mode 100644 index bec638a4972..00000000000 --- a/intern/gawain/src/gwn_primitive.c +++ /dev/null @@ -1,84 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_primitive.c - * \ingroup gpu - * - * Gawain geometric primitives - */ - -#include "gwn_primitive.h" -#include "gwn_primitive_private.h" - -Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type) -{ - static const Gwn_PrimClass classes[] = { - [GWN_PRIM_POINTS] = GWN_PRIM_CLASS_POINT, - [GWN_PRIM_LINES] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_STRIP] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_LOOP] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_TRIS] = GWN_PRIM_CLASS_SURFACE, - [GWN_PRIM_TRI_STRIP] = GWN_PRIM_CLASS_SURFACE, - [GWN_PRIM_TRI_FAN] = GWN_PRIM_CLASS_SURFACE, - - [GWN_PRIM_LINES_ADJ] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_STRIP_ADJ] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_TRIS_ADJ] = GWN_PRIM_CLASS_SURFACE, - - [GWN_PRIM_NONE] = GWN_PRIM_CLASS_NONE - }; - - return classes[prim_type]; -} - -bool GWN_primtype_belongs_to_class(Gwn_PrimType prim_type, Gwn_PrimClass prim_class) -{ - if (prim_class == GWN_PRIM_CLASS_NONE && prim_type == GWN_PRIM_NONE) { - return true; - } - return prim_class & GWN_primtype_class(prim_type); -} - -GLenum convert_prim_type_to_gl(Gwn_PrimType prim_type) -{ -#if TRUST_NO_ONE - assert(prim_type != GWN_PRIM_NONE); -#endif - static const GLenum table[] = { - [GWN_PRIM_POINTS] = GL_POINTS, - [GWN_PRIM_LINES] = GL_LINES, - [GWN_PRIM_LINE_STRIP] = GL_LINE_STRIP, - [GWN_PRIM_LINE_LOOP] = GL_LINE_LOOP, - [GWN_PRIM_TRIS] = GL_TRIANGLES, - [GWN_PRIM_TRI_STRIP] = GL_TRIANGLE_STRIP, - [GWN_PRIM_TRI_FAN] = GL_TRIANGLE_FAN, - - [GWN_PRIM_LINES_ADJ] = GL_LINES_ADJACENCY, - [GWN_PRIM_LINE_STRIP_ADJ] = GL_LINE_STRIP_ADJACENCY, - [GWN_PRIM_TRIS_ADJ] = GL_TRIANGLES_ADJACENCY, - }; - - return table[prim_type]; -} diff --git a/intern/gawain/src/gwn_shader_interface.c b/intern/gawain/src/gwn_shader_interface.c deleted file mode 100644 index 997d5215d5b..00000000000 --- a/intern/gawain/src/gwn_shader_interface.c +++ /dev/null @@ -1,361 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_shader_interface.c - * \ingroup gpu - * - * Gawain shader interface (C --> GLSL) - */ - -#include "gwn_batch_private.h" -#include "gwn_shader_interface.h" -#include "gwn_vertex_array_id.h" -#include -#include -#include - -#define DEBUG_SHADER_INTERFACE 0 - -#if DEBUG_SHADER_INTERFACE - #include -#endif - -static const char* BuiltinUniform_name(Gwn_UniformBuiltin u) -{ - static const char* names[] = { - [GWN_UNIFORM_NONE] = NULL, - - [GWN_UNIFORM_MODEL] = "ModelMatrix", - [GWN_UNIFORM_VIEW] = "ViewMatrix", - [GWN_UNIFORM_MODELVIEW] = "ModelViewMatrix", - [GWN_UNIFORM_PROJECTION] = "ProjectionMatrix", - [GWN_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix", - [GWN_UNIFORM_MVP] = "ModelViewProjectionMatrix", - - [GWN_UNIFORM_MODEL_INV] = "ModelMatrixInverse", - [GWN_UNIFORM_VIEW_INV] = "ViewMatrixInverse", - [GWN_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse", - [GWN_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse", - [GWN_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse", - - [GWN_UNIFORM_NORMAL] = "NormalMatrix", - [GWN_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix", - [GWN_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors", - [GWN_UNIFORM_ORCO] = "OrcoTexCoFactors", - - [GWN_UNIFORM_COLOR] = "color", - [GWN_UNIFORM_EYE] = "eye", - [GWN_UNIFORM_CALLID] = "callId", - - [GWN_UNIFORM_CUSTOM] = NULL, - [GWN_NUM_UNIFORMS] = NULL, - }; - - return names[u]; -} - -GWN_INLINE bool match(const char* a, const char* b) -{ - return strcmp(a, b) == 0; -} - -GWN_INLINE uint hash_string(const char *str) -{ - uint i = 0, c; - while ((c = *str++)) { - i = i * 37 + c; - } - return i; -} - -GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* input, - const char* name, uint32_t name_len) -{ - input->name_offset = shaderface->name_buffer_offset; - input->name_hash = hash_string(name); - shaderface->name_buffer_offset += name_len + 1; /* include NULL terminator */ -} - -GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input, - Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) -{ - const uint bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; - input->next = buckets[bucket_index]; - buckets[bucket_index] = input; -} - -GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], - const char *name_buffer, const char *name) -{ - const uint name_hash = hash_string(name); - const uint bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; - const Gwn_ShaderInput* input = buckets[bucket_index]; - if (input == NULL) { - /* Requested uniform is not found at all. */ - return NULL; - } - /* Optimization bit: if there is no hash collision detected when constructing shader interface - * it means we can only request the single possible uniform. Surely, it's possible we request - * uniform which causes hash collision, but that will be detected in debug builds. */ - if (input->next == NULL) { - if (name_hash == input->name_hash) { -#if TRUST_NO_ONE - assert(match(name_buffer + input->name_offset, name)); -#endif - return input; - } - return NULL; - } - /* Work through possible collisions. */ - const Gwn_ShaderInput* next = input; - while (next != NULL) { - input = next; - next = input->next; - if (input->name_hash != name_hash) { - continue; - } - if (match(name_buffer + input->name_offset, name)) { - return input; - } - } - return NULL; /* not found */ -} - -GWN_INLINE void buckets_free(Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) -{ - for (uint bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { - Gwn_ShaderInput *input = buckets[bucket_index]; - while (input != NULL) { - Gwn_ShaderInput *input_next = input->next; - free(input); - input = input_next; - } - } -} - -static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name) -{ - /* TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types */ - - /* detect built-in uniforms (name must match) */ - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { - const char* builtin_name = BuiltinUniform_name(u); - if (match(name, builtin_name)) { - input->builtin_type = u; - return true; - } - } - input->builtin_type = GWN_UNIFORM_CUSTOM; - return false; -} - -static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const char* name) -{ - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); - - input->location = glGetUniformLocation(shaderface->program, name); - - uint name_len = strlen(name); - shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ - char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; - strcpy(name_buffer, name); - - set_input_name(shaderface, input, name, name_len); - setup_builtin_uniform(input, name); - - shader_input_to_bucket(input, shaderface->uniform_buckets); - if (input->builtin_type != GWN_UNIFORM_NONE && - input->builtin_type != GWN_UNIFORM_CUSTOM) - { - shaderface->builtin_uniforms[input->builtin_type] = input; - } -#if DEBUG_SHADER_INTERFACE - printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, - shaderface->program, - name, - input->location); -#endif - return input; -} - -Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) -{ - Gwn_ShaderInterface* shaderface = calloc(1, sizeof(Gwn_ShaderInterface)); - shaderface->program = program; - -#if DEBUG_SHADER_INTERFACE - printf("%s {\n", __func__); /* enter function */ - printf("Gwn_ShaderInterface %p, program %d\n", shaderface, program); -#endif - - GLint max_attrib_name_len, attr_len; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len); - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len); - - GLint max_ubo_name_len, ubo_len; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len); - glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len); - - const uint32_t name_buffer_len = attr_len * max_attrib_name_len + ubo_len * max_ubo_name_len; - shaderface->name_buffer = malloc(name_buffer_len); - - /* Attributes */ - for (uint32_t i = 0; i < attr_len; ++i) { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); - GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; - char* name = shaderface->name_buffer + shaderface->name_buffer_offset; - GLsizei name_len = 0; - - glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name); - - /* remove "[0]" from array name */ - if (name[name_len-1] == ']') { - name[name_len-3] = '\0'; - name_len -= 3; - } - - /* TODO: reject DOUBLE gl_types */ - - input->location = glGetAttribLocation(program, name); - - set_input_name(shaderface, input, name, name_len); - - shader_input_to_bucket(input, shaderface->attrib_buckets); - -#if DEBUG_SHADER_INTERFACE - printf("attrib[%u] '%s' at location %d\n", i, name, input->location); -#endif - } - /* Uniform Blocks */ - for (uint32_t i = 0; i < ubo_len; ++i) { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); - GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; - char* name = shaderface->name_buffer + shaderface->name_buffer_offset; - GLsizei name_len = 0; - - glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name); - - input->location = i; - - set_input_name(shaderface, input, name, name_len); - - shader_input_to_bucket(input, shaderface->ubo_buckets); - -#if DEBUG_SHADER_INTERFACE - printf("ubo '%s' at location %d\n", name, input->location); -#endif - } - /* Builtin Uniforms */ - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { - const char* builtin_name = BuiltinUniform_name(u); - if (glGetUniformLocation(program, builtin_name) != -1) { - add_uniform((Gwn_ShaderInterface*)shaderface, builtin_name); - } - } - /* Batches ref buffer */ - shaderface->batches_len = GWN_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = calloc(shaderface->batches_len, sizeof(Gwn_Batch*)); - - return shaderface; -} - -void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) -{ - /* Free memory used by buckets and has entries. */ - buckets_free(shaderface->uniform_buckets); - buckets_free(shaderface->attrib_buckets); - buckets_free(shaderface->ubo_buckets); - /* Free memory used by name_buffer. */ - free(shaderface->name_buffer); - /* Remove this interface from all linked Batches vao cache. */ - for (int i = 0; i < shaderface->batches_len; ++i) { - if (shaderface->batches[i] != NULL) { - gwn_batch_remove_interface_ref(shaderface->batches[i], shaderface); - } - } - free(shaderface->batches); - /* Free memory used by shader interface by its self. */ - free(shaderface); -} - -const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name) -{ - /* TODO: Warn if we find a matching builtin, since these can be looked up much quicker. */ - const Gwn_ShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); - /* If input is not found add it so it's found next time. */ - if (input == NULL) { - input = add_uniform((Gwn_ShaderInterface*)shaderface, name); - } - return (input->location != -1) ? input : NULL; -} - -const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin( - const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin) -{ -#if TRUST_NO_ONE - assert(builtin != GWN_UNIFORM_NONE); - assert(builtin != GWN_UNIFORM_CUSTOM); - assert(builtin != GWN_NUM_UNIFORMS); -#endif - return shaderface->builtin_uniforms[builtin]; -} - -const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name) -{ - return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name); -} - -const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name) -{ - return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name); -} - -void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) -{ - int i; /* find first unused slot */ - for (i = 0; i < shaderface->batches_len; ++i) { - if (shaderface->batches[i] == NULL) { - break; - } - } - if (i == shaderface->batches_len) { - /* Not enough place, realloc the array. */ - i = shaderface->batches_len; - shaderface->batches_len += GWN_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = realloc(shaderface->batches, sizeof(Gwn_Batch*) * shaderface->batches_len); - memset(shaderface->batches + i, 0, sizeof(Gwn_Batch*) * GWN_SHADERINTERFACE_REF_ALLOC_COUNT); - } - shaderface->batches[i] = batch; -} - -void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) -{ - for (int i = 0; i < shaderface->batches_len; ++i) { - if (shaderface->batches[i] == batch) { - shaderface->batches[i] = NULL; - break; /* cannot have duplicates */ - } - } -} diff --git a/intern/gawain/src/gwn_vertex_array_id.cpp b/intern/gawain/src/gwn_vertex_array_id.cpp deleted file mode 100644 index 04470bf6844..00000000000 --- a/intern/gawain/src/gwn_vertex_array_id.cpp +++ /dev/null @@ -1,196 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Clément Foucault - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/gwn_vertex_array_id.cpp - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#include "gwn_batch_private.h" -#include "gwn_vertex_array_id.h" -#include "gwn_context.h" -#include -#include -#include -#include -#include - -#if TRUST_NO_ONE -#if 0 -extern "C" { -extern int BLI_thread_is_main(void); /* Blender-specific function */ -} - -static bool thread_is_main() { - /* "main" here means the GL context's thread */ - return BLI_thread_is_main(); -} -#endif -#endif - -struct Gwn_Context { - GLuint default_vao; - std::unordered_set batches; /* Batches that have VAOs from this context */ - std::vector orphaned_vertarray_ids; - std::mutex orphans_mutex; /* todo: try spinlock instead */ -#if TRUST_NO_ONE - pthread_t thread; /* Thread on which this context is active. */ - bool thread_is_used; - - Gwn_Context() { - thread_is_used = false; - } -#endif -}; - -#if defined(_MSC_VER) && (_MSC_VER == 1800) -#define thread_local __declspec(thread) -thread_local Gwn_Context* active_ctx = NULL; -#else -static thread_local Gwn_Context* active_ctx = NULL; -#endif - -static void clear_orphans(Gwn_Context* ctx) -{ - ctx->orphans_mutex.lock(); - if (!ctx->orphaned_vertarray_ids.empty()) { - uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size(); - glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data()); - ctx->orphaned_vertarray_ids.clear(); - } - ctx->orphans_mutex.unlock(); -} - -Gwn_Context* GWN_context_create(void) -{ -#if TRUST_NO_ONE - /* assert(thread_is_main()); */ -#endif - Gwn_Context* ctx = new Gwn_Context; - glGenVertexArrays(1, &ctx->default_vao); - GWN_context_active_set(ctx); - return ctx; -} - -/* to be called after GWN_context_active_set(ctx_to_destroy) */ -void GWN_context_discard(Gwn_Context* ctx) -{ -#if TRUST_NO_ONE - /* Make sure no other thread has locked it. */ - assert(ctx == active_ctx); - assert(pthread_equal(pthread_self(), ctx->thread)); - assert(ctx->orphaned_vertarray_ids.empty()); -#endif - /* delete remaining vaos */ - while (!ctx->batches.empty()) { - /* this removes the array entry */ - gwn_batch_vao_cache_clear(*ctx->batches.begin()); - } - glDeleteVertexArrays(1, &ctx->default_vao); - delete ctx; - active_ctx = NULL; -} - -/* ctx can be NULL */ -void GWN_context_active_set(Gwn_Context* ctx) -{ -#if TRUST_NO_ONE - if (active_ctx) { - active_ctx->thread_is_used = false; - } - /* Make sure no other context is already bound to this thread. */ - if (ctx) { - /* Make sure no other thread has locked it. */ - assert(ctx->thread_is_used == false); - ctx->thread = pthread_self(); - ctx->thread_is_used = true; - } -#endif - if (ctx) { - clear_orphans(ctx); - } - active_ctx = ctx; -} - -Gwn_Context* GWN_context_active_get(void) -{ - return active_ctx; -} - -GLuint GWN_vao_default(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - return active_ctx->default_vao; -} - -GLuint GWN_vao_alloc(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - clear_orphans(active_ctx); - - GLuint new_vao_id = 0; - glGenVertexArrays(1, &new_vao_id); - return new_vao_id; -} - -/* this can be called from multiple thread */ -void GWN_vao_free(GLuint vao_id, Gwn_Context* ctx) -{ -#if TRUST_NO_ONE - assert(ctx); -#endif - if (ctx == active_ctx) { - glDeleteVertexArrays(1, &vao_id); - } - else { - ctx->orphans_mutex.lock(); - ctx->orphaned_vertarray_ids.emplace_back(vao_id); - ctx->orphans_mutex.unlock(); - } -} - -void gwn_context_add_batch(Gwn_Context* ctx, Gwn_Batch* batch) -{ - ctx->batches.emplace(batch); -} - -void gwn_context_remove_batch(Gwn_Context* ctx, Gwn_Batch* batch) -{ - ctx->orphans_mutex.lock(); - ctx->batches.erase(batch); - ctx->orphans_mutex.unlock(); -} diff --git a/intern/gawain/src/gwn_vertex_buffer.c b/intern/gawain/src/gwn_vertex_buffer.c deleted file mode 100644 index c3440b25da2..00000000000 --- a/intern/gawain/src/gwn_vertex_buffer.c +++ /dev/null @@ -1,268 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Clément Foucault - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_vertex_buffer.c - * \ingroup gpu - * - * Gawain vertex buffer - */ - -#include "gwn_vertex_buffer.h" -#include "gwn_buffer_id.h" -#include "gwn_vertex_format_private.h" -#include -#include - -#define KEEP_SINGLE_COPY 1 - -static uint vbo_memory_usage; - -static GLenum convert_usage_type_to_gl(Gwn_UsageType type) -{ - static const GLenum table[] = { - [GWN_USAGE_STREAM] = GL_STREAM_DRAW, - [GWN_USAGE_STATIC] = GL_STATIC_DRAW, - [GWN_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW - }; - return table[type]; -} - -Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType usage) -{ - Gwn_VertBuf* verts = malloc(sizeof(Gwn_VertBuf)); - GWN_vertbuf_init(verts, usage); - return verts; -} - -Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat* format, Gwn_UsageType usage) -{ - Gwn_VertBuf* verts = GWN_vertbuf_create(usage); - GWN_vertformat_copy(&verts->format, format); - if (!format->packed) { - VertexFormat_pack(&verts->format); - } - return verts; - - /* this function might seem redundant, but there is potential for memory savings here... */ - /* TODO: implement those memory savings */ -} - -void GWN_vertbuf_init(Gwn_VertBuf* verts, Gwn_UsageType usage) -{ - memset(verts, 0, sizeof(Gwn_VertBuf)); - verts->usage = usage; - verts->dirty = true; -} - -void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf* verts, const Gwn_VertFormat* format, Gwn_UsageType usage) -{ - GWN_vertbuf_init(verts, usage); - GWN_vertformat_copy(&verts->format, format); - if (!format->packed) { - VertexFormat_pack(&verts->format); - } -} - -void GWN_vertbuf_discard(Gwn_VertBuf* verts) -{ - if (verts->vbo_id) { - GWN_buf_id_free(verts->vbo_id); -#if VRAM_USAGE - vbo_memory_usage -= GWN_vertbuf_size_get(verts); -#endif - } - if (verts->data) { - free(verts->data); - } - free(verts); -} - -uint GWN_vertbuf_size_get(const Gwn_VertBuf* verts) -{ - return vertex_buffer_size(&verts->format, verts->vertex_len); -} - -/* create a new allocation, discarding any existing data */ -void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) -{ - Gwn_VertFormat* format = &verts->format; - if (!format->packed) { - VertexFormat_pack(format); - } -#if TRUST_NO_ONE - /* catch any unnecessary use */ - assert(verts->vertex_alloc != v_len || verts->data == NULL); -#endif - /* only create the buffer the 1st time */ - if (verts->vbo_id == 0) { - verts->vbo_id = GWN_buf_id_alloc(); - } - /* discard previous data if any */ - if (verts->data) { - free(verts->data); - } -#if VRAM_USAGE - uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); -#endif - verts->dirty = true; - verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = malloc(sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); -} - -/* resize buffer keeping existing data */ -void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, uint v_len) -{ -#if TRUST_NO_ONE - assert(verts->data != NULL); - assert(verts->vertex_alloc != v_len); -#endif - -#if VRAM_USAGE - uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); -#endif - verts->dirty = true; - verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = realloc(verts->data, sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); -} - -/* Set vertex count but does not change allocation. - * Only this many verts will be uploaded to the GPU and rendered. - * This is usefull for streaming data. */ -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, uint v_len) -{ -#if TRUST_NO_ONE - assert(verts->data != NULL); /* only for dynamic data */ - assert(v_len <= verts->vertex_alloc); -#endif - -#if VRAM_USAGE - uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); -#endif - verts->vertex_len = v_len; -} - -void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, uint a_idx, uint v_idx, const void* data) -{ - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; - -#if TRUST_NO_ONE - assert(a_idx < format->attr_len); - assert(v_idx < verts->vertex_alloc); - assert(verts->data != NULL); -#endif - verts->dirty = true; - memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz); -} - -void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, uint a_idx, const void* data) -{ - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; - -#if TRUST_NO_ONE - assert(a_idx < format->attr_len); -#endif - const uint stride = a->sz; /* tightly packed input data */ - - GWN_vertbuf_attr_fill_stride(verts, a_idx, stride, data); -} - -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, uint a_idx, uint stride, const void* data) -{ - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; - -#if TRUST_NO_ONE - assert(a_idx < format->attr_len); - assert(verts->data != NULL); -#endif - verts->dirty = true; - const uint vertex_len = verts->vertex_len; - - if (format->attr_len == 1 && stride == format->stride) { - /* we can copy it all at once */ - memcpy(verts->data, data, vertex_len * a->sz); - } - else { - /* we must copy it per vertex */ - for (uint v = 0; v < vertex_len; ++v) { - memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz); - } - } -} - -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, uint a_idx, Gwn_VertBufRaw *access) -{ - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; - -#if TRUST_NO_ONE - assert(a_idx < format->attr_len); - assert(verts->data != NULL); -#endif - - verts->dirty = true; - - access->size = a->sz; - access->stride = format->stride; - access->data = (GLubyte*)verts->data + a->offset; - access->data_init = access->data; -#if TRUST_NO_ONE - access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride); -#endif -} - -static void VertBuffer_upload_data(Gwn_VertBuf* verts) -{ - uint buffer_sz = GWN_vertbuf_size_get(verts); - - /* orphan the vbo to avoid sync */ - glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); - /* upload data */ - glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); - - if (verts->usage == GWN_USAGE_STATIC) { - free(verts->data); - verts->data = NULL; - } - verts->dirty = false; -} - -void GWN_vertbuf_use(Gwn_VertBuf* verts) -{ - glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); - if (verts->dirty) { - VertBuffer_upload_data(verts); - } -} - -uint GWN_vertbuf_get_memory_usage(void) -{ - return vbo_memory_usage; -} diff --git a/intern/gawain/src/gwn_vertex_format.c b/intern/gawain/src/gwn_vertex_format.c deleted file mode 100644 index 41179ae21eb..00000000000 --- a/intern/gawain/src/gwn_vertex_format.c +++ /dev/null @@ -1,310 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Clément Foucault - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gwn_vertex_format.c - * \ingroup gpu - * - * Gawain vertex format - */ - -#include "gwn_vertex_format.h" -#include "gwn_vertex_format_private.h" -#include -#include - -#define PACK_DEBUG 0 - -#if PACK_DEBUG - #include -#endif - -void GWN_vertformat_clear(Gwn_VertFormat* format) -{ -#if TRUST_NO_ONE - memset(format, 0, sizeof(Gwn_VertFormat)); -#else - format->attr_len = 0; - format->packed = false; - format->name_offset = 0; - format->name_len = 0; - - for (unsigned i = 0; i < GWN_VERT_ATTR_MAX_LEN; i++) { - format->attribs[i].name_len = 0; - } -#endif -} - -void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src) -{ - /* copy regular struct fields */ - memcpy(dest, src, sizeof(Gwn_VertFormat)); - - for (unsigned i = 0; i < dest->attr_len; i++) { - for (unsigned j = 0; j < dest->attribs[i].name_len; j++) { - dest->attribs[i].name[j] = (char *)dest + (src->attribs[i].name[j] - ((char *)src)); - } - } -} - -static GLenum convert_comp_type_to_gl(Gwn_VertCompType type) -{ - static const GLenum table[] = { - [GWN_COMP_I8] = GL_BYTE, - [GWN_COMP_U8] = GL_UNSIGNED_BYTE, - [GWN_COMP_I16] = GL_SHORT, - [GWN_COMP_U16] = GL_UNSIGNED_SHORT, - [GWN_COMP_I32] = GL_INT, - [GWN_COMP_U32] = GL_UNSIGNED_INT, - - [GWN_COMP_F32] = GL_FLOAT, - - [GWN_COMP_I10] = GL_INT_2_10_10_10_REV - }; - return table[type]; -} - -static unsigned comp_sz(Gwn_VertCompType type) -{ -#if TRUST_NO_ONE - assert(type <= GWN_COMP_F32); /* other types have irregular sizes (not bytes) */ -#endif - const GLubyte sizes[] = {1,1,2,2,4,4,4}; - return sizes[type]; -} - -static unsigned attrib_sz(const Gwn_VertAttr *a) -{ - if (a->comp_type == GWN_COMP_I10) { - return 4; /* always packed as 10_10_10_2 */ - } - return a->comp_len * comp_sz(a->comp_type); -} - -static unsigned attrib_align(const Gwn_VertAttr *a) -{ - if (a->comp_type == GWN_COMP_I10) { - return 4; /* always packed as 10_10_10_2 */ - } - unsigned c = comp_sz(a->comp_type); - if (a->comp_len == 3 && c <= 2) { - return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */ - } - else { - return c; /* most fetches are ok if components are naturally aligned */ - } -} - -unsigned vertex_buffer_size(const Gwn_VertFormat* format, unsigned vertex_len) -{ -#if TRUST_NO_ONE - assert(format->packed && format->stride > 0); -#endif - return format->stride * vertex_len; -} - -static const char* copy_attrib_name(Gwn_VertFormat* format, const char* name) -{ - /* strncpy does 110% of what we need; let's do exactly 100% */ - char* name_copy = format->names + format->name_offset; - unsigned available = GWN_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; - bool terminated = false; - - for (unsigned i = 0; i < available; ++i) { - const char c = name[i]; - name_copy[i] = c; - if (c == '\0') { - terminated = true; - format->name_offset += (i + 1); - break; - } - } -#if TRUST_NO_ONE - assert(terminated); - assert(format->name_offset <= GWN_VERT_ATTR_NAMES_BUF_LEN); -#else - (void)terminated; -#endif - return name_copy; -} - -unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_VertCompType comp_type, unsigned comp_len, Gwn_VertFetchMode fetch_mode) -{ -#if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(format->attr_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(!format->packed); /* packed means frozen/locked */ - assert((comp_len >= 1 && comp_len <= 4) || comp_len == 8 || comp_len == 12 || comp_len == 16); - - switch (comp_type) { - case GWN_COMP_F32: - /* float type can only kept as float */ - assert(fetch_mode == GWN_FETCH_FLOAT); - break; - case GWN_COMP_I10: - /* 10_10_10 format intended for normals (xyz) or colors (rgb) - * extra component packed.w can be manually set to { -2, -1, 0, 1 } */ - assert(comp_len == 3 || comp_len == 4); - assert(fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT); /* not strictly required, may relax later */ - break; - default: - /* integer types can be kept as int or converted/normalized to float */ - assert(fetch_mode != GWN_FETCH_FLOAT); - /* only support float matrices (see Batch_update_program_bindings) */ - assert(comp_len != 8 && comp_len != 12 && comp_len != 16); - } -#endif - format->name_len++; /* multiname support */ - - const unsigned attrib_id = format->attr_len++; - Gwn_VertAttr* attrib = format->attribs + attrib_id; - - attrib->name[attrib->name_len++] = copy_attrib_name(format, name); - attrib->comp_type = comp_type; - attrib->gl_comp_type = convert_comp_type_to_gl(comp_type); - attrib->comp_len = (comp_type == GWN_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ - attrib->sz = attrib_sz(attrib); - attrib->offset = 0; /* offsets & stride are calculated later (during pack) */ - attrib->fetch_mode = fetch_mode; - - return attrib_id; -} - -void GWN_vertformat_alias_add(Gwn_VertFormat* format, const char* alias) -{ - Gwn_VertAttr* attrib = format->attribs + (format->attr_len - 1); -#if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(attrib->name_len < GWN_VERT_ATTR_MAX_NAMES); -#endif - format->name_len++; /* multiname support */ - attrib->name[attrib->name_len++] = copy_attrib_name(format, alias); -} - -unsigned padding(unsigned offset, unsigned alignment) -{ - const unsigned mod = offset % alignment; - return (mod == 0) ? 0 : (alignment - mod); -} - -#if PACK_DEBUG -static void show_pack(unsigned a_idx, unsigned sz, unsigned pad) -{ - const char c = 'A' + a_idx; - for (unsigned i = 0; i < pad; ++i) { - putchar('-'); - } - for (unsigned i = 0; i < sz; ++i) { - putchar(c); - } -} -#endif - -void VertexFormat_pack(Gwn_VertFormat* format) -{ - /* For now, attributes are packed in the order they were added, - * making sure each attrib is naturally aligned (add padding where necessary) - * Later we can implement more efficient packing w/ reordering - * (keep attrib ID order, adjust their offsets to reorder in buffer). */ - - /* TODO: realloc just enough to hold the final combo string. And just enough to - * hold used attribs, not all 16. */ - - Gwn_VertAttr* a0 = format->attribs + 0; - a0->offset = 0; - unsigned offset = a0->sz; - -#if PACK_DEBUG - show_pack(0, a0->sz, 0); -#endif - - for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) { - Gwn_VertAttr* a = format->attribs + a_idx; - unsigned mid_padding = padding(offset, attrib_align(a)); - offset += mid_padding; - a->offset = offset; - offset += a->sz; - -#if PACK_DEBUG - show_pack(a_idx, a->sz, mid_padding); -#endif - } - - unsigned end_padding = padding(offset, attrib_align(a0)); - -#if PACK_DEBUG - show_pack(0, 0, end_padding); - putchar('\n'); -#endif - format->stride = offset + end_padding; - format->packed = true; -} - - -/* OpenGL ES packs in a different order as desktop GL but component conversion is the same. - * Of the code here, only struct Gwn_PackedNormal needs to change. */ - -#define SIGNED_INT_10_MAX 511 -#define SIGNED_INT_10_MIN -512 - -static int clampi(int x, int min_allowed, int max_allowed) -{ -#if TRUST_NO_ONE - assert(min_allowed <= max_allowed); -#endif - if (x < min_allowed) { - return min_allowed; - } - else if (x > max_allowed) { - return max_allowed; - } - else { - return x; - } -} - -static int quantize(float x) -{ - int qx = x * 511.0f; - return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX); -} - -static int convert_i16(short x) -{ - /* 16-bit signed --> 10-bit signed */ - /* TODO: round? */ - return x >> 6; -} - -Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]) -{ - Gwn_PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) }; - return n; -} - -Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]) -{ - Gwn_PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) }; - return n; -} diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index 2611477252a..10898e4239b 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -27,8 +27,8 @@ set(INC . ../glew-mx ../guardedalloc - ../gawain ../../source/blender/blenlib + ../../source/blender/gpu ) set(INC_SYS diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 090422ff795..10acdb9d281 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -49,7 +49,7 @@ #endif extern "C" { -#include "gawain/gwn_immediate.h" +#include "GPU_immediate.h" } using namespace OCIO_NAMESPACE; diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 999773d0212..03bf7fa67d8 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -31,7 +31,7 @@ #ifndef __BLF_INTERNAL_TYPES_H__ #define __BLF_INTERNAL_TYPES_H__ -#include "../../../intern/gawain/gawain/gwn_vertex_buffer.h" +#include "GPU_vertex_buffer.h" #include "GPU_texture.h" #define BLF_BATCH_DRAW_LEN_MAX 2048 /* in glyph */ diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index bf3ee34a03e..a6d11f1edac 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -45,7 +45,7 @@ #include "eevee_lightcache.h" #include "eevee_private.h" -#include "../../../intern/gawain/gawain/gwn_context.h" +#include "GPU_context.h" #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 58ce9dd5218..4c6f8962d82 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -82,7 +82,7 @@ #include "engines/workbench/workbench_engine.h" #include "engines/external/external_engine.h" -#include "../../../intern/gawain/gawain/gwn_context.h" +#include "GPU_context.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index d25e372c26e..2d44fb5b6d8 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -35,6 +35,7 @@ #include "BLI_threads.h" #include "GPU_batch.h" +#include "GPU_context.h" #include "GPU_framebuffer.h" #include "GPU_shader.h" #include "GPU_uniformbuffer.h" diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 716e00164ce..3d207b85760 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -50,7 +50,6 @@ set(INC ../../../intern/glew-mx ../../../intern/guardedalloc ../../../intern/smoke/extern - ../../../intern/gawain ) set(INC_SYS @@ -58,14 +57,17 @@ set(INC_SYS ) set(SRC + intern/gpu_attr_binding.c intern/gpu_basic_shader.c intern/gpu_batch.c intern/gpu_batch_presets.c intern/gpu_batch_utils.c + intern/gpu_buffer_id.cpp intern/gpu_buffers.c intern/gpu_codegen.c intern/gpu_debug.c intern/gpu_draw.c + intern/gpu_element.c intern/gpu_extensions.c intern/gpu_framebuffer.c intern/gpu_immediate.c @@ -73,13 +75,18 @@ set(SRC intern/gpu_init_exit.c intern/gpu_material.c intern/gpu_matrix.c + intern/gpu_primitive.c intern/gpu_select.c intern/gpu_select_pick.c intern/gpu_select_sample_query.c intern/gpu_shader.c + intern/gpu_shader_interface.c intern/gpu_state.c intern/gpu_texture.c intern/gpu_uniformbuffer.c + intern/gpu_vertex_array_id.cpp + intern/gpu_vertex_buffer.c + intern/gpu_vertex_format.c intern/gpu_viewport.c shaders/gpu_shader_fx_lib.glsl @@ -103,11 +110,15 @@ set(SRC shaders/gpu_shader_smoke_frag.glsl shaders/gpu_shader_smoke_vert.glsl + GPU_attr_binding.h GPU_basic_shader.h GPU_batch.h + GPU_buffer_id.h GPU_buffers.h + GPU_common.h GPU_debug.h GPU_draw.h + GPU_element.h GPU_extensions.h GPU_framebuffer.h GPU_glew.h @@ -117,17 +128,26 @@ set(SRC GPU_legacy_stubs.h GPU_material.h GPU_matrix.h + GPU_primitive.h GPU_select.h GPU_shader.h + GPU_shader_interface.h GPU_state.h GPU_texture.h GPU_uniformbuffer.h + GPU_vertex_array_id.h + GPU_vertex_buffer.h + GPU_vertex_format.h GPU_viewport.h + intern/gpu_attr_binding_private.h + intern/gpu_batch_private.h intern/gpu_codegen.h + intern/gpu_primitive_private.h intern/gpu_private.h intern/gpu_select_private.h intern/gpu_shader_private.h + intern/gpu_vertex_format_private.h ) data_to_c_simple(shaders/gpu_shader_depth_only_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_attr_binding.h b/source/blender/gpu/GPU_attr_binding.h new file mode 100644 index 00000000000..41050a095cd --- /dev/null +++ b/source/blender/gpu/GPU_attr_binding.h @@ -0,0 +1,42 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_attr_binding.h + * \ingroup gpu + * + * Gawain vertex attribute binding + */ + +#ifndef __GWN_ATTR_BINDING_H__ +#define __GWN_ATTR_BINDING_H__ + +#include "GPU_common.h" + +typedef struct Gwn_AttrBinding { + uint64_t loc_bits; /* store 4 bits for each of the 16 attribs */ + uint16_t enabled_bits; /* 1 bit for each attrib */ +} Gwn_AttrBinding; + +#endif /* __GWN_ATTR_BINDING_H__ */ diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index f73968eda54..4c98eb8f537 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -15,37 +15,185 @@ * 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) 2016 Blender Foundation. + * The Original Code is Copyright (C) 2016 by Mike Erwin. * All rights reserved. * - * - * Contributor(s): Mike Erwin + * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ -/* Batched geometry rendering is powered by the Gawain library. - * This file contains any additions or modifications specific to Blender. +/** \file blender/gpu/gwn_batch.h + * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. */ -#ifndef __GPU_BATCH_H__ -#define __GPU_BATCH_H__ +#ifndef __GWN_BATCH_H__ +#define __GWN_BATCH_H__ -#include "../../../intern/gawain/gawain/gwn_batch.h" -#include "../../../intern/gawain/gawain/gwn_batch_private.h" +#include "GPU_vertex_buffer.h" +#include "GPU_element.h" +#include "GPU_shader_interface.h" +#include "GPU_shader.h" -// TODO: CMake magic to do this: -// #include "gawain/batch.h" +typedef enum { + GWN_BATCH_READY_TO_FORMAT, + GWN_BATCH_READY_TO_BUILD, + GWN_BATCH_BUILDING, + GWN_BATCH_READY_TO_DRAW +} Gwn_BatchPhase; -#include "BLI_compiler_attrs.h" -#include "BLI_sys_types.h" +#define GWN_BATCH_VBO_MAX_LEN 3 +#define GWN_BATCH_VAO_STATIC_LEN 3 +#define GWN_BATCH_VAO_DYN_ALLOC_COUNT 16 -#include "GPU_shader.h" +typedef struct Gwn_Batch { + /* geometry */ + Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ + Gwn_VertBuf* inst; /* instance attribs */ + Gwn_IndexBuf* elem; /* NULL if element list not needed */ + uint32_t gl_prim_type; + + /* cached values (avoid dereferencing later) */ + uint32_t vao_id; + uint32_t program; + const struct Gwn_ShaderInterface* interface; + + /* book-keeping */ + uint owns_flag; + struct Gwn_Context *context; /* used to free all vaos. this implies all vaos were created under the same context. */ + Gwn_BatchPhase phase; + bool program_in_use; + + /* Vao management: remembers all geometry state (vertex attrib bindings & element buffer) + * for each shader interface. Start with a static number of vaos and fallback to dynamic count + * if necessary. Once a batch goes dynamic it does not go back. */ + bool is_dynamic_vao_count; + union { + /* Static handle count */ + struct { + const struct Gwn_ShaderInterface* interfaces[GWN_BATCH_VAO_STATIC_LEN]; + uint32_t vao_ids[GWN_BATCH_VAO_STATIC_LEN]; + } static_vaos; + /* Dynamic handle count */ + struct { + uint count; + const struct Gwn_ShaderInterface** interfaces; + uint32_t* vao_ids; + } dynamic_vaos; + }; + + /* XXX This is the only solution if we want to have some data structure using + * batches as key to identify nodes. We must destroy these nodes with this callback. */ + void (*free_callback)(struct Gwn_Batch*, void*); + void* callback_data; +} Gwn_Batch; + +enum { + GWN_BATCH_OWNS_VBO = (1 << 0), + /* each vbo index gets bit-shifted */ + GWN_BATCH_OWNS_INSTANCES = (1 << 30), + GWN_BATCH_OWNS_INDEX = (1 << 31), +}; + +Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); +void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); +Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src); + +#define GWN_batch_create(prim, verts, elem) \ + GWN_batch_create_ex(prim, verts, elem, 0) +#define GWN_batch_init(batch, prim, verts, elem) \ + GWN_batch_init_ex(batch, prim, verts, elem, 0) + +void GWN_batch_discard(Gwn_Batch*); /* verts & elem are not discarded */ + +void gwn_batch_vao_cache_clear(Gwn_Batch*); + +void GWN_batch_callback_free_set(Gwn_Batch*, void (*callback)(Gwn_Batch*, void*), void*); + +void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); /* Instancing */ + +int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); + +#define GWN_batch_vertbuf_add(batch, verts) \ + GWN_batch_vertbuf_add_ex(batch, verts, false) -/* gpu_batch.c */ -void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id) ATTR_NONNULL(1); +void GWN_batch_program_set_no_use(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); +void GWN_batch_program_set(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); +void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id); +/* Entire batch draws with one shader program, but can be redrawn later with another program. */ +/* Vertex shader's inputs must be compatible with the batch's vertex format. */ + +void GWN_batch_program_use_begin(Gwn_Batch*); /* call before Batch_Uniform (temp hack?) */ +void GWN_batch_program_use_end(Gwn_Batch*); + +void GWN_batch_uniform_1ui(Gwn_Batch*, const char* name, int value); +void GWN_batch_uniform_1i(Gwn_Batch*, const char* name, int value); +void GWN_batch_uniform_1b(Gwn_Batch*, const char* name, bool value); +void GWN_batch_uniform_1f(Gwn_Batch*, const char* name, float value); +void GWN_batch_uniform_2f(Gwn_Batch*, const char* name, float x, float y); +void GWN_batch_uniform_3f(Gwn_Batch*, const char* name, float x, float y, float z); +void GWN_batch_uniform_4f(Gwn_Batch*, const char* name, float x, float y, float z, float w); +void GWN_batch_uniform_2fv(Gwn_Batch*, const char* name, const float data[2]); +void GWN_batch_uniform_3fv(Gwn_Batch*, const char* name, const float data[3]); +void GWN_batch_uniform_4fv(Gwn_Batch*, const char* name, const float data[4]); +void GWN_batch_uniform_2fv_array(Gwn_Batch*, const char* name, int len, const float *data); +void GWN_batch_uniform_4fv_array(Gwn_Batch*, const char* name, int len, const float *data); +void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4]); + +void GWN_batch_draw(Gwn_Batch*); + +/* This does not bind/unbind shader and does not call GPU_matrix_bind() */ +void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance); + +/* Does not even need batch */ +void GWN_draw_primitive(Gwn_PrimType, int v_count); + +#if 0 /* future plans */ + +/* Can multiple batches share a Gwn_VertBuf? Use ref count? */ + + +/* We often need a batch with its own data, to be created and discarded together. */ +/* WithOwn variants reduce number of system allocations. */ + +typedef struct BatchWithOwnVertexBuffer { + Gwn_Batch batch; + Gwn_VertBuf verts; /* link batch.verts to this */ +} BatchWithOwnVertexBuffer; + +typedef struct BatchWithOwnElementList { + Gwn_Batch batch; + Gwn_IndexBuf elem; /* link batch.elem to this */ +} BatchWithOwnElementList; + +typedef struct BatchWithOwnVertexBufferAndElementList { + Gwn_Batch batch; + Gwn_IndexBuf elem; /* link batch.elem to this */ + Gwn_VertBuf verts; /* link batch.verts to this */ +} BatchWithOwnVertexBufferAndElementList; + +Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, uint v_len, Gwn_IndexBuf*); +Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, uint prim_len); +Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, uint v_len, uint prim_len); +/* verts: shared, own */ +/* elem: none, shared, own */ +Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStuff); + +#endif /* future plans */ void gpu_batch_init(void); void gpu_batch_exit(void); -#endif /* __GPU_BATCH_H__ */ +/* Macros */ + +#define GWN_BATCH_DISCARD_SAFE(batch) do { \ + if (batch != NULL) { \ + GWN_batch_discard(batch); \ + batch = NULL; \ + } \ +} while (0) + +#endif /* __GWN_BATCH_H__ */ diff --git a/source/blender/gpu/GPU_buffer_id.h b/source/blender/gpu/GPU_buffer_id.h new file mode 100644 index 00000000000..fd680ff31f5 --- /dev/null +++ b/source/blender/gpu/GPU_buffer_id.h @@ -0,0 +1,53 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_buffer_id.h + * \ingroup gpu + * + * Gawain buffer IDs + */ + +#ifndef __GWN_BUFFER_ID_H__ +#define __GWN_BUFFER_ID_H__ + +/* Manage GL buffer IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from main thread + * - free can be called from any thread */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_common.h" + +GLuint GWN_buf_id_alloc(void); +void GWN_buf_id_free(GLuint buffer_id); + +#ifdef __cplusplus +} +#endif + +#endif /* __GWN_BUFFER_ID_H__ */ diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h new file mode 100644 index 00000000000..2587e8670a9 --- /dev/null +++ b/source/blender/gpu/GPU_common.h @@ -0,0 +1,61 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_common.h + * \ingroup gpu + */ + +#ifndef __GWN_COMMON_H__ +#define __GWN_COMMON_H__ + +#define PROGRAM_NO_OPTI 0 + +#if defined(NDEBUG) + #define TRUST_NO_ONE 0 +#else + /* strict error checking, enabled for debug builds during early development */ + #define TRUST_NO_ONE 1 +#endif + +#if defined(WITH_OPENGL) + #include +#endif + +#include +#include +#include + +#if TRUST_NO_ONE + #include +#endif + +/* GWN_INLINE */ +#if defined(_MSC_VER) +# define GWN_INLINE static __forceinline +#else +# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) +#endif + +#endif /* __GWN_COMMON_H__ */ diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h new file mode 100644 index 00000000000..0cedc109645 --- /dev/null +++ b/source/blender/gpu/GPU_context.h @@ -0,0 +1,55 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_context.h + * \ingroup gpu + * + * This interface allow Gawain to manage VAOs for mutiple context and threads. + */ + +#ifndef __GWN_CONTEXT_H__ +#define __GWN_CONTEXT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_common.h" +#include "GPU_batch.h" +#include "GPU_shader_interface.h" + +typedef struct Gwn_Context Gwn_Context; + +Gwn_Context* GWN_context_create(void); +void GWN_context_discard(Gwn_Context*); + +void GWN_context_active_set(Gwn_Context*); +Gwn_Context* GWN_context_active_get(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __GWN_CONTEXT_H__ */ diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h new file mode 100644 index 00000000000..0c23e90569b --- /dev/null +++ b/source/blender/gpu/GPU_element.h @@ -0,0 +1,102 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_element.h + * \ingroup gpu + * + * Gawain element list (AKA index buffer) + */ + +#ifndef __GWN_ELEMENT_H__ +#define __GWN_ELEMENT_H__ + +#include "GPU_primitive.h" + +#define GWN_TRACK_INDEX_RANGE 1 + +#define GWN_PRIM_RESTART 0xFFFFFFFF + +typedef enum { + GWN_INDEX_U8, /* GL has this, Vulkan does not */ + GWN_INDEX_U16, + GWN_INDEX_U32 +} Gwn_IndexBufType; + +typedef struct Gwn_IndexBuf { + uint index_len; +#if GWN_TRACK_INDEX_RANGE + Gwn_IndexBufType index_type; + uint32_t gl_index_type; + uint min_index; + uint max_index; + uint base_index; +#endif + uint32_t vbo_id; /* 0 indicates not yet sent to VRAM */ + bool use_prim_restart; +} Gwn_IndexBuf; + +void GWN_indexbuf_use(Gwn_IndexBuf*); +uint GWN_indexbuf_size_get(const Gwn_IndexBuf*); + +typedef struct Gwn_IndexBufBuilder { + uint max_allowed_index; + uint max_index_len; + uint index_len; + Gwn_PrimType prim_type; + uint* data; + bool use_prim_restart; +} Gwn_IndexBufBuilder; + + +/* supports all primitive types. */ +void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, uint index_len, uint vertex_len, bool use_prim_restart); + +/* supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS. */ +void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, uint prim_len, uint vertex_len); + +void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, uint v); +void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder*); + +void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, uint v); +void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, uint v1, uint v2); +void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3); +void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); + +Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder*); +void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder*, Gwn_IndexBuf*); + +void GWN_indexbuf_discard(Gwn_IndexBuf*); + + +/* Macros */ + +#define GWN_INDEXBUF_DISCARD_SAFE(elem) do { \ + if (elem != NULL) { \ + GWN_indexbuf_discard(elem); \ + elem = NULL; \ + } \ +} while (0) + +#endif /* __GWN_ELEMENT_H__ */ diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index 2a2692e6baf..c5892886825 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -24,29 +24,113 @@ * ***** END GPL LICENSE BLOCK ***** */ -/* Immediate mode rendering is powered by the Gawain library. - * This file contains any additions or modifications specific to Blender. +/** \file blender/gpu/GPU_immediate.h + * \ingroup gpu + * + * Gawain immediate mode work-alike */ #ifndef __GPU_IMMEDIATE_H__ #define __GPU_IMMEDIATE_H__ -#include "../../../intern/gawain/gawain/gwn_immediate.h" -#include "../../../intern/gawain/gawain/gwn_imm_util.h" +#include "GPU_vertex_format.h" +#include "GPU_primitive.h" +#include "GPU_shader_interface.h" +#include "GPU_batch.h" +#include "GPU_immediate_util.h" +#include "GPU_shader.h" -// TODO: CMake magic to do this: -// #include "gawain/gwn_immediate.h" -// #include "gawain/gwn_imm_util.h" +Gwn_VertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ -#include "GPU_shader.h" +void immBindProgram(uint32_t program, const Gwn_ShaderInterface*); /* every immBegin must have a program bound first. */ +void immUnbindProgram(void); /* call after your last immEnd, or before binding another program. */ + +void immBegin(Gwn_PrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ +void immBeginAtMost(Gwn_PrimType, uint max_vertex_len); /* can supply fewer vertices. */ +void immEnd(void); /* finishes and draws. */ + +/* ImmBegin a batch, then use standard immFunctions as usual. */ +/* ImmEnd will finalize the batch instead of drawing. */ +/* Then you can draw it as many times as you like! Partially replaces the need for display lists. */ +Gwn_Batch* immBeginBatch(Gwn_PrimType, uint vertex_len); +Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, uint vertex_len); + +/* Provide attribute values that can change per vertex. */ +/* First vertex after immBegin must have all its attributes specified. */ +/* Skipped attributes will continue using the previous value for that attrib_id. */ +void immAttrib1f(uint attrib_id, float x); +void immAttrib2f(uint attrib_id, float x, float y); +void immAttrib3f(uint attrib_id, float x, float y, float z); +void immAttrib4f(uint attrib_id, float x, float y, float z, float w); + +void immAttrib2i(uint attrib_id, int x, int y); + +void immAttrib1u(uint attrib_id, uint x); + +void immAttrib2s(uint attrib_id, short x, short y); + +void immAttrib2fv(uint attrib_id, const float data[2]); +void immAttrib3fv(uint attrib_id, const float data[3]); +void immAttrib4fv(uint attrib_id, const float data[4]); + +void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b); +void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +void immAttrib3ubv(uint attrib_id, const unsigned char data[4]); +void immAttrib4ubv(uint attrib_id, const unsigned char data[4]); + +/* Explicitly skip an attribute. */ +/* This advanced option kills automatic value copying for this attrib_id. */ +void immSkipAttrib(uint attrib_id); + +/* Provide one last attribute value & end the current vertex. */ +/* This is most often used for 2D or 3D position (similar to glVertex). */ +void immVertex2f(uint attrib_id, float x, float y); +void immVertex3f(uint attrib_id, float x, float y, float z); +void immVertex4f(uint attrib_id, float x, float y, float z, float w); + +void immVertex2i(uint attrib_id, int x, int y); + +void immVertex2s(uint attrib_id, short x, short y); + +void immVertex2fv(uint attrib_id, const float data[2]); +void immVertex3fv(uint attrib_id, const float data[3]); + +void immVertex2iv(uint attrib_id, const int data[2]); + +/* Provide uniform values that don't change for the entire draw call. */ +void immUniform1i(const char* name, int x); +void immUniform4iv(const char* name, const int data[4]); +void immUniform1f(const char* name, float x); +void immUniform2f(const char* name, float x, float y); +void immUniform2fv(const char* name, const float data[2]); +void immUniform3f(const char* name, float x, float y, float z); +void immUniform3fv(const char* name, const float data[3]); +void immUniformArray3fv(const char* name, const float *data, int count); +void immUniform4f(const char* name, float x, float y, float z, float w); +void immUniform4fv(const char* name, const float data[4]); +void immUniformArray4fv(const char* bare_name, const float *data, int count); +void immUniformMatrix4fv(const char* name, const float data[4][4]); + +/* Convenience functions for setting "uniform vec4 color". */ +/* The rgb functions have implicit alpha = 1.0. */ +void immUniformColor4f(float r, float g, float b, float a); +void immUniformColor4fv(const float rgba[4]); +void immUniformColor3f(float r, float g, float b); +void immUniformColor3fv(const float rgb[3]); +void immUniformColor3fvAlpha(const float rgb[3], float a); + +void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b); +void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); +void immUniformColor3ubv(const unsigned char rgb[3]); +void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a); +void immUniformColor4ubv(const unsigned char rgba[4]); /* Extend immBindProgram to use Blender’s library of built-in shader programs. * Use immUnbindProgram() when done. */ void immBindBuiltinProgram(GPUBuiltinShader shader_id); -/* - * Extend immUniformColor to take Blender's themes - */ +/* Extend immUniformColor to take Blender's themes */ void immUniformThemeColor(int color_id); void immUniformThemeColor3(int color_id); void immUniformThemeColorShade(int color_id, int offset); @@ -55,4 +139,10 @@ void immUniformThemeColorBlendShade(int color_id1, int color_id2, float fac, int void immUniformThemeColorBlend(int color_id1, int color_id2, float fac); void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset); +/* These are called by the system -- not part of drawing API. */ +void immInit(void); +void immActivate(void); +void immDeactivate(void); +void immDestroy(void); + #endif /* __GPU_IMMEDIATE_H__ */ diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h index c31d477ff5b..0a5c9805509 100644 --- a/source/blender/gpu/GPU_immediate_util.h +++ b/source/blender/gpu/GPU_immediate_util.h @@ -27,6 +27,15 @@ #ifndef __GPU_IMMEDIATE_UTIL_H__ #define __GPU_IMMEDIATE_UTIL_H__ +/* Draw 2D rectangles (replaces glRect functions) */ +/* caller is reponsible for vertex format & shader */ +void immRectf(uint pos, float x1, float y1, float x2, float y2); +void immRecti(uint pos, int x1, int y1, int x2, int y2); + +/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS. */ +void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]); +void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]); + void imm_cpack(uint x); void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments); diff --git a/source/blender/gpu/GPU_primitive.h b/source/blender/gpu/GPU_primitive.h new file mode 100644 index 00000000000..44348b9b593 --- /dev/null +++ b/source/blender/gpu/GPU_primitive.h @@ -0,0 +1,65 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_primitive.h + * \ingroup gpu + * + * Gawain geometric primitives + */ + +#ifndef __GWN_PRIMITIVE_H__ +#define __GWN_PRIMITIVE_H__ + +#include "GPU_common.h" + +typedef enum { + GWN_PRIM_POINTS, + GWN_PRIM_LINES, + GWN_PRIM_TRIS, + GWN_PRIM_LINE_STRIP, + GWN_PRIM_LINE_LOOP, /* GL has this, Vulkan does not */ + GWN_PRIM_TRI_STRIP, + GWN_PRIM_TRI_FAN, + + GWN_PRIM_LINES_ADJ, + GWN_PRIM_TRIS_ADJ, + GWN_PRIM_LINE_STRIP_ADJ, + + GWN_PRIM_NONE +} Gwn_PrimType; + +/* what types of primitives does each shader expect? */ +typedef enum { + GWN_PRIM_CLASS_NONE = 0, + GWN_PRIM_CLASS_POINT = (1 << 0), + GWN_PRIM_CLASS_LINE = (1 << 1), + GWN_PRIM_CLASS_SURFACE = (1 << 2), + GWN_PRIM_CLASS_ANY = GWN_PRIM_CLASS_POINT | GWN_PRIM_CLASS_LINE | GWN_PRIM_CLASS_SURFACE +} Gwn_PrimClass; + +Gwn_PrimClass GWN_primtype_class(Gwn_PrimType); +bool GWN_primtype_belongs_to_class(Gwn_PrimType, Gwn_PrimClass); + +#endif /* __GWN_PRIMITIVE_H__ */ diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h new file mode 100644 index 00000000000..36842e9847a --- /dev/null +++ b/source/blender/gpu/GPU_shader_interface.h @@ -0,0 +1,104 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_shader_interface.h + * \ingroup gpu + * + * Gawain shader interface (C --> GLSL) + */ + +#ifndef __GWN_SHADER_INTERFACE_H__ +#define __GWN_SHADER_INTERFACE_H__ + +#include "GPU_common.h" + +typedef enum { + GWN_UNIFORM_NONE = 0, /* uninitialized/unknown */ + + GWN_UNIFORM_MODEL, /* mat4 ModelMatrix */ + GWN_UNIFORM_VIEW, /* mat4 ViewMatrix */ + GWN_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */ + GWN_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */ + GWN_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */ + GWN_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */ + + GWN_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */ + GWN_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */ + GWN_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */ + GWN_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */ + GWN_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */ + + GWN_UNIFORM_NORMAL, /* mat3 NormalMatrix */ + GWN_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */ + GWN_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */ + GWN_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */ + + GWN_UNIFORM_COLOR, /* vec4 color */ + GWN_UNIFORM_EYE, /* vec3 eye */ + GWN_UNIFORM_CALLID, /* int callId */ + + GWN_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */ + + GWN_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ +} Gwn_UniformBuiltin; + +typedef struct Gwn_ShaderInput { + struct Gwn_ShaderInput* next; + uint32_t name_offset; + uint name_hash; + Gwn_UniformBuiltin builtin_type; /* only for uniform inputs */ + uint32_t gl_type; /* only for attrib inputs */ + int32_t size; /* only for attrib inputs */ + int32_t location; +} Gwn_ShaderInput; + +#define GWN_NUM_SHADERINTERFACE_BUCKETS 257 +#define GWN_SHADERINTERFACE_REF_ALLOC_COUNT 16 + +typedef struct Gwn_ShaderInterface { + int32_t program; + uint32_t name_buffer_offset; + Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; + Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; + Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; + Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS]; + char* name_buffer; + struct Gwn_Batch** batches; /* references to batches using this interface */ + uint batches_len; +} Gwn_ShaderInterface; + +Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program_id); +void GWN_shaderinterface_discard(Gwn_ShaderInterface*); + +const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface*, const char* name); +const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface*, Gwn_UniformBuiltin); +const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name); +const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name); + +/* keep track of batches using this interface */ +void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); +void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); + +#endif /* __GWN_SHADER_INTERFACE_H__ */ diff --git a/source/blender/gpu/GPU_vertex_array_id.h b/source/blender/gpu/GPU_vertex_array_id.h new file mode 100644 index 00000000000..925cd74511d --- /dev/null +++ b/source/blender/gpu/GPU_vertex_array_id.h @@ -0,0 +1,55 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_array_id.h + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ + +#ifndef __GWN_VERTEX_ARRAY_ID_H__ +#define __GWN_VERTEX_ARRAY_ID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_common.h" +#include "GPU_context.h" + +GLuint GWN_vao_default(void); +GLuint GWN_vao_alloc(void); +void GWN_vao_free(GLuint vao_id, Gwn_Context*); + +#ifdef __cplusplus +} +#endif + +#endif /* __GWN_VERTEX_ARRAY_ID_H__ */ diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h new file mode 100644 index 00000000000..7e4aa24ff2c --- /dev/null +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -0,0 +1,144 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_buffer.h + * \ingroup gpu + * + * Gawain vertex buffer + */ + +#ifndef __GWN_VERTEX_BUFFER_H__ +#define __GWN_VERTEX_BUFFER_H__ + +#include "GPU_vertex_format.h" + +#define VRAM_USAGE 1 +/* How to create a Gwn_VertBuf: */ +/* 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts) */ +/* 2) GWN_vertformat_attr_add(verts->format, ...) */ +/* 3) GWN_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format */ +/* 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ + +/* Is Gwn_VertBuf always used as part of a Gwn_Batch? */ + +typedef enum { + /* can be extended to support more types */ + GWN_USAGE_STREAM, + GWN_USAGE_STATIC, /* do not keep data in memory */ + GWN_USAGE_DYNAMIC +} Gwn_UsageType; + +typedef struct Gwn_VertBuf { + Gwn_VertFormat format; + uint vertex_len; /* number of verts we want to draw */ + uint vertex_alloc; /* number of verts data */ + bool dirty; + unsigned char* data; /* NULL indicates data in VRAM (unmapped) */ + uint32_t vbo_id; /* 0 indicates not yet allocated */ + Gwn_UsageType usage; /* usage hint for GL optimisation */ +} Gwn_VertBuf; + +Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType); +Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat*, Gwn_UsageType); + +#define GWN_vertbuf_create_with_format(format) \ + GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_STATIC) + +void GWN_vertbuf_discard(Gwn_VertBuf*); + +void GWN_vertbuf_init(Gwn_VertBuf*, Gwn_UsageType); +void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf*, const Gwn_VertFormat*, Gwn_UsageType); + +#define GWN_vertbuf_init_with_format(verts, format) \ + GWN_vertbuf_init_with_format_ex(verts, format, GWN_USAGE_STATIC) + +uint GWN_vertbuf_size_get(const Gwn_VertBuf*); +void GWN_vertbuf_data_alloc(Gwn_VertBuf*, uint v_len); +void GWN_vertbuf_data_resize(Gwn_VertBuf*, uint v_len); +void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, uint v_len); + +/* The most important set_attrib variant is the untyped one. Get it right first. */ +/* It takes a void* so the app developer is responsible for matching their app data types */ +/* to the vertex attribute's type and component count. They're in control of both, so this */ +/* should not be a problem. */ + +void GWN_vertbuf_attr_set(Gwn_VertBuf*, uint a_idx, uint v_idx, const void* data); +void GWN_vertbuf_attr_fill(Gwn_VertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ +void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, uint a_idx, uint stride, const void* data); + +/* For low level access only */ +typedef struct Gwn_VertBufRaw { + uint size; + uint stride; + unsigned char* data; + unsigned char* data_init; +#if TRUST_NO_ONE + /* Only for overflow check */ + unsigned char* _data_end; +#endif +} Gwn_VertBufRaw; + +GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) +{ + unsigned char* data = a->data; + a->data += a->stride; +#if TRUST_NO_ONE + assert(data < a->_data_end); +#endif + return (void *)data; +} + +GWN_INLINE uint GWN_vertbuf_raw_used(Gwn_VertBufRaw *a) +{ + return ((a->data - a->data_init) / a->stride); +} + +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, uint a_idx, Gwn_VertBufRaw *access); + +/* TODO: decide whether to keep the functions below */ +/* doesn't immediate mode satisfy these needs? */ + +/* void setAttrib1f(uint a_idx, uint v_idx, float x); */ +/* void setAttrib2f(uint a_idx, unsigned v_idx, float x, float y); */ +/* void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z); */ +/* void setAttrib4f(unsigned a_idx, unsigned v_idx, float x, float y, float z, float w); */ + +/* void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); */ +/* void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); */ + +void GWN_vertbuf_use(Gwn_VertBuf*); + +/* Metrics */ +uint GWN_vertbuf_get_memory_usage(void); + +/* Macros */ +#define GWN_VERTBUF_DISCARD_SAFE(verts) do { \ + if (verts != NULL) { \ + GWN_vertbuf_discard(verts); \ + verts = NULL; \ + } \ +} while (0) + +#endif /* __GWN_VERTEX_BUFFER_H__ */ diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h new file mode 100644 index 00000000000..91e31b5ece4 --- /dev/null +++ b/source/blender/gpu/GPU_vertex_format.h @@ -0,0 +1,101 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_format.h + * \ingroup gpu + * + * Gawain vertex format + */ + +#ifndef __GWN_VERTEX_FORMAT_H__ +#define __GWN_VERTEX_FORMAT_H__ + +#include "GPU_common.h" + +#define GWN_VERT_ATTR_MAX_LEN 16 +#define GWN_VERT_ATTR_MAX_NAMES 3 +#define GWN_VERT_ATTR_NAME_AVERAGE_LEN 11 +#define GWN_VERT_ATTR_NAMES_BUF_LEN ((GWN_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GWN_VERT_ATTR_MAX_LEN) + +typedef enum { + GWN_COMP_I8, + GWN_COMP_U8, + GWN_COMP_I16, + GWN_COMP_U16, + GWN_COMP_I32, + GWN_COMP_U32, + + GWN_COMP_F32, + + GWN_COMP_I10 +} Gwn_VertCompType; + +typedef enum { + GWN_FETCH_FLOAT, + GWN_FETCH_INT, + GWN_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ + GWN_FETCH_INT_TO_FLOAT /* 127 (any int type) -> 127.0 */ +} Gwn_VertFetchMode; + +typedef struct Gwn_VertAttr { + Gwn_VertFetchMode fetch_mode; + Gwn_VertCompType comp_type; + uint gl_comp_type; + uint comp_len; /* 1 to 4 or 8 or 12 or 16 */ + uint sz; /* size in bytes, 1 to 64 */ + uint offset; /* from beginning of vertex, in bytes */ + uint name_len; /* up to GWN_VERT_ATTR_MAX_NAMES */ + const char* name[GWN_VERT_ATTR_MAX_NAMES]; +} Gwn_VertAttr; + +typedef struct Gwn_VertFormat { + uint attr_len; /* 0 to 16 (GWN_VERT_ATTR_MAX_LEN) */ + uint name_len; /* total count of active vertex attrib */ + uint stride; /* stride in bytes, 1 to 256 */ + uint name_offset; + bool packed; + char names[GWN_VERT_ATTR_NAMES_BUF_LEN]; + Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ +} Gwn_VertFormat; + +void GWN_vertformat_clear(Gwn_VertFormat*); +void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src); + +uint GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, uint comp_len, Gwn_VertFetchMode); +void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias); + +/* format conversion */ + +typedef struct Gwn_PackedNormal { + int x : 10; + int y : 10; + int z : 10; + int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ +} Gwn_PackedNormal; + +Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]); +Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]); + +#endif /* __GWN_VERTEX_FORMAT_H__ */ diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.c new file mode 100644 index 00000000000..e7eba369335 --- /dev/null +++ b/source/blender/gpu/intern/gpu_attr_binding.c @@ -0,0 +1,85 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_attr_binding.c + * \ingroup gpu + * + * Gawain vertex attribute binding + */ + +#include "GPU_attr_binding.h" +#include "gpu_attr_binding_private.h" +#include +#include + +#if GWN_VERT_ATTR_MAX_LEN != 16 + #error "attrib binding code assumes GWN_VERT_ATTR_MAX_LEN = 16" +#endif + +void AttribBinding_clear(Gwn_AttrBinding* binding) +{ + binding->loc_bits = 0; + binding->enabled_bits = 0; +} + +uint read_attrib_location(const Gwn_AttrBinding* binding, uint a_idx) +{ +#if TRUST_NO_ONE + assert(a_idx < GWN_VERT_ATTR_MAX_LEN); + assert(binding->enabled_bits & (1 << a_idx)); +#endif + return (binding->loc_bits >> (4 * a_idx)) & 0xF; +} + +static void write_attrib_location(Gwn_AttrBinding* binding, uint a_idx, uint location) +{ +#if TRUST_NO_ONE + assert(a_idx < GWN_VERT_ATTR_MAX_LEN); + assert(location < GWN_VERT_ATTR_MAX_LEN); +#endif + const uint shift = 4 * a_idx; + const uint64_t mask = ((uint64_t)0xF) << shift; + /* overwrite this attrib's previous location */ + binding->loc_bits = (binding->loc_bits & ~mask) | (location << shift); + /* mark this attrib as enabled */ + binding->enabled_bits |= 1 << a_idx; +} + +void get_attrib_locations(const Gwn_VertFormat* format, Gwn_AttrBinding* binding, const Gwn_ShaderInterface* shaderface) +{ + AttribBinding_clear(binding); + + for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) { + const Gwn_VertAttr* a = format->attribs + a_idx; + for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { + const Gwn_ShaderInput* input = GWN_shaderinterface_attr(shaderface, a->name[n_idx]); +#if TRUST_NO_ONE + assert(input != NULL); + /* TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program */ +#endif + write_attrib_location(binding, a_idx, input->location); + } + } +} diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h new file mode 100644 index 00000000000..0e0bf89178a --- /dev/null +++ b/source/blender/gpu/intern/gpu_attr_binding_private.h @@ -0,0 +1,43 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_attr_binding_private.h + * \ingroup gpu + * + * Gawain vertex attribute binding + */ + +#ifndef __GWN_ATTR_BINDING_PRIVATE_H__ +#define __GWN_ATTR_BINDING_PRIVATE_H__ + +#include "GPU_vertex_format.h" +#include "GPU_shader_interface.h" + +void AttribBinding_clear(Gwn_AttrBinding*); + +void get_attrib_locations(const Gwn_VertFormat*, Gwn_AttrBinding*, const Gwn_ShaderInterface*); +unsigned read_attrib_location(const Gwn_AttrBinding*, unsigned a_idx); + +#endif /* __GWN_ATTR_BINDING_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 5bfd20e3c8b..90f30930884 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -15,32 +15,639 @@ * 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) 2016 Blender Foundation. + * The Original Code is Copyright (C) 2016 by Mike Erwin. * All rights reserved. * - * The Original Code is: all of this file. - * - * Contributor(s): Mike Erwin + * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gpu_batch.c +/** \file blender/gpu/intern/gwn_batch.c * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. */ -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_rect.h" -#include "BLI_math.h" -#include "BLI_polyfill_2d.h" -#include "BLI_sort_utils.h" - -#include "GPU_batch.h" /* own include */ +#include "GPU_batch.h" #include "GPU_batch_presets.h" +#include "GPU_buffer_id.h" +#include "GPU_matrix.h" +#include "GPU_shader.h" +#include "GPU_vertex_array_id.h" + +#include "gpu_batch_private.h" +#include "gpu_primitive_private.h" #include "gpu_shader_private.h" +#include +#include + +static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first); + +void gwn_batch_vao_cache_clear(Gwn_Batch* batch) +{ + if (batch->context == NULL) { + return; + } + if (batch->is_dynamic_vao_count) { + for (int i = 0; i < batch->dynamic_vaos.count; ++i) { + if (batch->dynamic_vaos.vao_ids[i]) { + GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); + } + if (batch->dynamic_vaos.interfaces[i]) { + GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); + } + } + free(batch->dynamic_vaos.interfaces); + free(batch->dynamic_vaos.vao_ids); + } + else { + for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + if (batch->static_vaos.vao_ids[i]) { + GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); + } + if (batch->static_vaos.interfaces[i]) { + GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->static_vaos.interfaces[i], batch); + } + } + } + batch->is_dynamic_vao_count = false; + for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + batch->static_vaos.vao_ids[i] = 0; + batch->static_vaos.interfaces[i] = NULL; + } + gwn_context_remove_batch(batch->context, batch); + batch->context = NULL; +} + +Gwn_Batch* GWN_batch_create_ex( + Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, + uint owns_flag) +{ + Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch)); + GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag); + return batch; +} + +void GWN_batch_init_ex( + Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, + uint owns_flag) +{ +#if TRUST_NO_ONE + assert(verts != NULL); +#endif + + batch->verts[0] = verts; + for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + batch->verts[v] = NULL; + } + batch->inst = NULL; + batch->elem = elem; + batch->gl_prim_type = convert_prim_type_to_gl(prim_type); + batch->phase = GWN_BATCH_READY_TO_DRAW; + batch->is_dynamic_vao_count = false; + batch->owns_flag = owns_flag; + batch->free_callback = NULL; +} + +/* This will share the VBOs with the new batch. */ +Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src) +{ + Gwn_Batch* batch = GWN_batch_create_ex(GWN_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); + + batch->gl_prim_type = batch_src->gl_prim_type; + for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + batch->verts[v] = batch_src->verts[v]; + } + return batch; +} + +void GWN_batch_discard(Gwn_Batch* batch) +{ + if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) { + GWN_indexbuf_discard(batch->elem); + } + if (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES) { + GWN_vertbuf_discard(batch->inst); + } + if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) { + for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + if (batch->verts[v] == NULL) { + break; + } + if (batch->owns_flag & (1 << v)) { + GWN_vertbuf_discard(batch->verts[v]); + } + } + } + gwn_batch_vao_cache_clear(batch); + + if (batch->free_callback) { + batch->free_callback(batch, batch->callback_data); + } + free(batch); +} + +void GWN_batch_callback_free_set(Gwn_Batch* batch, void (*callback)(Gwn_Batch*, void*), void* user_data) +{ + batch->free_callback = callback; + batch->callback_data = user_data; +} + +void GWN_batch_instbuf_set(Gwn_Batch* batch, Gwn_VertBuf* inst, bool own_vbo) +{ +#if TRUST_NO_ONE + assert(inst != NULL); +#endif + /* redo the bindings */ + gwn_batch_vao_cache_clear(batch); + + if (batch->inst != NULL && (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES)) { + GWN_vertbuf_discard(batch->inst); + } + batch->inst = inst; + + if (own_vbo) { + batch->owns_flag |= GWN_BATCH_OWNS_INSTANCES; + } + else { + batch->owns_flag &= ~GWN_BATCH_OWNS_INSTANCES; + } +} + +/* Returns the index of verts in the batch. */ +int GWN_batch_vertbuf_add_ex( + Gwn_Batch* batch, Gwn_VertBuf* verts, + bool own_vbo) +{ + /* redo the bindings */ + gwn_batch_vao_cache_clear(batch); + + for (uint v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + if (batch->verts[v] == NULL) { +#if TRUST_NO_ONE + /* for now all VertexBuffers must have same vertex_len */ + assert(verts->vertex_len == batch->verts[0]->vertex_len); +#endif + batch->verts[v] = verts; + /* TODO: mark dirty so we can keep attrib bindings up-to-date */ + if (own_vbo) + batch->owns_flag |= (1 << v); + return v; + } + } + + /* we only make it this far if there is no room for another Gwn_VertBuf */ +#if TRUST_NO_ONE + assert(false); +#endif + return -1; +} + +static GLuint batch_vao_get(Gwn_Batch *batch) +{ + /* Search through cache */ + if (batch->is_dynamic_vao_count) { + for (int i = 0; i < batch->dynamic_vaos.count; ++i) + if (batch->dynamic_vaos.interfaces[i] == batch->interface) + return batch->dynamic_vaos.vao_ids[i]; + } + else { + for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) + if (batch->static_vaos.interfaces[i] == batch->interface) + return batch->static_vaos.vao_ids[i]; + } + + /* Set context of this batch. + * It will be bound to it until gwn_batch_vao_cache_clear is called. + * Until then it can only be drawn with this context. */ + if (batch->context == NULL) { + batch->context = GWN_context_active_get(); + gwn_context_add_batch(batch->context, batch); + } +#if TRUST_NO_ONE + else { + /* Make sure you are not trying to draw this batch in another context. */ + assert(batch->context == GWN_context_active_get()); + } +#endif + + /* Cache miss, time to add a new entry! */ + GLuint new_vao = 0; + if (!batch->is_dynamic_vao_count) { + int i; /* find first unused slot */ + for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) + if (batch->static_vaos.vao_ids[i] == 0) + break; + + if (i < GWN_BATCH_VAO_STATIC_LEN) { + batch->static_vaos.interfaces[i] = batch->interface; + batch->static_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); + } + else { + /* Not enough place switch to dynamic. */ + batch->is_dynamic_vao_count = true; + /* Erase previous entries, they will be added back if drawn again. */ + for (int j = 0; j < GWN_BATCH_VAO_STATIC_LEN; ++j) { + GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface*)batch->static_vaos.interfaces[j], batch); + GWN_vao_free(batch->static_vaos.vao_ids[j], batch->context); + } + /* Init dynamic arrays and let the branch below set the values. */ + batch->dynamic_vaos.count = GWN_BATCH_VAO_DYN_ALLOC_COUNT; + batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(Gwn_ShaderInterface*)); + batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); + } + } + + if (batch->is_dynamic_vao_count) { + int i; /* find first unused slot */ + for (i = 0; i < batch->dynamic_vaos.count; ++i) + if (batch->dynamic_vaos.vao_ids[i] == 0) + break; + + if (i == batch->dynamic_vaos.count) { + /* Not enough place, realloc the array. */ + i = batch->dynamic_vaos.count; + batch->dynamic_vaos.count += GWN_BATCH_VAO_DYN_ALLOC_COUNT; + batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(Gwn_ShaderInterface*) * batch->dynamic_vaos.count); + batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); + memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(Gwn_ShaderInterface*) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); + memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); + } + batch->dynamic_vaos.interfaces[i] = batch->interface; + batch->dynamic_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); + } + + GWN_shaderinterface_add_batch_ref((Gwn_ShaderInterface*)batch->interface, batch); + +#if TRUST_NO_ONE + assert(new_vao != 0); +#endif + + /* We just got a fresh VAO we need to initialize it. */ + glBindVertexArray(new_vao); + batch_update_program_bindings(batch, 0); + glBindVertexArray(0); + + return new_vao; +} + +void GWN_batch_program_set_no_use(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) +{ +#if TRUST_NO_ONE + assert(glIsProgram(shaderface->program)); + assert(batch->program_in_use == 0); +#endif + batch->interface = shaderface; + batch->program = program; + batch->vao_id = batch_vao_get(batch); +} + +void GWN_batch_program_set(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) +{ + GWN_batch_program_set_no_use(batch, program, shaderface); + GWN_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ +} + +void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* interface) +{ + if (batch->is_dynamic_vao_count) { + for (int i = 0; i < batch->dynamic_vaos.count; ++i) { + if (batch->dynamic_vaos.interfaces[i] == interface) { + GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); + batch->dynamic_vaos.vao_ids[i] = 0; + batch->dynamic_vaos.interfaces[i] = NULL; + break; /* cannot have duplicates */ + } + } + } + else { + int i; + for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + if (batch->static_vaos.interfaces[i] == interface) { + GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); + batch->static_vaos.vao_ids[i] = 0; + batch->static_vaos.interfaces[i] = NULL; + break; /* cannot have duplicates */ + } + } + } +} + +static void create_bindings( + Gwn_VertBuf* verts, const Gwn_ShaderInterface* interface, + uint v_first, const bool use_instancing) +{ + const Gwn_VertFormat* format = &verts->format; + + const uint attr_len = format->attr_len; + const uint stride = format->stride; + + GWN_vertbuf_use(verts); + + for (uint a_idx = 0; a_idx < attr_len; ++a_idx) { + const Gwn_VertAttr* a = format->attribs + a_idx; + const GLvoid* pointer = (const GLubyte*)0 + a->offset + v_first * stride; + + for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { + const Gwn_ShaderInput* input = GWN_shaderinterface_attr(interface, a->name[n_idx]); + + if (input == NULL) continue; + + if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { +#if TRUST_NO_ONE + assert(a->fetch_mode == GWN_FETCH_FLOAT); + assert(a->gl_comp_type == GL_FLOAT); +#endif + for (int i = 0; i < a->comp_len / 4; ++i) { + glEnableVertexAttribArray(input->location + i); + glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0); + glVertexAttribPointer(input->location + i, 4, a->gl_comp_type, GL_FALSE, stride, + (const GLubyte*)pointer + i * 16); + } + } + else + { + glEnableVertexAttribArray(input->location); + glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0); + + switch (a->fetch_mode) { + case GWN_FETCH_FLOAT: + case GWN_FETCH_INT_TO_FLOAT: + glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); + break; + case GWN_FETCH_INT_TO_FLOAT_UNIT: + glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); + break; + case GWN_FETCH_INT: + glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer); + break; + } + } + } + } +} + +static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first) +{ + for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { + create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false); + } + if (batch->inst) { + create_bindings(batch->inst, batch->interface, v_first, true); + } + if (batch->elem) { + GWN_indexbuf_use(batch->elem); + } +} + +void GWN_batch_program_use_begin(Gwn_Batch* batch) +{ + /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with + * the GL context's active program. use_program doesn't mark other programs as "not used". */ + /* TODO: make not fragile (somehow) */ + + if (!batch->program_in_use) { + glUseProgram(batch->program); + batch->program_in_use = true; + } +} + +void GWN_batch_program_use_end(Gwn_Batch* batch) +{ + if (batch->program_in_use) { +#if PROGRAM_NO_OPTI + glUseProgram(0); +#endif + batch->program_in_use = false; + } +} + +#if TRUST_NO_ONE + #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); assert(uniform); +#else + #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); +#endif + +void GWN_batch_uniform_1ui(Gwn_Batch* batch, const char* name, int value) +{ + GET_UNIFORM + glUniform1ui(uniform->location, value); +} + +void GWN_batch_uniform_1i(Gwn_Batch* batch, const char* name, int value) +{ + GET_UNIFORM + glUniform1i(uniform->location, value); +} + +void GWN_batch_uniform_1b(Gwn_Batch* batch, const char* name, bool value) +{ + GET_UNIFORM + glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE); +} + +void GWN_batch_uniform_2f(Gwn_Batch* batch, const char* name, float x, float y) +{ + GET_UNIFORM + glUniform2f(uniform->location, x, y); +} + +void GWN_batch_uniform_3f(Gwn_Batch* batch, const char* name, float x, float y, float z) +{ + GET_UNIFORM + glUniform3f(uniform->location, x, y, z); +} + +void GWN_batch_uniform_4f(Gwn_Batch* batch, const char* name, float x, float y, float z, float w) +{ + GET_UNIFORM + glUniform4f(uniform->location, x, y, z, w); +} + +void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x) +{ + GET_UNIFORM + glUniform1f(uniform->location, x); +} + +void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2]) +{ + GET_UNIFORM + glUniform2fv(uniform->location, 1, data); +} + +void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3]) +{ + GET_UNIFORM + glUniform3fv(uniform->location, 1, data); +} + +void GWN_batch_uniform_4fv(Gwn_Batch* batch, const char* name, const float data[4]) +{ + GET_UNIFORM + glUniform4fv(uniform->location, 1, data); +} + +void GWN_batch_uniform_2fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) +{ + GET_UNIFORM + glUniform2fv(uniform->location, len, data); +} + +void GWN_batch_uniform_4fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) +{ + GET_UNIFORM + glUniform4fv(uniform->location, len, data); +} + +void GWN_batch_uniform_mat4(Gwn_Batch* batch, const char* name, const float data[4][4]) +{ + GET_UNIFORM + glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); +} + +static void primitive_restart_enable(const Gwn_IndexBuf *el) +{ + // TODO(fclem) Replace by GL_PRIMITIVE_RESTART_FIXED_INDEX when we have ogl 4.3 + glEnable(GL_PRIMITIVE_RESTART); + GLuint restart_index = (GLuint)0xFFFFFFFF; + +#if GWN_TRACK_INDEX_RANGE + if (el->index_type == GWN_INDEX_U8) + restart_index = (GLuint)0xFF; + else if (el->index_type == GWN_INDEX_U16) + restart_index = (GLuint)0xFFFF; +#endif + + glPrimitiveRestartIndex(restart_index); +} + +static void primitive_restart_disable(void) +{ + glDisable(GL_PRIMITIVE_RESTART); +} + +void GWN_batch_draw(Gwn_Batch* batch) +{ +#if TRUST_NO_ONE + assert(batch->phase == GWN_BATCH_READY_TO_DRAW); + assert(batch->verts[0]->vbo_id != 0); +#endif + GWN_batch_program_use_begin(batch); + GPU_matrix_bind(batch->interface); // external call. + + GWN_batch_draw_range_ex(batch, 0, 0, false); + + GWN_batch_program_use_end(batch); +} + +void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool force_instance) +{ +#if TRUST_NO_ONE + assert(!(force_instance && (batch->inst == NULL)) || v_count > 0); // we cannot infer length if force_instance +#endif + const bool do_instance = (force_instance || batch->inst); + + // If using offset drawing, use the default VAO and redo bindings. + if (v_first != 0 && (do_instance || batch->elem)) { + glBindVertexArray(GWN_vao_default()); + batch_update_program_bindings(batch, v_first); + } + else { + glBindVertexArray(batch->vao_id); + } + + if (do_instance) { + /* Infer length if vertex count is not given */ + if (v_count == 0) { + v_count = batch->inst->vertex_len; + } + + if (batch->elem) { + const Gwn_IndexBuf* el = batch->elem; + + if (el->use_prim_restart) { + primitive_restart_enable(el); + } +#if GWN_TRACK_INDEX_RANGE + glDrawElementsInstancedBaseVertex(batch->gl_prim_type, + el->index_len, + el->gl_index_type, + 0, + v_count, + el->base_index); +#else + glDrawElementsInstanced(batch->gl_prim_type, el->index_len, GL_UNSIGNED_INT, 0, v_count); +#endif + if (el->use_prim_restart) { + primitive_restart_disable(); + } + } + else { + glDrawArraysInstanced(batch->gl_prim_type, 0, batch->verts[0]->vertex_len, v_count); + } + } + else { + /* Infer length if vertex count is not given */ + if (v_count == 0) { + v_count = (batch->elem) ? batch->elem->index_len : batch->verts[0]->vertex_len; + } + + if (batch->elem) { + const Gwn_IndexBuf* el = batch->elem; + + if (el->use_prim_restart) { + primitive_restart_enable(el); + } + +#if GWN_TRACK_INDEX_RANGE + if (el->base_index) { + glDrawRangeElementsBaseVertex(batch->gl_prim_type, + el->min_index, + el->max_index, + v_count, + el->gl_index_type, + 0, + el->base_index); + } + else { + glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, v_count, el->gl_index_type, 0); + } +#else + glDrawElements(batch->gl_prim_type, v_count, GL_UNSIGNED_INT, 0); +#endif + if (el->use_prim_restart) { + primitive_restart_disable(); + } + } + else { + glDrawArrays(batch->gl_prim_type, v_first, v_count); + } + } + + /* Performance hog if you are drawing with the same vao multiple time. + * Only activate for debugging. */ + // glBindVertexArray(0); +} + +/* just draw some vertices and let shader place them where we want. */ +void GWN_draw_primitive(Gwn_PrimType prim_type, int v_count) + { + /* we cannot draw without vao ... annoying ... */ + glBindVertexArray(GWN_vao_default()); + + GLenum type = convert_prim_type_to_gl(prim_type); + glDrawArrays(type, 0, v_count); + + /* Performance hog if you are drawing with the same vao multiple time. + * Only activate for debugging.*/ + // glBindVertexArray(0); + } + + /* -------------------------------------------------------------------- */ /** \name Utilities * \{ */ @@ -67,4 +674,4 @@ void gpu_batch_exit(void) gpu_batch_presets_exit(); } -/** \} */ +/** \} */ \ No newline at end of file diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h new file mode 100644 index 00000000000..1e72bae503f --- /dev/null +++ b/source/blender/gpu/intern/gpu_batch_private.h @@ -0,0 +1,53 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_batch_private.h + * \ingroup gpu + * + * Gawain geometry batch + * Contains VAOs + VBOs + Shader representing a drawable entity. + */ + +#ifndef __GWN_BATCH_PRIVATE_H__ +#define __GWN_BATCH_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_batch.h" +#include "GPU_context.h" +#include "GPU_shader_interface.h" + +void gwn_batch_remove_interface_ref(Gwn_Batch*, const Gwn_ShaderInterface*); + +void gwn_context_add_batch(Gwn_Context*, Gwn_Batch*); +void gwn_context_remove_batch(Gwn_Context*, Gwn_Batch*); + +#ifdef __cplusplus +} +#endif + +#endif /* __GWN_BATCH_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_buffer_id.cpp b/source/blender/gpu/intern/gpu_buffer_id.cpp new file mode 100644 index 00000000000..0c442f687a0 --- /dev/null +++ b/source/blender/gpu/intern/gpu_buffer_id.cpp @@ -0,0 +1,90 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_buffer_id.cpp + * \ingroup gpu + * + * Gawain buffer IDs + */ + +#include "GPU_buffer_id.h" + +#include +#include + +#define ORPHAN_DEBUG 0 + +#if ORPHAN_DEBUG + #include +#endif + +static std::vector orphaned_buffer_ids; + +static std::mutex orphan_mutex; + +extern "C" { +extern int BLI_thread_is_main(void); /* Blender-specific function */ +} + +static bool thread_is_main() +{ + /* "main" here means the GL context's thread */ + return BLI_thread_is_main(); +} + +GLuint GWN_buf_id_alloc() +{ + /* delete orphaned IDs */ + orphan_mutex.lock(); + if (!orphaned_buffer_ids.empty()) { + const auto orphaned_buffer_len = (uint)orphaned_buffer_ids.size(); +#if ORPHAN_DEBUG + printf("deleting %u orphaned VBO%s\n", orphaned_buffer_len, orphaned_buffer_len == 1 ? "" : "s"); +#endif + glDeleteBuffers(orphaned_buffer_len, orphaned_buffer_ids.data()); + orphaned_buffer_ids.clear(); + } + orphan_mutex.unlock(); + + GLuint new_buffer_id = 0; + glGenBuffers(1, &new_buffer_id); + return new_buffer_id; +} + +void GWN_buf_id_free(GLuint buffer_id) +{ + if (thread_is_main()) { + glDeleteBuffers(1, &buffer_id); + } + else { + /* add this ID to the orphaned list */ + orphan_mutex.lock(); +#if ORPHAN_DEBUG + printf("orphaning VBO %u\n", buffer_id); +#endif + orphaned_buffer_ids.emplace_back(buffer_id); + orphan_mutex.unlock(); + } +} diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c new file mode 100644 index 00000000000..596530a6ff4 --- /dev/null +++ b/source/blender/gpu/intern/gpu_element.c @@ -0,0 +1,308 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_element.c + * \ingroup gpu + * + * Gawain element list (AKA index buffer) + */ + +#include "GPU_element.h" +#include "GPU_buffer_id.h" + +#include + +#define KEEP_SINGLE_COPY 1 + +static GLenum convert_index_type_to_gl(Gwn_IndexBufType type) +{ + static const GLenum table[] = { + [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ + [GWN_INDEX_U16] = GL_UNSIGNED_SHORT, + [GWN_INDEX_U32] = GL_UNSIGNED_INT + }; + return table[type]; +} + +uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) +{ +#if GWN_TRACK_INDEX_RANGE + static const uint table[] = { + [GWN_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ + [GWN_INDEX_U16] = sizeof(GLushort), + [GWN_INDEX_U32] = sizeof(GLuint) + }; + return elem->index_len * table[elem->index_type]; +#else + return elem->index_len * sizeof(GLuint); +#endif +} + +void GWN_indexbuf_init_ex( + Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, + uint index_len, uint vertex_len, bool use_prim_restart) +{ + builder->use_prim_restart = use_prim_restart; + builder->max_allowed_index = vertex_len - 1; + builder->max_index_len = index_len; + builder->index_len = 0; // start empty + builder->prim_type = prim_type; + builder->data = calloc(builder->max_index_len, sizeof(uint)); +} + +void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uint prim_len, uint vertex_len) +{ + uint verts_per_prim = 0; + switch (prim_type) { + case GWN_PRIM_POINTS: + verts_per_prim = 1; + break; + case GWN_PRIM_LINES: + verts_per_prim = 2; + break; + case GWN_PRIM_TRIS: + verts_per_prim = 3; + break; + case GWN_PRIM_LINES_ADJ: + verts_per_prim = 4; + break; + default: +#if TRUST_NO_ONE + assert(false); +#endif + return; + } + + GWN_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); +} + +void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v) +{ +#if TRUST_NO_ONE + assert(builder->data != NULL); + assert(builder->index_len < builder->max_index_len); + assert(v <= builder->max_allowed_index); +#endif + builder->data[builder->index_len++] = v; +} + +void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder* builder) +{ +#if TRUST_NO_ONE + assert(builder->data != NULL); + assert(builder->index_len < builder->max_index_len); + assert(builder->use_prim_restart); +#endif + builder->data[builder->index_len++] = GWN_PRIM_RESTART; +} + +void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, uint v) +{ +#if TRUST_NO_ONE + assert(builder->prim_type == GWN_PRIM_POINTS); +#endif + GWN_indexbuf_add_generic_vert(builder, v); +} + +void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2) +{ +#if TRUST_NO_ONE + assert(builder->prim_type == GWN_PRIM_LINES); + assert(v1 != v2); +#endif + GWN_indexbuf_add_generic_vert(builder, v1); + GWN_indexbuf_add_generic_vert(builder, v2); +} + +void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3) +{ +#if TRUST_NO_ONE + assert(builder->prim_type == GWN_PRIM_TRIS); + assert(v1 != v2 && v2 != v3 && v3 != v1); +#endif + GWN_indexbuf_add_generic_vert(builder, v1); + GWN_indexbuf_add_generic_vert(builder, v2); + GWN_indexbuf_add_generic_vert(builder, v3); +} + +void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) +{ +#if TRUST_NO_ONE + assert(builder->prim_type == GWN_PRIM_LINES_ADJ); + assert(v2 != v3); /* only the line need diff indices */ +#endif + GWN_indexbuf_add_generic_vert(builder, v1); + GWN_indexbuf_add_generic_vert(builder, v2); + GWN_indexbuf_add_generic_vert(builder, v3); + GWN_indexbuf_add_generic_vert(builder, v4); +} + +#if GWN_TRACK_INDEX_RANGE +/* Everything remains 32 bit while building to keep things simple. + * Find min/max after, then convert to smallest index type possible. */ + +static uint index_range(const uint values[], uint value_len, uint* min_out, uint* max_out) +{ + if (value_len == 0) { + *min_out = 0; + *max_out = 0; + return 0; + } + uint min_value = values[0]; + uint max_value = values[0]; + for (uint i = 1; i < value_len; ++i) { + const uint value = values[i]; + if (value == GWN_PRIM_RESTART) + continue; + else if (value < min_value) + min_value = value; + else if (value > max_value) + max_value = value; + } + *min_out = min_value; + *max_out = max_value; + return max_value - min_value; +} + +static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) +{ + const uint *values = builder->data; + const uint index_len = elem->index_len; + + /* data will never be *larger* than builder->data... + * converting in place to avoid extra allocation */ + GLubyte *data = (GLubyte *)builder->data; + + if (elem->max_index > 0xFF) { + const uint base = elem->min_index; + elem->base_index = base; + elem->min_index = 0; + elem->max_index -= base; + for (uint i = 0; i < index_len; ++i) { + data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); + } + } + else { + elem->base_index = 0; + for (uint i = 0; i < index_len; ++i) { + data[i] = (GLubyte)(values[i]); + } + } +} + +static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) +{ + const uint *values = builder->data; + const uint index_len = elem->index_len; + + /* data will never be *larger* than builder->data... + * converting in place to avoid extra allocation */ + GLushort *data = (GLushort *)builder->data; + + if (elem->max_index > 0xFFFF) { + const uint base = elem->min_index; + elem->base_index = base; + elem->min_index = 0; + elem->max_index -= base; + for (uint i = 0; i < index_len; ++i) { + data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); + } + } + else { + elem->base_index = 0; + for (uint i = 0; i < index_len; ++i) { + data[i] = (GLushort)(values[i]); + } + } +} + +#endif /* GWN_TRACK_INDEX_RANGE */ + +Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder* builder) +{ + Gwn_IndexBuf* elem = calloc(1, sizeof(Gwn_IndexBuf)); + GWN_indexbuf_build_in_place(builder, elem); + return elem; +} + +void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* elem) +{ +#if TRUST_NO_ONE + assert(builder->data != NULL); +#endif + elem->index_len = builder->index_len; + elem->use_prim_restart = builder->use_prim_restart; + +#if GWN_TRACK_INDEX_RANGE + uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); + + /* count the primitive restart index. */ + if (elem->use_prim_restart) { + range += 1; + } + + if (range <= 0xFF) { + elem->index_type = GWN_INDEX_U8; + squeeze_indices_byte(builder, elem); + } + else if (range <= 0xFFFF) { + elem->index_type = GWN_INDEX_U16; + squeeze_indices_short(builder, elem); + } + else { + elem->index_type = GWN_INDEX_U32; + elem->base_index = 0; + } + elem->gl_index_type = convert_index_type_to_gl(elem->index_type); +#endif + + if (elem->vbo_id == 0) { + elem->vbo_id = GWN_buf_id_alloc(); + } + /* send data to GPU */ + /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, + * so we use the GL_ARRAY_BUFFER here to create a buffer without + * interfering in the VAO state. */ + glBindBuffer(GL_ARRAY_BUFFER, elem->vbo_id); + glBufferData(GL_ARRAY_BUFFER, GWN_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); + + /* discard builder (one-time use) */ + free(builder->data); + builder->data = NULL; + /* other fields are safe to leave */ +} + +void GWN_indexbuf_use(Gwn_IndexBuf* elem) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id); +} + +void GWN_indexbuf_discard(Gwn_IndexBuf* elem) +{ + if (elem->vbo_id) { + GWN_buf_id_free(elem->vbo_id); + } + free(elem); +} diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 5f22b7f9279..661594faf39 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -15,22 +15,145 @@ * 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) 2016 Blender Foundation. + * The Original Code is Copyright (C) 2016 by Mike Erwin. * All rights reserved. * - * The Original Code is: all of this file. - * - * Contributor(s): Mike Erwin + * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ -#include "GPU_immediate.h" -#include "GPU_matrix.h" +/** \file blender/gpu/intern/gwn_immediate.c + * \ingroup gpu + * + * Gawain immediate mode work-alike + */ + #include "UI_resources.h" -#include "BLI_utildefines.h" +#include "GPU_attr_binding.h" +#include "GPU_buffer_id.h" +#include "GPU_immediate.h" +#include "GPU_vertex_array_id.h" + +#include "gpu_attr_binding_private.h" +#include "gpu_primitive_private.h" #include "gpu_shader_private.h" +#include "gpu_vertex_format_private.h" + +#include +#include + +/* necessary functions from matrix API */ +extern void GPU_matrix_bind(const Gwn_ShaderInterface*); +extern bool GPU_matrix_dirty_get(void); + +typedef struct { + /* TODO: organize this struct by frequency of change (run-time) */ + + Gwn_Batch* batch; + Gwn_Context* context; + + /* current draw call */ + GLubyte* buffer_data; + uint buffer_offset; + uint buffer_bytes_mapped; + uint vertex_len; + bool strict_vertex_len; + Gwn_PrimType prim_type; + + Gwn_VertFormat vertex_format; + + /* current vertex */ + uint vertex_idx; + GLubyte* vertex_data; + uint16_t unassigned_attrib_bits; /* which attributes of current vertex have not been given values? */ + + GLuint vbo_id; + GLuint vao_id; + + GLuint bound_program; + const Gwn_ShaderInterface* shader_interface; + Gwn_AttrBinding attrib_binding; + uint16_t prev_enabled_attrib_bits; /* <-- only affects this VAO, so we're ok */ +} Immediate; + +/* size of internal buffer -- make this adjustable? */ +#define IMM_BUFFER_SIZE (4 * 1024 * 1024) + +static bool initialized = false; +static Immediate imm; + +void immInit(void) +{ +#if TRUST_NO_ONE + assert(!initialized); +#endif + memset(&imm, 0, sizeof(Immediate)); + + imm.vbo_id = GWN_buf_id_alloc(); + glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); + glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); + + imm.prim_type = GWN_PRIM_NONE; + imm.strict_vertex_len = true; + + glBindBuffer(GL_ARRAY_BUFFER, 0); + initialized = true; +} + +void immActivate(void) +{ +#if TRUST_NO_ONE + assert(initialized); + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ + assert(imm.vao_id == 0); +#endif + imm.vao_id = GWN_vao_alloc(); + imm.context = GWN_context_active_get(); +} + +void immDeactivate(void) +{ +#if TRUST_NO_ONE + assert(initialized); + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ + assert(imm.vao_id != 0); +#endif + GWN_vao_free(imm.vao_id, imm.context); + imm.vao_id = 0; + imm.prev_enabled_attrib_bits = 0; +} + +void immDestroy(void) +{ + GWN_buf_id_free(imm.vbo_id); + initialized = false; +} + +Gwn_VertFormat* immVertexFormat(void) +{ + GWN_vertformat_clear(&imm.vertex_format); + return &imm.vertex_format; +} + +void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) +{ +#if TRUST_NO_ONE + assert(imm.bound_program == 0); + assert(glIsProgram(program)); +#endif + + imm.bound_program = program; + imm.shader_interface = shaderface; + + if (!imm.vertex_format.packed) + VertexFormat_pack(&imm.vertex_format); + + glUseProgram(program); + get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface); + GPU_matrix_bind(shaderface); +} void immBindBuiltinProgram(GPUBuiltinShader shader_id) { @@ -38,6 +161,718 @@ void immBindBuiltinProgram(GPUBuiltinShader shader_id) immBindProgram(shader->program, shader->interface); } +void immUnbindProgram(void) +{ +#if TRUST_NO_ONE + assert(imm.bound_program != 0); +#endif +#if PROGRAM_NO_OPTI + glUseProgram(0); +#endif + imm.bound_program = 0; +} + +#if TRUST_NO_ONE +static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType prim_type) +{ + /* does vertex_len make sense for this primitive type? */ + if (vertex_len == 0) { + return false; + } + + switch (prim_type) { + case GWN_PRIM_POINTS: + return true; + case GWN_PRIM_LINES: + return vertex_len % 2 == 0; + case GWN_PRIM_LINE_STRIP: + case GWN_PRIM_LINE_LOOP: + return vertex_len >= 2; + case GWN_PRIM_LINE_STRIP_ADJ: + return vertex_len >= 4; + case GWN_PRIM_TRIS: + return vertex_len % 3 == 0; + case GWN_PRIM_TRI_STRIP: + case GWN_PRIM_TRI_FAN: + return vertex_len >= 3; + default: + return false; + } +} +#endif + +void immBegin(Gwn_PrimType prim_type, uint vertex_len) +{ +#if TRUST_NO_ONE + assert(initialized); + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ + assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); +#endif + imm.prim_type = prim_type; + imm.vertex_len = vertex_len; + imm.vertex_idx = 0; + imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; + + /* how many bytes do we need for this draw call? */ + const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); + +#if TRUST_NO_ONE + assert(bytes_needed <= IMM_BUFFER_SIZE); +#endif + + glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); + + /* does the current buffer have enough room? */ + const uint available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; + /* ensure vertex data is aligned */ + const uint pre_padding = padding(imm.buffer_offset, imm.vertex_format.stride); /* might waste a little space, but it's safe */ + if ((bytes_needed + pre_padding) <= available_bytes) { + imm.buffer_offset += pre_padding; + } + else { + /* orphan this buffer & start with a fresh one */ + /* this method works on all platforms, old & new */ + glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); + + imm.buffer_offset = 0; + } + +/* printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */ + + imm.buffer_data = glMapBufferRange(GL_ARRAY_BUFFER, imm.buffer_offset, bytes_needed, + GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)); + +#if TRUST_NO_ONE + assert(imm.buffer_data != NULL); +#endif + + imm.buffer_bytes_mapped = bytes_needed; + imm.vertex_data = imm.buffer_data; +} + +void immBeginAtMost(Gwn_PrimType prim_type, uint vertex_len) +{ +#if TRUST_NO_ONE + assert(vertex_len > 0); +#endif + + imm.strict_vertex_len = false; + immBegin(prim_type, vertex_len); +} + + +Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, uint vertex_len) +{ +#if TRUST_NO_ONE + assert(initialized); + assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ + assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); +#endif + imm.prim_type = prim_type; + imm.vertex_len = vertex_len; + imm.vertex_idx = 0; + imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; + + Gwn_VertBuf* verts = GWN_vertbuf_create_with_format(&imm.vertex_format); + GWN_vertbuf_data_alloc(verts, vertex_len); + + imm.buffer_bytes_mapped = GWN_vertbuf_size_get(verts); + imm.vertex_data = verts->data; + + imm.batch = GWN_batch_create_ex(prim_type, verts, NULL, GWN_BATCH_OWNS_VBO); + imm.batch->phase = GWN_BATCH_BUILDING; + + return imm.batch; +} + +Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType prim_type, uint vertex_len) +{ + imm.strict_vertex_len = false; + return immBeginBatch(prim_type, vertex_len); +} + +static void immDrawSetup(void) +{ + /* set up VAO -- can be done during Begin or End really */ + glBindVertexArray(imm.vao_id); + + /* enable/disable vertex attribs as needed */ + if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits) { + for (uint loc = 0; loc < GWN_VERT_ATTR_MAX_LEN; ++loc) { + bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc); + bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc); + + if (is_enabled && !was_enabled) { + glEnableVertexAttribArray(loc); + } + else if (was_enabled && !is_enabled) { + glDisableVertexAttribArray(loc); + } + } + + imm.prev_enabled_attrib_bits = imm.attrib_binding.enabled_bits; + } + + const uint stride = imm.vertex_format.stride; + + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { + const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; + + const uint offset = imm.buffer_offset + a->offset; + const GLvoid* pointer = (const GLubyte*)0 + offset; + + const uint loc = read_attrib_location(&imm.attrib_binding, a_idx); + + switch (a->fetch_mode) { + case GWN_FETCH_FLOAT: + case GWN_FETCH_INT_TO_FLOAT: + glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); + break; + case GWN_FETCH_INT_TO_FLOAT_UNIT: + glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); + break; + case GWN_FETCH_INT: + glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); + } + } + + if (GPU_matrix_dirty_get()) { + GPU_matrix_bind(imm.shader_interface); + } +} + +void immEnd(void) +{ +#if TRUST_NO_ONE + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + + uint buffer_bytes_used; + if (imm.strict_vertex_len) { +#if TRUST_NO_ONE + assert(imm.vertex_idx == imm.vertex_len); /* with all vertices defined */ +#endif + buffer_bytes_used = imm.buffer_bytes_mapped; + } + else { +#if TRUST_NO_ONE + assert(imm.vertex_idx <= imm.vertex_len); +#endif + if (imm.vertex_idx == imm.vertex_len) { + buffer_bytes_used = imm.buffer_bytes_mapped; + } + else { +#if TRUST_NO_ONE + assert(imm.vertex_idx == 0 || vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.prim_type)); +#endif + imm.vertex_len = imm.vertex_idx; + buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_len); + /* unused buffer bytes are available to the next immBegin */ + } + /* tell OpenGL what range was modified so it doesn't copy the whole mapped range */ + glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, buffer_bytes_used); + } + + if (imm.batch) { + if (buffer_bytes_used != imm.buffer_bytes_mapped) { + GWN_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); + /* TODO: resize only if vertex count is much smaller */ + } + GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); + imm.batch->phase = GWN_BATCH_READY_TO_DRAW; + imm.batch = NULL; /* don't free, batch belongs to caller */ + } + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + if (imm.vertex_len > 0) { + immDrawSetup(); + glDrawArrays(convert_prim_type_to_gl(imm.prim_type), 0, imm.vertex_len); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + /* prep for next immBegin */ + imm.buffer_offset += buffer_bytes_used; + } + + /* prep for next immBegin */ + imm.prim_type = GWN_PRIM_NONE; + imm.strict_vertex_len = true; +} + +static void setAttribValueBit(uint attrib_id) +{ + uint16_t mask = 1 << attrib_id; +#if TRUST_NO_ONE + assert(imm.unassigned_attrib_bits & mask); /* not already set */ +#endif + imm.unassigned_attrib_bits &= ~mask; +} + + +/* --- generic attribute functions --- */ + +void immAttrib1f(uint attrib_id, float x) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_len == 1); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + float* data = (float*)(imm.vertex_data + attrib->offset); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ + + data[0] = x; +} + +void immAttrib2f(uint attrib_id, float x, float y) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_len == 2); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + float* data = (float*)(imm.vertex_data + attrib->offset); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ + + data[0] = x; + data[1] = y; +} + +void immAttrib3f(uint attrib_id, float x, float y, float z) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_len == 3); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + float* data = (float*)(imm.vertex_data + attrib->offset); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ + + data[0] = x; + data[1] = y; + data[2] = z; +} + +void immAttrib4f(uint attrib_id, float x, float y, float z, float w) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_len == 4); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + float* data = (float*)(imm.vertex_data + attrib->offset); +/* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ + + data[0] = x; + data[1] = y; + data[2] = z; + data[3] = w; +} + +void immAttrib1u(uint attrib_id, uint x) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_U32); + assert(attrib->comp_len == 1); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + uint* data = (uint*)(imm.vertex_data + attrib->offset); + + data[0] = x; +} + +void immAttrib2i(uint attrib_id, int x, int y) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_I32); + assert(attrib->comp_len == 2); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + int* data = (int*)(imm.vertex_data + attrib->offset); + + data[0] = x; + data[1] = y; +} + +void immAttrib2s(uint attrib_id, short x, short y) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_I16); + assert(attrib->comp_len == 2); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + short* data = (short*)(imm.vertex_data + attrib->offset); + + data[0] = x; + data[1] = y; +} + +void immAttrib2fv(uint attrib_id, const float data[2]) +{ + immAttrib2f(attrib_id, data[0], data[1]); +} + +void immAttrib3fv(uint attrib_id, const float data[3]) +{ + immAttrib3f(attrib_id, data[0], data[1], data[2]); +} + +void immAttrib4fv(uint attrib_id, const float data[4]) +{ + immAttrib4f(attrib_id, data[0], data[1], data[2], data[3]); +} + +void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_U8); + assert(attrib->comp_len == 3); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + GLubyte* data = imm.vertex_data + attrib->offset; +/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ + + data[0] = r; + data[1] = g; + data[2] = b; +} + +void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(attrib->comp_type == GWN_COMP_U8); + assert(attrib->comp_len == 4); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); + + GLubyte* data = imm.vertex_data + attrib->offset; +/* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ + + data[0] = r; + data[1] = g; + data[2] = b; + data[3] = a; +} + +void immAttrib3ubv(uint attrib_id, const unsigned char data[3]) +{ + immAttrib3ub(attrib_id, data[0], data[1], data[2]); +} + +void immAttrib4ubv(uint attrib_id, const unsigned char data[4]) +{ + immAttrib4ub(attrib_id, data[0], data[1], data[2], data[3]); +} + +void immSkipAttrib(uint attrib_id) +{ +#if TRUST_NO_ONE + assert(attrib_id < imm.vertex_format.attr_len); + assert(imm.vertex_idx < imm.vertex_len); + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ +#endif + setAttribValueBit(attrib_id); +} + +static void immEndVertex(void) /* and move on to the next vertex */ +{ +#if TRUST_NO_ONE + assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.vertex_idx < imm.vertex_len); +#endif + + /* have all attribs been assigned values? + * if not, copy value from previous vertex */ + if (imm.unassigned_attrib_bits) { +#if TRUST_NO_ONE + assert(imm.vertex_idx > 0); /* first vertex must have all attribs specified */ +#endif + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { + if ((imm.unassigned_attrib_bits >> a_idx) & 1) { + const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; + +/* printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); */ + + GLubyte* data = imm.vertex_data + a->offset; + memcpy(data, data - imm.vertex_format.stride, a->sz); + /* TODO: consolidate copy of adjacent attributes */ + } + } + } + + imm.vertex_idx++; + imm.vertex_data += imm.vertex_format.stride; + imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; +} + +void immVertex2f(uint attrib_id, float x, float y) +{ + immAttrib2f(attrib_id, x, y); + immEndVertex(); +} + +void immVertex3f(uint attrib_id, float x, float y, float z) +{ + immAttrib3f(attrib_id, x, y, z); + immEndVertex(); +} + +void immVertex4f(uint attrib_id, float x, float y, float z, float w) +{ + immAttrib4f(attrib_id, x, y, z, w); + immEndVertex(); +} + +void immVertex2i(uint attrib_id, int x, int y) +{ + immAttrib2i(attrib_id, x, y); + immEndVertex(); +} + +void immVertex2s(uint attrib_id, short x, short y) +{ + immAttrib2s(attrib_id, x, y); + immEndVertex(); +} + +void immVertex2fv(uint attrib_id, const float data[2]) +{ + immAttrib2f(attrib_id, data[0], data[1]); + immEndVertex(); +} + +void immVertex3fv(uint attrib_id, const float data[3]) +{ + immAttrib3f(attrib_id, data[0], data[1], data[2]); + immEndVertex(); +} + +void immVertex2iv(uint attrib_id, const int data[2]) +{ + immAttrib2i(attrib_id, data[0], data[1]); + immEndVertex(); +} + + +/* --- generic uniform functions --- */ + +#if 0 + #if TRUST_NO_ONE + #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); + #else + #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); + #endif +#else + /* NOTE: It is possible to have uniform fully optimized out from the shader. + * In this case we can't assert failure or allow NULL-pointer dereference. + * TODO(sergey): How can we detect existing-but-optimized-out uniform but still + * catch typos in uniform names passed to immUniform*() functions? */ + #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; +#endif + +void immUniform1f(const char* name, float x) +{ + GET_UNIFORM + glUniform1f(uniform->location, x); +} + +void immUniform2f(const char* name, float x, float y) +{ + GET_UNIFORM + glUniform2f(uniform->location, x, y); +} + +void immUniform2fv(const char* name, const float data[2]) +{ + GET_UNIFORM + glUniform2fv(uniform->location, 1, data); +} + +void immUniform3f(const char* name, float x, float y, float z) +{ + GET_UNIFORM + glUniform3f(uniform->location, x, y, z); +} + +void immUniform3fv(const char* name, const float data[3]) +{ + GET_UNIFORM + glUniform3fv(uniform->location, 1, data); +} + +/* can increase this limit or move to another file */ +#define MAX_UNIFORM_NAME_LEN 60 + +void immUniformArray3fv(const char* bare_name, const float *data, int count) +{ + /* look up "name[0]" when given "name" */ + const size_t len = strlen(bare_name); +#if TRUST_NO_ONE + assert(len <= MAX_UNIFORM_NAME_LEN); +#endif + char name[MAX_UNIFORM_NAME_LEN]; + strcpy(name, bare_name); + name[len + 0] = '['; + name[len + 1] = '0'; + name[len + 2] = ']'; + name[len + 3] = '\0'; + + GET_UNIFORM + glUniform3fv(uniform->location, count, data); +} + +void immUniform4f(const char* name, float x, float y, float z, float w) +{ + GET_UNIFORM + glUniform4f(uniform->location, x, y, z, w); +} + +void immUniform4fv(const char* name, const float data[4]) +{ + GET_UNIFORM + glUniform4fv(uniform->location, 1, data); +} + +void immUniformArray4fv(const char* bare_name, const float *data, int count) +{ + /* look up "name[0]" when given "name" */ + const size_t len = strlen(bare_name); +#if TRUST_NO_ONE + assert(len <= MAX_UNIFORM_NAME_LEN); +#endif + char name[MAX_UNIFORM_NAME_LEN]; + strcpy(name, bare_name); + name[len + 0] = '['; + name[len + 1] = '0'; + name[len + 2] = ']'; + name[len + 3] = '\0'; + + GET_UNIFORM + glUniform4fv(uniform->location, count, data); +} + +void immUniformMatrix4fv(const char* name, const float data[4][4]) +{ + GET_UNIFORM + glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data); +} + +void immUniform1i(const char* name, int x) +{ + GET_UNIFORM + glUniform1i(uniform->location, x); +} + +void immUniform4iv(const char* name, const int data[4]) +{ + GET_UNIFORM + glUniform4iv(uniform->location, 1, data); +} + +/* --- convenience functions for setting "uniform vec4 color" --- */ + +void immUniformColor4f(float r, float g, float b, float a) +{ + const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform_builtin(imm.shader_interface, GWN_UNIFORM_COLOR); +#if TRUST_NO_ONE + assert(uniform != NULL); +#endif + glUniform4f(uniform->location, r, g, b, a); +} + +void immUniformColor4fv(const float rgba[4]) +{ + immUniformColor4f(rgba[0], rgba[1], rgba[2], rgba[3]); +} + +void immUniformColor3f(float r, float g, float b) +{ + immUniformColor4f(r, g, b, 1.0f); +} + +void immUniformColor3fv(const float rgb[3]) +{ + immUniformColor4f(rgb[0], rgb[1], rgb[2], 1.0f); +} + +void immUniformColor3fvAlpha(const float rgb[3], float a) +{ + immUniformColor4f(rgb[0], rgb[1], rgb[2], a); +} + +/* TODO: v-- treat as sRGB? --v */ + +void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b) +{ + const float scale = 1.0f / 255.0f; + immUniformColor4f(scale * r, scale * g, scale * b, 1.0f); +} + +void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + const float scale = 1.0f / 255.0f; + immUniformColor4f(scale * r, scale * g, scale * b, scale * a); +} + +void immUniformColor3ubv(const unsigned char rgb[3]) +{ + immUniformColor3ub(rgb[0], rgb[1], rgb[2]); +} + +void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char alpha) +{ + immUniformColor4ub(rgb[0], rgb[1], rgb[2], alpha); +} + +void immUniformColor4ubv(const unsigned char rgba[4]) +{ + immUniformColor4ub(rgba[0], rgba[1], rgba[2], rgba[3]); +} + void immUniformThemeColor(int color_id) { float color[4]; diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index 30672af9c02..4b2fb1b8e8a 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -18,8 +18,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file source/blender/gpu/intern/gpu_immediate_util.c +/** \file blender/gpu/intern/gwn_imm_util.c * \ingroup gpu + * + * Gawain immediate mode drawing utilities */ #include @@ -66,6 +68,72 @@ static const int cube_line_index[12][2] = { {6, 7}, }; +void immRectf(uint pos, float x1, float y1, float x2, float y2) +{ + immBegin(GWN_PRIM_TRI_FAN, 4); + immVertex2f(pos, x1, y1); + immVertex2f(pos, x2, y1); + immVertex2f(pos, x2, y2); + immVertex2f(pos, x1, y2); + immEnd(); +} + +void immRecti(uint pos, int x1, int y1, int x2, int y2) +{ + immBegin(GWN_PRIM_TRI_FAN, 4); + immVertex2i(pos, x1, y1); + immVertex2i(pos, x2, y1); + immVertex2i(pos, x2, y2); + immVertex2i(pos, x1, y2); + immEnd(); +} + +void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]) +{ + immAttrib4fv(col, color); + immVertex2f(pos, x1, y1); + immAttrib4fv(col, color); + immVertex2f(pos, x2, y1); + immAttrib4fv(col, color); + immVertex2f(pos, x2, y2); + + immAttrib4fv(col, color); + immVertex2f(pos, x1, y1); + immAttrib4fv(col, color); + immVertex2f(pos, x2, y2); + immAttrib4fv(col, color); + immVertex2f(pos, x1, y2); +} + +void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]) +{ + immAttrib4fv(col, color); + immVertex2i(pos, x1, y1); + immAttrib4fv(col, color); + immVertex2i(pos, x2, y1); + immAttrib4fv(col, color); + immVertex2i(pos, x2, y2); + + immAttrib4fv(col, color); + immVertex2i(pos, x1, y1); + immAttrib4fv(col, color); + immVertex2i(pos, x2, y2); + immAttrib4fv(col, color); + immVertex2i(pos, x1, y2); +} + +#if 0 /* more complete version in case we want that */ +void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4]) +{ + Gwn_VertFormat *format = immVertexFormat(); + uint pos = add_attrib(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(color); + immRecti(pos, x1, y1, x2, y2); + immUnbindProgram(); +} +#endif + /** * Pack color into 3 bytes * diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c index 2af1375a620..13c6fbea1c6 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.c @@ -29,7 +29,7 @@ * \ingroup gpu */ -#include "../../../intern/gawain/gawain/gwn_shader_interface.h" +#include "GPU_shader_interface.h" #define SUPPRESS_GENERIC_MATRIX_API #define USE_GPU_PY_MATRIX_API /* only so values are declared */ diff --git a/source/blender/gpu/intern/gpu_primitive.c b/source/blender/gpu/intern/gpu_primitive.c new file mode 100644 index 00000000000..0f0c28c05dc --- /dev/null +++ b/source/blender/gpu/intern/gpu_primitive.c @@ -0,0 +1,84 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_primitive.c + * \ingroup gpu + * + * Gawain geometric primitives + */ + +#include "GPU_primitive.h" +#include "gpu_primitive_private.h" + +Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type) +{ + static const Gwn_PrimClass classes[] = { + [GWN_PRIM_POINTS] = GWN_PRIM_CLASS_POINT, + [GWN_PRIM_LINES] = GWN_PRIM_CLASS_LINE, + [GWN_PRIM_LINE_STRIP] = GWN_PRIM_CLASS_LINE, + [GWN_PRIM_LINE_LOOP] = GWN_PRIM_CLASS_LINE, + [GWN_PRIM_TRIS] = GWN_PRIM_CLASS_SURFACE, + [GWN_PRIM_TRI_STRIP] = GWN_PRIM_CLASS_SURFACE, + [GWN_PRIM_TRI_FAN] = GWN_PRIM_CLASS_SURFACE, + + [GWN_PRIM_LINES_ADJ] = GWN_PRIM_CLASS_LINE, + [GWN_PRIM_LINE_STRIP_ADJ] = GWN_PRIM_CLASS_LINE, + [GWN_PRIM_TRIS_ADJ] = GWN_PRIM_CLASS_SURFACE, + + [GWN_PRIM_NONE] = GWN_PRIM_CLASS_NONE + }; + + return classes[prim_type]; +} + +bool GWN_primtype_belongs_to_class(Gwn_PrimType prim_type, Gwn_PrimClass prim_class) +{ + if (prim_class == GWN_PRIM_CLASS_NONE && prim_type == GWN_PRIM_NONE) { + return true; + } + return prim_class & GWN_primtype_class(prim_type); +} + +GLenum convert_prim_type_to_gl(Gwn_PrimType prim_type) +{ +#if TRUST_NO_ONE + assert(prim_type != GWN_PRIM_NONE); +#endif + static const GLenum table[] = { + [GWN_PRIM_POINTS] = GL_POINTS, + [GWN_PRIM_LINES] = GL_LINES, + [GWN_PRIM_LINE_STRIP] = GL_LINE_STRIP, + [GWN_PRIM_LINE_LOOP] = GL_LINE_LOOP, + [GWN_PRIM_TRIS] = GL_TRIANGLES, + [GWN_PRIM_TRI_STRIP] = GL_TRIANGLE_STRIP, + [GWN_PRIM_TRI_FAN] = GL_TRIANGLE_FAN, + + [GWN_PRIM_LINES_ADJ] = GL_LINES_ADJACENCY, + [GWN_PRIM_LINE_STRIP_ADJ] = GL_LINE_STRIP_ADJACENCY, + [GWN_PRIM_TRIS_ADJ] = GL_TRIANGLES_ADJACENCY, + }; + + return table[prim_type]; +} diff --git a/source/blender/gpu/intern/gpu_primitive_private.h b/source/blender/gpu/intern/gpu_primitive_private.h new file mode 100644 index 00000000000..6d3f1e20da7 --- /dev/null +++ b/source/blender/gpu/intern/gpu_primitive_private.h @@ -0,0 +1,37 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_primitive_private.h + * \ingroup gpu + * + * Gawain geometric primitives + */ + +#ifndef __GWN_PRIMITIVE_PRIVATE_H__ +#define __GWN_PRIMITIVE_PRIVATE_H__ + +GLenum convert_prim_type_to_gl(Gwn_PrimType); + +#endif /* __GWN_PRIMITIVE_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c new file mode 100644 index 00000000000..56b25726a84 --- /dev/null +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -0,0 +1,361 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_shader_interface.c + * \ingroup gpu + * + * Gawain shader interface (C --> GLSL) + */ + +#include "gpu_batch_private.h" +#include "GPU_shader_interface.h" +#include "GPU_vertex_array_id.h" +#include +#include +#include + +#define DEBUG_SHADER_INTERFACE 0 + +#if DEBUG_SHADER_INTERFACE + #include +#endif + +static const char* BuiltinUniform_name(Gwn_UniformBuiltin u) +{ + static const char* names[] = { + [GWN_UNIFORM_NONE] = NULL, + + [GWN_UNIFORM_MODEL] = "ModelMatrix", + [GWN_UNIFORM_VIEW] = "ViewMatrix", + [GWN_UNIFORM_MODELVIEW] = "ModelViewMatrix", + [GWN_UNIFORM_PROJECTION] = "ProjectionMatrix", + [GWN_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix", + [GWN_UNIFORM_MVP] = "ModelViewProjectionMatrix", + + [GWN_UNIFORM_MODEL_INV] = "ModelMatrixInverse", + [GWN_UNIFORM_VIEW_INV] = "ViewMatrixInverse", + [GWN_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse", + [GWN_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse", + [GWN_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse", + + [GWN_UNIFORM_NORMAL] = "NormalMatrix", + [GWN_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix", + [GWN_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors", + [GWN_UNIFORM_ORCO] = "OrcoTexCoFactors", + + [GWN_UNIFORM_COLOR] = "color", + [GWN_UNIFORM_EYE] = "eye", + [GWN_UNIFORM_CALLID] = "callId", + + [GWN_UNIFORM_CUSTOM] = NULL, + [GWN_NUM_UNIFORMS] = NULL, + }; + + return names[u]; +} + +GWN_INLINE bool match(const char* a, const char* b) +{ + return strcmp(a, b) == 0; +} + +GWN_INLINE uint hash_string(const char *str) +{ + uint i = 0, c; + while ((c = *str++)) { + i = i * 37 + c; + } + return i; +} + +GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* input, + const char* name, uint32_t name_len) +{ + input->name_offset = shaderface->name_buffer_offset; + input->name_hash = hash_string(name); + shaderface->name_buffer_offset += name_len + 1; /* include NULL terminator */ +} + +GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input, + Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) +{ + const uint bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; + input->next = buckets[bucket_index]; + buckets[bucket_index] = input; +} + +GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], + const char *name_buffer, const char *name) +{ + const uint name_hash = hash_string(name); + const uint bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; + const Gwn_ShaderInput* input = buckets[bucket_index]; + if (input == NULL) { + /* Requested uniform is not found at all. */ + return NULL; + } + /* Optimization bit: if there is no hash collision detected when constructing shader interface + * it means we can only request the single possible uniform. Surely, it's possible we request + * uniform which causes hash collision, but that will be detected in debug builds. */ + if (input->next == NULL) { + if (name_hash == input->name_hash) { +#if TRUST_NO_ONE + assert(match(name_buffer + input->name_offset, name)); +#endif + return input; + } + return NULL; + } + /* Work through possible collisions. */ + const Gwn_ShaderInput* next = input; + while (next != NULL) { + input = next; + next = input->next; + if (input->name_hash != name_hash) { + continue; + } + if (match(name_buffer + input->name_offset, name)) { + return input; + } + } + return NULL; /* not found */ +} + +GWN_INLINE void buckets_free(Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) +{ + for (uint bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { + Gwn_ShaderInput *input = buckets[bucket_index]; + while (input != NULL) { + Gwn_ShaderInput *input_next = input->next; + free(input); + input = input_next; + } + } +} + +static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name) +{ + /* TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types */ + + /* detect built-in uniforms (name must match) */ + for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { + const char* builtin_name = BuiltinUniform_name(u); + if (match(name, builtin_name)) { + input->builtin_type = u; + return true; + } + } + input->builtin_type = GWN_UNIFORM_CUSTOM; + return false; +} + +static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const char* name) +{ + Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + + input->location = glGetUniformLocation(shaderface->program, name); + + uint name_len = strlen(name); + shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ + char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; + strcpy(name_buffer, name); + + set_input_name(shaderface, input, name, name_len); + setup_builtin_uniform(input, name); + + shader_input_to_bucket(input, shaderface->uniform_buckets); + if (input->builtin_type != GWN_UNIFORM_NONE && + input->builtin_type != GWN_UNIFORM_CUSTOM) + { + shaderface->builtin_uniforms[input->builtin_type] = input; + } +#if DEBUG_SHADER_INTERFACE + printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, + shaderface->program, + name, + input->location); +#endif + return input; +} + +Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) +{ + Gwn_ShaderInterface* shaderface = calloc(1, sizeof(Gwn_ShaderInterface)); + shaderface->program = program; + +#if DEBUG_SHADER_INTERFACE + printf("%s {\n", __func__); /* enter function */ + printf("Gwn_ShaderInterface %p, program %d\n", shaderface, program); +#endif + + GLint max_attrib_name_len, attr_len; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len); + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attr_len); + + GLint max_ubo_name_len, ubo_len; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len); + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len); + + const uint32_t name_buffer_len = attr_len * max_attrib_name_len + ubo_len * max_ubo_name_len; + shaderface->name_buffer = malloc(name_buffer_len); + + /* Attributes */ + for (uint32_t i = 0; i < attr_len; ++i) { + Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; + char* name = shaderface->name_buffer + shaderface->name_buffer_offset; + GLsizei name_len = 0; + + glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name); + + /* remove "[0]" from array name */ + if (name[name_len-1] == ']') { + name[name_len-3] = '\0'; + name_len -= 3; + } + + /* TODO: reject DOUBLE gl_types */ + + input->location = glGetAttribLocation(program, name); + + set_input_name(shaderface, input, name, name_len); + + shader_input_to_bucket(input, shaderface->attrib_buckets); + +#if DEBUG_SHADER_INTERFACE + printf("attrib[%u] '%s' at location %d\n", i, name, input->location); +#endif + } + /* Uniform Blocks */ + for (uint32_t i = 0; i < ubo_len; ++i) { + Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; + char* name = shaderface->name_buffer + shaderface->name_buffer_offset; + GLsizei name_len = 0; + + glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name); + + input->location = i; + + set_input_name(shaderface, input, name, name_len); + + shader_input_to_bucket(input, shaderface->ubo_buckets); + +#if DEBUG_SHADER_INTERFACE + printf("ubo '%s' at location %d\n", name, input->location); +#endif + } + /* Builtin Uniforms */ + for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { + const char* builtin_name = BuiltinUniform_name(u); + if (glGetUniformLocation(program, builtin_name) != -1) { + add_uniform((Gwn_ShaderInterface*)shaderface, builtin_name); + } + } + /* Batches ref buffer */ + shaderface->batches_len = GWN_SHADERINTERFACE_REF_ALLOC_COUNT; + shaderface->batches = calloc(shaderface->batches_len, sizeof(Gwn_Batch*)); + + return shaderface; +} + +void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) +{ + /* Free memory used by buckets and has entries. */ + buckets_free(shaderface->uniform_buckets); + buckets_free(shaderface->attrib_buckets); + buckets_free(shaderface->ubo_buckets); + /* Free memory used by name_buffer. */ + free(shaderface->name_buffer); + /* Remove this interface from all linked Batches vao cache. */ + for (int i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] != NULL) { + gwn_batch_remove_interface_ref(shaderface->batches[i], shaderface); + } + } + free(shaderface->batches); + /* Free memory used by shader interface by its self. */ + free(shaderface); +} + +const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name) +{ + /* TODO: Warn if we find a matching builtin, since these can be looked up much quicker. */ + const Gwn_ShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); + /* If input is not found add it so it's found next time. */ + if (input == NULL) { + input = add_uniform((Gwn_ShaderInterface*)shaderface, name); + } + return (input->location != -1) ? input : NULL; +} + +const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin( + const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin) +{ +#if TRUST_NO_ONE + assert(builtin != GWN_UNIFORM_NONE); + assert(builtin != GWN_UNIFORM_CUSTOM); + assert(builtin != GWN_NUM_UNIFORMS); +#endif + return shaderface->builtin_uniforms[builtin]; +} + +const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name) +{ + return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name); +} + +const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name) +{ + return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name); +} + +void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) +{ + int i; /* find first unused slot */ + for (i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] == NULL) { + break; + } + } + if (i == shaderface->batches_len) { + /* Not enough place, realloc the array. */ + i = shaderface->batches_len; + shaderface->batches_len += GWN_SHADERINTERFACE_REF_ALLOC_COUNT; + shaderface->batches = realloc(shaderface->batches, sizeof(Gwn_Batch*) * shaderface->batches_len); + memset(shaderface->batches + i, 0, sizeof(Gwn_Batch*) * GWN_SHADERINTERFACE_REF_ALLOC_COUNT); + } + shaderface->batches[i] = batch; +} + +void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) +{ + for (int i = 0; i < shaderface->batches_len; ++i) { + if (shaderface->batches[i] == batch) { + shaderface->batches[i] = NULL; + break; /* cannot have duplicates */ + } + } +} diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index de5439c5638..bf54d269fb5 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -26,7 +26,7 @@ #define __GPU_SHADER_PRIVATE_H__ #include "GPU_glew.h" -#include "gawain/gwn_shader_interface.h" +#include "GPU_shader_interface.h" struct GPUShader { GLuint program; /* handle for full program (links shader stages below) */ diff --git a/source/blender/gpu/intern/gpu_vertex_array_id.cpp b/source/blender/gpu/intern/gpu_vertex_array_id.cpp new file mode 100644 index 00000000000..de5be15ec19 --- /dev/null +++ b/source/blender/gpu/intern/gpu_vertex_array_id.cpp @@ -0,0 +1,196 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_array_id.cpp + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ + +#include "gpu_batch_private.h" +#include "GPU_vertex_array_id.h" +#include "GPU_context.h" +#include +#include +#include +#include +#include + +#if TRUST_NO_ONE +#if 0 +extern "C" { +extern int BLI_thread_is_main(void); /* Blender-specific function */ +} + +static bool thread_is_main() { + /* "main" here means the GL context's thread */ + return BLI_thread_is_main(); +} +#endif +#endif + +struct Gwn_Context { + GLuint default_vao; + std::unordered_set batches; /* Batches that have VAOs from this context */ + std::vector orphaned_vertarray_ids; + std::mutex orphans_mutex; /* todo: try spinlock instead */ +#if TRUST_NO_ONE + pthread_t thread; /* Thread on which this context is active. */ + bool thread_is_used; + + Gwn_Context() { + thread_is_used = false; + } +#endif +}; + +#if defined(_MSC_VER) && (_MSC_VER == 1800) +#define thread_local __declspec(thread) +thread_local Gwn_Context* active_ctx = NULL; +#else +static thread_local Gwn_Context* active_ctx = NULL; +#endif + +static void clear_orphans(Gwn_Context* ctx) +{ + ctx->orphans_mutex.lock(); + if (!ctx->orphaned_vertarray_ids.empty()) { + uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size(); + glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data()); + ctx->orphaned_vertarray_ids.clear(); + } + ctx->orphans_mutex.unlock(); +} + +Gwn_Context* GWN_context_create(void) +{ +#if TRUST_NO_ONE + /* assert(thread_is_main()); */ +#endif + Gwn_Context* ctx = new Gwn_Context; + glGenVertexArrays(1, &ctx->default_vao); + GWN_context_active_set(ctx); + return ctx; +} + +/* to be called after GWN_context_active_set(ctx_to_destroy) */ +void GWN_context_discard(Gwn_Context* ctx) +{ +#if TRUST_NO_ONE + /* Make sure no other thread has locked it. */ + assert(ctx == active_ctx); + assert(pthread_equal(pthread_self(), ctx->thread)); + assert(ctx->orphaned_vertarray_ids.empty()); +#endif + /* delete remaining vaos */ + while (!ctx->batches.empty()) { + /* this removes the array entry */ + gwn_batch_vao_cache_clear(*ctx->batches.begin()); + } + glDeleteVertexArrays(1, &ctx->default_vao); + delete ctx; + active_ctx = NULL; +} + +/* ctx can be NULL */ +void GWN_context_active_set(Gwn_Context* ctx) +{ +#if TRUST_NO_ONE + if (active_ctx) { + active_ctx->thread_is_used = false; + } + /* Make sure no other context is already bound to this thread. */ + if (ctx) { + /* Make sure no other thread has locked it. */ + assert(ctx->thread_is_used == false); + ctx->thread = pthread_self(); + ctx->thread_is_used = true; + } +#endif + if (ctx) { + clear_orphans(ctx); + } + active_ctx = ctx; +} + +Gwn_Context* GWN_context_active_get(void) +{ + return active_ctx; +} + +GLuint GWN_vao_default(void) +{ +#if TRUST_NO_ONE + assert(active_ctx); /* need at least an active context */ + assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ +#endif + return active_ctx->default_vao; +} + +GLuint GWN_vao_alloc(void) +{ +#if TRUST_NO_ONE + assert(active_ctx); /* need at least an active context */ + assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ +#endif + clear_orphans(active_ctx); + + GLuint new_vao_id = 0; + glGenVertexArrays(1, &new_vao_id); + return new_vao_id; +} + +/* this can be called from multiple thread */ +void GWN_vao_free(GLuint vao_id, Gwn_Context* ctx) +{ +#if TRUST_NO_ONE + assert(ctx); +#endif + if (ctx == active_ctx) { + glDeleteVertexArrays(1, &vao_id); + } + else { + ctx->orphans_mutex.lock(); + ctx->orphaned_vertarray_ids.emplace_back(vao_id); + ctx->orphans_mutex.unlock(); + } +} + +void gwn_context_add_batch(Gwn_Context* ctx, Gwn_Batch* batch) +{ + ctx->batches.emplace(batch); +} + +void gwn_context_remove_batch(Gwn_Context* ctx, Gwn_Batch* batch) +{ + ctx->orphans_mutex.lock(); + ctx->batches.erase(batch); + ctx->orphans_mutex.unlock(); +} diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c new file mode 100644 index 00000000000..32f3d494015 --- /dev/null +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -0,0 +1,268 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_vertex_buffer.c + * \ingroup gpu + * + * Gawain vertex buffer + */ + +#include "GPU_vertex_buffer.h" +#include "GPU_buffer_id.h" +#include "gpu_vertex_format_private.h" +#include +#include + +#define KEEP_SINGLE_COPY 1 + +static uint vbo_memory_usage; + +static GLenum convert_usage_type_to_gl(Gwn_UsageType type) +{ + static const GLenum table[] = { + [GWN_USAGE_STREAM] = GL_STREAM_DRAW, + [GWN_USAGE_STATIC] = GL_STATIC_DRAW, + [GWN_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW + }; + return table[type]; +} + +Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType usage) +{ + Gwn_VertBuf* verts = malloc(sizeof(Gwn_VertBuf)); + GWN_vertbuf_init(verts, usage); + return verts; +} + +Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat* format, Gwn_UsageType usage) +{ + Gwn_VertBuf* verts = GWN_vertbuf_create(usage); + GWN_vertformat_copy(&verts->format, format); + if (!format->packed) { + VertexFormat_pack(&verts->format); + } + return verts; + + /* this function might seem redundant, but there is potential for memory savings here... */ + /* TODO: implement those memory savings */ +} + +void GWN_vertbuf_init(Gwn_VertBuf* verts, Gwn_UsageType usage) +{ + memset(verts, 0, sizeof(Gwn_VertBuf)); + verts->usage = usage; + verts->dirty = true; +} + +void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf* verts, const Gwn_VertFormat* format, Gwn_UsageType usage) +{ + GWN_vertbuf_init(verts, usage); + GWN_vertformat_copy(&verts->format, format); + if (!format->packed) { + VertexFormat_pack(&verts->format); + } +} + +void GWN_vertbuf_discard(Gwn_VertBuf* verts) +{ + if (verts->vbo_id) { + GWN_buf_id_free(verts->vbo_id); +#if VRAM_USAGE + vbo_memory_usage -= GWN_vertbuf_size_get(verts); +#endif + } + if (verts->data) { + free(verts->data); + } + free(verts); +} + +uint GWN_vertbuf_size_get(const Gwn_VertBuf* verts) +{ + return vertex_buffer_size(&verts->format, verts->vertex_len); +} + +/* create a new allocation, discarding any existing data */ +void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) +{ + Gwn_VertFormat* format = &verts->format; + if (!format->packed) { + VertexFormat_pack(format); + } +#if TRUST_NO_ONE + /* catch any unnecessary use */ + assert(verts->vertex_alloc != v_len || verts->data == NULL); +#endif + /* only create the buffer the 1st time */ + if (verts->vbo_id == 0) { + verts->vbo_id = GWN_buf_id_alloc(); + } + /* discard previous data if any */ + if (verts->data) { + free(verts->data); + } +#if VRAM_USAGE + uint new_size = vertex_buffer_size(&verts->format, v_len); + vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); +#endif + verts->dirty = true; + verts->vertex_len = verts->vertex_alloc = v_len; + verts->data = malloc(sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); +} + +/* resize buffer keeping existing data */ +void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, uint v_len) +{ +#if TRUST_NO_ONE + assert(verts->data != NULL); + assert(verts->vertex_alloc != v_len); +#endif + +#if VRAM_USAGE + uint new_size = vertex_buffer_size(&verts->format, v_len); + vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); +#endif + verts->dirty = true; + verts->vertex_len = verts->vertex_alloc = v_len; + verts->data = realloc(verts->data, sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); +} + +/* Set vertex count but does not change allocation. + * Only this many verts will be uploaded to the GPU and rendered. + * This is usefull for streaming data. */ +void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, uint v_len) +{ +#if TRUST_NO_ONE + assert(verts->data != NULL); /* only for dynamic data */ + assert(v_len <= verts->vertex_alloc); +#endif + +#if VRAM_USAGE + uint new_size = vertex_buffer_size(&verts->format, v_len); + vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); +#endif + verts->vertex_len = v_len; +} + +void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, uint a_idx, uint v_idx, const void* data) +{ + const Gwn_VertFormat* format = &verts->format; + const Gwn_VertAttr* a = format->attribs + a_idx; + +#if TRUST_NO_ONE + assert(a_idx < format->attr_len); + assert(v_idx < verts->vertex_alloc); + assert(verts->data != NULL); +#endif + verts->dirty = true; + memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz); +} + +void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, uint a_idx, const void* data) +{ + const Gwn_VertFormat* format = &verts->format; + const Gwn_VertAttr* a = format->attribs + a_idx; + +#if TRUST_NO_ONE + assert(a_idx < format->attr_len); +#endif + const uint stride = a->sz; /* tightly packed input data */ + + GWN_vertbuf_attr_fill_stride(verts, a_idx, stride, data); +} + +void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, uint a_idx, uint stride, const void* data) +{ + const Gwn_VertFormat* format = &verts->format; + const Gwn_VertAttr* a = format->attribs + a_idx; + +#if TRUST_NO_ONE + assert(a_idx < format->attr_len); + assert(verts->data != NULL); +#endif + verts->dirty = true; + const uint vertex_len = verts->vertex_len; + + if (format->attr_len == 1 && stride == format->stride) { + /* we can copy it all at once */ + memcpy(verts->data, data, vertex_len * a->sz); + } + else { + /* we must copy it per vertex */ + for (uint v = 0; v < vertex_len; ++v) { + memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz); + } + } +} + +void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, uint a_idx, Gwn_VertBufRaw *access) +{ + const Gwn_VertFormat* format = &verts->format; + const Gwn_VertAttr* a = format->attribs + a_idx; + +#if TRUST_NO_ONE + assert(a_idx < format->attr_len); + assert(verts->data != NULL); +#endif + + verts->dirty = true; + + access->size = a->sz; + access->stride = format->stride; + access->data = (GLubyte*)verts->data + a->offset; + access->data_init = access->data; +#if TRUST_NO_ONE + access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride); +#endif +} + +static void VertBuffer_upload_data(Gwn_VertBuf* verts) +{ + uint buffer_sz = GWN_vertbuf_size_get(verts); + + /* orphan the vbo to avoid sync */ + glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); + /* upload data */ + glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); + + if (verts->usage == GWN_USAGE_STATIC) { + free(verts->data); + verts->data = NULL; + } + verts->dirty = false; +} + +void GWN_vertbuf_use(Gwn_VertBuf* verts) +{ + glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); + if (verts->dirty) { + VertBuffer_upload_data(verts); + } +} + +uint GWN_vertbuf_get_memory_usage(void) +{ + return vbo_memory_usage; +} diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c new file mode 100644 index 00000000000..bd9f9250564 --- /dev/null +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -0,0 +1,310 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gwn_vertex_format.c + * \ingroup gpu + * + * Gawain vertex format + */ + +#include "GPU_vertex_format.h" +#include "gpu_vertex_format_private.h" +#include +#include + +#define PACK_DEBUG 0 + +#if PACK_DEBUG + #include +#endif + +void GWN_vertformat_clear(Gwn_VertFormat* format) +{ +#if TRUST_NO_ONE + memset(format, 0, sizeof(Gwn_VertFormat)); +#else + format->attr_len = 0; + format->packed = false; + format->name_offset = 0; + format->name_len = 0; + + for (unsigned i = 0; i < GWN_VERT_ATTR_MAX_LEN; i++) { + format->attribs[i].name_len = 0; + } +#endif +} + +void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src) +{ + /* copy regular struct fields */ + memcpy(dest, src, sizeof(Gwn_VertFormat)); + + for (unsigned i = 0; i < dest->attr_len; i++) { + for (unsigned j = 0; j < dest->attribs[i].name_len; j++) { + dest->attribs[i].name[j] = (char *)dest + (src->attribs[i].name[j] - ((char *)src)); + } + } +} + +static GLenum convert_comp_type_to_gl(Gwn_VertCompType type) +{ + static const GLenum table[] = { + [GWN_COMP_I8] = GL_BYTE, + [GWN_COMP_U8] = GL_UNSIGNED_BYTE, + [GWN_COMP_I16] = GL_SHORT, + [GWN_COMP_U16] = GL_UNSIGNED_SHORT, + [GWN_COMP_I32] = GL_INT, + [GWN_COMP_U32] = GL_UNSIGNED_INT, + + [GWN_COMP_F32] = GL_FLOAT, + + [GWN_COMP_I10] = GL_INT_2_10_10_10_REV + }; + return table[type]; +} + +static unsigned comp_sz(Gwn_VertCompType type) +{ +#if TRUST_NO_ONE + assert(type <= GWN_COMP_F32); /* other types have irregular sizes (not bytes) */ +#endif + const GLubyte sizes[] = {1,1,2,2,4,4,4}; + return sizes[type]; +} + +static unsigned attrib_sz(const Gwn_VertAttr *a) +{ + if (a->comp_type == GWN_COMP_I10) { + return 4; /* always packed as 10_10_10_2 */ + } + return a->comp_len * comp_sz(a->comp_type); +} + +static unsigned attrib_align(const Gwn_VertAttr *a) +{ + if (a->comp_type == GWN_COMP_I10) { + return 4; /* always packed as 10_10_10_2 */ + } + unsigned c = comp_sz(a->comp_type); + if (a->comp_len == 3 && c <= 2) { + return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */ + } + else { + return c; /* most fetches are ok if components are naturally aligned */ + } +} + +unsigned vertex_buffer_size(const Gwn_VertFormat* format, unsigned vertex_len) +{ +#if TRUST_NO_ONE + assert(format->packed && format->stride > 0); +#endif + return format->stride * vertex_len; +} + +static const char* copy_attrib_name(Gwn_VertFormat* format, const char* name) +{ + /* strncpy does 110% of what we need; let's do exactly 100% */ + char* name_copy = format->names + format->name_offset; + unsigned available = GWN_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; + bool terminated = false; + + for (unsigned i = 0; i < available; ++i) { + const char c = name[i]; + name_copy[i] = c; + if (c == '\0') { + terminated = true; + format->name_offset += (i + 1); + break; + } + } +#if TRUST_NO_ONE + assert(terminated); + assert(format->name_offset <= GWN_VERT_ATTR_NAMES_BUF_LEN); +#else + (void)terminated; +#endif + return name_copy; +} + +unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_VertCompType comp_type, unsigned comp_len, Gwn_VertFetchMode fetch_mode) +{ +#if TRUST_NO_ONE + assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(format->attr_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(!format->packed); /* packed means frozen/locked */ + assert((comp_len >= 1 && comp_len <= 4) || comp_len == 8 || comp_len == 12 || comp_len == 16); + + switch (comp_type) { + case GWN_COMP_F32: + /* float type can only kept as float */ + assert(fetch_mode == GWN_FETCH_FLOAT); + break; + case GWN_COMP_I10: + /* 10_10_10 format intended for normals (xyz) or colors (rgb) + * extra component packed.w can be manually set to { -2, -1, 0, 1 } */ + assert(comp_len == 3 || comp_len == 4); + assert(fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT); /* not strictly required, may relax later */ + break; + default: + /* integer types can be kept as int or converted/normalized to float */ + assert(fetch_mode != GWN_FETCH_FLOAT); + /* only support float matrices (see Batch_update_program_bindings) */ + assert(comp_len != 8 && comp_len != 12 && comp_len != 16); + } +#endif + format->name_len++; /* multiname support */ + + const unsigned attrib_id = format->attr_len++; + Gwn_VertAttr* attrib = format->attribs + attrib_id; + + attrib->name[attrib->name_len++] = copy_attrib_name(format, name); + attrib->comp_type = comp_type; + attrib->gl_comp_type = convert_comp_type_to_gl(comp_type); + attrib->comp_len = (comp_type == GWN_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ + attrib->sz = attrib_sz(attrib); + attrib->offset = 0; /* offsets & stride are calculated later (during pack) */ + attrib->fetch_mode = fetch_mode; + + return attrib_id; +} + +void GWN_vertformat_alias_add(Gwn_VertFormat* format, const char* alias) +{ + Gwn_VertAttr* attrib = format->attribs + (format->attr_len - 1); +#if TRUST_NO_ONE + assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(attrib->name_len < GWN_VERT_ATTR_MAX_NAMES); +#endif + format->name_len++; /* multiname support */ + attrib->name[attrib->name_len++] = copy_attrib_name(format, alias); +} + +unsigned padding(unsigned offset, unsigned alignment) +{ + const unsigned mod = offset % alignment; + return (mod == 0) ? 0 : (alignment - mod); +} + +#if PACK_DEBUG +static void show_pack(unsigned a_idx, unsigned sz, unsigned pad) +{ + const char c = 'A' + a_idx; + for (unsigned i = 0; i < pad; ++i) { + putchar('-'); + } + for (unsigned i = 0; i < sz; ++i) { + putchar(c); + } +} +#endif + +void VertexFormat_pack(Gwn_VertFormat* format) +{ + /* For now, attributes are packed in the order they were added, + * making sure each attrib is naturally aligned (add padding where necessary) + * Later we can implement more efficient packing w/ reordering + * (keep attrib ID order, adjust their offsets to reorder in buffer). */ + + /* TODO: realloc just enough to hold the final combo string. And just enough to + * hold used attribs, not all 16. */ + + Gwn_VertAttr* a0 = format->attribs + 0; + a0->offset = 0; + unsigned offset = a0->sz; + +#if PACK_DEBUG + show_pack(0, a0->sz, 0); +#endif + + for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) { + Gwn_VertAttr* a = format->attribs + a_idx; + unsigned mid_padding = padding(offset, attrib_align(a)); + offset += mid_padding; + a->offset = offset; + offset += a->sz; + +#if PACK_DEBUG + show_pack(a_idx, a->sz, mid_padding); +#endif + } + + unsigned end_padding = padding(offset, attrib_align(a0)); + +#if PACK_DEBUG + show_pack(0, 0, end_padding); + putchar('\n'); +#endif + format->stride = offset + end_padding; + format->packed = true; +} + + +/* OpenGL ES packs in a different order as desktop GL but component conversion is the same. + * Of the code here, only struct Gwn_PackedNormal needs to change. */ + +#define SIGNED_INT_10_MAX 511 +#define SIGNED_INT_10_MIN -512 + +static int clampi(int x, int min_allowed, int max_allowed) +{ +#if TRUST_NO_ONE + assert(min_allowed <= max_allowed); +#endif + if (x < min_allowed) { + return min_allowed; + } + else if (x > max_allowed) { + return max_allowed; + } + else { + return x; + } +} + +static int quantize(float x) +{ + int qx = x * 511.0f; + return clampi(qx, SIGNED_INT_10_MIN, SIGNED_INT_10_MAX); +} + +static int convert_i16(short x) +{ + /* 16-bit signed --> 10-bit signed */ + /* TODO: round? */ + return x >> 6; +} + +Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]) +{ + Gwn_PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) }; + return n; +} + +Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]) +{ + Gwn_PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) }; + return n; +} diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h new file mode 100644 index 00000000000..3cae9969fd8 --- /dev/null +++ b/source/blender/gpu/intern/gpu_vertex_format_private.h @@ -0,0 +1,39 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/gwn_vertex_format_private.h + * \ingroup gpu + * + * Gawain vertex format + */ + +#ifndef __GWN_VERTEX_FORMAT_PRIVATE_H__ +#define __GWN_VERTEX_FORMAT_PRIVATE_H__ + +void VertexFormat_pack(Gwn_VertFormat*); +uint padding(uint offset, uint alignment); +uint vertex_buffer_size(const Gwn_VertFormat*, uint vertex_len); + +#endif /* __GWN_VERTEX_FORMAT_PRIVATE_H__ */ diff --git a/source/blender/python/gawain/gwn_py_api.c b/source/blender/python/gawain/gwn_py_api.c index d79ef070649..1f7a1297448 100644 --- a/source/blender/python/gawain/gwn_py_api.c +++ b/source/blender/python/gawain/gwn_py_api.c @@ -27,8 +27,8 @@ #include -#include "gawain/gwn_batch.h" -#include "gawain/gwn_vertex_format.h" +#include "GPU_batch.h" +#include "GPU_vertex_format.h" #include "gwn_py_api.h" #include "gwn_py_types.h" diff --git a/source/blender/python/gawain/gwn_py_types.c b/source/blender/python/gawain/gwn_py_types.c index bdf0be9f7e1..04c50ac0784 100644 --- a/source/blender/python/gawain/gwn_py_types.c +++ b/source/blender/python/gawain/gwn_py_types.c @@ -27,8 +27,8 @@ #include -#include "gawain/gwn_batch.h" -#include "gawain/gwn_vertex_format.h" +#include "GPU_batch.h" +#include "GPU_vertex_format.h" #include "BLI_math.h" diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index d3fef51e9e9..8f921d7850a 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -37,6 +37,7 @@ set(INC ../nodes ../physics ../draw + ../gpu ../../../intern/atomic ../../../intern/guardedalloc ../../../intern/mikktspace diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 82595527d30..af8746a4734 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -97,7 +97,7 @@ #include "../../../windowmanager/WM_api.h" /* XXX */ #include "../../../windowmanager/wm_window.h" /* XXX */ -#include "../../../intern/gawain/gawain/gwn_context.h" +#include "GPU_context.h" #ifdef WITH_FREESTYLE # include "FRS_freestyle.h" diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index d1a7f4ffea1..00e7f77569b 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -69,7 +69,7 @@ #include "GPU_matrix.h" #include "GPU_immediate.h" #include "GPU_immediate_util.h" -#include "GPU_batch.h" +#include "GPU_context.h" #include "GPU_init_exit.h" #include "DNA_scene_types.h" diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index f55fc5703f4..669480bf098 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -90,12 +90,11 @@ #include "GPU_immediate.h" #include "GPU_material.h" #include "GPU_texture.h" +#include "GPU_context.h" #include "BLF_api.h" #include "UI_resources.h" -#include "../../../intern/gawain/gawain/gwn_context.h" - /* for assert */ #ifndef NDEBUG # include "BLI_threads.h" -- cgit v1.2.3 From 8cd7828792419fb4eac9a2a477968535b4c71535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jul 2018 00:12:21 +0200 Subject: GWN: Port to GPU module: Replace GWN prefix by GPU --- build_files/cmake/macros.cmake | 2 +- intern/opencolorio/ocio_impl_glsl.cc | 14 +- release/scripts/modules/bpy_types.py | 16 +- source/blender/blenfont/intern/blf_font.c | 40 +- source/blender/blenfont/intern/blf_glyph.c | 6 +- .../blender/blenfont/intern/blf_internal_types.h | 6 +- source/blender/blenkernel/BKE_animsys.h | 2 +- source/blender/blenkernel/BKE_pbvh.h | 4 +- source/blender/blenkernel/intern/anim.c | 12 +- source/blender/blenkernel/intern/cloth.c | 4 +- source/blender/blenkernel/intern/pbvh.c | 6 +- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/draw/DRW_engine.h | 4 +- source/blender/draw/engines/basic/basic_engine.c | 4 +- source/blender/draw/engines/eevee/eevee_bloom.c | 2 +- .../draw/engines/eevee/eevee_depth_of_field.c | 2 +- source/blender/draw/engines/eevee/eevee_effects.c | 2 +- .../blender/draw/engines/eevee/eevee_lightcache.c | 26 +- .../blender/draw/engines/eevee/eevee_lightprobes.c | 12 +- source/blender/draw/engines/eevee/eevee_lights.c | 4 +- source/blender/draw/engines/eevee/eevee_lookdev.c | 2 +- .../blender/draw/engines/eevee/eevee_materials.c | 10 +- .../blender/draw/engines/eevee/eevee_motion_blur.c | 2 +- .../blender/draw/engines/eevee/eevee_occlusion.c | 2 +- source/blender/draw/engines/eevee/eevee_private.h | 4 +- .../draw/engines/eevee/eevee_screen_raytrace.c | 2 +- .../blender/draw/engines/eevee/eevee_subsurface.c | 2 +- .../draw/engines/external/external_engine.c | 2 +- .../draw/engines/workbench/workbench_deferred.c | 8 +- .../draw/engines/workbench/workbench_forward.c | 6 +- source/blender/draw/intern/DRW_render.h | 30 +- source/blender/draw/intern/draw_anim_viz.c | 26 +- source/blender/draw/intern/draw_armature.c | 16 +- source/blender/draw/intern/draw_cache.c | 1546 ++++++++++---------- source/blender/draw/intern/draw_cache.h | 209 ++- source/blender/draw/intern/draw_cache_impl.h | 104 +- source/blender/draw/intern/draw_cache_impl_curve.c | 260 ++-- .../blender/draw/intern/draw_cache_impl_displist.c | 98 +- .../blender/draw/intern/draw_cache_impl_lattice.c | 86 +- source/blender/draw/intern/draw_cache_impl_mesh.c | 1160 +++++++-------- .../blender/draw/intern/draw_cache_impl_metaball.c | 20 +- .../draw/intern/draw_cache_impl_particles.c | 304 ++-- source/blender/draw/intern/draw_common.c | 64 +- source/blender/draw/intern/draw_common.h | 30 +- source/blender/draw/intern/draw_debug.c | 38 +- source/blender/draw/intern/draw_hair_private.h | 18 +- source/blender/draw/intern/draw_instance_data.c | 68 +- source/blender/draw/intern/draw_instance_data.h | 8 +- source/blender/draw/intern/draw_manager.c | 76 +- source/blender/draw/intern/draw_manager.h | 24 +- source/blender/draw/intern/draw_manager_data.c | 126 +- source/blender/draw/intern/draw_manager_exec.c | 18 +- .../blender/draw/intern/draw_manager_profiling.c | 2 +- source/blender/draw/intern/draw_view.c | 44 +- source/blender/draw/modes/edit_curve_mode.c | 2 +- source/blender/draw/modes/edit_lattice_mode.c | 2 +- source/blender/draw/modes/edit_mesh_mode.c | 8 +- source/blender/draw/modes/edit_surface_mode.c | 2 +- source/blender/draw/modes/edit_text_mode.c | 2 +- source/blender/draw/modes/object_mode.c | 38 +- source/blender/draw/modes/overlay_mode.c | 2 +- source/blender/draw/modes/paint_texture_mode.c | 10 +- source/blender/draw/modes/paint_vertex_mode.c | 2 +- source/blender/draw/modes/paint_weight_mode.c | 2 +- source/blender/draw/modes/particle_mode.c | 6 +- source/blender/draw/modes/pose_mode.c | 2 +- .../editors/animation/anim_channels_defines.c | 12 +- source/blender/editors/animation/anim_draw.c | 16 +- source/blender/editors/animation/anim_markers.c | 8 +- source/blender/editors/animation/keyframes_draw.c | 20 +- source/blender/editors/curve/editcurve_paint.c | 16 +- .../editors/gizmo_library/gizmo_draw_utils.c | 34 +- .../gizmo_library/gizmo_types/arrow2d_gizmo.c | 6 +- .../gizmo_library/gizmo_types/arrow3d_gizmo.c | 8 +- .../gizmo_library/gizmo_types/button2d_gizmo.c | 18 +- .../gizmo_library/gizmo_types/cage2d_gizmo.c | 76 +- .../gizmo_library/gizmo_types/cage3d_gizmo.c | 12 +- .../gizmo_library/gizmo_types/dial3d_gizmo.c | 12 +- .../gizmo_library/gizmo_types/grab3d_gizmo.c | 6 +- .../gizmo_library/gizmo_types/primitive3d_gizmo.c | 6 +- source/blender/editors/gpencil/drawgpencil.c | 92 +- source/blender/editors/gpencil/gpencil_brush.c | 4 +- source/blender/editors/gpencil/gpencil_paint.c | 4 +- source/blender/editors/include/ED_keyframes_draw.h | 2 +- source/blender/editors/interface/interface_draw.c | 238 +-- source/blender/editors/interface/interface_icons.c | 26 +- .../editors/interface/interface_icons_event.c | 6 +- .../blender/editors/interface/interface_intern.h | 6 +- source/blender/editors/interface/interface_panel.c | 36 +- .../blender/editors/interface/interface_widgets.c | 168 +-- source/blender/editors/interface/view2d.c | 24 +- source/blender/editors/mask/mask_draw.c | 32 +- source/blender/editors/mesh/editmesh_knife.c | 26 +- source/blender/editors/mesh/editmesh_loopcut.c | 6 +- source/blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/screen/area.c | 50 +- source/blender/editors/screen/glutil.c | 16 +- source/blender/editors/screen/screen_draw.c | 30 +- source/blender/editors/sculpt_paint/paint_cursor.c | 34 +- source/blender/editors/sculpt_paint/paint_image.c | 8 +- source/blender/editors/sculpt_paint/paint_stroke.c | 8 +- source/blender/editors/sculpt_paint/sculpt_uv.c | 2 +- source/blender/editors/space_action/action_draw.c | 10 +- .../editors/space_clip/clip_dopesheet_draw.c | 18 +- source/blender/editors/space_clip/clip_draw.c | 74 +- .../blender/editors/space_clip/clip_graph_draw.c | 12 +- source/blender/editors/space_clip/clip_utils.c | 4 +- .../blender/editors/space_console/console_draw.c | 4 +- source/blender/editors/space_file/file_draw.c | 14 +- source/blender/editors/space_graph/graph_draw.c | 46 +- source/blender/editors/space_graph/space_graph.c | 6 +- source/blender/editors/space_image/image_draw.c | 16 +- source/blender/editors/space_info/textview.c | 12 +- source/blender/editors/space_nla/nla_draw.c | 38 +- source/blender/editors/space_node/drawnode.c | 124 +- source/blender/editors/space_node/node_draw.c | 22 +- .../blender/editors/space_outliner/outliner_draw.c | 42 +- .../editors/space_sequencer/sequencer_draw.c | 40 +- source/blender/editors/space_text/text_draw.c | 22 +- source/blender/editors/space_view3d/drawobject.c | 98 +- source/blender/editors/space_view3d/view3d_draw.c | 32 +- source/blender/editors/space_view3d/view3d_fly.c | 6 +- .../space_view3d/view3d_gizmo_navigate_type.c | 20 +- .../editors/space_view3d/view3d_gizmo_ruler.c | 14 +- .../blender/editors/space_view3d/view3d_intern.h | 2 +- source/blender/editors/space_view3d/view3d_ruler.c | 14 +- source/blender/editors/space_view3d/view3d_walk.c | 6 +- source/blender/editors/transform/transform.c | 32 +- .../editors/transform/transform_constraints.c | 6 +- .../blender/editors/transform/transform_generics.c | 4 +- source/blender/editors/transform/transform_snap.c | 6 +- source/blender/editors/util/ed_util.c | 4 +- source/blender/editors/uvedit/uvedit_draw.c | 124 +- .../blender/editors/uvedit/uvedit_smart_stitch.c | 88 +- source/blender/gpu/CMakeLists.txt | 2 +- source/blender/gpu/GPU_attr_binding.h | 14 +- source/blender/gpu/GPU_batch.h | 158 +- source/blender/gpu/GPU_batch_presets.h | 12 +- source/blender/gpu/GPU_batch_utils.h | 6 +- source/blender/gpu/GPU_buffer_id.h | 14 +- source/blender/gpu/GPU_buffers.h | 2 +- source/blender/gpu/GPU_common.h | 14 +- source/blender/gpu/GPU_context.h | 20 +- source/blender/gpu/GPU_element.h | 68 +- source/blender/gpu/GPU_immediate.h | 14 +- source/blender/gpu/GPU_immediate_util.h | 4 +- source/blender/gpu/GPU_matrix.h | 4 +- source/blender/gpu/GPU_primitive.h | 50 +- source/blender/gpu/GPU_shader_interface.h | 96 +- source/blender/gpu/GPU_texture.h | 4 +- source/blender/gpu/GPU_vertex_array_id.h | 14 +- source/blender/gpu/GPU_vertex_buffer.h | 88 +- source/blender/gpu/GPU_vertex_format.h | 86 +- source/blender/gpu/intern/gpu_attr_binding.c | 26 +- .../blender/gpu/intern/gpu_attr_binding_private.h | 16 +- source/blender/gpu/intern/gpu_batch.c | 240 +-- source/blender/gpu/intern/gpu_batch_presets.c | 76 +- source/blender/gpu/intern/gpu_batch_private.h | 16 +- source/blender/gpu/intern/gpu_batch_utils.c | 54 +- source/blender/gpu/intern/gpu_buffer_id.cpp | 8 +- source/blender/gpu/intern/gpu_buffers.c | 154 +- source/blender/gpu/intern/gpu_codegen.c | 2 +- source/blender/gpu/intern/gpu_element.c | 120 +- source/blender/gpu/intern/gpu_immediate.c | 170 +-- source/blender/gpu/intern/gpu_immediate_util.c | 50 +- source/blender/gpu/intern/gpu_matrix.c | 14 +- source/blender/gpu/intern/gpu_primitive.c | 60 +- source/blender/gpu/intern/gpu_primitive_private.h | 12 +- source/blender/gpu/intern/gpu_shader.c | 20 +- source/blender/gpu/intern/gpu_shader_interface.c | 154 +- source/blender/gpu/intern/gpu_shader_private.h | 2 +- source/blender/gpu/intern/gpu_texture.c | 20 +- source/blender/gpu/intern/gpu_vertex_array_id.cpp | 40 +- source/blender/gpu/intern/gpu_vertex_buffer.c | 98 +- source/blender/gpu/intern/gpu_vertex_format.c | 96 +- .../blender/gpu/intern/gpu_vertex_format_private.h | 14 +- source/blender/gpu/intern/gpu_viewport.c | 4 +- source/blender/makesdna/DNA_action_types.h | 6 +- source/blender/makesdna/DNA_windowmanager_types.h | 2 +- source/blender/python/CMakeLists.txt | 2 +- source/blender/python/gawain/CMakeLists.txt | 47 - source/blender/python/gawain/gwn_py_api.c | 63 - source/blender/python/gawain/gwn_py_api.h | 30 - source/blender/python/gawain/gwn_py_types.c | 847 ----------- source/blender/python/gawain/gwn_py_types.h | 67 - source/blender/python/gpu/CMakeLists.txt | 46 + source/blender/python/gpu/gpu_py_api.c | 63 + source/blender/python/gpu/gpu_py_api.h | 30 + source/blender/python/gpu/gpu_py_types.c | 847 +++++++++++ source/blender/python/gpu/gpu_py_types.h | 67 + source/blender/python/intern/bpy_interface.c | 4 +- source/blender/render/extern/include/RE_pipeline.h | 2 +- .../blender/render/intern/include/render_types.h | 2 +- source/blender/render/intern/source/pipeline.c | 16 +- source/blender/windowmanager/intern/wm_draw.c | 4 +- source/blender/windowmanager/intern/wm_files.c | 4 +- source/blender/windowmanager/intern/wm_gesture.c | 18 +- source/blender/windowmanager/intern/wm_operators.c | 16 +- source/blender/windowmanager/intern/wm_playanim.c | 16 +- source/blender/windowmanager/intern/wm_stereo.c | 24 +- source/blender/windowmanager/intern/wm_window.c | 12 +- 201 files changed, 5517 insertions(+), 5547 deletions(-) delete mode 100644 source/blender/python/gawain/CMakeLists.txt delete mode 100644 source/blender/python/gawain/gwn_py_api.c delete mode 100644 source/blender/python/gawain/gwn_py_api.h delete mode 100644 source/blender/python/gawain/gwn_py_types.c delete mode 100644 source/blender/python/gawain/gwn_py_types.h create mode 100644 source/blender/python/gpu/CMakeLists.txt create mode 100644 source/blender/python/gpu/gpu_py_api.c create mode 100644 source/blender/python/gpu/gpu_py_api.h create mode 100644 source/blender/python/gpu/gpu_py_types.c create mode 100644 source/blender/python/gpu/gpu_py_types.h diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index b2ec8f6e7a9..0ceaee08e64 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -621,7 +621,7 @@ function(SETUP_BLENDER_SORTED_LIBS) bf_python bf_python_ext bf_python_mathutils - bf_python_gawain + bf_python_gpu bf_python_bmesh bf_freestyle bf_ikplugin diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 10acdb9d281..78c73a6e3bf 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -98,7 +98,7 @@ typedef struct OCIO_GLSLShader { GLuint ocio_shader; GLuint vert_shader; GLuint program; - Gwn_ShaderInterface *shader_interface; + GPUShaderInterface *shader_interface; } GLSLDrawState; typedef struct OCIO_GLSLDrawState { @@ -251,7 +251,7 @@ static void freeGLSLShader(OCIO_GLSLShader *shader) } if (shader->shader_interface) { - GWN_shaderinterface_discard(shader->shader_interface); + GPU_shaderinterface_discard(shader->shader_interface); } if (shader->ocio_shader) { @@ -424,9 +424,9 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc if (shader->program) { if (shader->shader_interface) { - GWN_shaderinterface_discard(shader->shader_interface); + GPU_shaderinterface_discard(shader->shader_interface); } - shader->shader_interface = GWN_shaderinterface_create(shader->program); + shader->shader_interface = GPU_shaderinterface_create(shader->program); } } } @@ -461,9 +461,9 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc * * TODO(sergey): Look into some nicer solution. */ - Gwn_VertFormat *format = immVertexFormat(); - GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindProgram(shader->program, shader->shader_interface); immUniform1i("image_texture", 0); diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index f4fd188c641..d6d4ecd6fce 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -587,7 +587,7 @@ class Gizmo(StructRNA): _rna_gizmo_target_get_range as target_get_range, ) - # Convenience wrappers around private `_gawain` module. + # Convenience wrappers around private `_gpu` module. def draw_custom_shape(self, shape, *, matrix=None, select_id=None): """ Draw a shape created form :class:`bpy.types.Gizmo.draw_custom_shape`. @@ -638,19 +638,19 @@ class Gizmo(StructRNA): :return: The newly created shape. :rtype: Undefined (it may change). """ - from _gawain.types import ( - Gwn_Batch, - Gwn_VertBuf, - Gwn_VertFormat, + from _gpu.types import ( + GPUBatch, + GPUVertBuf, + GPUVertFormat, ) dims = len(verts[0]) if dims not in {2, 3}: raise ValueError("Expected 2D or 3D vertex") - fmt = Gwn_VertFormat() + fmt = GPUVertFormat() pos_id = fmt.attr_add(id="pos", comp_type='F32', len=dims, fetch_mode='FLOAT') - vbo = Gwn_VertBuf(len=len(verts), format=fmt) + vbo = GPUVertBuf(len=len(verts), format=fmt) vbo.fill(id=pos_id, data=verts) - batch = Gwn_Batch(type=type, buf=vbo) + batch = GPUBatch(type=type, buf=vbo) return (batch, dims) diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 3f4c430ee4b..ea81106e60f 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -91,31 +91,31 @@ static SpinLock ft_lib_mutex; **/ static void blf_batch_draw_init(void) { - Gwn_VertFormat format = {0}; - g_batch.pos_loc = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - g_batch.tex_loc = GWN_vertformat_attr_add(&format, "tex", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - g_batch.col_loc = GWN_vertformat_attr_add(&format, "col", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat format = {0}; + g_batch.pos_loc = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + g_batch.tex_loc = GPU_vertformat_attr_add(&format, "tex", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + g_batch.col_loc = GPU_vertformat_attr_add(&format, "col", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - g_batch.verts = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STREAM); - GWN_vertbuf_data_alloc(g_batch.verts, BLF_BATCH_DRAW_LEN_MAX); + g_batch.verts = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STREAM); + GPU_vertbuf_data_alloc(g_batch.verts, BLF_BATCH_DRAW_LEN_MAX); - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step); - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step); g_batch.glyph_len = 0; - g_batch.batch = GWN_batch_create_ex(GWN_PRIM_POINTS, g_batch.verts, NULL, GWN_BATCH_OWNS_VBO); + g_batch.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, g_batch.verts, NULL, GPU_BATCH_OWNS_VBO); } static void blf_batch_draw_exit(void) { - GWN_BATCH_DISCARD_SAFE(g_batch.batch); + GPU_BATCH_DISCARD_SAFE(g_batch.batch); } void blf_batch_draw_vao_clear(void) { if (g_batch.batch) { - gwn_batch_vao_cache_clear(g_batch.batch); + GPU_batch_vao_cache_clear(g_batch.batch); } } @@ -190,20 +190,20 @@ void blf_batch_draw(void) UI_widgetbase_draw_cache_flush(); GPU_texture_bind(g_batch.tex_bind_state, 0); - GWN_vertbuf_vertex_count_set(g_batch.verts, g_batch.glyph_len); - GWN_vertbuf_use(g_batch.verts); /* send data */ + GPU_vertbuf_vertex_count_set(g_batch.verts, g_batch.glyph_len); + GPU_vertbuf_use(g_batch.verts); /* send data */ GPUBuiltinShader shader = (g_batch.simple_shader) ? GPU_SHADER_TEXT_SIMPLE : GPU_SHADER_TEXT; - GWN_batch_program_set_builtin(g_batch.batch, shader); - GWN_batch_uniform_1i(g_batch.batch, "glyph", 0); - GWN_batch_draw(g_batch.batch); + GPU_batch_program_set_builtin(g_batch.batch, shader); + GPU_batch_uniform_1i(g_batch.batch, "glyph", 0); + GPU_batch_draw(g_batch.batch); GPU_blend(false); /* restart to 1st vertex data pointers */ - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step); - GWN_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step); + GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step); g_batch.glyph_len = 0; } diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 8dc11443124..30e31bb2580 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -382,10 +382,10 @@ static void blf_texture_draw(const unsigned char color[4], const float uv[2][2], { /* Only one vertex per glyph, geometry shader expand it into a quad. */ /* TODO Get rid of Geom Shader because it's not optimal AT ALL for the GPU */ - copy_v4_fl4(GWN_vertbuf_raw_step(&g_batch.pos_step), x1 + g_batch.ofs[0], y1 + g_batch.ofs[1], + copy_v4_fl4(GPU_vertbuf_raw_step(&g_batch.pos_step), x1 + g_batch.ofs[0], y1 + g_batch.ofs[1], x2 + g_batch.ofs[0], y2 + g_batch.ofs[1]); - copy_v4_v4(GWN_vertbuf_raw_step(&g_batch.tex_step), (float *)uv); - copy_v4_v4_uchar(GWN_vertbuf_raw_step(&g_batch.col_step), color); + copy_v4_v4(GPU_vertbuf_raw_step(&g_batch.tex_step), (float *)uv); + copy_v4_v4_uchar(GPU_vertbuf_raw_step(&g_batch.col_step), color); g_batch.glyph_len++; /* Flush cache if it's full. */ if (g_batch.glyph_len == BLF_BATCH_DRAW_LEN_MAX) { diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index 03bf7fa67d8..265835f4c75 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -38,9 +38,9 @@ typedef struct BatchBLF { struct FontBLF *font; /* can only batch glyph from the same font */ - struct Gwn_Batch *batch; - struct Gwn_VertBuf *verts; - struct Gwn_VertBufRaw pos_step, tex_step, col_step; + struct GPUBatch *batch; + struct GPUVertBuf *verts; + struct GPUVertBufRaw pos_step, tex_step, col_step; unsigned int pos_loc, tex_loc, col_loc; unsigned int glyph_len; float ofs[2]; /* copy of font->pos */ diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index b16e8c17a12..9e8e7f7b724 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -153,7 +153,7 @@ char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, char *base_path); /* ************************************* */ -/* Gwn_Batch AnimData API */ +/* GPUBatch AnimData API */ /* Define for callback looper used in BKE_animdata_main_cb */ typedef void (*ID_AnimData_Edit_Callback)(struct ID *id, struct AnimData *adt, void *user_data); diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 78c766f6115..095f442ca50 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -30,7 +30,7 @@ #include "BLI_ghash.h" #include "BLI_utildefines.h" -struct Gwn_Batch; +struct GPUBatch; struct CCGElem; struct CCGKey; struct CCGDerivedMesh; @@ -131,7 +131,7 @@ bool BKE_pbvh_node_find_nearest_to_ray( void BKE_pbvh_draw_cb( PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, - void (*draw_fn)(void *user_data, struct Gwn_Batch *batch), void *user_data); + void (*draw_fn)(void *user_data, struct GPUBatch *batch), void *user_data); /* PBVH Access */ typedef enum { diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 07b8b69bc70..eed8943cd5b 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -114,9 +114,9 @@ void animviz_free_motionpath_cache(bMotionPath *mpath) if (mpath->points) MEM_freeN(mpath->points); - GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo); - GWN_BATCH_DISCARD_SAFE(mpath->batch_line); - GWN_BATCH_DISCARD_SAFE(mpath->batch_points); + GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo); + GPU_BATCH_DISCARD_SAFE(mpath->batch_line); + GPU_BATCH_DISCARD_SAFE(mpath->batch_points); /* reset the relevant parameters */ mpath->points = NULL; @@ -495,9 +495,9 @@ static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets) BLI_dlrbTree_free(&mpt->keys); /* Free previous batches to force update. */ - GWN_VERTBUF_DISCARD_SAFE(mpath->points_vbo); - GWN_BATCH_DISCARD_SAFE(mpath->batch_line); - GWN_BATCH_DISCARD_SAFE(mpath->batch_points); + GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo); + GPU_BATCH_DISCARD_SAFE(mpath->batch_line); + GPU_BATCH_DISCARD_SAFE(mpath->batch_points); } } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ccef747a31c..caf5b94b30e 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -924,7 +924,7 @@ static void cloth_from_mesh ( ClothModifierData *clmd, Mesh *mesh ) } /*************************************************************************************** - * SPRING NETWORK GWN_BATCH_BUILDING IMPLEMENTATION BEGIN + * SPRING NETWORK GPU_BATCH_BUILDING IMPLEMENTATION BEGIN ***************************************************************************************/ BLI_INLINE void spring_verts_ordered_set(ClothSpring *spring, int v0, int v1) @@ -1506,5 +1506,5 @@ static int cloth_build_springs ( ClothModifierData *clmd, Mesh *mesh ) } /* cloth_build_springs */ /*************************************************************************************** - * SPRING NETWORK GWN_BATCH_BUILDING IMPLEMENTATION END + * SPRING NETWORK GPU_BATCH_BUILDING IMPLEMENTATION END ***************************************************************************************/ diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 0a4cd3ec3c1..3e7a9b7ce24 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2077,7 +2077,7 @@ static void pbvh_node_check_mask_changed(PBVH *bvh, PBVHNode *node) struct PBVHNodeDrawCallbackData { - void (*draw_fn)(void *user_data, Gwn_Batch *batch); + void (*draw_fn)(void *user_data, GPUBatch *batch); void *user_data; bool fast; }; @@ -2087,7 +2087,7 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v) struct PBVHNodeDrawCallbackData *data = data_v; if (!(node->flag & PBVH_FullyHidden)) { - Gwn_Batch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast); + GPUBatch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast); if (triangles != NULL) { data->draw_fn(data->user_data, triangles); } @@ -2099,7 +2099,7 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v) */ void BKE_pbvh_draw_cb( PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, - void (*draw_fn)(void *user_data, Gwn_Batch *batch), void *user_data) + void (*draw_fn)(void *user_data, GPUBatch *batch), void *user_data) { struct PBVHNodeDrawCallbackData draw_data = { .fast = fast, diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 18a6198254e..ab94b5334bd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7018,7 +7018,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) direct_link_area_map(fd, &win->global_areas); win->ghostwin = NULL; - win->gwnctx = NULL; + win->gpuctx = NULL; win->eventstate = NULL; win->cursor_keymap_status = NULL; win->tweak = NULL; diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index ab2001dcb6a..eb037d081e1 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -138,8 +138,8 @@ void DRW_opengl_context_disable(void); void DRW_opengl_render_context_enable(void *re_gl_context); void DRW_opengl_render_context_disable(void *re_gl_context); -void DRW_gawain_render_context_enable(void *re_gwn_context); -void DRW_gawain_render_context_disable(void *re_gwn_context); +void DRW_gawain_render_context_enable(void *re_gpu_context); +void DRW_gawain_render_context_disable(void *re_gpu_context); void DRW_deferred_shader_remove(struct GPUMaterial *mat); diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 5a315cde2b5..a9c758d5b6f 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -160,13 +160,13 @@ static void basic_cache_populate(void *vedata, Object *ob) ParticleSettings *part = psys->part; const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as; if (draw_as == PART_DRAW_PATH) { - struct Gwn_Batch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL); + struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL); DRW_shgroup_call_add(stl->g_data->depth_shgrp, hairs, NULL); } } } - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { bool do_cull = false; /* TODO (we probably wan't to take this from the viewport?) */ #ifdef USE_DEPTH diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c index 2ec6f841409..d111c28b256 100644 --- a/source/blender/draw/engines/eevee/eevee_bloom.c +++ b/source/blender/draw/engines/eevee/eevee_bloom.c @@ -196,7 +196,7 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) static DRWShadingGroup *eevee_create_bloom_pass( const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample) { - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); *pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR); diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index b9f7624552c..cb54ad3a164 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -192,7 +192,7 @@ void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_ * - Finally composite the 2 blurred buffers with the original render. **/ DRWShadingGroup *grp; - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); psl->dof_down = DRW_pass_create("DoF Downsample", DRW_STATE_WRITE_COLOR); diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index d7a978066d5..28658d5126c 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -302,7 +302,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) downsample_write = DRW_STATE_WRITE_COLOR; } - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); { psl->color_downsample_ps = DRW_pass_create( diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index a6d11f1edac..4f5ad5159cf 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -83,8 +83,8 @@ extern void DRW_opengl_context_disable(void); extern void DRW_opengl_render_context_enable(void *re_gl_context); extern void DRW_opengl_render_context_disable(void *re_gl_context); -extern void DRW_gawain_render_context_enable(void *re_gwn_context); -extern void DRW_gawain_render_context_disable(void *re_gwn_context); +extern void DRW_gawain_render_context_enable(void *re_gpu_context); +extern void DRW_gawain_render_context_disable(void *re_gpu_context); typedef struct EEVEE_LightBake { Depsgraph *depsgraph; @@ -144,7 +144,7 @@ typedef struct EEVEE_LightBake { bool own_light_cache; /* If the lightcache was created for baking, it's first owned by the baker. */ int delay; /* ms. delay the start of the baking to not slowdown interactions (TODO remove) */ - void *gl_context, *gwn_context; /* If running in parallel (in a separate thread), use this context. */ + void *gl_context, *gpu_context; /* If running in parallel (in a separate thread), use this context. */ } EEVEE_LightBake; /* -------------------------------------------------------------------- */ @@ -369,10 +369,10 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake) { if (lbake->gl_context) { DRW_opengl_render_context_enable(lbake->gl_context); - if (lbake->gwn_context == NULL) { - lbake->gwn_context = GWN_context_create(); + if (lbake->gpu_context == NULL) { + lbake->gpu_context = GPU_context_create(); } - DRW_gawain_render_context_enable(lbake->gwn_context); + DRW_gawain_render_context_enable(lbake->gpu_context); } else { DRW_opengl_context_enable(); @@ -382,7 +382,7 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake) static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake) { if (lbake->gl_context) { - DRW_gawain_render_context_disable(lbake->gwn_context); + DRW_gawain_render_context_disable(lbake->gpu_context); DRW_opengl_render_context_disable(lbake->gl_context); } else { @@ -586,7 +586,7 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake) { if (lbake->gl_context) { DRW_opengl_render_context_enable(lbake->gl_context); - DRW_gawain_render_context_enable(lbake->gwn_context); + DRW_gawain_render_context_enable(lbake->gpu_context); } else if (!lbake->resource_only) { DRW_opengl_context_enable(); @@ -605,17 +605,17 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake) GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]); } - if (lbake->gwn_context) { - DRW_gawain_render_context_disable(lbake->gwn_context); - DRW_gawain_render_context_enable(lbake->gwn_context); - GWN_context_discard(lbake->gwn_context); + if (lbake->gpu_context) { + DRW_gawain_render_context_disable(lbake->gpu_context); + DRW_gawain_render_context_enable(lbake->gpu_context); + GPU_context_discard(lbake->gpu_context); } if (lbake->gl_context && lbake->own_resources) { /* Delete the baking context. */ DRW_opengl_render_context_disable(lbake->gl_context); WM_opengl_context_dispose(lbake->gl_context); - lbake->gwn_context = NULL; + lbake->gpu_context = NULL; lbake->gl_context = NULL; } else if (lbake->gl_context) { diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 1b341aced07..691d6ffe6eb 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -74,8 +74,8 @@ static struct { struct GPUTexture *depth_array_placeholder; struct GPUTexture *cube_face_minmaxz; - struct Gwn_VertFormat *format_probe_display_cube; - struct Gwn_VertFormat *format_probe_display_planar; + struct GPUVertFormat *format_probe_display_cube; + struct GPUVertFormat *format_probe_display_planar; } e_data = {NULL}; /* Engine data */ extern char datatoc_background_vert_glsl[]; @@ -395,7 +395,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); } @@ -414,7 +414,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); } @@ -424,7 +424,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_fill_sh, psl->probe_grid_fill); DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &light_cache->grid_tx.tex); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); } } @@ -447,7 +447,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat { psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; Scene *scene = draw_ctx->scene; diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index dc9ce29a148..2c970fa5285 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -425,7 +425,7 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) /* Add a shadow caster to the shadowpasses */ void EEVEE_lights_cache_shcaster_add( - EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_StorageList *stl, struct Gwn_Batch *geom, Object *ob) + EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_StorageList *stl, struct GPUBatch *geom, Object *ob) { DRW_shgroup_call_object_add( stl->g_data->shadow_shgrp, @@ -434,7 +434,7 @@ void EEVEE_lights_cache_shcaster_add( void EEVEE_lights_cache_shcaster_material_add( EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_PassList *psl, struct GPUMaterial *gpumat, - struct Gwn_Batch *geom, struct Object *ob, float *alpha_threshold) + struct GPUBatch *geom, struct Object *ob, float *alpha_threshold) { /* TODO / PERF : reuse the same shading group for objects with the same material */ DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->shadow_pass); diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c index 2e568d97c07..345a28590c6 100644 --- a/source/blender/draw/engines/eevee/eevee_lookdev.c +++ b/source/blender/draw/engines/eevee/eevee_lookdev.c @@ -60,7 +60,7 @@ void EEVEE_lookdev_cache_init( if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) { StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE); if (sl && (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) { - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); GPUTexture *tex = NULL; /* If one of the component is missing we start from scratch. */ diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 20d755d2245..39f7443145f 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -135,7 +135,7 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h)) DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut"); @@ -197,7 +197,7 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h) DRW_shgroup_uniform_texture(grp, "texHammersley", hammersley); DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut"); @@ -946,7 +946,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { psl->background_pass = DRW_pass_create("Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = NULL; const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -1477,7 +1477,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld char *auto_layer_names; int *auto_layer_is_srgb; int auto_layer_count; - struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get( + struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get( ob, gpumat_array, materials_len, &auto_layer_names, &auto_layer_is_srgb, @@ -1690,7 +1690,7 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata) if (LOOK_DEV_OVERLAY_ENABLED(v3d)) { EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); EEVEE_LampsInfo *linfo = sldata->lamps; - struct Gwn_Batch *sphere = DRW_cache_sphere_get(); + struct GPUBatch *sphere = DRW_cache_sphere_get(); static float mat1[4][4]; static float color[3] = {0.8f, 0.8f, 0.8f}; static float metallic_on = 1.0f; diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 6dabc8f91cb..08745850bd4 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -178,7 +178,7 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat EEVEE_EffectsInfo *effects = stl->effects; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) { psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR); diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index f39fbe33a71..8ede22cda5a 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -183,7 +183,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_EffectsInfo *effects = stl->effects; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); if ((effects->enabled_effects & EFFECT_GTAO) != 0) { /** Occlusion algorithm overview diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 1e43d6fba08..6ef24d03df8 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -815,10 +815,10 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata); void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, struct Object *ob); void EEVEE_lights_cache_shcaster_add( - EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, struct Gwn_Batch *geom, Object *ob); + EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, struct GPUBatch *geom, Object *ob); void EEVEE_lights_cache_shcaster_material_add( EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, - struct GPUMaterial *gpumat, struct Gwn_Batch *geom, struct Object *ob, + struct GPUMaterial *gpumat, struct GPUBatch *geom, struct Object *ob, float *alpha_threshold); void EEVEE_lights_cache_shcaster_object_add(EEVEE_ViewLayerData *sldata, struct Object *ob); void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index ef949c32eed..204b730f8da 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -189,7 +189,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; LightCache *lcache = stl->g_data->light_cache; - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); if ((effects->enabled_effects & EFFECT_SSR) != 0) { int options = (effects->reflection_trace_full) ? SSR_FULL_TRACE : 0; diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index 6ee3b9cc286..9667f2ac9d7 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -204,7 +204,7 @@ void EEVEE_subsurface_add_pass( EEVEE_PassList *psl = vedata->psl; EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[0], psl->sss_blur_ps); DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 35ff777b885..b2c30ba723c 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -128,7 +128,7 @@ static void external_cache_populate(void *vedata, Object *ob) if (!DRW_object_is_renderable(ob)) return; - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { /* Depth Prepass */ DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat); diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 0ad755049b1..cf53004e126 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -678,7 +678,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) if (me->mloopuv) { const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len); - struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; + struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; if (materials_len > 0 && geom_array) { for (int i = 0; i < materials_len; i++) { if (geom_array[i] == NULL) { @@ -701,7 +701,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) if (!is_drawn) { if (ELEM(wpd->shading.color_type, V3D_SHADING_SINGLE_COLOR, V3D_SHADING_RANDOM_COLOR)) { /* No material split needed */ - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type); if (is_sculpt_mode) { @@ -719,7 +719,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) gpumat_array[i] = NULL; } - struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get( + struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get( ob, gpumat_array, materials_len, NULL, NULL, NULL); if (mat_geom) { for (int i = 0; i < materials_len; ++i) { @@ -742,7 +742,7 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) if (SHADOW_ENABLED(wpd) && (ob->display.flag & OB_SHOW_SHADOW)) { bool is_manifold; - struct Gwn_Batch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold); + struct GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold); if (geom_shadow) { if (is_sculpt_mode) { /* Currently unsupported in sculpt mode. We could revert to the slow diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index e0e0bdea0f5..2a65feeb28c 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -483,7 +483,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) if (me->mloopuv) { const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol)); struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len); - struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; + struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; if (materials_len > 0 && geom_array) { for (int i = 0; i < materials_len; i++) { if (geom_array[i] == NULL) { @@ -516,7 +516,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) if (!is_drawn) { if (ELEM(wpd->shading.color_type, V3D_SHADING_SINGLE_COLOR, V3D_SHADING_RANDOM_COLOR)) { /* No material split needed */ - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type); if (is_sculpt_mode) { @@ -536,7 +536,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) gpumat_array[i] = NULL; } - struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get( + struct GPUBatch **mat_geom = DRW_cache_object_surface_material_get( ob, gpumat_array, materials_len, NULL, NULL, NULL); if (mat_geom) { for (int i = 0; i < materials_len; ++i) { diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 16a17f4f21d..adcfe2524c7 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -71,7 +71,7 @@ struct GPUMaterial; struct GPUTexture; struct GPUUniformBuffer; struct Object; -struct Gwn_Batch; +struct GPUBatch; struct DefaultFramebufferList; struct DefaultTextureList; struct DRWTextStore; @@ -306,7 +306,7 @@ typedef struct DRWInstanceAttribFormat { int components; } DRWInstanceAttribFormat; -struct Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize); +struct GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize); #define DRW_shgroup_instance_format(format, ...) do { \ if (format == NULL) { \ DRWInstanceAttribFormat drw_format[] = __VA_ARGS__;\ @@ -317,25 +317,25 @@ struct Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrib DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass); DRWShadingGroup *DRW_shgroup_material_instance_create( - struct GPUMaterial *material, DRWPass *pass, struct Gwn_Batch *geom, struct Object *ob, - struct Gwn_VertFormat *format); + struct GPUMaterial *material, DRWPass *pass, struct GPUBatch *geom, struct Object *ob, + struct GPUVertFormat *format); DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial *material, DRWPass *pass, int size); DRWShadingGroup *DRW_shgroup_instance_create( - struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom, struct Gwn_VertFormat *format); + struct GPUShader *shader, DRWPass *pass, struct GPUBatch *geom, struct GPUVertFormat *format); DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_line_batch_create_with_format( - struct GPUShader *shader, DRWPass *pass, struct Gwn_VertFormat *format); + struct GPUShader *shader, DRWPass *pass, struct GPUVertFormat *format); DRWShadingGroup *DRW_shgroup_line_batch_create( struct GPUShader *shader, DRWPass *pass); DRWShadingGroup *DRW_shgroup_empty_tri_batch_create( struct GPUShader *shader, DRWPass *pass, int size); DRWShadingGroup *DRW_shgroup_transform_feedback_create( - struct GPUShader *shader, DRWPass *pass, struct Gwn_VertBuf *tf_target); + struct GPUShader *shader, DRWPass *pass, struct GPUVertBuf *tf_target); typedef void (DRWCallGenerateFn)( DRWShadingGroup *shgroup, - void (*draw_fn)(DRWShadingGroup *shgroup, struct Gwn_Batch *geom), + void (*draw_fn)(DRWShadingGroup *shgroup, struct GPUBatch *geom), void *user_data); /* return final visibility */ @@ -343,27 +343,27 @@ typedef bool (DRWCallVisibilityFn)( bool vis_in, void *user_data); -void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batch); +void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct GPUBatch *batch); void DRW_shgroup_free(struct DRWShadingGroup *shgroup); -void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4]); +void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct GPUBatch *geom, float (*obmat)[4]); void DRW_shgroup_call_range_add( - DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4], uint v_sta, uint v_count); + DRWShadingGroup *shgroup, struct GPUBatch *geom, float (*obmat)[4], uint v_sta, uint v_count); void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, uint point_len, float (*obmat)[4]); void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, uint line_count, float (*obmat)[4]); void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tria_count, float (*obmat)[4]); void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *shgroup, uint tria_count, struct Object *ob); -void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob, bool bypass_culling); +void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, bool bypass_culling); #define DRW_shgroup_call_object_add(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, false) #define DRW_shgroup_call_object_add_no_cull(shgroup, geom, ob) DRW_shgroup_call_object_add_ex(shgroup, geom, ob, true) void DRW_shgroup_call_object_add_with_callback( - DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob, + DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, DRWCallVisibilityFn *callback, void *user_data); /* Used for drawing a batch with instancing without instance attribs. */ void DRW_shgroup_call_instances_add( - DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4], uint *count); + DRWShadingGroup *shgroup, struct GPUBatch *geom, float (*obmat)[4], uint *count); void DRW_shgroup_call_object_instances_add( - DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob, uint *count); + DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, uint *count); void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, struct Object *ob, float (*obmat)[4]); void DRW_shgroup_call_generate_add( DRWShadingGroup *shgroup, DRWCallGenerateFn *geometry_fn, void *user_data, float (*obmat)[4]); diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c index e634710980a..95894783cfe 100644 --- a/source/blender/draw/intern/draw_anim_viz.c +++ b/source/blender/draw/intern/draw_anim_viz.c @@ -98,36 +98,36 @@ struct { /* *************************** Path Cache *********************************** */ /* Just convert the CPU cache to GPU cache. */ -static Gwn_VertBuf *mpath_vbo_get(bMotionPath *mpath) +static GPUVertBuf *mpath_vbo_get(bMotionPath *mpath) { if (!mpath->points_vbo) { - Gwn_VertFormat format = {0}; + GPUVertFormat format = {0}; /* Match structure of bMotionPathVert. */ - uint pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - GWN_vertformat_attr_add(&format, "flag", GWN_COMP_I32, 1, GWN_FETCH_INT); - mpath->points_vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(mpath->points_vbo, mpath->length); + uint pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "flag", GPU_COMP_I32, 1, GPU_FETCH_INT); + mpath->points_vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(mpath->points_vbo, mpath->length); /* meh... a useless memcpy. */ - Gwn_VertBufRaw raw_data; - GWN_vertbuf_attr_get_raw_data(mpath->points_vbo, pos, &raw_data); - memcpy(GWN_vertbuf_raw_step(&raw_data), mpath->points, sizeof(bMotionPathVert) * mpath->length); + GPUVertBufRaw raw_data; + GPU_vertbuf_attr_get_raw_data(mpath->points_vbo, pos, &raw_data); + memcpy(GPU_vertbuf_raw_step(&raw_data), mpath->points, sizeof(bMotionPathVert) * mpath->length); } return mpath->points_vbo; } -static Gwn_Batch *mpath_batch_line_get(bMotionPath *mpath) +static GPUBatch *mpath_batch_line_get(bMotionPath *mpath) { if (!mpath->batch_line) { - mpath->batch_line = GWN_batch_create(GWN_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL); + mpath->batch_line = GPU_batch_create(GPU_PRIM_LINE_STRIP, mpath_vbo_get(mpath), NULL); } return mpath->batch_line; } -static Gwn_Batch *mpath_batch_points_get(bMotionPath *mpath) +static GPUBatch *mpath_batch_points_get(bMotionPath *mpath) { if (!mpath->batch_points) { - mpath->batch_points = GWN_batch_create(GWN_PRIM_POINTS, mpath_vbo_get(mpath), NULL); + mpath->batch_points = GPU_batch_create(GPU_PRIM_POINTS, mpath_vbo_get(mpath), NULL); } return mpath->batch_points; } diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 9bc8b70b67c..b49ca4d0d00 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -134,11 +134,11 @@ static void drw_shgroup_bone_octahedral( const float bone_color[4], const float hint_color[4], const float outline_color[4]) { if (g_data.bone_octahedral_outline == NULL) { - struct Gwn_Batch *geom = DRW_cache_bone_octahedral_wire_get(); + struct GPUBatch *geom = DRW_cache_bone_octahedral_wire_get(); g_data.bone_octahedral_outline = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom); } if (g_data.bone_octahedral_solid == NULL) { - struct Gwn_Batch *geom = DRW_cache_bone_octahedral_get(); + struct GPUBatch *geom = DRW_cache_bone_octahedral_get(); g_data.bone_octahedral_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom); } float final_bonemat[4][4]; @@ -155,11 +155,11 @@ static void drw_shgroup_bone_box( const float bone_color[4], const float hint_color[4], const float outline_color[4]) { if (g_data.bone_box_wire == NULL) { - struct Gwn_Batch *geom = DRW_cache_bone_box_wire_get(); + struct GPUBatch *geom = DRW_cache_bone_box_wire_get(); g_data.bone_box_outline = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom); } if (g_data.bone_box_solid == NULL) { - struct Gwn_Batch *geom = DRW_cache_bone_box_get(); + struct GPUBatch *geom = DRW_cache_bone_box_get(); g_data.bone_box_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom); } float final_bonemat[4][4]; @@ -319,9 +319,9 @@ static void drw_shgroup_bone_custom_solid( Object *custom) { /* grr, not re-using instances! */ - struct Gwn_Batch *surf = DRW_cache_object_surface_get(custom); - struct Gwn_Batch *edges = DRW_cache_object_edge_detection_get(custom, NULL); - struct Gwn_Batch *ledges = DRW_cache_object_loose_edges_get(custom); + struct GPUBatch *surf = DRW_cache_object_surface_get(custom); + struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL); + struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom); float final_bonemat[4][4]; if (surf || edges || ledges) { @@ -352,7 +352,7 @@ static void drw_shgroup_bone_custom_wire( const float color[4], Object *custom) { /* grr, not re-using instances! */ - struct Gwn_Batch *geom = DRW_cache_object_wire_outline_get(custom); + struct GPUBatch *geom = DRW_cache_object_wire_outline_get(custom); if (geom) { DRWShadingGroup *shgrp_geom_wire = shgroup_instance_wire(g_data.passes.bone_wire, geom); float final_bonemat[4][4], final_color[4]; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index d23b9e693ce..bb73a8c1b19 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -47,85 +47,85 @@ /* Batch's only (free'd as an array) */ static struct DRWShapeCache { - Gwn_Batch *drw_single_vertice; - Gwn_Batch *drw_cursor; - Gwn_Batch *drw_cursor_only_circle; - Gwn_Batch *drw_fullscreen_quad; - Gwn_Batch *drw_fullscreen_quad_texcoord; - Gwn_Batch *drw_quad; - Gwn_Batch *drw_sphere; - Gwn_Batch *drw_screenspace_circle; - Gwn_Batch *drw_plain_axes; - Gwn_Batch *drw_single_arrow; - Gwn_Batch *drw_cube; - Gwn_Batch *drw_circle; - Gwn_Batch *drw_square; - Gwn_Batch *drw_line; - Gwn_Batch *drw_line_endpoints; - Gwn_Batch *drw_empty_cube; - Gwn_Batch *drw_empty_sphere; - Gwn_Batch *drw_empty_cylinder; - Gwn_Batch *drw_empty_capsule_body; - Gwn_Batch *drw_empty_capsule_cap; - Gwn_Batch *drw_empty_cone; - Gwn_Batch *drw_arrows; - Gwn_Batch *drw_axis_names; - Gwn_Batch *drw_image_plane; - Gwn_Batch *drw_image_plane_wire; - Gwn_Batch *drw_field_wind; - Gwn_Batch *drw_field_force; - Gwn_Batch *drw_field_vortex; - Gwn_Batch *drw_field_tube_limit; - Gwn_Batch *drw_field_cone_limit; - Gwn_Batch *drw_lamp; - Gwn_Batch *drw_lamp_shadows; - Gwn_Batch *drw_lamp_sunrays; - Gwn_Batch *drw_lamp_area_square; - Gwn_Batch *drw_lamp_area_disk; - Gwn_Batch *drw_lamp_hemi; - Gwn_Batch *drw_lamp_spot; - Gwn_Batch *drw_lamp_spot_square; - Gwn_Batch *drw_speaker; - Gwn_Batch *drw_lightprobe_cube; - Gwn_Batch *drw_lightprobe_planar; - Gwn_Batch *drw_lightprobe_grid; - Gwn_Batch *drw_bone_octahedral; - Gwn_Batch *drw_bone_octahedral_wire; - Gwn_Batch *drw_bone_box; - Gwn_Batch *drw_bone_box_wire; - Gwn_Batch *drw_bone_wire_wire; - Gwn_Batch *drw_bone_envelope; - Gwn_Batch *drw_bone_envelope_outline; - Gwn_Batch *drw_bone_point; - Gwn_Batch *drw_bone_point_wire; - Gwn_Batch *drw_bone_stick; - Gwn_Batch *drw_bone_arrows; - Gwn_Batch *drw_camera; - Gwn_Batch *drw_camera_frame; - Gwn_Batch *drw_camera_tria; - Gwn_Batch *drw_camera_focus; - Gwn_Batch *drw_particle_cross; - Gwn_Batch *drw_particle_circle; - Gwn_Batch *drw_particle_axis; + GPUBatch *drw_single_vertice; + GPUBatch *drw_cursor; + GPUBatch *drw_cursor_only_circle; + GPUBatch *drw_fullscreen_quad; + GPUBatch *drw_fullscreen_quad_texcoord; + GPUBatch *drw_quad; + GPUBatch *drw_sphere; + GPUBatch *drw_screenspace_circle; + GPUBatch *drw_plain_axes; + GPUBatch *drw_single_arrow; + GPUBatch *drw_cube; + GPUBatch *drw_circle; + GPUBatch *drw_square; + GPUBatch *drw_line; + GPUBatch *drw_line_endpoints; + GPUBatch *drw_empty_cube; + GPUBatch *drw_empty_sphere; + GPUBatch *drw_empty_cylinder; + GPUBatch *drw_empty_capsule_body; + GPUBatch *drw_empty_capsule_cap; + GPUBatch *drw_empty_cone; + GPUBatch *drw_arrows; + GPUBatch *drw_axis_names; + GPUBatch *drw_image_plane; + GPUBatch *drw_image_plane_wire; + GPUBatch *drw_field_wind; + GPUBatch *drw_field_force; + GPUBatch *drw_field_vortex; + GPUBatch *drw_field_tube_limit; + GPUBatch *drw_field_cone_limit; + GPUBatch *drw_lamp; + GPUBatch *drw_lamp_shadows; + GPUBatch *drw_lamp_sunrays; + GPUBatch *drw_lamp_area_square; + GPUBatch *drw_lamp_area_disk; + GPUBatch *drw_lamp_hemi; + GPUBatch *drw_lamp_spot; + GPUBatch *drw_lamp_spot_square; + GPUBatch *drw_speaker; + GPUBatch *drw_lightprobe_cube; + GPUBatch *drw_lightprobe_planar; + GPUBatch *drw_lightprobe_grid; + GPUBatch *drw_bone_octahedral; + GPUBatch *drw_bone_octahedral_wire; + GPUBatch *drw_bone_box; + GPUBatch *drw_bone_box_wire; + GPUBatch *drw_bone_wire_wire; + GPUBatch *drw_bone_envelope; + GPUBatch *drw_bone_envelope_outline; + GPUBatch *drw_bone_point; + GPUBatch *drw_bone_point_wire; + GPUBatch *drw_bone_stick; + GPUBatch *drw_bone_arrows; + GPUBatch *drw_camera; + GPUBatch *drw_camera_frame; + GPUBatch *drw_camera_tria; + GPUBatch *drw_camera_focus; + GPUBatch *drw_particle_cross; + GPUBatch *drw_particle_circle; + GPUBatch *drw_particle_axis; } SHC = {NULL}; void DRW_shape_cache_free(void) { - uint i = sizeof(SHC) / sizeof(Gwn_Batch *); - Gwn_Batch **batch = (Gwn_Batch **)&SHC; + uint i = sizeof(SHC) / sizeof(GPUBatch *); + GPUBatch **batch = (GPUBatch **)&SHC; while (i--) { - GWN_BATCH_DISCARD_SAFE(*batch); + GPU_BATCH_DISCARD_SAFE(*batch); batch++; } } void DRW_shape_cache_reset(void) { - uint i = sizeof(SHC) / sizeof(Gwn_Batch *); - Gwn_Batch **batch = (Gwn_Batch **)&SHC; + uint i = sizeof(SHC) / sizeof(GPUBatch *); + GPUBatch **batch = (GPUBatch **)&SHC; while (i--) { if (*batch) { - gwn_batch_vao_cache_clear(*batch); + GPU_batch_vao_cache_clear(*batch); } batch++; } @@ -137,22 +137,22 @@ void DRW_shape_cache_reset(void) * \{ */ static void UNUSED_FUNCTION(add_fancy_edge)( - Gwn_VertBuf *vbo, uint pos_id, uint n1_id, uint n2_id, + GPUVertBuf *vbo, uint pos_id, uint n1_id, uint n2_id, uint *v_idx, const float co1[3], const float co2[3], const float n1[3], const float n2[3]) { - GWN_vertbuf_attr_set(vbo, n1_id, *v_idx, n1); - GWN_vertbuf_attr_set(vbo, n2_id, *v_idx, n2); - GWN_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co1); + GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1); + GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2); + GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co1); - GWN_vertbuf_attr_set(vbo, n1_id, *v_idx, n1); - GWN_vertbuf_attr_set(vbo, n2_id, *v_idx, n2); - GWN_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co2); + GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1); + GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2); + GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co2); } #if 0 /* UNUSED */ static void add_lat_lon_vert( - Gwn_VertBuf *vbo, uint pos_id, uint nor_id, + GPUVertBuf *vbo, uint pos_id, uint nor_id, uint *v_idx, const float rad, const float lat, const float lon) { float pos[3], nor[3]; @@ -161,23 +161,23 @@ static void add_lat_lon_vert( nor[2] = sinf(lat) * sinf(lon); mul_v3_v3fl(pos, nor, rad); - GWN_vertbuf_attr_set(vbo, nor_id, *v_idx, nor); - GWN_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, pos); + GPU_vertbuf_attr_set(vbo, nor_id, *v_idx, nor); + GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, pos); } #endif -static Gwn_VertBuf *fill_arrows_vbo(const float scale) +static GPUVertBuf *fill_arrows_vbo(const float scale) { /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Line */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 6 * 3); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 6 * 3); float v1[3] = {0.0, 0.0, 0.0}; float v2[3] = {0.0, 0.0, 0.0}; @@ -189,21 +189,21 @@ static Gwn_VertBuf *fill_arrows_vbo(const float scale) v2[axis] = 1.0f; mul_v3_v3fl(vtmp1, v1, scale); mul_v3_v3fl(vtmp2, v2, scale); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 0, vtmp1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 1, vtmp2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 0, vtmp1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 1, vtmp2); v1[axis] = 0.85f; v1[arrow_axis] = -0.08f; mul_v3_v3fl(vtmp1, v1, scale); mul_v3_v3fl(vtmp2, v2, scale); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 2, vtmp1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 3, vtmp2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 2, vtmp1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 3, vtmp2); v1[arrow_axis] = 0.08f; mul_v3_v3fl(vtmp1, v1, scale); mul_v3_v3fl(vtmp2, v2, scale); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 4, vtmp1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 5, vtmp2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 4, vtmp1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 5, vtmp2); /* reset v1 & v2 to zero */ v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f; @@ -212,18 +212,18 @@ static Gwn_VertBuf *fill_arrows_vbo(const float scale) return vbo; } -static Gwn_VertBuf *sphere_wire_vbo(const float rad) +static GPUVertBuf *sphere_wire_vbo(const float rad) { #define NSEGMENTS 32 /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 2 * 3); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 2 * 3); /* a single ring of vertices */ float p[NSEGMENTS][2]; @@ -248,7 +248,7 @@ static Gwn_VertBuf *sphere_wire_vbo(const float rad) else v[0] = 0.0f, v[1] = cv[0], v[2] = cv[1]; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + j + (NSEGMENTS * 2 * axis), v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + j + (NSEGMENTS * 2 * axis), v); } } } @@ -259,7 +259,7 @@ static Gwn_VertBuf *sphere_wire_vbo(const float rad) /* Quads */ /* Use this one for rendering fullscreen passes. For 3D objects use DRW_cache_quad_get(). */ -Gwn_Batch *DRW_cache_fullscreen_quad_get(void) +GPUBatch *DRW_cache_fullscreen_quad_get(void) { if (!SHC.drw_fullscreen_quad) { /* Use a triangle instead of a real quad */ @@ -268,85 +268,57 @@ Gwn_Batch *DRW_cache_fullscreen_quad_get(void) float uvs[3][2] = {{ 0.0f, 0.0f}, { 2.0f, 0.0f}, { 0.0f, 2.0f}}; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, uvs; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.uvs = GWN_vertformat_attr_add(&format, "uvs", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_vertformat_alias_add(&format, "texCoord"); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 3); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 3); for (int i = 0; i < 3; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); - GWN_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); + GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]); } - SHC.drw_fullscreen_quad = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_fullscreen_quad = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_fullscreen_quad; } -Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void) -{ - if (!SHC.drw_fullscreen_quad_texcoord) { - /* Use a triangle instead of a real quad */ - /* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */ - float pos[3][2] = {{-1.0f, -1.0f}, { 3.0f, -1.0f}, {-1.0f, 3.0f}}; - float texCoord[3][2] = {{ 0.0f, 0.0f}, { 2.0f, 0.0f}, { 0.0f, 2.0f}}; - - /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; - static struct { uint pos, texCoord; } attr_id; - if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.texCoord = GWN_vertformat_attr_add(&format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - } - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 3); - - for (int i = 0; i < 3; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); - GWN_vertbuf_attr_set(vbo, attr_id.texCoord, i, texCoord[i]); - } - - SHC.drw_fullscreen_quad_texcoord = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); - } - return SHC.drw_fullscreen_quad_texcoord; -} - /* Just a regular quad with 4 vertices. */ -Gwn_Batch *DRW_cache_quad_get(void) +GPUBatch *DRW_cache_quad_get(void) { if (!SHC.drw_quad) { float pos[4][2] = {{-1.0f, -1.0f}, { 1.0f, -1.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}}; float uvs[4][2] = {{ 0.0f, 0.0f}, { 1.0f, 0.0f}, {1.0f, 1.0f}, { 0.0f, 1.0f}}; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, uvs; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.uvs = GWN_vertformat_attr_add(&format, "uvs", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 4); for (int i = 0; i < 4; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); - GWN_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]); + GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]); } - SHC.drw_quad = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_quad = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_quad; } /* Sphere */ -Gwn_Batch *DRW_cache_sphere_get(void) +GPUBatch *DRW_cache_sphere_get(void) { if (!SHC.drw_sphere) { SHC.drw_sphere = gpu_batch_sphere(32, 24); @@ -361,7 +333,7 @@ Gwn_Batch *DRW_cache_sphere_get(void) /** \name Common * \{ */ -Gwn_Batch *DRW_cache_cube_get(void) +GPUBatch *DRW_cache_cube_get(void) { if (!SHC.drw_cube) { const GLfloat verts[8][3] = { @@ -391,25 +363,25 @@ Gwn_Batch *DRW_cache_cube_get(void) }; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 36); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 36); for (int i = 0; i < 36; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); } - SHC.drw_cube = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_cube = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_cube; } -Gwn_Batch *DRW_cache_empty_cube_get(void) +GPUBatch *DRW_cache_empty_cube_get(void) { if (!SHC.drw_empty_cube) { const GLfloat verts[8][3] = { @@ -426,54 +398,54 @@ Gwn_Batch *DRW_cache_empty_cube_get(void) 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}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 24); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 24); for (int i = 0; i < 24; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]); } - SHC.drw_empty_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_cube = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_cube; } -Gwn_Batch *DRW_cache_circle_get(void) +GPUBatch *DRW_cache_circle_get(void) { #define CIRCLE_RESOL 64 if (!SHC.drw_circle) { float v[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL); for (int a = 0; a < CIRCLE_RESOL; a++) { v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v); } - SHC.drw_circle = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_circle = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_circle; #undef CIRCLE_RESOL } -Gwn_Batch *DRW_cache_square_get(void) +GPUBatch *DRW_cache_square_get(void) { if (!SHC.drw_square) { float p[4][3] = {{ 1.0f, 0.0f, 1.0f}, @@ -482,26 +454,26 @@ Gwn_Batch *DRW_cache_square_get(void) {-1.0f, 0.0f, 1.0f}}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 8); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 8); for (int i = 0; i < 4; i++) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 2, p[i % 4]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + 1, p[(i + 1) % 4]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 2, p[i % 4]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + 1, p[(i + 1) % 4]); } - SHC.drw_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_square = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_square; } -Gwn_Batch *DRW_cache_single_line_get(void) +GPUBatch *DRW_cache_single_line_get(void) { /* Z axis line */ if (!SHC.drw_line) { @@ -509,24 +481,24 @@ Gwn_Batch *DRW_cache_single_line_get(void) float v2[3] = {0.0f, 0.0f, 1.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); - SHC.drw_line = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_line = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_line; } -Gwn_Batch *DRW_cache_single_line_endpoints_get(void) +GPUBatch *DRW_cache_single_line_endpoints_get(void) { /* Z axis line */ if (!SHC.drw_line_endpoints) { @@ -534,46 +506,46 @@ Gwn_Batch *DRW_cache_single_line_endpoints_get(void) float v2[3] = {0.0f, 0.0f, 1.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); - SHC.drw_line_endpoints = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_line_endpoints = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_line_endpoints; } -Gwn_Batch *DRW_cache_screenspace_circle_get(void) +GPUBatch *DRW_cache_screenspace_circle_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_screenspace_circle) { float v[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1); for (int a = 0; a <= CIRCLE_RESOL; a++) { v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v); } - SHC.drw_screenspace_circle = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_screenspace_circle = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_screenspace_circle; #undef CIRCLE_RESOL @@ -586,7 +558,7 @@ Gwn_Batch *DRW_cache_screenspace_circle_get(void) /** \name Common Object API * \{ */ -Gwn_Batch *DRW_cache_object_wire_outline_get(Object *ob) +GPUBatch *DRW_cache_object_wire_outline_get(Object *ob) { switch (ob->type) { case OB_MESH: @@ -598,7 +570,7 @@ Gwn_Batch *DRW_cache_object_wire_outline_get(Object *ob) } } -Gwn_Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold) +GPUBatch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold) { switch (ob->type) { case OB_MESH: @@ -622,7 +594,7 @@ void DRW_cache_object_face_wireframe_get( } } -Gwn_Batch *DRW_cache_object_loose_edges_get(struct Object *ob) +GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob) { switch (ob->type) { case OB_MESH: @@ -634,7 +606,7 @@ Gwn_Batch *DRW_cache_object_loose_edges_get(struct Object *ob) } } -Gwn_Batch *DRW_cache_object_surface_get(Object *ob) +GPUBatch *DRW_cache_object_surface_get(Object *ob) { switch (ob->type) { case OB_MESH: @@ -652,7 +624,7 @@ Gwn_Batch *DRW_cache_object_surface_get(Object *ob) } } -Gwn_Batch **DRW_cache_object_surface_material_get( +GPUBatch **DRW_cache_object_surface_material_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count) { @@ -687,7 +659,7 @@ Gwn_Batch **DRW_cache_object_surface_material_get( /** \name Empties * \{ */ -Gwn_Batch *DRW_cache_plain_axes_get(void) +GPUBatch *DRW_cache_plain_axes_get(void) { if (!SHC.drw_plain_axes) { int axis; @@ -695,46 +667,46 @@ Gwn_Batch *DRW_cache_plain_axes_get(void) float v2[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 6); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 6); for (axis = 0; axis < 3; axis++) { v1[axis] = 1.0f; v2[axis] = -1.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 2, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, axis * 2 + 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 2, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 2 + 1, v2); /* reset v1 & v2 to zero for next axis */ v1[axis] = v2[axis] = 0.0f; } - SHC.drw_plain_axes = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_plain_axes = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_plain_axes; } -Gwn_Batch *DRW_cache_single_arrow_get(void) +GPUBatch *DRW_cache_single_arrow_get(void) { if (!SHC.drw_single_arrow) { float v1[3] = {0.0f, 0.0f, 1.0f}, v2[3], v3[3]; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Square Pyramid */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 12); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 12); v2[0] = 0.035f; v2[1] = 0.035f; v3[0] = -0.035f; v3[1] = 0.035f; @@ -750,26 +722,26 @@ Gwn_Batch *DRW_cache_single_arrow_get(void) v3[0] = -v3[0]; } - GWN_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 0, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 1, v2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 2, v3); + GPU_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 2, v3); } - SHC.drw_single_arrow = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_single_arrow = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_single_arrow; } -Gwn_Batch *DRW_cache_empty_sphere_get(void) +GPUBatch *DRW_cache_empty_sphere_get(void) { if (!SHC.drw_empty_sphere) { - Gwn_VertBuf *vbo = sphere_wire_vbo(1.0f); - SHC.drw_empty_sphere = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + GPUVertBuf *vbo = sphere_wire_vbo(1.0f); + SHC.drw_empty_sphere = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_sphere; } -Gwn_Batch *DRW_cache_empty_cone_get(void) +GPUBatch *DRW_cache_empty_cone_get(void) { #define NSEGMENTS 8 if (!SHC.drw_empty_cone) { @@ -782,14 +754,14 @@ Gwn_Batch *DRW_cache_empty_cone_get(void) } /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 4); for (int i = 0; i < NSEGMENTS; ++i) { float cv[2], v[3]; @@ -798,26 +770,26 @@ Gwn_Batch *DRW_cache_empty_cone_get(void) /* cone sides */ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); v[0] = 0.0f, v[1] = 2.0f, v[2] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); /* end ring */ v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); cv[0] = p[(i + 1) % NSEGMENTS][0]; cv[1] = p[(i + 1) % NSEGMENTS][1]; v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); } - SHC.drw_empty_cone = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_cone = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_cone; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_empty_cylinder_get(void) +GPUBatch *DRW_cache_empty_cylinder_get(void) { #define NSEGMENTS 12 if (!SHC.drw_empty_cylinder) { @@ -830,14 +802,14 @@ Gwn_Batch *DRW_cache_empty_cylinder_get(void) } /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 6); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 6); for (int i = 0; i < NSEGMENTS; ++i) { float cv[2], pv[2], v[3]; @@ -848,30 +820,30 @@ Gwn_Batch *DRW_cache_empty_cylinder_get(void) /* cylinder sides */ copy_v3_fl3(v, cv[0], cv[1], -1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6, v); copy_v3_fl3(v, cv[0], cv[1], 1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 1, v); /* top ring */ copy_v3_fl3(v, cv[0], cv[1], 1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 2, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 2, v); copy_v3_fl3(v, pv[0], pv[1], 1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 3, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 3, v); /* bottom ring */ copy_v3_fl3(v, cv[0], cv[1], -1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 4, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 4, v); copy_v3_fl3(v, pv[0], pv[1], -1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 5, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 6 + 5, v); } - SHC.drw_empty_cylinder = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_cylinder = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_cylinder; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_empty_capsule_body_get(void) +GPUBatch *DRW_cache_empty_capsule_body_get(void) { if (!SHC.drw_empty_capsule_body) { const float pos[8][3] = { @@ -886,22 +858,22 @@ Gwn_Batch *DRW_cache_empty_capsule_body_get(void) }; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 8); - GWN_vertbuf_attr_fill(vbo, attr_id.pos, pos); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 8); + GPU_vertbuf_attr_fill(vbo, attr_id.pos, pos); - SHC.drw_empty_capsule_body = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_capsule_body = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_capsule_body; } -Gwn_Batch *DRW_cache_empty_capsule_cap_get(void) +GPUBatch *DRW_cache_empty_capsule_cap_get(void) { #define NSEGMENTS 24 /* Must be multiple of 2. */ if (!SHC.drw_empty_capsule_cap) { @@ -914,23 +886,23 @@ Gwn_Batch *DRW_cache_empty_capsule_cap_get(void) } /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (NSEGMENTS * 2) * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (NSEGMENTS * 2) * 2); /* Base circle */ int vidx = 0; for (int i = 0; i < NSEGMENTS; ++i) { float v[3] = {0.0f, 0.0f, 0.0f}; copy_v2_v2(v, p[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); copy_v2_v2(v, p[(i+1) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } for (int i = 0; i < NSEGMENTS / 2; ++i) { @@ -939,149 +911,149 @@ Gwn_Batch *DRW_cache_empty_capsule_cap_get(void) int pi = (i + 1) % NSEGMENTS; /* Y half circle */ copy_v3_fl3(v, p[ci][0], 0.0f, p[ci][1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); copy_v3_fl3(v, p[pi][0], 0.0f, p[pi][1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); /* X half circle */ copy_v3_fl3(v, 0.0f, p[ci][0], p[ci][1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); copy_v3_fl3(v, 0.0f, p[pi][0], p[pi][1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } - SHC.drw_empty_capsule_cap = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_empty_capsule_cap = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_empty_capsule_cap; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_arrows_get(void) +GPUBatch *DRW_cache_arrows_get(void) { if (!SHC.drw_arrows) { - Gwn_VertBuf *vbo = fill_arrows_vbo(1.0f); + GPUVertBuf *vbo = fill_arrows_vbo(1.0f); - SHC.drw_arrows = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_arrows = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_arrows; } -Gwn_Batch *DRW_cache_axis_names_get(void) +GPUBatch *DRW_cache_axis_names_get(void) { if (!SHC.drw_axis_names) { const float size = 0.1f; float v1[3], v2[3]; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { /* Using 3rd component as axis indicator */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Line */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 14); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 14); /* X */ copy_v3_fl3(v1, -size, size, 0.0f); copy_v3_fl3(v2, size, -size, 0.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 1, v2); copy_v3_fl3(v1, size, size, 0.0f); copy_v3_fl3(v2, -size, -size, 0.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 3, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 3, v2); /* Y */ copy_v3_fl3(v1, -size + 0.25f * size, size, 1.0f); copy_v3_fl3(v2, 0.0f, 0.0f, 1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 4, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 5, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 4, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 5, v2); copy_v3_fl3(v1, size - 0.25f * size, size, 1.0f); copy_v3_fl3(v2, -size + 0.25f * size, -size, 1.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 6, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 7, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 6, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 7, v2); /* Z */ copy_v3_fl3(v1, -size, size, 2.0f); copy_v3_fl3(v2, size, size, 2.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 8, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 9, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 8, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 9, v2); copy_v3_fl3(v1, size, size, 2.0f); copy_v3_fl3(v2, -size, -size, 2.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 10, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 11, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 10, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 11, v2); copy_v3_fl3(v1, -size, -size, 2.0f); copy_v3_fl3(v2, size, -size, 2.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 12, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 13, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 12, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 13, v2); - SHC.drw_axis_names = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_axis_names = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_axis_names; } -Gwn_Batch *DRW_cache_image_plane_get(void) +GPUBatch *DRW_cache_image_plane_get(void) { if (!SHC.drw_image_plane) { const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, texCoords; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.texCoords = GWN_vertformat_attr_add(&format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.texCoords = GPU_vertformat_attr_add(&format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 4); for (uint j = 0; j < 4; j++) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]); - GWN_vertbuf_attr_set(vbo, attr_id.texCoords, j, quad[j]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]); + GPU_vertbuf_attr_set(vbo, attr_id.texCoords, j, quad[j]); } - SHC.drw_image_plane = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_image_plane = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_image_plane; } -Gwn_Batch *DRW_cache_image_plane_wire_get(void) +GPUBatch *DRW_cache_image_plane_wire_get(void) { if (!SHC.drw_image_plane_wire) { const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 4); for (uint j = 0; j < 4; j++) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]); } - SHC.drw_image_plane_wire = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_image_plane_wire = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_image_plane_wire; } /* Force Field */ -Gwn_Batch *DRW_cache_field_wind_get(void) +GPUBatch *DRW_cache_field_wind_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_field_wind) { float v[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 4); for (int i = 0; i < 4; i++) { float z = 0.05f * (float)i; @@ -1089,36 +1061,36 @@ Gwn_Batch *DRW_cache_field_wind_get(void) v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); } } - SHC.drw_field_wind = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_field_wind = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_field_wind; #undef CIRCLE_RESOL } -Gwn_Batch *DRW_cache_field_force_get(void) +GPUBatch *DRW_cache_field_force_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_field_force) { float v[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 3); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 3); for (int i = 0; i < 3; i++) { float radius = 1.0f + 0.5f * (float)i; @@ -1126,22 +1098,22 @@ Gwn_Batch *DRW_cache_field_force_get(void) v[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2, v); v[0] = radius * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[1] = radius * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[2] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); } } - SHC.drw_field_force = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_field_force = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_field_force; #undef CIRCLE_RESOL } -Gwn_Batch *DRW_cache_field_vortex_get(void) +GPUBatch *DRW_cache_field_vortex_get(void) { #define SPIRAL_RESOL 32 if (!SHC.drw_field_vortex) { @@ -1149,36 +1121,36 @@ Gwn_Batch *DRW_cache_field_vortex_get(void) uint v_idx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, SPIRAL_RESOL * 2 + 1); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, SPIRAL_RESOL * 2 + 1); for (int a = SPIRAL_RESOL; a > -1; a--) { v[0] = sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); v[1] = cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } for (int a = 1; a <= SPIRAL_RESOL; a++) { v[0] = -sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); v[1] = -cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } - SHC.drw_field_vortex = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_field_vortex = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_field_vortex; #undef SPIRAL_RESOL } -Gwn_Batch *DRW_cache_field_tube_limit_get(void) +GPUBatch *DRW_cache_field_tube_limit_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_field_tube_limit) { @@ -1186,14 +1158,14 @@ Gwn_Batch *DRW_cache_field_tube_limit_get(void) uint v_idx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 + 8); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 + 8); /* Caps */ for (int i = 0; i < 2; i++) { @@ -1202,12 +1174,12 @@ Gwn_Batch *DRW_cache_field_tube_limit_get(void) v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } } /* Side Edges */ @@ -1217,17 +1189,17 @@ Gwn_Batch *DRW_cache_field_tube_limit_get(void) v[0] = sinf((2.0f * M_PI * a) / 4.0f); v[1] = cosf((2.0f * M_PI * a) / 4.0f); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } } - SHC.drw_field_tube_limit = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_field_tube_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_field_tube_limit; #undef CIRCLE_RESOL } -Gwn_Batch *DRW_cache_field_cone_limit_get(void) +GPUBatch *DRW_cache_field_cone_limit_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_field_cone_limit) { @@ -1235,14 +1207,14 @@ Gwn_Batch *DRW_cache_field_cone_limit_get(void) uint v_idx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 + 8); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 + 8); /* Caps */ for (int i = 0; i < 2; i++) { @@ -1251,12 +1223,12 @@ Gwn_Batch *DRW_cache_field_cone_limit_get(void) v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } } /* Side Edges */ @@ -1266,11 +1238,11 @@ Gwn_Batch *DRW_cache_field_cone_limit_get(void) v[0] = z * sinf((2.0f * M_PI * a) / 4.0f); v[1] = z * cosf((2.0f * M_PI * a) / 4.0f); v[2] = z; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); } } - SHC.drw_field_cone_limit = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_field_cone_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_field_cone_limit; #undef CIRCLE_RESOL @@ -1283,84 +1255,84 @@ Gwn_Batch *DRW_cache_field_cone_limit_get(void) /** \name Lamps * \{ */ -Gwn_Batch *DRW_cache_lamp_get(void) +GPUBatch *DRW_cache_lamp_get(void) { #define NSEGMENTS 8 if (!SHC.drw_lamp) { float v[2]; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 2); for (int a = 0; a < NSEGMENTS * 2; a += 2) { v[0] = sinf((2.0f * M_PI * a) / ((float)NSEGMENTS * 2)); v[1] = cosf((2.0f * M_PI * a) / ((float)NSEGMENTS * 2)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS * 2)); v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS * 2)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a + 1, v); } - SHC.drw_lamp = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_lamp_shadows_get(void) +GPUBatch *DRW_cache_lamp_shadows_get(void) { #define NSEGMENTS 10 if (!SHC.drw_lamp_shadows) { float v[2]; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 2); for (int a = 0; a < NSEGMENTS * 2; a += 2) { v[0] = sinf((2.0f * M_PI * a) / ((float)NSEGMENTS * 2)); v[1] = cosf((2.0f * M_PI * a) / ((float)NSEGMENTS * 2)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS * 2)); v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)NSEGMENTS * 2)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a + 1, v); } - SHC.drw_lamp_shadows = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_shadows = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_shadows; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_lamp_sunrays_get(void) +GPUBatch *DRW_cache_lamp_sunrays_get(void) { if (!SHC.drw_lamp_sunrays) { float v[2], v1[2], v2[2]; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 32); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 32); for (int a = 0; a < 8; a++) { v[0] = sinf((2.0f * M_PI * a) / 8.0f); @@ -1368,86 +1340,86 @@ Gwn_Batch *DRW_cache_lamp_sunrays_get(void) mul_v2_v2fl(v1, v, 1.6f); mul_v2_v2fl(v2, v, 1.9f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 4, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 1, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a * 4, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 1, v2); mul_v2_v2fl(v1, v, 2.2f); mul_v2_v2fl(v2, v, 2.5f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 2, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 3, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 2, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a * 4 + 3, v2); } - SHC.drw_lamp_sunrays = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_sunrays = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_sunrays; } -Gwn_Batch *DRW_cache_lamp_area_square_get(void) +GPUBatch *DRW_cache_lamp_area_square_get(void) { if (!SHC.drw_lamp_area_square) { float v1[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 8); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 8); v1[0] = v1[1] = 0.5f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); v1[0] = -0.5f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 1, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2, v1); v1[1] = -0.5f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 3, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 4, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 3, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 4, v1); v1[0] = 0.5f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 5, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 6, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 5, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 6, v1); v1[1] = 0.5f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 7, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 7, v1); - SHC.drw_lamp_area_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_area_square = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_area_square; } -Gwn_Batch *DRW_cache_lamp_area_disk_get(void) +GPUBatch *DRW_cache_lamp_area_disk_get(void) { #define NSEGMENTS 32 if (!SHC.drw_lamp_area_disk) { /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 2 * NSEGMENTS); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 2 * NSEGMENTS); float v[3] = {0.0f, 0.5f, 0.0f}; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v); for (int a = 1; a < NSEGMENTS; a++) { v[0] = 0.5f * sinf(2.0f * (float)M_PI * a / NSEGMENTS); v[1] = 0.5f * cosf(2.0f * (float)M_PI * a / NSEGMENTS); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * a - 1, v); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2 * a - 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2 * a, v); } copy_v3_fl3(v, 0.0f, 0.5f, 0.0f); - GWN_vertbuf_attr_set(vbo, attr_id.pos, (2 * NSEGMENTS) - 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, (2 * NSEGMENTS) - 1, v); - SHC.drw_lamp_area_disk = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_area_disk = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_area_disk; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_lamp_hemi_get(void) +GPUBatch *DRW_cache_lamp_hemi_get(void) { #define CIRCLE_RESOL 32 if (!SHC.drw_lamp_hemi) { @@ -1455,26 +1427,26 @@ Gwn_Batch *DRW_cache_lamp_hemi_get(void) int vidx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 - 6 * 2 * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL * 2 * 2 - 6 * 2 * 2); /* XZ plane */ for (int a = 3; a < CIRCLE_RESOL / 2 - 3; a++) { v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL) - M_PI / 2); v[2] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL) - M_PI / 2) - 1.0f; v[1] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL) - M_PI / 2); v[2] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL) - M_PI / 2) - 1.0f; v[1] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } /* XY plane */ @@ -1482,12 +1454,12 @@ Gwn_Batch *DRW_cache_lamp_hemi_get(void) v[2] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)) - 1.0f; v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[0] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); v[2] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)) - 1.0f; v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[0] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } /* YZ plane full circle */ @@ -1496,22 +1468,22 @@ Gwn_Batch *DRW_cache_lamp_hemi_get(void) for (int a = 0; a < CIRCLE_RESOL; a++) { v[1] = rad * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[0] = rad * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); v[1] = rad * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); v[0] = rad * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } - SHC.drw_lamp_hemi = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_hemi = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_hemi; #undef CIRCLE_RESOL } -Gwn_Batch *DRW_cache_lamp_spot_get(void) +GPUBatch *DRW_cache_lamp_spot_get(void) { #define NSEGMENTS 32 if (!SHC.drw_lamp_spot) { @@ -1533,16 +1505,16 @@ Gwn_Batch *DRW_cache_lamp_spot_get(void) } /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, n1, n2; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n1 = GWN_vertformat_attr_add(&format, "N1", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.n2 = GWN_vertformat_attr_add(&format, "N2", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.n1 = GPU_vertformat_attr_add(&format, "N1", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.n2 = GPU_vertformat_attr_add(&format, "N2", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, NSEGMENTS * 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 4); for (int i = 0; i < NSEGMENTS; ++i) { float cv[2], v[3]; @@ -1551,36 +1523,36 @@ Gwn_Batch *DRW_cache_lamp_spot_get(void) /* cone sides */ v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); v[0] = 0.0f, v[1] = 0.0f, v[2] = 0.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); - GWN_vertbuf_attr_set(vbo, attr_id.n1, i * 4, n[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 1, n[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n2, i * 4, n[(i + 1) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 1, n[(i + 1) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4, n[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 1, n[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n2, i * 4, n[(i + 1) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 1, n[(i + 1) % NSEGMENTS]); /* end ring */ v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); cv[0] = p[(i + 1) % NSEGMENTS][0]; cv[1] = p[(i + 1) % NSEGMENTS][1]; v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; - GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); - GWN_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 2, n[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 3, n[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 2, neg[(i) % NSEGMENTS]); - GWN_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 3, neg[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 2, n[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 3, n[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 2, neg[(i) % NSEGMENTS]); + GPU_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 3, neg[(i) % NSEGMENTS]); } - SHC.drw_lamp_spot = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_spot = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_spot; #undef NSEGMENTS } -Gwn_Batch *DRW_cache_lamp_spot_square_get(void) +GPUBatch *DRW_cache_lamp_spot_square_get(void) { if (!SHC.drw_lamp_spot_square) { float p[5][3] = {{ 0.0f, 0.0f, 0.0f}, @@ -1592,25 +1564,25 @@ Gwn_Batch *DRW_cache_lamp_spot_square_get(void) uint v_idx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 16); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 16); /* piramid sides */ for (int i = 1; i <= 4; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[0]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[0]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[i]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[(i % 4) + 1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[((i + 1) % 4) + 1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[(i % 4) + 1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[((i + 1) % 4) + 1]); } - SHC.drw_lamp_spot_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lamp_spot_square = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lamp_spot_square; } @@ -1622,7 +1594,7 @@ Gwn_Batch *DRW_cache_lamp_spot_square_get(void) /** \name Speaker * \{ */ -Gwn_Batch *DRW_cache_speaker_get(void) +GPUBatch *DRW_cache_speaker_get(void) { if (!SHC.drw_speaker) { float v[3]; @@ -1630,30 +1602,30 @@ Gwn_Batch *DRW_cache_speaker_get(void) int vidx = 0; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 3 * segments * 2 + 4 * 4); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 3 * segments * 2 + 4 * 4); for (int j = 0; j < 3; j++) { float z = 0.25f * j - 0.125f; float r = (j == 0 ? 0.5f : 0.25f); copy_v3_fl3(v, r, 0.0f, z); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); for (int i = 1; i < segments; i++) { float x = cosf(2.f * (float)M_PI * i / segments) * r; float y = sinf(2.f * (float)M_PI * i / segments) * r; copy_v3_fl3(v, x, y, z); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } copy_v3_fl3(v, r, 0.0f, z); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } for (int j = 0; j < 4; j++) { @@ -1667,14 +1639,14 @@ Gwn_Batch *DRW_cache_speaker_get(void) float z = 0.25f * i - 0.125f; copy_v3_fl3(v, x, y, z); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); if (i == 1) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } } } - SHC.drw_speaker = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_speaker = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_speaker; } @@ -1686,7 +1658,7 @@ Gwn_Batch *DRW_cache_speaker_get(void) /** \name Probe * \{ */ -Gwn_Batch *DRW_cache_lightprobe_cube_get(void) +GPUBatch *DRW_cache_lightprobe_cube_get(void) { if (!SHC.drw_lightprobe_cube) { int v_idx = 0; @@ -1703,35 +1675,35 @@ Gwn_Batch *DRW_cache_lightprobe_cube_get(void) }; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (6 + 3) * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (6 + 3) * 2); for (int i = 0; i < 6; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[i]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[(i + 1) % 6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[(i + 1) % 6]); } - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[5]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[5]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - SHC.drw_lightprobe_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lightprobe_cube = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lightprobe_cube; } -Gwn_Batch *DRW_cache_lightprobe_grid_get(void) +GPUBatch *DRW_cache_lightprobe_grid_get(void) { if (!SHC.drw_lightprobe_grid) { int v_idx = 0; @@ -1748,47 +1720,47 @@ Gwn_Batch *DRW_cache_lightprobe_grid_get(void) }; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (6 * 2 + 3) * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (6 * 2 + 3) * 2); for (int i = 0; i < 6; ++i) { float tmp_v1[3], tmp_v2[3], tmp_tr[3]; copy_v3_v3(tmp_v1, v[i]); copy_v3_v3(tmp_v2, v[(i + 1) % 6]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v2); /* Internal wires. */ for (int j = 1; j < 2; ++j) { mul_v3_v3fl(tmp_tr, v[(i / 2) * 2 + 1], -0.5f * j); add_v3_v3v3(tmp_v1, v[i], tmp_tr); add_v3_v3v3(tmp_v2, v[(i + 1) % 6], tmp_tr); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, tmp_v2); } } - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[5]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[5]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]); - SHC.drw_lightprobe_grid = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lightprobe_grid = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lightprobe_grid; } -Gwn_Batch *DRW_cache_lightprobe_planar_get(void) +GPUBatch *DRW_cache_lightprobe_planar_get(void) { if (!SHC.drw_lightprobe_planar) { int v_idx = 0; @@ -1801,21 +1773,21 @@ Gwn_Batch *DRW_cache_lightprobe_planar_get(void) }; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 4 * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 4 * 2); for (int i = 0; i < 4; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[i]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[(i + 1) % 4]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[(i + 1) % 4]); } - SHC.drw_lightprobe_planar = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_lightprobe_planar = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_lightprobe_planar; } @@ -1924,45 +1896,45 @@ static const float bone_octahedral_solid_normals[8][3] = { { 0.00000000f, 0.11043154f, 0.99388373f} }; -Gwn_Batch *DRW_cache_bone_octahedral_get(void) +GPUBatch *DRW_cache_bone_octahedral_get(void) { if (!SHC.drw_bone_octahedral) { uint v_idx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor, snor; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.snor = GWN_vertformat_attr_add(&format, "snor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.snor = GPU_vertformat_attr_add(&format, "snor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 24); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 24); for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; ++j) { - GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]); - GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][j]]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][j]]); + GPU_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]); + GPU_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][j]]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][j]]); } } - SHC.drw_bone_octahedral = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, - GWN_BATCH_OWNS_VBO); + SHC.drw_bone_octahedral = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, + GPU_BATCH_OWNS_VBO); } return SHC.drw_bone_octahedral; } -Gwn_Batch *DRW_cache_bone_octahedral_wire_get(void) +GPUBatch *DRW_cache_bone_octahedral_wire_get(void) { if (!SHC.drw_bone_octahedral_wire) { - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, 12, 24); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, 12, 24); for (int i = 0; i < 12; i++) { - GWN_indexbuf_add_line_adj_verts(&elb, + GPU_indexbuf_add_line_adj_verts(&elb, bone_octahedral_wire_lines_adjacency[i][0], bone_octahedral_wire_lines_adjacency[i][1], bone_octahedral_wire_lines_adjacency[i][2], @@ -1970,10 +1942,10 @@ Gwn_Batch *DRW_cache_bone_octahedral_wire_get(void) } /* HACK Reuse vertex buffer. */ - Gwn_Batch *pos_nor_batch = DRW_cache_bone_octahedral_get(); + GPUBatch *pos_nor_batch = DRW_cache_bone_octahedral_get(); - SHC.drw_bone_octahedral_wire = GWN_batch_create_ex(GWN_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GWN_indexbuf_build(&elb), - GWN_BATCH_OWNS_INDEX); + SHC.drw_bone_octahedral_wire = GPU_batch_create_ex(GPU_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GPU_indexbuf_build(&elb), + GPU_BATCH_OWNS_INDEX); } return SHC.drw_bone_octahedral_wire; } @@ -2090,45 +2062,45 @@ static const float bone_box_solid_normals[12][3] = { { 0.0f, 1.0f, 0.0f}, }; -Gwn_Batch *DRW_cache_bone_box_get(void) +GPUBatch *DRW_cache_bone_box_get(void) { if (!SHC.drw_bone_box) { uint v_idx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor, snor; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.snor = GWN_vertformat_attr_add(&format, "snor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.snor = GPU_vertformat_attr_add(&format, "snor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 36); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 36); for (int i = 0; i < 12; i++) { for (int j = 0; j < 3; j++) { - GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_box_solid_normals[i]); - GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_box_smooth_normals[bone_box_solid_tris[i][j]]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_box_verts[bone_box_solid_tris[i][j]]); + GPU_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_box_solid_normals[i]); + GPU_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_box_smooth_normals[bone_box_solid_tris[i][j]]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_box_verts[bone_box_solid_tris[i][j]]); } } - SHC.drw_bone_box = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, - GWN_BATCH_OWNS_VBO); + SHC.drw_bone_box = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, + GPU_BATCH_OWNS_VBO); } return SHC.drw_bone_box; } -Gwn_Batch *DRW_cache_bone_box_wire_get(void) +GPUBatch *DRW_cache_bone_box_wire_get(void) { if (!SHC.drw_bone_box_wire) { - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, 12, 36); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, 12, 36); for (int i = 0; i < 12; i++) { - GWN_indexbuf_add_line_adj_verts(&elb, + GPU_indexbuf_add_line_adj_verts(&elb, bone_box_wire_lines_adjacency[i][0], bone_box_wire_lines_adjacency[i][1], bone_box_wire_lines_adjacency[i][2], @@ -2136,10 +2108,10 @@ Gwn_Batch *DRW_cache_bone_box_wire_get(void) } /* HACK Reuse vertex buffer. */ - Gwn_Batch *pos_nor_batch = DRW_cache_bone_box_get(); + GPUBatch *pos_nor_batch = DRW_cache_bone_box_get(); - SHC.drw_bone_box_wire = GWN_batch_create_ex(GWN_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GWN_indexbuf_build(&elb), - GWN_BATCH_OWNS_INDEX); + SHC.drw_bone_box_wire = GPU_batch_create_ex(GPU_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GPU_indexbuf_build(&elb), + GPU_BATCH_OWNS_INDEX); } return SHC.drw_bone_box_wire; } @@ -2153,7 +2125,7 @@ static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3]) r_nor[2] = cosf(lat); } -Gwn_Batch *DRW_cache_bone_envelope_solid_get(void) +GPUBatch *DRW_cache_bone_envelope_solid_get(void) { if (!SHC.drw_bone_envelope) { const int lon_res = 24; @@ -2162,15 +2134,15 @@ Gwn_Batch *DRW_cache_bone_envelope_solid_get(void) const float lat_inc = M_PI / lat_res; uint v_idx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, ((lat_res + 1) * 2) * lon_res * 1); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, ((lat_res + 1) * 2) * lon_res * 1); float lon = 0.0f; for (int i = 0; i < lon_res; i++, lon += lon_inc) { @@ -2184,24 +2156,24 @@ Gwn_Batch *DRW_cache_bone_envelope_solid_get(void) benv_lat_lon_to_co(lat, lon, co1); benv_lat_lon_to_co(lat, lon + lon_inc, co2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2); } /* Closing the loop */ benv_lat_lon_to_co(M_PI, lon, co1); benv_lat_lon_to_co(M_PI, lon + lon_inc, co2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2); } - SHC.drw_bone_envelope = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_bone_envelope = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_bone_envelope; } -Gwn_Batch *DRW_cache_bone_envelope_outline_get(void) +GPUBatch *DRW_cache_bone_envelope_outline_get(void) { if (!SHC.drw_bone_envelope_outline) { # define CIRCLE_RESOL 64 @@ -2209,16 +2181,16 @@ Gwn_Batch *DRW_cache_bone_envelope_outline_get(void) const float radius = 1.0f; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos0, pos1, pos2; } attr_id; if (format.attr_len == 0) { - attr_id.pos0 = GWN_vertformat_attr_add(&format, "pos0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.pos1 = GWN_vertformat_attr_add(&format, "pos1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.pos2 = GWN_vertformat_attr_add(&format, "pos2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos0 = GPU_vertformat_attr_add(&format, "pos0", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.pos1 = GPU_vertformat_attr_add(&format, "pos1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.pos2 = GPU_vertformat_attr_add(&format, "pos2", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (CIRCLE_RESOL + 1) * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (CIRCLE_RESOL + 1) * 2); v0[0] = radius * sinf((2.0f * M_PI * -2) / ((float)CIRCLE_RESOL)); v0[1] = radius * cosf((2.0f * M_PI * -2) / ((float)CIRCLE_RESOL)); @@ -2230,31 +2202,31 @@ Gwn_Batch *DRW_cache_bone_envelope_outline_get(void) for (int a = 0; a < CIRCLE_RESOL; a++) { v2[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v2[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); copy_v2_v2(v0, v1); copy_v2_v2(v1, v2); } v2[0] = 0.0f; v2[1] = radius; - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); - - SHC.drw_bone_envelope_outline = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2); + + SHC.drw_bone_envelope_outline = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); # undef CIRCLE_RESOL } return SHC.drw_bone_envelope_outline; } -Gwn_Batch *DRW_cache_bone_point_get(void) +GPUBatch *DRW_cache_bone_point_get(void) { if (!SHC.drw_bone_point) { #if 0 /* old style geometry sphere */ @@ -2265,16 +2237,16 @@ Gwn_Batch *DRW_cache_bone_point_get(void) const float lat_inc = M_PI / lat_res; uint v_idx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (lat_res - 1) * lon_res * 6); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (lat_res - 1) * lon_res * 6); float lon = 0.0f; for (int i = 0; i < lon_res; i++, lon += lon_inc) { @@ -2294,56 +2266,56 @@ Gwn_Batch *DRW_cache_bone_point_get(void) } } - SHC.drw_bone_point = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); #else # define CIRCLE_RESOL 64 float v[2]; const float radius = 0.05f; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL); for (int a = 0; a < CIRCLE_RESOL; a++) { v[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v); + GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v); } - SHC.drw_bone_point = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO); # undef CIRCLE_RESOL #endif } return SHC.drw_bone_point; } -Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void) +GPUBatch *DRW_cache_bone_point_wire_outline_get(void) { if (!SHC.drw_bone_point_wire) { #if 0 /* old style geometry sphere */ - Gwn_VertBuf *vbo = sphere_wire_vbo(0.05f); - SHC.drw_bone_point_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + GPUVertBuf *vbo = sphere_wire_vbo(0.05f); + SHC.drw_bone_point_wire = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); #else # define CIRCLE_RESOL 64 float v0[2], v1[2]; const float radius = 0.05f; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos0, pos1; } attr_id; if (format.attr_len == 0) { - attr_id.pos0 = GWN_vertformat_attr_add(&format, "pos0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.pos1 = GWN_vertformat_attr_add(&format, "pos1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos0 = GPU_vertformat_attr_add(&format, "pos0", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.pos1 = GPU_vertformat_attr_add(&format, "pos1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (CIRCLE_RESOL + 1) * 2); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (CIRCLE_RESOL + 1) * 2); v0[0] = radius * sinf((2.0f * M_PI * -1) / ((float)CIRCLE_RESOL)); v0[1] = radius * cosf((2.0f * M_PI * -1) / ((float)CIRCLE_RESOL)); @@ -2352,20 +2324,20 @@ Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void) for (int a = 0; a < CIRCLE_RESOL; a++) { v1[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v1[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); copy_v2_v2(v0, v1); } v1[0] = 0.0f; v1[1] = radius; - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); - GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); - GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0); + GPU_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1); - SHC.drw_bone_point_wire = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_bone_point_wire = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); # undef CIRCLE_RESOL #endif } @@ -2382,7 +2354,7 @@ Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void) #define POS_TAIL (1 << 5) #define POS_BONE (1 << 6) -Gwn_Batch *DRW_cache_bone_stick_get(void) +GPUBatch *DRW_cache_bone_stick_get(void) { if (!SHC.drw_bone_stick) { #define CIRCLE_RESOL 12 @@ -2392,20 +2364,20 @@ Gwn_Batch *DRW_cache_bone_stick_get(void) float pos[2]; /* Position Only 2D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, flag; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.flag = GWN_vertformat_attr_add(&format, "flag", GWN_COMP_U32, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.flag = GPU_vertformat_attr_add(&format, "flag", GPU_COMP_U32, 1, GPU_FETCH_INT); } const uint vcount = (CIRCLE_RESOL + 1) * 2 + 6; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vcount); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vcount); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init_ex(&elb, GWN_PRIM_TRI_FAN, (CIRCLE_RESOL + 2) * 2 + 6 + 2, vcount, true); + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, GPU_PRIM_TRI_FAN, (CIRCLE_RESOL + 2) * 2 + 6 + 2, vcount, true); /* head/tail points */ for (int i = 0; i < 2; ++i) { @@ -2413,22 +2385,22 @@ Gwn_Batch *DRW_cache_bone_stick_get(void) copy_v2_fl(pos, 0.0f); flag = (i == 0) ? POS_HEAD : POS_TAIL; flag |= (i == 0) ? COL_HEAD : COL_TAIL; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos); - GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos); + GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); + GPU_indexbuf_add_generic_vert(&elb, v++); /* circle vertices */ flag |= COL_WIRE; for (int a = 0; a < CIRCLE_RESOL; a++) { pos[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); pos[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos); - GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos); + GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); + GPU_indexbuf_add_generic_vert(&elb, v++); } /* Close the circle */ - GWN_indexbuf_add_generic_vert(&elb, v - CIRCLE_RESOL); + GPU_indexbuf_add_generic_vert(&elb, v - CIRCLE_RESOL); - GWN_indexbuf_add_primitive_restart(&elb); + GPU_indexbuf_add_primitive_restart(&elb); } /* Bone rectangle */ @@ -2437,25 +2409,25 @@ Gwn_Batch *DRW_cache_bone_stick_get(void) pos[1] = (i == 0 || i == 3) ? 0.0f : ((i < 3) ? 1.0f : -1.0f); flag = ((i < 2 || i > 4) ? POS_HEAD : POS_TAIL) | ((i == 0 || i == 3) ? 0 : COL_WIRE) | COL_BONE | POS_BONE; - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, pos); - GWN_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos); + GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag); + GPU_indexbuf_add_generic_vert(&elb, v++); } - SHC.drw_bone_stick = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, GWN_indexbuf_build(&elb), - GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + SHC.drw_bone_stick = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, GPU_indexbuf_build(&elb), + GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); #undef CIRCLE_RESOL } return SHC.drw_bone_stick; } static void set_bone_axis_vert( - Gwn_VertBuf *vbo, uint axis, uint pos, uint col, + GPUVertBuf *vbo, uint axis, uint pos, uint col, uint *v, const float *a, const float *p, const float *c) { - GWN_vertbuf_attr_set(vbo, axis, *v, a); - GWN_vertbuf_attr_set(vbo, pos, *v, p); - GWN_vertbuf_attr_set(vbo, col, *v, c); + GPU_vertbuf_attr_set(vbo, axis, *v, a); + GPU_vertbuf_attr_set(vbo, pos, *v, p); + GPU_vertbuf_attr_set(vbo, col, *v, c); *v += 1; } @@ -2530,21 +2502,21 @@ static float axis_name_shadow[8][2] = { #undef S_X #undef S_Y -Gwn_Batch *DRW_cache_bone_arrows_get(void) +GPUBatch *DRW_cache_bone_arrows_get(void) { if (!SHC.drw_bone_arrows) { /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint axis, pos, col; } attr_id; if (format.attr_len == 0) { - attr_id.axis = GWN_vertformat_attr_add(&format, "axis", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - attr_id.pos = GWN_vertformat_attr_add(&format, "screenPos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.col = GWN_vertformat_attr_add(&format, "colorAxis", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.axis = GPU_vertformat_attr_add(&format, "axis", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "screenPos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.col = GPU_vertformat_attr_add(&format, "colorAxis", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } /* Line */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, (2 + MARKER_LEN * MARKER_FILL_LAYER) * 3 + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, (2 + MARKER_LEN * MARKER_FILL_LAYER) * 3 + (X_LEN + Y_LEN + Z_LEN) * (1 + SHADOW_RES)); uint v = 0; @@ -2607,7 +2579,7 @@ Gwn_Batch *DRW_cache_bone_arrows_get(void) } } - SHC.drw_bone_arrows = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_bone_arrows = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_bone_arrows; } @@ -2642,52 +2614,52 @@ static const float camera_coords_frame_tri[3] = { /** Draw a loop of lines. */ static void camera_fill_lines_loop_fl_v1( - Gwn_VertBufRaw *pos_step, + GPUVertBufRaw *pos_step, const float *coords, const uint coords_len) { for (uint i = 0, i_prev = coords_len - 1; i < coords_len; i_prev = i++) { - *((float *)GWN_vertbuf_raw_step(pos_step)) = coords[i_prev]; - *((float *)GWN_vertbuf_raw_step(pos_step)) = coords[i]; + *((float *)GPU_vertbuf_raw_step(pos_step)) = coords[i_prev]; + *((float *)GPU_vertbuf_raw_step(pos_step)) = coords[i]; } } /** Fan lines out from the first vertex. */ static void camera_fill_lines_fan_fl_v1( - Gwn_VertBufRaw *pos_step, + GPUVertBufRaw *pos_step, const float *coords, const uint coords_len) { for (uint i = 1; i < coords_len; i++) { - *((float *)GWN_vertbuf_raw_step(pos_step)) = coords[0]; - *((float *)GWN_vertbuf_raw_step(pos_step)) = coords[i]; + *((float *)GPU_vertbuf_raw_step(pos_step)) = coords[0]; + *((float *)GPU_vertbuf_raw_step(pos_step)) = coords[i]; } } /** Simply fill the array. */ static void camera_fill_array_fl_v1( - Gwn_VertBufRaw *pos_step, + GPUVertBufRaw *pos_step, const float *coords, const uint coords_len) { for (uint i = 0; i < coords_len; i++) { - *((float *)GWN_vertbuf_raw_step(pos_step)) = coords[i]; + *((float *)GPU_vertbuf_raw_step(pos_step)) = coords[i]; } } -Gwn_Batch *DRW_cache_camera_get(void) +GPUBatch *DRW_cache_camera_get(void) { if (!SHC.drw_camera) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = 22; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); /* camera cone (from center to frame) */ camera_fill_lines_fan_fl_v1(&pos_step, camera_coords_frame_bounds, ARRAY_SIZE(camera_coords_frame_bounds)); @@ -2698,62 +2670,62 @@ Gwn_Batch *DRW_cache_camera_get(void) /* camera triangle (above the frame) */ camera_fill_lines_loop_fl_v1(&pos_step, camera_coords_frame_tri, ARRAY_SIZE(camera_coords_frame_tri)); - BLI_assert(vbo_len_capacity == GWN_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len_capacity == GPU_vertbuf_raw_used(&pos_step)); - SHC.drw_camera = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_camera = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_camera; } -Gwn_Batch *DRW_cache_camera_frame_get(void) +GPUBatch *DRW_cache_camera_frame_get(void) { if (!SHC.drw_camera_frame) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = 8; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); /* camera frame (skip center) */ camera_fill_lines_loop_fl_v1(&pos_step, &camera_coords_frame_bounds[1], ARRAY_SIZE(camera_coords_frame_bounds) - 1); - BLI_assert(vbo_len_capacity == GWN_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len_capacity == GPU_vertbuf_raw_used(&pos_step)); - SHC.drw_camera_frame = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_camera_frame = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_camera_frame; } -Gwn_Batch *DRW_cache_camera_tria_get(void) +GPUBatch *DRW_cache_camera_tria_get(void) { if (!SHC.drw_camera_tria) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } /* Vertices */ - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = 3; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); /* camera triangle (above the frame) */ camera_fill_array_fl_v1(&pos_step, camera_coords_frame_tri, ARRAY_SIZE(camera_coords_frame_tri)); - BLI_assert(vbo_len_capacity == GWN_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len_capacity == GPU_vertbuf_raw_used(&pos_step)); - SHC.drw_camera_tria = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_camera_tria = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_camera_tria; } @@ -2766,24 +2738,24 @@ Gwn_Batch *DRW_cache_camera_tria_get(void) * \{ */ /* Object Center */ -Gwn_Batch *DRW_cache_single_vert_get(void) +GPUBatch *DRW_cache_single_vert_get(void) { if (!SHC.drw_single_vertice) { float v1[3] = {0.0f, 0.0f, 0.0f}; /* Position Only 3D format */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 1); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 1); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 0, v1); - SHC.drw_single_vertice = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_single_vertice = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_single_vertice; } @@ -2795,7 +2767,7 @@ Gwn_Batch *DRW_cache_single_vert_get(void) /** \name Meshes * \{ */ -Gwn_Batch *DRW_cache_mesh_surface_overlay_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_overlay_get(Object *ob) { BLI_assert(ob->type == OB_MESH); Mesh *me = ob->data; @@ -2804,7 +2776,7 @@ Gwn_Batch *DRW_cache_mesh_surface_overlay_get(Object *ob) void DRW_cache_mesh_wire_overlay_get( Object *ob, - Gwn_Batch **r_tris, Gwn_Batch **r_ledges, Gwn_Batch **r_lverts) + GPUBatch **r_tris, GPUBatch **r_ledges, GPUBatch **r_lverts) { BLI_assert(ob->type == OB_MESH); @@ -2817,7 +2789,7 @@ void DRW_cache_mesh_wire_overlay_get( void DRW_cache_mesh_normals_overlay_get( Object *ob, - Gwn_Batch **r_tris, Gwn_Batch **r_ledges, Gwn_Batch **r_lverts) + GPUBatch **r_tris, GPUBatch **r_ledges, GPUBatch **r_lverts) { BLI_assert(ob->type == OB_MESH); @@ -2828,7 +2800,7 @@ void DRW_cache_mesh_normals_overlay_get( *r_lverts = DRW_mesh_batch_cache_get_overlay_loose_verts(me); } -Gwn_Batch *DRW_cache_face_centers_get(Object *ob) +GPUBatch *DRW_cache_face_centers_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2837,7 +2809,7 @@ Gwn_Batch *DRW_cache_face_centers_get(Object *ob) return DRW_mesh_batch_cache_get_overlay_facedots(me); } -Gwn_Batch *DRW_cache_mesh_wire_outline_get(Object *ob) +GPUBatch *DRW_cache_mesh_wire_outline_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2845,7 +2817,7 @@ Gwn_Batch *DRW_cache_mesh_wire_outline_get(Object *ob) return DRW_mesh_batch_cache_get_fancy_edges(me); } -Gwn_Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold) +GPUBatch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold) { BLI_assert(ob->type == OB_MESH); @@ -2853,7 +2825,7 @@ Gwn_Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold) return DRW_mesh_batch_cache_get_edge_detection(me, r_is_manifold); } -Gwn_Batch *DRW_cache_mesh_surface_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2861,7 +2833,7 @@ Gwn_Batch *DRW_cache_mesh_surface_get(Object *ob) return DRW_mesh_batch_cache_get_triangles_with_normals(me); } -Gwn_Batch *DRW_cache_mesh_loose_edges_get(Object *ob) +GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2869,7 +2841,7 @@ Gwn_Batch *DRW_cache_mesh_loose_edges_get(Object *ob) return DRW_mesh_batch_cache_get_loose_edges_with_normals(me); } -Gwn_Batch *DRW_cache_mesh_surface_weights_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_weights_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2877,7 +2849,7 @@ Gwn_Batch *DRW_cache_mesh_surface_weights_get(Object *ob) return DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(me, ob->actdef - 1); } -Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_vert_colors_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2886,7 +2858,7 @@ Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(Object *ob) } /* Return list of batches */ -Gwn_Batch **DRW_cache_mesh_surface_shaded_get( +GPUBatch **DRW_cache_mesh_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count) { @@ -2898,7 +2870,7 @@ Gwn_Batch **DRW_cache_mesh_surface_shaded_get( } /* Return list of batches */ -Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(Object *ob) +GPUBatch **DRW_cache_mesh_surface_texpaint_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2906,7 +2878,7 @@ Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(Object *ob) return DRW_mesh_batch_cache_get_surface_texpaint(me); } -Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2914,7 +2886,7 @@ Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob) return DRW_mesh_batch_cache_get_surface_texpaint_single(me); } -Gwn_Batch *DRW_cache_mesh_surface_verts_get(Object *ob) +GPUBatch *DRW_cache_mesh_surface_verts_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2922,7 +2894,7 @@ Gwn_Batch *DRW_cache_mesh_surface_verts_get(Object *ob) return DRW_mesh_batch_cache_get_points_with_normals(me); } -Gwn_Batch *DRW_cache_mesh_edges_get(Object *ob) +GPUBatch *DRW_cache_mesh_edges_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2930,7 +2902,7 @@ Gwn_Batch *DRW_cache_mesh_edges_get(Object *ob) return DRW_mesh_batch_cache_get_all_edges(me); } -Gwn_Batch *DRW_cache_mesh_verts_get(Object *ob) +GPUBatch *DRW_cache_mesh_verts_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2938,7 +2910,7 @@ Gwn_Batch *DRW_cache_mesh_verts_get(Object *ob) return DRW_mesh_batch_cache_get_all_verts(me); } -Gwn_Batch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel) +GPUBatch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, bool use_sel) { BLI_assert(ob->type == OB_MESH); @@ -2946,7 +2918,7 @@ Gwn_Batch *DRW_cache_mesh_edges_paint_overlay_get(Object *ob, bool use_wire, boo return DRW_mesh_batch_cache_get_weight_overlay_edges(me, use_wire, use_sel); } -Gwn_Batch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob) +GPUBatch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2954,7 +2926,7 @@ Gwn_Batch *DRW_cache_mesh_faces_weight_overlay_get(Object *ob) return DRW_mesh_batch_cache_get_weight_overlay_faces(me); } -Gwn_Batch *DRW_cache_mesh_verts_weight_overlay_get(Object *ob) +GPUBatch *DRW_cache_mesh_verts_weight_overlay_get(Object *ob) { BLI_assert(ob->type == OB_MESH); @@ -2977,7 +2949,7 @@ void DRW_cache_mesh_sculpt_coords_ensure(Object *ob) /** \name Curve * \{ */ -Gwn_Batch *DRW_cache_curve_edge_wire_get(Object *ob) +GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) { BLI_assert(ob->type == OB_CURVE); @@ -2985,7 +2957,7 @@ Gwn_Batch *DRW_cache_curve_edge_wire_get(Object *ob) return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache); } -Gwn_Batch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) +GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) { BLI_assert(ob->type == OB_CURVE); @@ -2993,7 +2965,7 @@ Gwn_Batch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) return DRW_curve_batch_cache_get_normal_edge(cu, ob->curve_cache, normal_size); } -Gwn_Batch *DRW_cache_curve_edge_overlay_get(Object *ob) +GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob) { BLI_assert(ob->type == OB_CURVE); @@ -3001,7 +2973,7 @@ Gwn_Batch *DRW_cache_curve_edge_overlay_get(Object *ob) return DRW_curve_batch_cache_get_overlay_edges(cu); } -Gwn_Batch *DRW_cache_curve_vert_overlay_get(Object *ob) +GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob) { BLI_assert(ob->type == OB_CURVE); @@ -3009,7 +2981,7 @@ Gwn_Batch *DRW_cache_curve_vert_overlay_get(Object *ob) return DRW_curve_batch_cache_get_overlay_verts(cu); } -Gwn_Batch *DRW_cache_curve_surface_get(Object *ob) +GPUBatch *DRW_cache_curve_surface_get(Object *ob) { BLI_assert(ob->type == OB_CURVE); @@ -3018,7 +2990,7 @@ Gwn_Batch *DRW_cache_curve_surface_get(Object *ob) } /* Return list of batches */ -Gwn_Batch **DRW_cache_curve_surface_shaded_get( +GPUBatch **DRW_cache_curve_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) { BLI_assert(ob->type == OB_CURVE); @@ -3034,13 +3006,13 @@ Gwn_Batch **DRW_cache_curve_surface_shaded_get( /** \name MetaBall * \{ */ -Gwn_Batch *DRW_cache_mball_surface_get(Object *ob) +GPUBatch *DRW_cache_mball_surface_get(Object *ob) { BLI_assert(ob->type == OB_MBALL); return DRW_metaball_batch_cache_get_triangles_with_normals(ob); } -Gwn_Batch **DRW_cache_mball_surface_shaded_get( +GPUBatch **DRW_cache_mball_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) { BLI_assert(ob->type == OB_MBALL); @@ -3055,7 +3027,7 @@ Gwn_Batch **DRW_cache_mball_surface_shaded_get( /** \name Font * \{ */ -Gwn_Batch *DRW_cache_text_edge_wire_get(Object *ob) +GPUBatch *DRW_cache_text_edge_wire_get(Object *ob) { BLI_assert(ob->type == OB_FONT); @@ -3063,7 +3035,7 @@ Gwn_Batch *DRW_cache_text_edge_wire_get(Object *ob) return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache); } -Gwn_Batch *DRW_cache_text_surface_get(Object *ob) +GPUBatch *DRW_cache_text_surface_get(Object *ob) { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; @@ -3073,7 +3045,7 @@ Gwn_Batch *DRW_cache_text_surface_get(Object *ob) return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); } -Gwn_Batch **DRW_cache_text_surface_shaded_get( +GPUBatch **DRW_cache_text_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) { BLI_assert(ob->type == OB_FONT); @@ -3084,14 +3056,14 @@ Gwn_Batch **DRW_cache_text_surface_shaded_get( return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); } -Gwn_Batch *DRW_cache_text_cursor_overlay_get(Object *ob) +GPUBatch *DRW_cache_text_cursor_overlay_get(Object *ob) { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; return DRW_curve_batch_cache_get_overlay_cursor(cu); } -Gwn_Batch *DRW_cache_text_select_overlay_get(Object *ob) +GPUBatch *DRW_cache_text_select_overlay_get(Object *ob) { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; @@ -3105,7 +3077,7 @@ Gwn_Batch *DRW_cache_text_select_overlay_get(Object *ob) /** \name Surface * \{ */ -Gwn_Batch *DRW_cache_surf_surface_get(Object *ob) +GPUBatch *DRW_cache_surf_surface_get(Object *ob) { BLI_assert(ob->type == OB_SURF); @@ -3114,7 +3086,7 @@ Gwn_Batch *DRW_cache_surf_surface_get(Object *ob) } /* Return list of batches */ -Gwn_Batch **DRW_cache_surf_surface_shaded_get( +GPUBatch **DRW_cache_surf_surface_shaded_get( Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len) { BLI_assert(ob->type == OB_SURF); @@ -3130,7 +3102,7 @@ Gwn_Batch **DRW_cache_surf_surface_shaded_get( /** \name Lattice * \{ */ -Gwn_Batch *DRW_cache_lattice_verts_get(Object *ob) +GPUBatch *DRW_cache_lattice_verts_get(Object *ob) { BLI_assert(ob->type == OB_LATTICE); @@ -3138,7 +3110,7 @@ Gwn_Batch *DRW_cache_lattice_verts_get(Object *ob) return DRW_lattice_batch_cache_get_all_verts(lt); } -Gwn_Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight) +GPUBatch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight) { BLI_assert(ob->type == OB_LATTICE); @@ -3152,7 +3124,7 @@ Gwn_Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight) return DRW_lattice_batch_cache_get_all_edges(lt, use_weight, actdef); } -Gwn_Batch *DRW_cache_lattice_vert_overlay_get(Object *ob) +GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob) { BLI_assert(ob->type == OB_LATTICE); @@ -3167,17 +3139,17 @@ Gwn_Batch *DRW_cache_lattice_vert_overlay_get(Object *ob) /** \name Particles * \{ */ -Gwn_Batch *DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md) +GPUBatch *DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md) { return DRW_particles_batch_cache_get_hair(object, psys, md); } -Gwn_Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys) +GPUBatch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys) { return DRW_particles_batch_cache_get_dots(object, psys); } -Gwn_Batch *DRW_cache_particles_get_edit_strands( +GPUBatch *DRW_cache_particles_get_edit_strands( Object *object, ParticleSystem *psys, struct PTCacheEdit *edit) @@ -3185,7 +3157,7 @@ Gwn_Batch *DRW_cache_particles_get_edit_strands( return DRW_particles_batch_cache_get_edit_strands(object, psys, edit); } -Gwn_Batch *DRW_cache_particles_get_edit_inner_points( +GPUBatch *DRW_cache_particles_get_edit_inner_points( Object *object, ParticleSystem *psys, struct PTCacheEdit *edit) @@ -3193,7 +3165,7 @@ Gwn_Batch *DRW_cache_particles_get_edit_inner_points( return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit); } -Gwn_Batch *DRW_cache_particles_get_edit_tip_points( +GPUBatch *DRW_cache_particles_get_edit_tip_points( Object *object, ParticleSystem *psys, struct PTCacheEdit *edit) @@ -3201,100 +3173,100 @@ Gwn_Batch *DRW_cache_particles_get_edit_tip_points( return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit); } -Gwn_Batch *DRW_cache_particles_get_prim(int type) +GPUBatch *DRW_cache_particles_get_prim(int type) { switch (type) { case PART_DRAW_CROSS: if (!SHC.drw_particle_cross) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, axis_id; if (format.attr_len == 0) { - pos_id = GWN_vertformat_attr_add(&format, "inst_pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - axis_id = GWN_vertformat_attr_add(&format, "axis", GWN_COMP_I32, 1, GWN_FETCH_INT); + pos_id = GPU_vertformat_attr_add(&format, "inst_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + axis_id = GPU_vertformat_attr_add(&format, "axis", GPU_COMP_I32, 1, GPU_FETCH_INT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 6); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 6); /* X axis */ float co[3] = {-1.0f, 0.0f, 0.0f}; int axis = -1; - GWN_vertbuf_attr_set(vbo, pos_id, 0, co); - GWN_vertbuf_attr_set(vbo, axis_id, 0, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 0, co); + GPU_vertbuf_attr_set(vbo, axis_id, 0, &axis); co[0] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 1, co); - GWN_vertbuf_attr_set(vbo, axis_id, 1, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 1, co); + GPU_vertbuf_attr_set(vbo, axis_id, 1, &axis); /* Y axis */ co[0] = 0.0f; co[1] = -1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 2, co); - GWN_vertbuf_attr_set(vbo, axis_id, 2, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 2, co); + GPU_vertbuf_attr_set(vbo, axis_id, 2, &axis); co[1] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 3, co); - GWN_vertbuf_attr_set(vbo, axis_id, 3, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 3, co); + GPU_vertbuf_attr_set(vbo, axis_id, 3, &axis); /* Z axis */ co[1] = 0.0f; co[2] = -1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 4, co); - GWN_vertbuf_attr_set(vbo, axis_id, 4, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 4, co); + GPU_vertbuf_attr_set(vbo, axis_id, 4, &axis); co[2] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 5, co); - GWN_vertbuf_attr_set(vbo, axis_id, 5, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 5, co); + GPU_vertbuf_attr_set(vbo, axis_id, 5, &axis); - SHC.drw_particle_cross = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_particle_cross = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_particle_cross; case PART_DRAW_AXIS: if (!SHC.drw_particle_axis) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, axis_id; if (format.attr_len == 0) { - pos_id = GWN_vertformat_attr_add(&format, "inst_pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - axis_id = GWN_vertformat_attr_add(&format, "axis", GWN_COMP_I32, 1, GWN_FETCH_INT); + pos_id = GPU_vertformat_attr_add(&format, "inst_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + axis_id = GPU_vertformat_attr_add(&format, "axis", GPU_COMP_I32, 1, GPU_FETCH_INT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 6); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 6); /* X axis */ float co[3] = {0.0f, 0.0f, 0.0f}; int axis = 0; - GWN_vertbuf_attr_set(vbo, pos_id, 0, co); - GWN_vertbuf_attr_set(vbo, axis_id, 0, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 0, co); + GPU_vertbuf_attr_set(vbo, axis_id, 0, &axis); co[0] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 1, co); - GWN_vertbuf_attr_set(vbo, axis_id, 1, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 1, co); + GPU_vertbuf_attr_set(vbo, axis_id, 1, &axis); /* Y axis */ co[0] = 0.0f; axis = 1; - GWN_vertbuf_attr_set(vbo, pos_id, 2, co); - GWN_vertbuf_attr_set(vbo, axis_id, 2, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 2, co); + GPU_vertbuf_attr_set(vbo, axis_id, 2, &axis); co[1] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 3, co); - GWN_vertbuf_attr_set(vbo, axis_id, 3, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 3, co); + GPU_vertbuf_attr_set(vbo, axis_id, 3, &axis); /* Z axis */ co[1] = 0.0f; axis = 2; - GWN_vertbuf_attr_set(vbo, pos_id, 4, co); - GWN_vertbuf_attr_set(vbo, axis_id, 4, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 4, co); + GPU_vertbuf_attr_set(vbo, axis_id, 4, &axis); co[2] = 1.0f; - GWN_vertbuf_attr_set(vbo, pos_id, 5, co); - GWN_vertbuf_attr_set(vbo, axis_id, 5, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, 5, co); + GPU_vertbuf_attr_set(vbo, axis_id, 5, &axis); - SHC.drw_particle_axis = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_particle_axis = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_particle_axis; @@ -3304,26 +3276,26 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type) float v[3] = {0.0f, 0.0f, 0.0f}; int axis = -1; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, axis_id; if (format.attr_len == 0) { - pos_id = GWN_vertformat_attr_add(&format, "inst_pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - axis_id = GWN_vertformat_attr_add(&format, "axis", GWN_COMP_I32, 1, GWN_FETCH_INT); + pos_id = GPU_vertformat_attr_add(&format, "inst_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + axis_id = GPU_vertformat_attr_add(&format, "axis", GPU_COMP_I32, 1, GPU_FETCH_INT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, CIRCLE_RESOL); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL); for (int a = 0; a < CIRCLE_RESOL; a++) { v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); v[2] = 0.0f; - GWN_vertbuf_attr_set(vbo, pos_id, a, v); - GWN_vertbuf_attr_set(vbo, axis_id, a, &axis); + GPU_vertbuf_attr_set(vbo, pos_id, a, v); + GPU_vertbuf_attr_set(vbo, axis_id, a, &axis); } - SHC.drw_particle_circle = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO); + SHC.drw_particle_circle = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_particle_circle; @@ -3337,9 +3309,9 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type) } /* 3D cursor */ -Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines) +GPUBatch *DRW_cache_cursor_get(bool crosshair_lines) { - Gwn_Batch **drw_cursor = crosshair_lines ? &SHC.drw_cursor : &SHC.drw_cursor_only_circle; + GPUBatch **drw_cursor = crosshair_lines ? &SHC.drw_cursor : &SHC.drw_cursor_only_circle; if (*drw_cursor == NULL) { const float f5 = 0.25f; @@ -3353,18 +3325,18 @@ Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines) uchar red[3] = {255, 0, 0}; uchar white[3] = {255, 255, 255}; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, color; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - attr_id.color = GWN_vertformat_attr_add(&format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + attr_id.color = GPU_vertformat_attr_add(&format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init_ex(&elb, GWN_PRIM_LINE_STRIP, index_len, vert_len, true); + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len, true); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_len); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vert_len); int v = 0; for (int i = 0; i < segments; ++i) { @@ -3373,59 +3345,59 @@ Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines) float y = f10 * sinf(angle); if (i % 2 == 0) - GWN_vertbuf_attr_set(vbo, attr_id.color, v, red); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, red); else - GWN_vertbuf_attr_set(vbo, attr_id.color, v, white); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, white); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){x, y}); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){x, y}); + GPU_indexbuf_add_generic_vert(&elb, v++); } - GWN_indexbuf_add_generic_vert(&elb, 0); + GPU_indexbuf_add_generic_vert(&elb, 0); if (crosshair_lines) { uchar crosshair_color[3]; UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); - GWN_indexbuf_add_primitive_restart(&elb); + GPU_indexbuf_add_primitive_restart(&elb); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); - GWN_indexbuf_add_primitive_restart(&elb); + GPU_indexbuf_add_primitive_restart(&elb); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); - GWN_indexbuf_add_primitive_restart(&elb); + GPU_indexbuf_add_primitive_restart(&elb); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); - GWN_indexbuf_add_primitive_restart(&elb); + GPU_indexbuf_add_primitive_restart(&elb); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); - GWN_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20}); - GWN_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); - GWN_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20}); + GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color); + GPU_indexbuf_add_generic_vert(&elb, v++); } - Gwn_IndexBuf *ibo = GWN_indexbuf_build(&elb); + GPUIndexBuf *ibo = GPU_indexbuf_build(&elb); - *drw_cursor = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, ibo, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + *drw_cursor = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, ibo, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } return *drw_cursor; } diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 07c8a571256..129c0252f30 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -26,7 +26,7 @@ #ifndef __DRAW_CACHE_H__ #define __DRAW_CACHE_H__ -struct Gwn_Batch; +struct GPUBatch; struct GPUMaterial; struct ModifierData; struct Object; @@ -36,163 +36,162 @@ void DRW_shape_cache_free(void); void DRW_shape_cache_reset(void); /* 3D cursor */ -struct Gwn_Batch *DRW_cache_cursor_get(bool crosshair_lines); +struct GPUBatch *DRW_cache_cursor_get(bool crosshair_lines); /* Common Shapes */ -struct Gwn_Batch *DRW_cache_fullscreen_quad_get(void); -struct Gwn_Batch *DRW_cache_fullscreen_quad_texcoord_get(void); -struct Gwn_Batch *DRW_cache_quad_get(void); -struct Gwn_Batch *DRW_cache_cube_get(void); -struct Gwn_Batch *DRW_cache_sphere_get(void); -struct Gwn_Batch *DRW_cache_single_vert_get(void); -struct Gwn_Batch *DRW_cache_single_line_get(void); -struct Gwn_Batch *DRW_cache_single_line_endpoints_get(void); -struct Gwn_Batch *DRW_cache_screenspace_circle_get(void); +struct GPUBatch *DRW_cache_fullscreen_quad_get(void); +struct GPUBatch *DRW_cache_quad_get(void); +struct GPUBatch *DRW_cache_cube_get(void); +struct GPUBatch *DRW_cache_sphere_get(void); +struct GPUBatch *DRW_cache_single_vert_get(void); +struct GPUBatch *DRW_cache_single_line_get(void); +struct GPUBatch *DRW_cache_single_line_endpoints_get(void); +struct GPUBatch *DRW_cache_screenspace_circle_get(void); /* Common Object */ -struct Gwn_Batch *DRW_cache_object_wire_outline_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_object_edge_detection_get(struct Object *ob, bool *r_is_manifold); -struct Gwn_Batch *DRW_cache_object_surface_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_object_loose_edges_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_object_surface_material_get( +struct GPUBatch *DRW_cache_object_wire_outline_get(struct Object *ob); +struct GPUBatch *DRW_cache_object_edge_detection_get(struct Object *ob, bool *r_is_manifold); +struct GPUBatch *DRW_cache_object_surface_get(struct Object *ob); +struct GPUBatch *DRW_cache_object_loose_edges_get(struct Object *ob); +struct GPUBatch **DRW_cache_object_surface_material_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); void DRW_cache_object_face_wireframe_get( Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count); /* Empties */ -struct Gwn_Batch *DRW_cache_plain_axes_get(void); -struct Gwn_Batch *DRW_cache_single_arrow_get(void); -struct Gwn_Batch *DRW_cache_empty_cube_get(void); -struct Gwn_Batch *DRW_cache_circle_get(void); -struct Gwn_Batch *DRW_cache_square_get(void); -struct Gwn_Batch *DRW_cache_empty_sphere_get(void); -struct Gwn_Batch *DRW_cache_empty_cylinder_get(void); -struct Gwn_Batch *DRW_cache_empty_cone_get(void); -struct Gwn_Batch *DRW_cache_empty_capsule_cap_get(void); -struct Gwn_Batch *DRW_cache_empty_capsule_body_get(void); -struct Gwn_Batch *DRW_cache_arrows_get(void); -struct Gwn_Batch *DRW_cache_axis_names_get(void); -struct Gwn_Batch *DRW_cache_image_plane_get(void); -struct Gwn_Batch *DRW_cache_image_plane_wire_get(void); +struct GPUBatch *DRW_cache_plain_axes_get(void); +struct GPUBatch *DRW_cache_single_arrow_get(void); +struct GPUBatch *DRW_cache_empty_cube_get(void); +struct GPUBatch *DRW_cache_circle_get(void); +struct GPUBatch *DRW_cache_square_get(void); +struct GPUBatch *DRW_cache_empty_sphere_get(void); +struct GPUBatch *DRW_cache_empty_cylinder_get(void); +struct GPUBatch *DRW_cache_empty_cone_get(void); +struct GPUBatch *DRW_cache_empty_capsule_cap_get(void); +struct GPUBatch *DRW_cache_empty_capsule_body_get(void); +struct GPUBatch *DRW_cache_arrows_get(void); +struct GPUBatch *DRW_cache_axis_names_get(void); +struct GPUBatch *DRW_cache_image_plane_get(void); +struct GPUBatch *DRW_cache_image_plane_wire_get(void); /* Force Field */ -struct Gwn_Batch *DRW_cache_field_wind_get(void); -struct Gwn_Batch *DRW_cache_field_force_get(void); -struct Gwn_Batch *DRW_cache_field_vortex_get(void); -struct Gwn_Batch *DRW_cache_field_tube_limit_get(void); -struct Gwn_Batch *DRW_cache_field_cone_limit_get(void); +struct GPUBatch *DRW_cache_field_wind_get(void); +struct GPUBatch *DRW_cache_field_force_get(void); +struct GPUBatch *DRW_cache_field_vortex_get(void); +struct GPUBatch *DRW_cache_field_tube_limit_get(void); +struct GPUBatch *DRW_cache_field_cone_limit_get(void); /* Lamps */ -struct Gwn_Batch *DRW_cache_lamp_get(void); -struct Gwn_Batch *DRW_cache_lamp_shadows_get(void); -struct Gwn_Batch *DRW_cache_lamp_sunrays_get(void); -struct Gwn_Batch *DRW_cache_lamp_area_square_get(void); -struct Gwn_Batch *DRW_cache_lamp_area_disk_get(void); -struct Gwn_Batch *DRW_cache_lamp_hemi_get(void); -struct Gwn_Batch *DRW_cache_lamp_spot_get(void); -struct Gwn_Batch *DRW_cache_lamp_spot_square_get(void); +struct GPUBatch *DRW_cache_lamp_get(void); +struct GPUBatch *DRW_cache_lamp_shadows_get(void); +struct GPUBatch *DRW_cache_lamp_sunrays_get(void); +struct GPUBatch *DRW_cache_lamp_area_square_get(void); +struct GPUBatch *DRW_cache_lamp_area_disk_get(void); +struct GPUBatch *DRW_cache_lamp_hemi_get(void); +struct GPUBatch *DRW_cache_lamp_spot_get(void); +struct GPUBatch *DRW_cache_lamp_spot_square_get(void); /* Camera */ -struct Gwn_Batch *DRW_cache_camera_get(void); -struct Gwn_Batch *DRW_cache_camera_frame_get(void); -struct Gwn_Batch *DRW_cache_camera_tria_get(void); +struct GPUBatch *DRW_cache_camera_get(void); +struct GPUBatch *DRW_cache_camera_frame_get(void); +struct GPUBatch *DRW_cache_camera_tria_get(void); /* Speaker */ -struct Gwn_Batch *DRW_cache_speaker_get(void); +struct GPUBatch *DRW_cache_speaker_get(void); /* Probe */ -struct Gwn_Batch *DRW_cache_lightprobe_cube_get(void); -struct Gwn_Batch *DRW_cache_lightprobe_grid_get(void); -struct Gwn_Batch *DRW_cache_lightprobe_planar_get(void); +struct GPUBatch *DRW_cache_lightprobe_cube_get(void); +struct GPUBatch *DRW_cache_lightprobe_grid_get(void); +struct GPUBatch *DRW_cache_lightprobe_planar_get(void); /* Bones */ -struct Gwn_Batch *DRW_cache_bone_octahedral_get(void); -struct Gwn_Batch *DRW_cache_bone_octahedral_wire_get(void); -struct Gwn_Batch *DRW_cache_bone_box_get(void); -struct Gwn_Batch *DRW_cache_bone_box_wire_get(void); -struct Gwn_Batch *DRW_cache_bone_envelope_solid_get(void); -struct Gwn_Batch *DRW_cache_bone_envelope_outline_get(void); -struct Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void); -struct Gwn_Batch *DRW_cache_bone_point_get(void); -struct Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void); -struct Gwn_Batch *DRW_cache_bone_stick_get(void); -struct Gwn_Batch *DRW_cache_bone_arrows_get(void); +struct GPUBatch *DRW_cache_bone_octahedral_get(void); +struct GPUBatch *DRW_cache_bone_octahedral_wire_get(void); +struct GPUBatch *DRW_cache_bone_box_get(void); +struct GPUBatch *DRW_cache_bone_box_wire_get(void); +struct GPUBatch *DRW_cache_bone_envelope_solid_get(void); +struct GPUBatch *DRW_cache_bone_envelope_outline_get(void); +struct GPUBatch *DRW_cache_bone_envelope_head_wire_outline_get(void); +struct GPUBatch *DRW_cache_bone_point_get(void); +struct GPUBatch *DRW_cache_bone_point_wire_outline_get(void); +struct GPUBatch *DRW_cache_bone_stick_get(void); +struct GPUBatch *DRW_cache_bone_arrows_get(void); /* Meshes */ -struct Gwn_Batch *DRW_cache_mesh_surface_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_overlay_get(struct Object *ob); void DRW_cache_mesh_wire_overlay_get( struct Object *ob, - struct Gwn_Batch **r_tris, struct Gwn_Batch **r_ledges, struct Gwn_Batch **r_lverts); + struct GPUBatch **r_tris, struct GPUBatch **r_ledges, struct GPUBatch **r_lverts); void DRW_cache_mesh_normals_overlay_get( struct Object *ob, - struct Gwn_Batch **r_tris, struct Gwn_Batch **r_ledges, struct Gwn_Batch **r_lverts); -struct Gwn_Batch *DRW_cache_face_centers_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_wire_outline_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold); -struct Gwn_Batch *DRW_cache_mesh_surface_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_loose_edges_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_surface_weights_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_surface_verts_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_edges_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_verts_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel); -struct Gwn_Batch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_mesh_surface_shaded_get( + struct GPUBatch **r_tris, struct GPUBatch **r_ledges, struct GPUBatch **r_lverts); +struct GPUBatch *DRW_cache_face_centers_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold); +struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_loose_edges_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_verts_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_edges_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_verts_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_edges_paint_overlay_get(struct Object *ob, bool use_wire, bool use_sel); +struct GPUBatch *DRW_cache_mesh_faces_weight_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_verts_weight_overlay_get(struct Object *ob); +struct GPUBatch **DRW_cache_mesh_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); -struct Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob); +struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob); +struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob); void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob); /* Curve */ -struct Gwn_Batch *DRW_cache_curve_surface_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_curve_surface_shaded_get( +struct GPUBatch *DRW_cache_curve_surface_get(struct Object *ob); +struct GPUBatch **DRW_cache_curve_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); -struct Gwn_Batch *DRW_cache_curve_surface_verts_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_curve_edge_wire_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); /* edit-mode */ -struct Gwn_Batch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size); -struct Gwn_Batch *DRW_cache_curve_edge_overlay_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_curve_vert_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size); +struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_vert_overlay_get(struct Object *ob); /* Font */ -struct Gwn_Batch *DRW_cache_text_edge_wire_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_text_surface_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_text_surface_shaded_get( +struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob); +struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob); +struct GPUBatch **DRW_cache_text_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* edit-mode */ -struct Gwn_Batch *DRW_cache_text_cursor_overlay_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_text_select_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_text_cursor_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob); /* Surface */ -struct Gwn_Batch *DRW_cache_surf_surface_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_surf_surface_shaded_get( +struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob); +struct GPUBatch **DRW_cache_surf_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* Lattice */ -struct Gwn_Batch *DRW_cache_lattice_verts_get(struct Object *ob); -struct Gwn_Batch *DRW_cache_lattice_wire_get(struct Object *ob, bool use_weight); -struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob); +struct GPUBatch *DRW_cache_lattice_verts_get(struct Object *ob); +struct GPUBatch *DRW_cache_lattice_wire_get(struct Object *ob, bool use_weight); +struct GPUBatch *DRW_cache_lattice_vert_overlay_get(struct Object *ob); /* Particles */ -struct Gwn_Batch *DRW_cache_particles_get_hair( +struct GPUBatch *DRW_cache_particles_get_hair( struct Object *object, struct ParticleSystem *psys, struct ModifierData *md); -struct Gwn_Batch *DRW_cache_particles_get_dots( +struct GPUBatch *DRW_cache_particles_get_dots( struct Object *object, struct ParticleSystem *psys); -struct Gwn_Batch *DRW_cache_particles_get_edit_strands( +struct GPUBatch *DRW_cache_particles_get_edit_strands( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points( +struct GPUBatch *DRW_cache_particles_get_edit_inner_points( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points( +struct GPUBatch *DRW_cache_particles_get_edit_tip_points( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_cache_particles_get_prim(int type); +struct GPUBatch *DRW_cache_particles_get_prim(int type); /* Metaball */ -struct Gwn_Batch *DRW_cache_mball_surface_get(struct Object *ob); -struct Gwn_Batch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +struct GPUBatch *DRW_cache_mball_surface_get(struct Object *ob); +struct GPUBatch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); #endif /* __DRAW_CACHE_H__ */ diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 5773daf8e96..eeb7b1c41ee 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -29,9 +29,9 @@ struct CurveCache; struct GPUMaterial; struct GPUTexture; -struct Gwn_Batch; -struct Gwn_IndexBuf; -struct Gwn_VertBuf; +struct GPUBatch; +struct GPUIndexBuf; +struct GPUVertBuf; struct ListBase; struct ModifierData; struct ParticleSystem; @@ -59,71 +59,71 @@ void DRW_particle_batch_cache_dirty(struct ParticleSystem *psys, int mode); void DRW_particle_batch_cache_free(struct ParticleSystem *psys); /* Curve */ -struct Gwn_Batch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache); -struct Gwn_Batch *DRW_curve_batch_cache_get_normal_edge( +struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache); +struct GPUBatch *DRW_curve_batch_cache_get_normal_edge( struct Curve *cu, struct CurveCache *ob_curve_cache, float normal_size); -struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_edges(struct Curve *cu); -struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_overlay_edges(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu); -struct Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals( +struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals( struct Curve *cu, struct CurveCache *ob_curve_cache); -struct Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( +struct GPUBatch **DRW_curve_batch_cache_get_surface_shaded( struct Curve *cu, struct CurveCache *ob_curve_cache, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* Metaball */ -struct Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); -struct Gwn_Batch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, struct MetaBall *mb, struct GPUMaterial **gpumat_array, uint gpumat_array_len); +struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob); +struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, struct MetaBall *mb, struct GPUMaterial **gpumat_array, uint gpumat_array_len); /* Curve (Font) */ -struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu); -struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_select(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu); +struct GPUBatch *DRW_curve_batch_cache_get_overlay_select(struct Curve *cu); /* DispList */ -struct Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(struct ListBase *lb); -struct Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(struct ListBase *lb); -struct Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material( +struct GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(struct ListBase *lb); +struct GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(struct ListBase *lb); +struct GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material( struct ListBase *lb, uint gpumat_array_len); -struct Gwn_Batch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material( +struct GPUBatch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material( struct ListBase *lb, uint gpumat_array_len); /* Lattice */ -struct Gwn_Batch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef); -struct Gwn_Batch *DRW_lattice_batch_cache_get_all_verts(struct Lattice *lt); -struct Gwn_Batch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt); +struct GPUBatch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef); +struct GPUBatch *DRW_lattice_batch_cache_get_all_verts(struct Lattice *lt); +struct GPUBatch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt); /* Mesh */ -struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded( +struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); -struct Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel); -struct Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup); -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset); -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide); -struct Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me, bool *r_is_manifold); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me); -struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me); +struct GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(struct Mesh *me, bool use_wire, bool use_sel); +struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup); +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset); +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide); +struct GPUBatch *DRW_mesh_batch_cache_get_loose_edges_with_normals(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me, bool *r_is_manifold); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles_nor(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me); /* edit-mesh selection (use generic function for faces) */ -struct Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset); -struct Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset); -struct Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset); +struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset); +struct GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset); +struct GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset); /* Object mode Wireframe overlays */ void DRW_mesh_batch_cache_get_wireframes_face_texbuf( struct Mesh *me, struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count); @@ -131,15 +131,15 @@ void DRW_mesh_batch_cache_get_wireframes_face_texbuf( void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me); /* Particles */ -struct Gwn_Batch *DRW_particles_batch_cache_get_hair( +struct GPUBatch *DRW_particles_batch_cache_get_hair( struct Object *object, struct ParticleSystem *psys, struct ModifierData *md); -struct Gwn_Batch *DRW_particles_batch_cache_get_dots( +struct GPUBatch *DRW_particles_batch_cache_get_dots( struct Object *object, struct ParticleSystem *psys); -struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands( +struct GPUBatch *DRW_particles_batch_cache_get_edit_strands( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points( +struct GPUBatch *DRW_particles_batch_cache_get_edit_inner_points( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); -struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points( +struct GPUBatch *DRW_particles_batch_cache_get_edit_tip_points( struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit); #endif /* __DRAW_CACHE_IMPL_H__ */ diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index 4de1dfd24f5..cfaa3c6914f 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -298,43 +298,43 @@ enum { }; /* ---------------------------------------------------------------------- */ -/* Curve Gwn_Batch Cache */ +/* Curve GPUBatch Cache */ typedef struct CurveBatchCache { /* center-line */ struct { - Gwn_VertBuf *verts; - Gwn_VertBuf *edges; - Gwn_Batch *batch; - Gwn_IndexBuf *elem; + GPUVertBuf *verts; + GPUVertBuf *edges; + GPUBatch *batch; + GPUIndexBuf *elem; } wire; /* normals */ struct { - Gwn_VertBuf *verts; - Gwn_VertBuf *edges; - Gwn_Batch *batch; - Gwn_IndexBuf *elem; + GPUVertBuf *verts; + GPUVertBuf *edges; + GPUBatch *batch; + GPUIndexBuf *elem; } normal; /* control handles and vertices */ struct { - Gwn_Batch *edges; - Gwn_Batch *verts; + GPUBatch *edges; + GPUBatch *verts; } overlay; struct { - Gwn_VertBuf *verts; - Gwn_IndexBuf *triangles_in_order; - Gwn_Batch **shaded_triangles; - Gwn_Batch *batch; + GPUVertBuf *verts; + GPUIndexBuf *triangles_in_order; + GPUBatch **shaded_triangles; + GPUBatch *batch; int mat_len; } surface; /* 3d text */ struct { - Gwn_Batch *select; - Gwn_Batch *cursor; + GPUBatch *select; + GPUBatch *cursor; } text; /* settings to determine if cache is invalid */ @@ -348,7 +348,7 @@ typedef struct CurveBatchCache { bool is_editmode; } CurveBatchCache; -/* Gwn_Batch cache management. */ +/* GPUBatch cache management. */ static bool curve_batch_cache_valid(Curve *cu) { @@ -434,12 +434,12 @@ void DRW_curve_batch_cache_dirty(Curve *cu, int mode) break; case BKE_CURVE_BATCH_DIRTY_SELECT: /* editnurb */ - GWN_BATCH_DISCARD_SAFE(cache->overlay.verts); - GWN_BATCH_DISCARD_SAFE(cache->overlay.edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay.verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay.edges); /* editfont */ - GWN_BATCH_DISCARD_SAFE(cache->text.select); - GWN_BATCH_DISCARD_SAFE(cache->text.cursor); + GPU_BATCH_DISCARD_SAFE(cache->text.select); + GPU_BATCH_DISCARD_SAFE(cache->text.cursor); break; default: BLI_assert(0); @@ -453,34 +453,34 @@ static void curve_batch_cache_clear(Curve *cu) return; } - GWN_BATCH_DISCARD_SAFE(cache->overlay.verts); - GWN_BATCH_DISCARD_SAFE(cache->overlay.edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay.verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay.edges); - GWN_VERTBUF_DISCARD_SAFE(cache->surface.verts); - GWN_INDEXBUF_DISCARD_SAFE(cache->surface.triangles_in_order); + GPU_VERTBUF_DISCARD_SAFE(cache->surface.verts); + GPU_INDEXBUF_DISCARD_SAFE(cache->surface.triangles_in_order); if (cache->surface.shaded_triangles) { for (int i = 0; i < cache->surface.mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); } } MEM_SAFE_FREE(cache->surface.shaded_triangles); - GWN_BATCH_DISCARD_SAFE(cache->surface.batch); + GPU_BATCH_DISCARD_SAFE(cache->surface.batch); /* don't own vbo & elems */ - GWN_BATCH_DISCARD_SAFE(cache->wire.batch); - GWN_VERTBUF_DISCARD_SAFE(cache->wire.verts); - GWN_VERTBUF_DISCARD_SAFE(cache->wire.edges); - GWN_INDEXBUF_DISCARD_SAFE(cache->wire.elem); + GPU_BATCH_DISCARD_SAFE(cache->wire.batch); + GPU_VERTBUF_DISCARD_SAFE(cache->wire.verts); + GPU_VERTBUF_DISCARD_SAFE(cache->wire.edges); + GPU_INDEXBUF_DISCARD_SAFE(cache->wire.elem); /* don't own vbo & elems */ - GWN_BATCH_DISCARD_SAFE(cache->normal.batch); - GWN_VERTBUF_DISCARD_SAFE(cache->normal.verts); - GWN_VERTBUF_DISCARD_SAFE(cache->normal.edges); - GWN_INDEXBUF_DISCARD_SAFE(cache->normal.elem); + GPU_BATCH_DISCARD_SAFE(cache->normal.batch); + GPU_VERTBUF_DISCARD_SAFE(cache->normal.verts); + GPU_VERTBUF_DISCARD_SAFE(cache->normal.edges); + GPU_INDEXBUF_DISCARD_SAFE(cache->normal.elem); /* 3d text */ - GWN_BATCH_DISCARD_SAFE(cache->text.cursor); - GWN_BATCH_DISCARD_SAFE(cache->text.select); + GPU_BATCH_DISCARD_SAFE(cache->text.cursor); + GPU_BATCH_DISCARD_SAFE(cache->text.select); } void DRW_curve_batch_cache_free(Curve *cu) @@ -494,30 +494,30 @@ void DRW_curve_batch_cache_free(Curve *cu) /** \name Private Curve Cache API * \{ */ -/* Gwn_Batch cache usage. */ -static Gwn_VertBuf *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, CurveBatchCache *cache) +/* GPUBatch cache usage. */ +static GPUVertBuf *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_WIRE); BLI_assert(rdata->ob_curve_cache != NULL); if (cache->wire.verts == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } const int vert_len = curve_render_data_wire_verts_len_get(rdata); - Gwn_VertBuf *vbo = cache->wire.verts = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_len); + GPUVertBuf *vbo = cache->wire.verts = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vert_len); int vbo_len_used = 0; for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { if (bl->nr > 0) { const int i_end = vbo_len_used + bl->nr; for (const BevPoint *bevp = bl->bevpoints; vbo_len_used < i_end; vbo_len_used++, bevp++) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bevp->vec); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bevp->vec); } } } @@ -527,7 +527,7 @@ static Gwn_VertBuf *curve_batch_cache_get_wire_verts(CurveRenderData *rdata, Cur return cache->wire.verts; } -static Gwn_IndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUIndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_WIRE); BLI_assert(rdata->ob_curve_cache != NULL); @@ -537,8 +537,8 @@ static Gwn_IndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, Cu const int edge_len = curve_render_data_wire_edges_len_get(rdata); int edge_len_used = 0; - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); int i = 0; for (const BevList *bl = rdata->ob_curve_cache->bev.first; bl; bl = bl->next) { @@ -554,7 +554,7 @@ static Gwn_IndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, Cu i += 1; } for (; i < i_end; i_prev = i++) { - GWN_indexbuf_add_line_verts(&elb, i_prev, i); + GPU_indexbuf_add_line_verts(&elb, i_prev, i); edge_len_used += 1; } } @@ -567,30 +567,30 @@ static Gwn_IndexBuf *curve_batch_cache_get_wire_edges(CurveRenderData *rdata, Cu BLI_assert(edge_len_used == edge_len); } - cache->wire.elem = GWN_indexbuf_build(&elb); + cache->wire.elem = GPU_indexbuf_build(&elb); } return cache->wire.elem; } -static Gwn_VertBuf *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUVertBuf *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_NORMAL); BLI_assert(rdata->ob_curve_cache != NULL); if (cache->normal.verts == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } const int normal_len = curve_render_data_normal_len_get(rdata); const int vert_len = normal_len * 3; - Gwn_VertBuf *vbo = cache->normal.verts = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_len); + GPUVertBuf *vbo = cache->normal.verts = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vert_len); int vbo_len_used = 0; const BevList *bl; @@ -622,9 +622,9 @@ static Gwn_VertBuf *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, C add_v3_v3(vec_a, bevp->vec); add_v3_v3(vec_b, bevp->vec); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_a); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, bevp->vec); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_b); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_a); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, bevp->vec); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, vec_b); bevp += skip + 1; nr -= skip; @@ -636,7 +636,7 @@ static Gwn_VertBuf *curve_batch_cache_get_normal_verts(CurveRenderData *rdata, C return cache->normal.verts; } -static Gwn_IndexBuf *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUIndexBuf *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_NORMAL); BLI_assert(rdata->ob_curve_cache != NULL); @@ -646,19 +646,19 @@ static Gwn_IndexBuf *curve_batch_cache_get_normal_edges(CurveRenderData *rdata, const int vert_len = normal_len * 3; const int edge_len = normal_len * 2; - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); int vbo_len_used = 0; for (int i = 0; i < normal_len; i++) { - GWN_indexbuf_add_line_verts(&elb, vbo_len_used + 0, vbo_len_used + 1); - GWN_indexbuf_add_line_verts(&elb, vbo_len_used + 1, vbo_len_used + 2); + GPU_indexbuf_add_line_verts(&elb, vbo_len_used + 0, vbo_len_used + 1); + GPU_indexbuf_add_line_verts(&elb, vbo_len_used + 1, vbo_len_used + 2); vbo_len_used += 3; } BLI_assert(vbo_len_used == vert_len); - cache->normal.elem = GWN_indexbuf_build(&elb); + cache->normal.elem = GPU_indexbuf_build(&elb); } return cache->normal.elem; @@ -673,18 +673,18 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) CurveRenderData *rdata = curve_render_data_create(cu, NULL, options); if (cache->overlay.verts == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.data = GWN_vertformat_attr_add(&format, "data", GWN_COMP_U8, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = curve_render_data_overlay_verts_len_get(rdata); int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); int i = 0; for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next) { if (nu->bezt) { @@ -697,16 +697,16 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) if (rdata->hide_handles) { vflag = (bezt->f2 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]); - GWN_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]); + GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); vbo_len_used += 1; } else { for (int j = 0; j < 3; j++) { vflag = ((&bezt->f1)[j] & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]); - GWN_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j]); + GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); vbo_len_used += 1; } } @@ -721,8 +721,8 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) const bool is_active = (i == rdata->actvert); char vflag; vflag = (bp->f1 & SELECT) ? (is_active ? VFLAG_VERTEX_ACTIVE : VFLAG_VERTEX_SELECTED) : 0; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp->vec); - GWN_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp->vec); + GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &vflag); vbo_len_used += 1; } i += 1; @@ -731,29 +731,29 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) i += nu->pntsu; } if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } - cache->overlay.verts = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->overlay.verts = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); } if ((cache->overlay.edges == NULL) && (rdata->hide_handles == false)) { /* Note: we could reference indices to vertices (above) */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.data = GWN_vertformat_attr_add(&format, "data", GWN_COMP_U8, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int edge_len = curve_render_data_overlay_edges_len_get(rdata); const int vbo_len_capacity = edge_len * 2; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); int i = 0; for (Nurb *nu = rdata->nurbs->first; nu; nu = nu->next, i++) { const bool is_active_nurb = (i == cu->actnu); @@ -766,7 +766,7 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) for (int j = 0; j < 2; j += 1) { /* same vertex twice, only check different selection */ - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[1]); vbo_len_used += 1; col_id = (&bezt->h1)[j]; @@ -777,8 +777,8 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) col_id |= ACTIVE_NURB; } - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j * 2]); - GWN_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bezt->vec[j * 2]); + GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); vbo_len_used += 1; } } @@ -794,11 +794,11 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) col_id |= ACTIVE_NURB; } - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_prev->vec); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_prev->vec); vbo_len_used += 1; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_curr->vec); - GWN_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, bp_curr->vec); + GPU_vertbuf_attr_set(vbo, attr_id.data, vbo_len_used, &col_id); vbo_len_used += 1; } @@ -806,16 +806,16 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu) } } if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } - cache->overlay.edges = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->overlay.edges = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } curve_render_data_free(rdata); } -static Gwn_Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUBatch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_SURFACE); if (cache->surface.batch == NULL) { @@ -827,8 +827,8 @@ static Gwn_Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, if (cache->surface.triangles_in_order == NULL) { cache->surface.triangles_in_order = DRW_displist_indexbuf_calc_triangles_in_order(lb); } - cache->surface.batch = GWN_batch_create( - GWN_PRIM_TRIS, cache->surface.verts, cache->surface.triangles_in_order); + cache->surface.batch = GPU_batch_create( + GPU_PRIM_TRIS, cache->surface.verts, cache->surface.triangles_in_order); } return cache->surface.batch; @@ -843,21 +843,21 @@ static Gwn_Batch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, * \{ */ -static Gwn_Batch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUBatch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); if (cache->text.select == NULL) { EditFont *ef = rdata->text.edit_font; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = ef->selboxes_len * 6; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); float box[4][3]; @@ -904,37 +904,37 @@ static Gwn_Batch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, C add_v2_v2(box[3], &sb->x); } - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[1]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[3]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[0]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[2]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[3]); } BLI_assert(vbo_len_used == vbo_len_capacity); - cache->text.select = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->text.select = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } return cache->text.select; } -static Gwn_Batch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, CurveBatchCache *cache) +static GPUBatch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, CurveBatchCache *cache) { BLI_assert(rdata->types & CU_DATATYPE_TEXT_SELECT); if (cache->text.cursor == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = 4; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); for (int i = 0; i < 4; i++) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->text.edit_font->textcurs[i]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->text.edit_font->textcurs[i]); } - cache->text.cursor = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->text.cursor = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO); } return cache->text.cursor; } @@ -946,7 +946,7 @@ static Gwn_Batch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, C /** \name Public Object/Curve API * \{ */ -Gwn_Batch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_cache) +GPUBatch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_cache) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -954,8 +954,8 @@ Gwn_Batch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_c /* create batch from Curve */ CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_WIRE); - cache->wire.batch = GWN_batch_create( - GWN_PRIM_LINES, + cache->wire.batch = GPU_batch_create( + GPU_PRIM_LINES, curve_batch_cache_get_wire_verts(rdata, cache), curve_batch_cache_get_wire_edges(rdata, cache)); @@ -964,15 +964,15 @@ Gwn_Batch *DRW_curve_batch_cache_get_wire_edge(Curve *cu, CurveCache *ob_curve_c return cache->wire.batch; } -Gwn_Batch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve_cache, float normal_size) +GPUBatch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve_cache, float normal_size) { CurveBatchCache *cache = curve_batch_cache_get(cu); if (cache->normal.batch != NULL) { cache->normal_size = normal_size; if (cache->normal_size != normal_size) { - GWN_BATCH_DISCARD_SAFE(cache->normal.batch); - GWN_VERTBUF_DISCARD_SAFE(cache->normal.edges); + GPU_BATCH_DISCARD_SAFE(cache->normal.batch); + GPU_VERTBUF_DISCARD_SAFE(cache->normal.edges); } } cache->normal_size = normal_size; @@ -981,8 +981,8 @@ Gwn_Batch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve /* create batch from Curve */ CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_NORMAL); - cache->normal.batch = GWN_batch_create( - GWN_PRIM_LINES, + cache->normal.batch = GPU_batch_create( + GPU_PRIM_LINES, curve_batch_cache_get_normal_verts(rdata, cache), curve_batch_cache_get_normal_edges(rdata, cache)); @@ -992,7 +992,7 @@ Gwn_Batch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve return cache->normal.batch; } -Gwn_Batch *DRW_curve_batch_cache_get_overlay_edges(Curve *cu) +GPUBatch *DRW_curve_batch_cache_get_overlay_edges(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -1003,7 +1003,7 @@ Gwn_Batch *DRW_curve_batch_cache_get_overlay_edges(Curve *cu) return cache->overlay.edges; } -Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(Curve *cu) +GPUBatch *DRW_curve_batch_cache_get_overlay_verts(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -1014,7 +1014,7 @@ Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(Curve *cu) return cache->overlay.verts; } -Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals( +GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals( struct Curve *cu, struct CurveCache *ob_curve_cache) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -1030,7 +1030,7 @@ Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals( return cache->surface.batch; } -Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( +GPUBatch **DRW_curve_batch_cache_get_surface_shaded( struct Curve *cu, struct CurveCache *ob_curve_cache, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) { @@ -1040,7 +1040,7 @@ Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( /* TODO: deduplicate code */ if (cache->surface.shaded_triangles) { for (int i = 0; i < cache->surface.mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->surface.shaded_triangles[i]); } } MEM_SAFE_FREE(cache->surface.shaded_triangles); @@ -1058,7 +1058,7 @@ Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( else { cache->surface.shaded_triangles = MEM_mallocN( sizeof(*cache->surface.shaded_triangles) * gpumat_array_len, __func__); - Gwn_IndexBuf **el = DRW_displist_indexbuf_calc_triangles_in_order_split_by_material( + GPUIndexBuf **el = DRW_displist_indexbuf_calc_triangles_in_order_split_by_material( lb, gpumat_array_len); if (cache->surface.verts == NULL) { @@ -1066,8 +1066,8 @@ Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( } for (int i = 0; i < gpumat_array_len; ++i) { - cache->surface.shaded_triangles[i] = GWN_batch_create_ex( - GWN_PRIM_TRIS, cache->surface.verts, el[i], GWN_BATCH_OWNS_INDEX); + cache->surface.shaded_triangles[i] = GPU_batch_create_ex( + GPU_PRIM_TRIS, cache->surface.verts, el[i], GPU_BATCH_OWNS_INDEX); } MEM_freeN(el); /* Save `el` in cache? */ @@ -1085,7 +1085,7 @@ Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded( /** \name Public Object/Font API * \{ */ -Gwn_Batch *DRW_curve_batch_cache_get_overlay_select(Curve *cu) +GPUBatch *DRW_curve_batch_cache_get_overlay_select(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); @@ -1100,7 +1100,7 @@ Gwn_Batch *DRW_curve_batch_cache_get_overlay_select(Curve *cu) return cache->text.select; } -Gwn_Batch *DRW_curve_batch_cache_get_overlay_cursor(Curve *cu) +GPUBatch *DRW_curve_batch_cache_get_overlay_cursor(Curve *cu) { CurveBatchCache *cache = curve_batch_cache_get(cu); diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c index 8d187af0501..5ea0f6fb05d 100644 --- a/source/blender/draw/intern/draw_cache_impl_displist.c +++ b/source/blender/draw/intern/draw_cache_impl_displist.c @@ -87,49 +87,49 @@ static int curve_render_surface_tri_len_get(const ListBase *lb) return tri_len; } -static void displist_indexbufbuilder_set(Gwn_IndexBufBuilder *elb, const DispList *dl, const int ofs) +static void displist_indexbufbuilder_set(GPUIndexBufBuilder *elb, const DispList *dl, const int ofs) { if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { const int *idx = dl->index; if (dl->type == DL_INDEX3) { const int i_end = dl->parts; for (int i = 0; i < i_end; i++, idx += 3) { - GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); + GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); } } else if (dl->type == DL_SURF) { const int i_end = dl->totindex; for (int i = 0; i < i_end; i++, idx += 4) { - GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); - GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[3] + ofs, idx[2] + ofs); + GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs); + GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[3] + ofs, idx[2] + ofs); } } else { BLI_assert(dl->type == DL_INDEX4); const int i_end = dl->parts; for (int i = 0; i < i_end; i++, idx += 4) { - GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); + GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs); if (idx[2] != idx[3]) { - GWN_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); + GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs); } } } } } -Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) +GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, curve_render_surface_vert_len_get(lb)); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, curve_render_surface_vert_len_get(lb)); BKE_displist_normals_add(lb); @@ -141,9 +141,9 @@ Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) const float *fp_no = dl->nors; const int vbo_end = vbo_len_used + dl_vert_len(dl); while (vbo_len_used < vbo_end) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co); if (fp_no) { - GWN_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, fp_no); + GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, fp_no); if (ndata_is_single == false) { fp_no += 3; } @@ -157,13 +157,13 @@ Gwn_VertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb) return vbo; } -Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) +GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) { const int tri_len = curve_render_surface_tri_len_get(lb); const int vert_len = curve_render_surface_vert_len_get(lb); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); int ofs = 0; for (const DispList *dl = lb->first; dl; dl = dl->next) { @@ -171,14 +171,14 @@ Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb) ofs += dl_vert_len(dl); } - return GWN_indexbuf_build(&elb); + return GPU_indexbuf_build(&elb); } -Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(ListBase *lb, uint gpumat_array_len) +GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(ListBase *lb, uint gpumat_array_len) { - Gwn_IndexBuf **shaded_triangles_in_order = MEM_callocN( + GPUIndexBuf **shaded_triangles_in_order = MEM_callocN( sizeof(*shaded_triangles_in_order) * gpumat_array_len, __func__); - Gwn_IndexBufBuilder *elb = BLI_array_alloca(elb, gpumat_array_len); + GPUIndexBufBuilder *elb = BLI_array_alloca(elb, gpumat_array_len); const int tri_len = curve_render_surface_tri_len_get(lb); const int vert_len = curve_render_surface_vert_len_get(lb); @@ -186,7 +186,7 @@ Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(L /* Init each index buffer builder */ for (i = 0; i < gpumat_array_len; i++) { - GWN_indexbuf_init(&elb[i], GWN_PRIM_TRIS, tri_len, vert_len); + GPU_indexbuf_init(&elb[i], GPU_PRIM_TRIS, tri_len, vert_len); } /* calc each index buffer builder */ @@ -198,56 +198,56 @@ Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(L /* build each indexbuf */ for (i = 0; i < gpumat_array_len; i++) { - shaded_triangles_in_order[i] = GWN_indexbuf_build(&elb[i]); + shaded_triangles_in_order[i] = GPU_indexbuf_build(&elb[i]); } return shaded_triangles_in_order; } static void displist_vertbuf_attr_set_tri_pos_normals_and_uv( - Gwn_VertBufRaw *pos_step, Gwn_VertBufRaw *nor_step, Gwn_VertBufRaw *uv_step, + GPUVertBufRaw *pos_step, GPUVertBufRaw *nor_step, GPUVertBufRaw *uv_step, const float v1[3], const float v2[3], const float v3[3], const float n1[3], const float n2[3], const float n3[3], const float uv1[2], const float uv2[2], const float uv3[2]) { - copy_v3_v3(GWN_vertbuf_raw_step(pos_step), v1); - copy_v3_v3(GWN_vertbuf_raw_step(nor_step), n1); - copy_v2_v2(GWN_vertbuf_raw_step(uv_step), uv1); + copy_v3_v3(GPU_vertbuf_raw_step(pos_step), v1); + copy_v3_v3(GPU_vertbuf_raw_step(nor_step), n1); + copy_v2_v2(GPU_vertbuf_raw_step(uv_step), uv1); - copy_v3_v3(GWN_vertbuf_raw_step(pos_step), v2); - copy_v3_v3(GWN_vertbuf_raw_step(nor_step), n2); - copy_v2_v2(GWN_vertbuf_raw_step(uv_step), uv2); + copy_v3_v3(GPU_vertbuf_raw_step(pos_step), v2); + copy_v3_v3(GPU_vertbuf_raw_step(nor_step), n2); + copy_v2_v2(GPU_vertbuf_raw_step(uv_step), uv2); - copy_v3_v3(GWN_vertbuf_raw_step(pos_step), v3); - copy_v3_v3(GWN_vertbuf_raw_step(nor_step), n3); - copy_v2_v2(GWN_vertbuf_raw_step(uv_step), uv3); + copy_v3_v3(GPU_vertbuf_raw_step(pos_step), v3); + copy_v3_v3(GPU_vertbuf_raw_step(nor_step), n3); + copy_v2_v2(GPU_vertbuf_raw_step(uv_step), uv3); } -Gwn_Batch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(ListBase *lb, uint gpumat_array_len) +GPUBatch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(ListBase *lb, uint gpumat_array_len) { - static Gwn_VertFormat shaded_triangles_format = { 0 }; + static GPUVertFormat shaded_triangles_format = { 0 }; static struct { uint pos, nor, uv; } attr_id; if (shaded_triangles_format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&shaded_triangles_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&shaded_triangles_format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.uv = GWN_vertformat_attr_add(&shaded_triangles_format, "u", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&shaded_triangles_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&shaded_triangles_format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.uv = GPU_vertformat_attr_add(&shaded_triangles_format, "u", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_Batch **shaded_triangles = MEM_mallocN(sizeof(*shaded_triangles) * gpumat_array_len, __func__); + GPUBatch **shaded_triangles = MEM_mallocN(sizeof(*shaded_triangles) * gpumat_array_len, __func__); - Gwn_VertBuf **vbo = BLI_array_alloca(vbo, gpumat_array_len); + GPUVertBuf **vbo = BLI_array_alloca(vbo, gpumat_array_len); uint *vbo_len_capacity = BLI_array_alloca(vbo_len_capacity, gpumat_array_len); - Gwn_VertBufRaw *pos_step, *nor_step, *uv_step; + GPUVertBufRaw *pos_step, *nor_step, *uv_step; pos_step = BLI_array_alloca(pos_step, gpumat_array_len); nor_step = BLI_array_alloca(nor_step, gpumat_array_len); uv_step = BLI_array_alloca(uv_step, gpumat_array_len); /* Create each vertex buffer */ for (int i = 0; i < gpumat_array_len; i++) { - vbo[i] = GWN_vertbuf_create_with_format(&shaded_triangles_format); + vbo[i] = GPU_vertbuf_create_with_format(&shaded_triangles_format); vbo_len_capacity[i] = 0; } @@ -258,10 +258,10 @@ Gwn_Batch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(Lis /* Alloc each vertex buffer and get each raw data */ for (int i = 0; i < gpumat_array_len; i++) { - GWN_vertbuf_data_alloc(vbo[i], vbo_len_capacity[i]); - GWN_vertbuf_attr_get_raw_data(vbo[i], attr_id.pos, &pos_step[i]); - GWN_vertbuf_attr_get_raw_data(vbo[i], attr_id.nor, &nor_step[i]); - GWN_vertbuf_attr_get_raw_data(vbo[i], attr_id.uv, &uv_step[i]); + GPU_vertbuf_data_alloc(vbo[i], vbo_len_capacity[i]); + GPU_vertbuf_attr_get_raw_data(vbo[i], attr_id.pos, &pos_step[i]); + GPU_vertbuf_attr_get_raw_data(vbo[i], attr_id.nor, &nor_step[i]); + GPU_vertbuf_attr_get_raw_data(vbo[i], attr_id.uv, &uv_step[i]); } BKE_displist_normals_add(lb); @@ -388,11 +388,11 @@ Gwn_Batch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(Lis } for (int i = 0; i < gpumat_array_len; i++) { - uint vbo_len_used = GWN_vertbuf_raw_used(&pos_step[i]); + uint vbo_len_used = GPU_vertbuf_raw_used(&pos_step[i]); if (vbo_len_capacity[i] != vbo_len_used) { - GWN_vertbuf_data_resize(vbo[i], vbo_len_used); + GPU_vertbuf_data_resize(vbo[i], vbo_len_used); } - shaded_triangles[i] = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo[i], NULL, GWN_BATCH_OWNS_VBO); + shaded_triangles[i] = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo[i], NULL, GPU_BATCH_OWNS_VBO); } return shaded_triangles; diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c index 99dce2d7343..d6acc4112d6 100644 --- a/source/blender/draw/intern/draw_cache_impl_lattice.c +++ b/source/blender/draw/intern/draw_cache_impl_lattice.c @@ -279,16 +279,16 @@ enum { }; /* ---------------------------------------------------------------------- */ -/* Lattice Gwn_Batch Cache */ +/* Lattice GPUBatch Cache */ typedef struct LatticeBatchCache { - Gwn_VertBuf *pos; - Gwn_IndexBuf *edges; + GPUVertBuf *pos; + GPUIndexBuf *edges; - Gwn_Batch *all_verts; - Gwn_Batch *all_edges; + GPUBatch *all_verts; + GPUBatch *all_edges; - Gwn_Batch *overlay_verts; + GPUBatch *overlay_verts; /* settings to determine if cache is invalid */ bool is_dirty; @@ -301,7 +301,7 @@ typedef struct LatticeBatchCache { bool is_editmode; } LatticeBatchCache; -/* Gwn_Batch cache management. */ +/* GPUBatch cache management. */ static bool lattice_batch_cache_valid(Lattice *lt) { @@ -373,7 +373,7 @@ void DRW_lattice_batch_cache_dirty(Lattice *lt, int mode) break; case BKE_LATTICE_BATCH_DIRTY_SELECT: /* TODO Separate Flag vbo */ - GWN_BATCH_DISCARD_SAFE(cache->overlay_verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay_verts); break; default: BLI_assert(0); @@ -387,12 +387,12 @@ static void lattice_batch_cache_clear(Lattice *lt) return; } - GWN_BATCH_DISCARD_SAFE(cache->all_verts); - GWN_BATCH_DISCARD_SAFE(cache->all_edges); - GWN_BATCH_DISCARD_SAFE(cache->overlay_verts); + GPU_BATCH_DISCARD_SAFE(cache->all_verts); + GPU_BATCH_DISCARD_SAFE(cache->all_edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay_verts); - GWN_VERTBUF_DISCARD_SAFE(cache->pos); - GWN_INDEXBUF_DISCARD_SAFE(cache->edges); + GPU_VERTBUF_DISCARD_SAFE(cache->pos); + GPU_INDEXBUF_DISCARD_SAFE(cache->edges); } void DRW_lattice_batch_cache_free(Lattice *lt) @@ -401,38 +401,38 @@ void DRW_lattice_batch_cache_free(Lattice *lt) MEM_SAFE_FREE(lt->batch_cache); } -/* Gwn_Batch cache usage. */ -static Gwn_VertBuf *lattice_batch_cache_get_pos(LatticeRenderData *rdata, LatticeBatchCache *cache, +/* GPUBatch cache usage. */ +static GPUVertBuf *lattice_batch_cache_get_pos(LatticeRenderData *rdata, LatticeBatchCache *cache, bool use_weight, const int actdef) { BLI_assert(rdata->types & LR_DATATYPE_VERT); if (cache->pos == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, col; } attr_id; - GWN_vertformat_clear(&format); + GPU_vertformat_clear(&format); /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); if (use_weight) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } const int vert_len = lattice_render_data_verts_len_get(rdata); - cache->pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->pos, vert_len); + cache->pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache->pos, vert_len); for (int i = 0; i < vert_len; ++i) { const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i); - GWN_vertbuf_attr_set(cache->pos, attr_id.pos, i, bp->vec); + GPU_vertbuf_attr_set(cache->pos, attr_id.pos, i, bp->vec); if (use_weight) { float w_col[4]; lattice_render_data_weight_col_get(rdata, i, actdef, w_col); - GWN_vertbuf_attr_set(cache->pos, attr_id.col, i, w_col); + GPU_vertbuf_attr_set(cache->pos, attr_id.col, i, w_col); } } } @@ -440,7 +440,7 @@ static Gwn_VertBuf *lattice_batch_cache_get_pos(LatticeRenderData *rdata, Lattic return cache->pos; } -static Gwn_IndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, LatticeBatchCache *cache) +static GPUIndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, LatticeBatchCache *cache) { BLI_assert(rdata->types & (LR_DATATYPE_VERT | LR_DATATYPE_EDGE)); @@ -449,8 +449,8 @@ static Gwn_IndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, Lat const int edge_len = lattice_render_data_edges_len_get(rdata); int edge_len_real = 0; - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); #define LATT_INDEX(u, v, w) \ ((((w) * rdata->dims.v_len + (v)) * rdata->dims.u_len) + (u)) @@ -463,17 +463,17 @@ static Gwn_IndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, Lat int uxt = (u == 0 || u == rdata->dims.u_len - 1); if (w && ((uxt || vxt) || !rdata->show_only_outside)) { - GWN_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w)); + GPU_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w)); BLI_assert(edge_len_real <= edge_len); edge_len_real++; } if (v && ((uxt || wxt) || !rdata->show_only_outside)) { - GWN_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v - 1, w), LATT_INDEX(u, v, w)); + GPU_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v - 1, w), LATT_INDEX(u, v, w)); BLI_assert(edge_len_real <= edge_len); edge_len_real++; } if (u && ((vxt || wxt) || !rdata->show_only_outside)) { - GWN_indexbuf_add_line_verts(&elb, LATT_INDEX(u - 1, v, w), LATT_INDEX(u, v, w)); + GPU_indexbuf_add_line_verts(&elb, LATT_INDEX(u - 1, v, w), LATT_INDEX(u, v, w)); BLI_assert(edge_len_real <= edge_len); edge_len_real++; } @@ -490,7 +490,7 @@ static Gwn_IndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, Lat BLI_assert(edge_len_real == edge_len); } - cache->edges = GWN_indexbuf_build(&elb); + cache->edges = GPU_indexbuf_build(&elb); } return cache->edges; @@ -505,18 +505,18 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt) LatticeRenderData *rdata = lattice_render_data_create(lt, options); if (cache->overlay_verts == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.data = GWN_vertformat_attr_add(&format, "data", GWN_COMP_U8, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); } const int vert_len = lattice_render_data_verts_len_get(rdata); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_len); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vert_len); for (int i = 0; i < vert_len; ++i) { const BPoint *bp = lattice_render_data_vert_bpoint(rdata, i); @@ -530,17 +530,17 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt) } } - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, bp->vec); - GWN_vertbuf_attr_set(vbo, attr_id.data, i, &vflag); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, bp->vec); + GPU_vertbuf_attr_set(vbo, attr_id.data, i, &vflag); } - cache->overlay_verts = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->overlay_verts = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); } lattice_render_data_free(rdata); } -Gwn_Batch *DRW_lattice_batch_cache_get_all_edges(Lattice *lt, bool use_weight, const int actdef) +GPUBatch *DRW_lattice_batch_cache_get_all_edges(Lattice *lt, bool use_weight, const int actdef) { LatticeBatchCache *cache = lattice_batch_cache_get(lt); @@ -548,7 +548,7 @@ Gwn_Batch *DRW_lattice_batch_cache_get_all_edges(Lattice *lt, bool use_weight, c /* create batch from Lattice */ LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT | LR_DATATYPE_EDGE); - cache->all_edges = GWN_batch_create(GWN_PRIM_LINES, lattice_batch_cache_get_pos(rdata, cache, use_weight, actdef), + cache->all_edges = GPU_batch_create(GPU_PRIM_LINES, lattice_batch_cache_get_pos(rdata, cache, use_weight, actdef), lattice_batch_cache_get_edges(rdata, cache)); lattice_render_data_free(rdata); @@ -557,14 +557,14 @@ Gwn_Batch *DRW_lattice_batch_cache_get_all_edges(Lattice *lt, bool use_weight, c return cache->all_edges; } -Gwn_Batch *DRW_lattice_batch_cache_get_all_verts(Lattice *lt) +GPUBatch *DRW_lattice_batch_cache_get_all_verts(Lattice *lt) { LatticeBatchCache *cache = lattice_batch_cache_get(lt); if (cache->all_verts == NULL) { LatticeRenderData *rdata = lattice_render_data_create(lt, LR_DATATYPE_VERT); - cache->all_verts = GWN_batch_create(GWN_PRIM_POINTS, lattice_batch_cache_get_pos(rdata, cache, false, -1), NULL); + cache->all_verts = GPU_batch_create(GPU_PRIM_POINTS, lattice_batch_cache_get_pos(rdata, cache, false, -1), NULL); lattice_render_data_free(rdata); } @@ -572,7 +572,7 @@ Gwn_Batch *DRW_lattice_batch_cache_get_all_verts(Lattice *lt) return cache->all_verts; } -Gwn_Batch *DRW_lattice_batch_cache_get_overlay_verts(Lattice *lt) +GPUBatch *DRW_lattice_batch_cache_get_overlay_verts(Lattice *lt) { LatticeBatchCache *cache = lattice_batch_cache_get(lt); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 7a72622cb9e..5ca1c65054c 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -202,8 +202,8 @@ typedef struct MeshRenderData { float (*poly_normals)[3]; float (*vert_weight_color)[3]; char (*vert_color)[3]; - Gwn_PackedNormal *poly_normals_pack; - Gwn_PackedNormal *vert_normals_pack; + GPUPackedNormal *poly_normals_pack; + GPUPackedNormal *vert_normals_pack; bool *edge_select_bool; } MeshRenderData; @@ -952,7 +952,7 @@ static int mesh_render_data_polys_len_get(const MeshRenderData *rdata) /** Ensure #MeshRenderData.poly_normals_pack */ static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata) { - Gwn_PackedNormal *pnors_pack = rdata->poly_normals_pack; + GPUPackedNormal *pnors_pack = rdata->poly_normals_pack; if (pnors_pack == NULL) { if (rdata->edit_bmesh) { BMesh *bm = rdata->edit_bmesh->bm; @@ -962,7 +962,7 @@ static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata) pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__); BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) { - pnors_pack[i] = GWN_normal_convert_i10_v3(efa->no); + pnors_pack[i] = GPU_normal_convert_i10_v3(efa->no); } } else { @@ -977,7 +977,7 @@ static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata) pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__); for (int i = 0; i < rdata->poly_len; i++) { - pnors_pack[i] = GWN_normal_convert_i10_v3(pnors[i]); + pnors_pack[i] = GPU_normal_convert_i10_v3(pnors[i]); } } } @@ -986,7 +986,7 @@ static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata) /** Ensure #MeshRenderData.vert_normals_pack */ static void mesh_render_data_ensure_vert_normals_pack(MeshRenderData *rdata) { - Gwn_PackedNormal *vnors_pack = rdata->vert_normals_pack; + GPUPackedNormal *vnors_pack = rdata->vert_normals_pack; if (vnors_pack == NULL) { if (rdata->edit_bmesh) { BMesh *bm = rdata->edit_bmesh->bm; @@ -996,7 +996,7 @@ static void mesh_render_data_ensure_vert_normals_pack(MeshRenderData *rdata) vnors_pack = rdata->vert_normals_pack = MEM_mallocN(sizeof(*vnors_pack) * rdata->vert_len, __func__); BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) { - vnors_pack[i] = GWN_normal_convert_i10_v3(eve->no); + vnors_pack[i] = GPU_normal_convert_i10_v3(eve->no); } } else { @@ -1413,7 +1413,7 @@ static uchar mesh_render_data_vertex_flag(MeshRenderData *rdata, const BMVert *e } static void add_overlay_tri( - MeshRenderData *rdata, Gwn_VertBuf *vbo_pos, Gwn_VertBuf *vbo_nor, Gwn_VertBuf *vbo_data, + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data, const uint pos_id, const uint vnor_id, const uint lnor_id, const uint data_id, const BMLoop **bm_looptri, const int base_vert_idx) { @@ -1426,24 +1426,24 @@ static void add_overlay_tri( for (uint i = 0; i < 3; i++) { int vidx = BM_elem_index_get(bm_looptri[i]->v); const float *pos = rdata->edit_data->vertexCos[vidx]; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); } } else { for (uint i = 0; i < 3; i++) { const float *pos = bm_looptri[i]->v->co; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); } } } if (vbo_nor) { /* TODO real loop normal */ - Gwn_PackedNormal lnor = GWN_normal_convert_i10_v3(bm_looptri[0]->f->no); + GPUPackedNormal lnor = GPU_normal_convert_i10_v3(bm_looptri[0]->f->no); for (uint i = 0; i < 3; i++) { - Gwn_PackedNormal vnor = GWN_normal_convert_i10_v3(bm_looptri[i]->v->no); - GWN_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); - GWN_vertbuf_attr_set(vbo_nor, lnor_id, base_vert_idx + i, &lnor); + GPUPackedNormal vnor = GPU_normal_convert_i10_v3(bm_looptri[i]->v->no); + GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); + GPU_vertbuf_attr_set(vbo_nor, lnor_id, base_vert_idx + i, &lnor); } } @@ -1457,7 +1457,7 @@ static void add_overlay_tri( mesh_render_data_edge_flag(rdata, bm_looptri[i_next]->e, &eattr); } eattr.v_flag = fflag | vflag; - GWN_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); + GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); i_prev = i; i = i_next; @@ -1466,7 +1466,7 @@ static void add_overlay_tri( } static void add_overlay_loose_edge( - MeshRenderData *rdata, Gwn_VertBuf *vbo_pos, Gwn_VertBuf *vbo_nor, Gwn_VertBuf *vbo_data, + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data, const uint pos_id, const uint vnor_id, const uint data_id, const BMEdge *eed, const int base_vert_idx) { @@ -1476,21 +1476,21 @@ static void add_overlay_loose_edge( for (uint i = 0; i < 2; i++) { int vidx = BM_elem_index_get((&eed->v1)[i]); const float *pos = rdata->edit_data->vertexCos[vidx]; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); } } else { for (int i = 0; i < 2; ++i) { const float *pos = (&eed->v1)[i]->co; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx + i, pos); } } } if (vbo_nor) { for (int i = 0; i < 2; ++i) { - Gwn_PackedNormal vnor = GWN_normal_convert_i10_v3((&eed->v1)[i]->no); - GWN_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); + GPUPackedNormal vnor = GPU_normal_convert_i10_v3((&eed->v1)[i]->no); + GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx + i, &vnor); } } @@ -1499,13 +1499,13 @@ static void add_overlay_loose_edge( mesh_render_data_edge_flag(rdata, eed, &eattr); for (int i = 0; i < 2; ++i) { eattr.v_flag = mesh_render_data_vertex_flag(rdata, (&eed->v1)[i]); - GWN_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); + GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx + i, &eattr); } } } static void add_overlay_loose_vert( - MeshRenderData *rdata, Gwn_VertBuf *vbo_pos, Gwn_VertBuf *vbo_nor, Gwn_VertBuf *vbo_data, + MeshRenderData *rdata, GPUVertBuf *vbo_pos, GPUVertBuf *vbo_nor, GPUVertBuf *vbo_data, const uint pos_id, const uint vnor_id, const uint data_id, const BMVert *eve, const int base_vert_idx) { @@ -1514,23 +1514,23 @@ static void add_overlay_loose_vert( if (rdata->edit_data && rdata->edit_data->vertexCos) { int vidx = BM_elem_index_get(eve); const float *pos = rdata->edit_data->vertexCos[vidx]; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos); } else { const float *pos = eve->co; - GWN_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos); + GPU_vertbuf_attr_set(vbo_pos, pos_id, base_vert_idx, pos); } } if (vbo_nor) { - Gwn_PackedNormal vnor = GWN_normal_convert_i10_v3(eve->no); - GWN_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx, &vnor); + GPUPackedNormal vnor = GPU_normal_convert_i10_v3(eve->no); + GPU_vertbuf_attr_set(vbo_nor, vnor_id, base_vert_idx, &vnor); } if (vbo_data) { uchar vflag[4] = {0, 0, 0, 0}; vflag[0] = mesh_render_data_vertex_flag(rdata, eve); - GWN_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag); + GPU_vertbuf_attr_set(vbo_data, data_id, base_vert_idx, vflag); } } @@ -1539,96 +1539,96 @@ static void add_overlay_loose_vert( /* ---------------------------------------------------------------------- */ -/** \name Mesh Gwn_Batch Cache +/** \name Mesh GPUBatch Cache * \{ */ typedef struct MeshBatchCache { - Gwn_VertBuf *pos_in_order; - Gwn_IndexBuf *edges_in_order; - Gwn_IndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */ - Gwn_IndexBuf *triangles_in_order; - Gwn_IndexBuf *ledges_in_order; + GPUVertBuf *pos_in_order; + GPUIndexBuf *edges_in_order; + GPUIndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */ + GPUIndexBuf *triangles_in_order; + GPUIndexBuf *ledges_in_order; GPUTexture *pos_in_order_tx; /* Depending on pos_in_order */ - Gwn_Batch *all_verts; - Gwn_Batch *all_edges; - Gwn_Batch *all_triangles; + GPUBatch *all_verts; + GPUBatch *all_edges; + GPUBatch *all_triangles; - Gwn_VertBuf *pos_with_normals; - Gwn_VertBuf *tri_aligned_uv; /* Active UV layer (mloopuv) */ + GPUVertBuf *pos_with_normals; + GPUVertBuf *tri_aligned_uv; /* Active UV layer (mloopuv) */ /** * Other uses are all positions or loose elements. * This stores all visible elements, needed for selection. */ - Gwn_VertBuf *ed_fcenter_pos_with_nor_and_sel; - Gwn_VertBuf *ed_edge_pos; - Gwn_VertBuf *ed_vert_pos; + GPUVertBuf *ed_fcenter_pos_with_nor_and_sel; + GPUVertBuf *ed_edge_pos; + GPUVertBuf *ed_vert_pos; - Gwn_Batch *triangles_with_normals; - Gwn_Batch *ledges_with_normals; + GPUBatch *triangles_with_normals; + GPUBatch *ledges_with_normals; /* Skip hidden (depending on paint select mode) */ - Gwn_Batch *triangles_with_weights; - Gwn_Batch *triangles_with_vert_colors; + GPUBatch *triangles_with_weights; + GPUBatch *triangles_with_vert_colors; /* Always skip hidden */ - Gwn_Batch *triangles_with_select_mask; - Gwn_Batch *triangles_with_select_id; + GPUBatch *triangles_with_select_mask; + GPUBatch *triangles_with_select_id; uint triangles_with_select_id_offset; - Gwn_Batch *facedot_with_select_id; /* shares vbo with 'overlay_facedots' */ - Gwn_Batch *edges_with_select_id; - Gwn_Batch *verts_with_select_id; + GPUBatch *facedot_with_select_id; /* shares vbo with 'overlay_facedots' */ + GPUBatch *edges_with_select_id; + GPUBatch *verts_with_select_id; uint facedot_with_select_id_offset; uint edges_with_select_id_offset; uint verts_with_select_id_offset; - Gwn_Batch *points_with_normals; - Gwn_Batch *fancy_edges; /* owns its vertex buffer (not shared) */ + GPUBatch *points_with_normals; + GPUBatch *fancy_edges; /* owns its vertex buffer (not shared) */ - Gwn_Batch *edge_detection; + GPUBatch *edge_detection; - Gwn_VertBuf *edges_face_overlay; + GPUVertBuf *edges_face_overlay; GPUTexture *edges_face_overlay_tx; int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay(_adj)_tx */ /* Maybe have shaded_triangles_data split into pos_nor and uv_tangent * to minimize data transfer for skinned mesh. */ - Gwn_VertFormat shaded_triangles_format; - Gwn_VertBuf *shaded_triangles_data; - Gwn_IndexBuf **shaded_triangles_in_order; - Gwn_Batch **shaded_triangles; + GPUVertFormat shaded_triangles_format; + GPUVertBuf *shaded_triangles_data; + GPUIndexBuf **shaded_triangles_in_order; + GPUBatch **shaded_triangles; /* Texture Paint.*/ /* per-texture batch */ - Gwn_Batch **texpaint_triangles; - Gwn_Batch *texpaint_triangles_single; + GPUBatch **texpaint_triangles; + GPUBatch *texpaint_triangles_single; /* Edit Cage Mesh buffers */ - Gwn_VertBuf *ed_tri_pos; - Gwn_VertBuf *ed_tri_nor; /* LoopNor, VertNor */ - Gwn_VertBuf *ed_tri_data; + GPUVertBuf *ed_tri_pos; + GPUVertBuf *ed_tri_nor; /* LoopNor, VertNor */ + GPUVertBuf *ed_tri_data; - Gwn_VertBuf *ed_ledge_pos; - Gwn_VertBuf *ed_ledge_nor; /* VertNor */ - Gwn_VertBuf *ed_ledge_data; + GPUVertBuf *ed_ledge_pos; + GPUVertBuf *ed_ledge_nor; /* VertNor */ + GPUVertBuf *ed_ledge_data; - Gwn_VertBuf *ed_lvert_pos; - Gwn_VertBuf *ed_lvert_nor; /* VertNor */ - Gwn_VertBuf *ed_lvert_data; + GPUVertBuf *ed_lvert_pos; + GPUVertBuf *ed_lvert_nor; /* VertNor */ + GPUVertBuf *ed_lvert_data; - Gwn_Batch *overlay_triangles; - Gwn_Batch *overlay_triangles_nor; /* GWN_PRIM_POINTS */ - Gwn_Batch *overlay_loose_edges; - Gwn_Batch *overlay_loose_edges_nor; /* GWN_PRIM_POINTS */ - Gwn_Batch *overlay_loose_verts; - Gwn_Batch *overlay_facedots; + GPUBatch *overlay_triangles; + GPUBatch *overlay_triangles_nor; /* GPU_PRIM_POINTS */ + GPUBatch *overlay_loose_edges; + GPUBatch *overlay_loose_edges_nor; /* GPU_PRIM_POINTS */ + GPUBatch *overlay_loose_verts; + GPUBatch *overlay_facedots; - Gwn_Batch *overlay_weight_faces; - Gwn_Batch *overlay_weight_verts; - Gwn_Batch *overlay_paint_edges; + GPUBatch *overlay_weight_faces; + GPUBatch *overlay_weight_verts; + GPUBatch *overlay_paint_edges; /* arrays of bool uniform names (and value) that will be use to * set srgb conversion for auto attribs.*/ @@ -1653,7 +1653,7 @@ typedef struct MeshBatchCache { bool is_manifold; } MeshBatchCache; -/* Gwn_Batch cache management. */ +/* GPUBatch cache management. */ static bool mesh_batch_cache_valid(Mesh *me) { @@ -1742,21 +1742,21 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode) cache->is_maybe_dirty = true; break; case BKE_MESH_BATCH_DIRTY_SELECT: - GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_data); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */ - GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos); - - GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles); - GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); - GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); - GWN_BATCH_DISCARD_SAFE(cache->overlay_facedots); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_data); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */ + GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos); + + GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay_facedots); /* Edit mode selection. */ - GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id); break; case BKE_MESH_BATCH_DIRTY_ALL: cache->is_dirty = true; @@ -1777,7 +1777,7 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode) /** * This only clear the batches associated to the given vertex buffer. **/ -static void mesh_batch_cache_clear_selective(Mesh *me, Gwn_VertBuf *vert) +static void mesh_batch_cache_clear_selective(Mesh *me, GPUVertBuf *vert) { MeshBatchCache *cache = me->runtime.batch_cache; if (!cache) { @@ -1787,26 +1787,26 @@ static void mesh_batch_cache_clear_selective(Mesh *me, Gwn_VertBuf *vert) BLI_assert(vert != NULL); if (cache->pos_with_normals == vert) { - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_normals); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_weights); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask); - GWN_BATCH_DISCARD_SAFE(cache->points_with_normals); - GWN_BATCH_DISCARD_SAFE(cache->ledges_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask); + GPU_BATCH_DISCARD_SAFE(cache->points_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals); if (cache->shaded_triangles) { for (int i = 0; i < cache->mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); } } MEM_SAFE_FREE(cache->shaded_triangles); if (cache->texpaint_triangles) { for (int i = 0; i < cache->mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); } } MEM_SAFE_FREE(cache->texpaint_triangles); - GWN_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single); + GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single); } /* TODO: add the other ones if needed. */ else { @@ -1822,69 +1822,69 @@ static void mesh_batch_cache_clear(Mesh *me) return; } - GWN_BATCH_DISCARD_SAFE(cache->all_verts); - GWN_BATCH_DISCARD_SAFE(cache->all_edges); - GWN_BATCH_DISCARD_SAFE(cache->all_triangles); + GPU_BATCH_DISCARD_SAFE(cache->all_verts); + GPU_BATCH_DISCARD_SAFE(cache->all_edges); + GPU_BATCH_DISCARD_SAFE(cache->all_triangles); - GWN_VERTBUF_DISCARD_SAFE(cache->pos_in_order); + GPU_VERTBUF_DISCARD_SAFE(cache->pos_in_order); DRW_TEXTURE_FREE_SAFE(cache->pos_in_order_tx); - GWN_INDEXBUF_DISCARD_SAFE(cache->edges_in_order); - GWN_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order); - GWN_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order); - - GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_pos); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_nor); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_data); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_pos); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_nor); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data); - GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles); - GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor); - GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); - GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); - GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor); - - GWN_BATCH_DISCARD_SAFE(cache->overlay_weight_faces); - GWN_BATCH_DISCARD_SAFE(cache->overlay_weight_verts); - GWN_BATCH_DISCARD_SAFE(cache->overlay_paint_edges); - GWN_BATCH_DISCARD_SAFE(cache->overlay_facedots); - - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_normals); - GWN_BATCH_DISCARD_SAFE(cache->points_with_normals); - GWN_BATCH_DISCARD_SAFE(cache->ledges_with_normals); - GWN_VERTBUF_DISCARD_SAFE(cache->pos_with_normals); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_weights); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors); - GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos); - GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask); - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id); - GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id); - - GWN_BATCH_DISCARD_SAFE(cache->fancy_edges); - - GWN_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency); - GWN_BATCH_DISCARD_SAFE(cache->edge_detection); - - GWN_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay); + GPU_INDEXBUF_DISCARD_SAFE(cache->edges_in_order); + GPU_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order); + GPU_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order); + + GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_nor); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_tri_data); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_nor); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data); + GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles); + GPU_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay_loose_edges_nor); + + GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_faces); + GPU_BATCH_DISCARD_SAFE(cache->overlay_weight_verts); + GPU_BATCH_DISCARD_SAFE(cache->overlay_paint_edges); + GPU_BATCH_DISCARD_SAFE(cache->overlay_facedots); + + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->points_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->ledges_with_normals); + GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors); + GPU_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->facedot_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id); + + GPU_BATCH_DISCARD_SAFE(cache->fancy_edges); + + GPU_INDEXBUF_DISCARD_SAFE(cache->edges_adjacency); + GPU_BATCH_DISCARD_SAFE(cache->edge_detection); + + GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay); DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx); - GWN_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data); + GPU_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data); if (cache->shaded_triangles_in_order) { for (int i = 0; i < cache->mat_len; ++i) { - GWN_INDEXBUF_DISCARD_SAFE(cache->shaded_triangles_in_order[i]); + GPU_INDEXBUF_DISCARD_SAFE(cache->shaded_triangles_in_order[i]); } } if (cache->shaded_triangles) { for (int i = 0; i < cache->mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); } } @@ -1896,12 +1896,12 @@ static void mesh_batch_cache_clear(Mesh *me) if (cache->texpaint_triangles) { for (int i = 0; i < cache->mat_len; ++i) { - GWN_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); + GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles[i]); } } MEM_SAFE_FREE(cache->texpaint_triangles); - GWN_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single); + GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single); } @@ -1911,9 +1911,9 @@ void DRW_mesh_batch_cache_free(Mesh *me) MEM_SAFE_FREE(me->runtime.batch_cache); } -/* Gwn_Batch cache usage. */ +/* GPUBatch cache usage. */ -static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, MeshBatchCache *cache) +static GPUVertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); #define USE_COMP_MESH_DATA @@ -1928,9 +1928,9 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, return NULL; } - Gwn_VertFormat *format = &cache->shaded_triangles_format; + GPUVertFormat *format = &cache->shaded_triangles_format; - GWN_vertformat_clear(format); + GPU_vertformat_clear(format); /* initialize vertex format */ uint *layers_combined_id = BLI_array_alloca(layers_combined_id, layers_combined_len); @@ -1968,14 +1968,14 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, /* UV */ const char *attrib_name = mesh_render_data_uv_layer_uuid_get(rdata, i); #if defined(USE_COMP_MESH_DATA) && 0 /* these are clamped. Maybe use them as an option in the future */ - uv_id[i] = GWN_vertformat_attr_add(format, attrib_name, GWN_COMP_I16, 2, GWN_FETCH_INT_TO_FLOAT_UNIT); + uv_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT); #else - uv_id[i] = GWN_vertformat_attr_add(format, attrib_name, GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uv_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT); #endif /* Auto Name */ attrib_name = mesh_render_data_uv_auto_layer_uuid_get(rdata, i); - GWN_vertformat_alias_add(format, attrib_name); + GPU_vertformat_alias_add(format, attrib_name); /* +1 include null terminator. */ auto_ofs += 1 + BLI_snprintf_rlen( @@ -1983,7 +1983,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, cache->auto_layer_is_srgb[auto_id++] = 0; /* tag as not srgb */ if (i == rdata->cd.layers.uv_active) { - GWN_vertformat_alias_add(format, "u"); + GPU_vertformat_alias_add(format, "u"); } } @@ -1993,25 +1993,25 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, * That may cause some problem but I could not make it to fail (fclem) */ #ifdef USE_COMP_MESH_DATA /* Tangents need more precision than 10_10_10 */ - tangent_id[i] = GWN_vertformat_attr_add(format, attrib_name, GWN_COMP_I16, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + tangent_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); #else - tangent_id[i] = GWN_vertformat_attr_add(format, attrib_name, GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + tangent_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_F32, 3, GPU_FETCH_FLOAT); #endif if (i == rdata->cd.layers.tangent_active) { - GWN_vertformat_alias_add(format, "t"); + GPU_vertformat_alias_add(format, "t"); } } for (uint i = 0; i < vcol_len; i++) { const char *attrib_name = mesh_render_data_vcol_layer_uuid_get(rdata, i); - vcol_id[i] = GWN_vertformat_attr_add(format, attrib_name, GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + vcol_id[i] = GPU_vertformat_attr_add(format, attrib_name, GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); /* Auto layer */ if (rdata->cd.layers.auto_vcol[i]) { attrib_name = mesh_render_data_vcol_auto_layer_uuid_get(rdata, i); - GWN_vertformat_alias_add(format, attrib_name); + GPU_vertformat_alias_add(format, attrib_name); /* +1 include null terminator. */ auto_ofs += 1 + BLI_snprintf_rlen( @@ -2020,23 +2020,23 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, } if (i == rdata->cd.layers.vcol_active) { - GWN_vertformat_alias_add(format, "c"); + GPU_vertformat_alias_add(format, "c"); } } const uint tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_VertBuf *vbo = cache->shaded_triangles_data = GWN_vertbuf_create_with_format(format); + GPUVertBuf *vbo = cache->shaded_triangles_data = GPU_vertbuf_create_with_format(format); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw *layers_combined_step = BLI_array_alloca(layers_combined_step, layers_combined_len); + GPUVertBufRaw *layers_combined_step = BLI_array_alloca(layers_combined_step, layers_combined_len); - Gwn_VertBufRaw *uv_step = layers_combined_step; - Gwn_VertBufRaw *tangent_step = uv_step + uv_len; - Gwn_VertBufRaw *vcol_step = tangent_step + tangent_len; + GPUVertBufRaw *uv_step = layers_combined_step; + GPUVertBufRaw *tangent_step = uv_step + uv_len; + GPUVertBufRaw *vcol_step = tangent_step + tangent_len; /* Not needed, just for sanity. */ if (uv_len == 0) { uv_step = NULL; } @@ -2044,16 +2044,16 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, if (vcol_len == 0) { vcol_step = NULL; } for (uint i = 0; i < uv_len; i++) { - GWN_vertbuf_attr_get_raw_data(vbo, uv_id[i], &uv_step[i]); + GPU_vertbuf_attr_get_raw_data(vbo, uv_id[i], &uv_step[i]); } for (uint i = 0; i < tangent_len; i++) { - GWN_vertbuf_attr_get_raw_data(vbo, tangent_id[i], &tangent_step[i]); + GPU_vertbuf_attr_get_raw_data(vbo, tangent_id[i], &tangent_step[i]); } for (uint i = 0; i < vcol_len; i++) { - GWN_vertbuf_attr_get_raw_data(vbo, vcol_id[i], &vcol_step[i]); + GPU_vertbuf_attr_get_raw_data(vbo, vcol_id[i], &vcol_step[i]); } - /* TODO deduplicate all verts and make use of Gwn_IndexBuf in + /* TODO deduplicate all verts and make use of GPUIndexBuf in * mesh_batch_cache_get_triangles_in_order_split_by_material. */ if (rdata->edit_bmesh) { for (uint i = 0; i < tri_len; i++) { @@ -2066,7 +2066,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, const uint layer_offset = rdata->cd.offset.uv[j]; for (uint t = 0; t < 3; t++) { const float *elem = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(bm_looptri[t], layer_offset))->uv; - copy_v2_v2(GWN_vertbuf_raw_step(&uv_step[j]), elem); + copy_v2_v2(GPU_vertbuf_raw_step(&uv_step[j]), elem); } } /* TANGENTs */ @@ -2074,7 +2074,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, float (*layer_data)[4] = rdata->cd.layers.tangent[j]; for (uint t = 0; t < 3; t++) { const float *elem = layer_data[BM_elem_index_get(bm_looptri[t])]; - normal_float_to_short_v3(GWN_vertbuf_raw_step(&tangent_step[j]), elem); + normal_float_to_short_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem); } } /* VCOLs */ @@ -2082,7 +2082,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, const uint layer_offset = rdata->cd.offset.vcol[j]; for (uint t = 0; t < 3; t++) { const uchar *elem = &((MLoopCol *)BM_ELEM_CD_GET_VOID_P(bm_looptri[t], layer_offset))->r; - copy_v3_v3_uchar(GWN_vertbuf_raw_step(&vcol_step[j]), elem); + copy_v3_v3_uchar(GPU_vertbuf_raw_step(&vcol_step[j]), elem); } } } @@ -2096,7 +2096,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, const MLoopUV *layer_data = rdata->cd.layers.uv[j]; for (uint t = 0; t < 3; t++) { const float *elem = layer_data[mlt->tri[t]].uv; - copy_v2_v2(GWN_vertbuf_raw_step(&uv_step[j]), elem); + copy_v2_v2(GPU_vertbuf_raw_step(&uv_step[j]), elem); } } /* TANGENTs */ @@ -2105,9 +2105,9 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, for (uint t = 0; t < 3; t++) { const float *elem = layer_data[mlt->tri[t]]; #ifdef USE_COMP_MESH_DATA - normal_float_to_short_v3(GWN_vertbuf_raw_step(&tangent_step[j]), elem); + normal_float_to_short_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem); #else - copy_v3_v3(GWN_vertbuf_raw_step(&tangent_step[j]), elem); + copy_v3_v3(GPU_vertbuf_raw_step(&tangent_step[j]), elem); #endif } } @@ -2116,25 +2116,25 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, const MLoopCol *layer_data = rdata->cd.layers.vcol[j]; for (uint t = 0; t < 3; t++) { const uchar *elem = &layer_data[mlt->tri[t]].r; - copy_v3_v3_uchar(GWN_vertbuf_raw_step(&vcol_step[j]), elem); + copy_v3_v3_uchar(GPU_vertbuf_raw_step(&vcol_step[j]), elem); } } } } - vbo_len_used = GWN_vertbuf_raw_used(&layers_combined_step[0]); + vbo_len_used = GPU_vertbuf_raw_used(&layers_combined_step[0]); #ifndef NDEBUG /* Check all layers are write aligned. */ if (layers_combined_len > 1) { for (uint i = 1; i < layers_combined_len; i++) { - BLI_assert(vbo_len_used == GWN_vertbuf_raw_used(&layers_combined_step[i])); + BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&layers_combined_step[i])); } } #endif if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } @@ -2143,7 +2143,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata, return cache->shaded_triangles_data; } -static Gwn_VertBuf *mesh_batch_cache_get_tri_uv_active( +static GPUVertBuf *mesh_batch_cache_get_tri_uv_active( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPUV)); @@ -2157,19 +2157,19 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_uv_active( uint vidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint uv; } attr_id; if (format.attr_len == 0) { - attr_id.uv = GWN_vertformat_attr_add(&format, "uv", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.uv = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } const int tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_VertBuf *vbo = cache->tri_aligned_uv = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = cache->tri_aligned_uv = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); BMEditMesh *embm = rdata->edit_bmesh; @@ -2189,7 +2189,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_uv_active( const int index = BM_elem_index_get(loop); if (index != -1) { const float *elem = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(loop, layer_offset))->uv; - GWN_vertbuf_attr_set(vbo, attr_id.uv, vidx++, elem); + GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, elem); } } } @@ -2198,9 +2198,9 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_uv_active( /* object mode */ for (int i = 0; i < tri_len; i++) { const MLoopTri *mlt = &rdata->mlooptri[i]; - GWN_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[0]].uv); - GWN_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[1]].uv); - GWN_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[2]].uv); + GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[0]].uv); + GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[1]].uv); + GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx++, mloopuv[mlt->tri[2]].uv); } } @@ -2213,36 +2213,36 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_uv_active( return cache->tri_aligned_uv; } -static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( +static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( MeshRenderData *rdata, const bool use_hide, - Gwn_VertBuf **r_vbo) + GPUVertBuf **r_vbo) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); if (*r_vbo == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } const int tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_VertBuf *vbo = *r_vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = *r_vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw pos_step, nor_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step); + GPUVertBufRaw pos_step, nor_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step); float (*lnors)[3] = rdata->loop_normals; if (rdata->edit_bmesh) { - Gwn_PackedNormal *pnors_pack, *vnors_pack; + GPUPackedNormal *pnors_pack, *vnors_pack; if (lnors == NULL) { mesh_render_data_ensure_poly_normals_pack(rdata); @@ -2264,18 +2264,18 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( if (lnors) { for (uint t = 0; t < 3; t++) { const float *nor = lnors[BM_elem_index_get(bm_looptri[t])]; - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = GWN_normal_convert_i10_v3(nor); + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); } } else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) { for (uint t = 0; t < 3; t++) { - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)]; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)]; } } else { - const Gwn_PackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)]; + const GPUPackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)]; for (uint t = 0; t < 3; t++) { - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = *snor_pack; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *snor_pack; } } @@ -2284,12 +2284,12 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( for (uint t = 0; t < 3; t++) { int vidx = BM_elem_index_get(bm_looptri[t]->v); const float *pos = rdata->edit_data->vertexCos[vidx]; - copy_v3_v3(GWN_vertbuf_raw_step(&pos_step), pos); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), pos); } } else { for (uint t = 0; t < 3; t++) { - copy_v3_v3(GWN_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co); } } } @@ -2317,85 +2317,85 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex( if (lnors) { for (uint t = 0; t < 3; t++) { const float *nor = lnors[mlt->tri[t]]; - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = GWN_normal_convert_i10_v3(nor); + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_v3(nor); } } else if (mp->flag & ME_SMOOTH) { for (uint t = 0; t < 3; t++) { const MVert *mv = &rdata->mvert[vtri[t]]; - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = GWN_normal_convert_i10_s3(mv->no); + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = GPU_normal_convert_i10_s3(mv->no); } } else { - const Gwn_PackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly]; + const GPUPackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly]; for (uint t = 0; t < 3; t++) { - *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = *pnors_pack; + *((GPUPackedNormal *)GPU_vertbuf_raw_step(&nor_step)) = *pnors_pack; } } for (uint t = 0; t < 3; t++) { const MVert *mv = &rdata->mvert[vtri[t]]; - copy_v3_v3(GWN_vertbuf_raw_step(&pos_step), mv->co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mv->co); } } } - vbo_len_used = GWN_vertbuf_raw_used(&pos_step); - BLI_assert(vbo_len_used == GWN_vertbuf_raw_used(&nor_step)); + vbo_len_used = GPU_vertbuf_raw_used(&pos_step); + BLI_assert(vbo_len_used == GPU_vertbuf_raw_used(&nor_step)); if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return *r_vbo; } -static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals( +static GPUVertBuf *mesh_batch_cache_get_tri_pos_and_normals( MeshRenderData *rdata, MeshBatchCache *cache) { return mesh_batch_cache_get_tri_pos_and_normals_ex( rdata, false, &cache->pos_with_normals); } -static Gwn_VertBuf *mesh_create_tri_pos_and_normals_visible_only( +static GPUVertBuf *mesh_create_tri_pos_and_normals_visible_only( MeshRenderData *rdata) { - Gwn_VertBuf *vbo_dummy = NULL; + GPUVertBuf *vbo_dummy = NULL; return mesh_batch_cache_get_tri_pos_and_normals_ex( rdata, true, &vbo_dummy); } -static Gwn_VertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag( +static GPUVertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); if (cache->ed_fcenter_pos_with_nor_and_sel == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.data = GWN_vertformat_attr_add(&format, "norAndFlag", GWN_COMP_I10, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.data = GPU_vertformat_attr_add(&format, "norAndFlag", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata); int vidx = 0; - Gwn_VertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); for (int i = 0; i < vbo_len_capacity; ++i) { float pcenter[3], pnor[3]; bool selected = false; if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) { - Gwn_PackedNormal nor = { .x = 0, .y = 0, .z = -511 }; - nor = GWN_normal_convert_i10_v3(pnor); + GPUPackedNormal nor = { .x = 0, .y = 0, .z = -511 }; + nor = GPU_normal_convert_i10_v3(pnor); nor.w = selected ? 1 : 0; - GWN_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor); + GPU_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter); vidx += 1; } @@ -2403,30 +2403,30 @@ static Gwn_VertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag( const int vbo_len_used = vidx; BLI_assert(vbo_len_used <= vbo_len_capacity); if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return cache->ed_fcenter_pos_with_nor_and_sel; } -static Gwn_VertBuf *mesh_batch_cache_get_edges_visible( +static GPUVertBuf *mesh_batch_cache_get_edges_visible( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE)); if (cache->ed_edge_pos == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2; int vidx = 0; - Gwn_VertBuf *vbo = cache->ed_edge_pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBuf *vbo = cache->ed_edge_pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); if (rdata->edit_bmesh) { BMesh *bm = rdata->edit_bmesh->bm; BMIter iter; @@ -2434,9 +2434,9 @@ static Gwn_VertBuf *mesh_batch_cache_get_edges_visible( BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co); vidx += 1; - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co); vidx += 1; } } @@ -2447,7 +2447,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edges_visible( } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } UNUSED_VARS_NDEBUG(vbo_len_used); } @@ -2455,23 +2455,23 @@ static Gwn_VertBuf *mesh_batch_cache_get_edges_visible( return cache->ed_edge_pos; } -static Gwn_VertBuf *mesh_batch_cache_get_verts_visible( +static GPUVertBuf *mesh_batch_cache_get_verts_visible( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->ed_vert_pos == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, data; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); uint vidx = 0; - Gwn_VertBuf *vbo = cache->ed_vert_pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPUVertBuf *vbo = cache->ed_vert_pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); if (rdata->edit_bmesh) { BMesh *bm = rdata->edit_bmesh->bm; BMIter iter; @@ -2479,7 +2479,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_verts_visible( BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co); vidx += 1; } } @@ -2488,14 +2488,14 @@ static Gwn_VertBuf *mesh_batch_cache_get_verts_visible( for (int i = 0; i < vbo_len_capacity; i++) { const MVert *mv = &rdata->mvert[i]; if (!(mv->flag & ME_HIDE)) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co); vidx += 1; } } } const uint vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } UNUSED_VARS_NDEBUG(vbo_len_used); @@ -2504,24 +2504,24 @@ static Gwn_VertBuf *mesh_batch_cache_get_verts_visible( return cache->ed_vert_pos; } -static Gwn_VertBuf *mesh_create_facedot_select_id( +static GPUVertBuf *mesh_create_facedot_select_id( MeshRenderData *rdata, uint select_id_offset) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata); int vidx = 0; - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); uint select_index = select_id_offset; if (rdata->edit_bmesh) { @@ -2533,7 +2533,7 @@ static Gwn_VertBuf *mesh_create_facedot_select_id( if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { int select_id; GPU_select_index_get(select_index, &select_id); - GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); vidx += 1; } select_index += 1; @@ -2545,31 +2545,31 @@ static Gwn_VertBuf *mesh_create_facedot_select_id( } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_create_edges_select_id( +static GPUVertBuf *mesh_create_edges_select_id( MeshRenderData *rdata, uint select_id_offset) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2; int vidx = 0; - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); uint select_index = select_id_offset; if (rdata->edit_bmesh) { @@ -2581,9 +2581,9 @@ static Gwn_VertBuf *mesh_create_edges_select_id( if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { int select_id; GPU_select_index_get(select_index, &select_id); - GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); vidx += 1; - GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); vidx += 1; } select_index += 1; @@ -2595,31 +2595,31 @@ static Gwn_VertBuf *mesh_create_edges_select_id( } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_create_verts_select_id( +static GPUVertBuf *mesh_create_verts_select_id( MeshRenderData *rdata, uint select_id_offset) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); int vidx = 0; - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); uint select_index = select_id_offset; if (rdata->edit_bmesh) { @@ -2631,7 +2631,7 @@ static Gwn_VertBuf *mesh_create_verts_select_id( if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { int select_id; GPU_select_index_get(select_index, &select_id); - GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); vidx += 1; } select_index += 1; @@ -2643,7 +2643,7 @@ static Gwn_VertBuf *mesh_create_verts_select_id( if (!(mv->flag & ME_HIDE)) { int select_id; GPU_select_index_get(select_index, &select_id); - GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id); vidx += 1; } select_index += 1; @@ -2651,36 +2651,36 @@ static Gwn_VertBuf *mesh_create_verts_select_id( } const int vbo_len_used = vidx; if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_create_tri_weights( +static GPUVertBuf *mesh_create_tri_weights( MeshRenderData *rdata, bool use_hide, int defgroup) { BLI_assert( rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { uint cidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } - vbo = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); const int tri_len = mesh_render_data_looptri_len_get(rdata); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); mesh_render_data_ensure_vert_weight_color(rdata, defgroup); const float (*vert_weight_color)[3] = rdata->vert_weight_color; @@ -2692,7 +2692,7 @@ static Gwn_VertBuf *mesh_create_tri_weights( if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { const int v_index = BM_elem_index_get(ltri[tri_corner]->v); - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); } } } @@ -2703,7 +2703,7 @@ static Gwn_VertBuf *mesh_create_tri_weights( if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { const uint v_index = rdata->mloop[mlt->tri[tri_corner]].v; - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); } } } @@ -2711,36 +2711,36 @@ static Gwn_VertBuf *mesh_create_tri_weights( vbo_len_used = cidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_create_tri_vert_colors( +static GPUVertBuf *mesh_create_tri_vert_colors( MeshRenderData *rdata, bool use_hide) { BLI_assert( rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { uint cidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } const int tri_len = mesh_render_data_looptri_len_get(rdata); - vbo = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); const uint vbo_len_capacity = tri_len * 3; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); mesh_render_data_ensure_vert_color(rdata); const char (*vert_color)[3] = rdata->vert_color; @@ -2752,7 +2752,7 @@ static Gwn_VertBuf *mesh_create_tri_vert_colors( if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { const int l_index = BM_elem_index_get(ltri[tri_corner]); - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]); } } } @@ -2763,7 +2763,7 @@ static Gwn_VertBuf *mesh_create_tri_vert_colors( if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { const uint l_index = mlt->tri[tri_corner]; - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_color[l_index]); } } } @@ -2771,37 +2771,37 @@ static Gwn_VertBuf *mesh_create_tri_vert_colors( const uint vbo_len_used = cidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_create_tri_select_id( +static GPUVertBuf *mesh_create_tri_select_id( MeshRenderData *rdata, bool use_hide, uint select_id_offset) { BLI_assert( rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY)); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { uint cidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint col; } attr_id; if (format.attr_len == 0) { - attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT); + attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_I32, 1, GPU_FETCH_INT); } const int tri_len = mesh_render_data_looptri_len_get(rdata); - vbo = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = tri_len * 3; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); if (rdata->edit_bmesh) { for (int i = 0; i < tri_len; i++) { @@ -2812,7 +2812,7 @@ static Gwn_VertBuf *mesh_create_tri_select_id( int select_id; GPU_select_index_get(poly_index + select_id_offset, &select_id); for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); } } } @@ -2825,7 +2825,7 @@ static Gwn_VertBuf *mesh_create_tri_select_id( int select_id; GPU_select_index_get(poly_index + select_id_offset, &select_id); for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); + GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id); } } } @@ -2833,29 +2833,29 @@ static Gwn_VertBuf *mesh_create_tri_select_id( vbo_len_used = cidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order( +static GPUVertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); if (cache->pos_in_order == NULL) { - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, nor; } attr_id; if (format.attr_len == 0) { /* Normal is padded so that the vbo can be used as a buffer texture */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_I16, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); } - Gwn_VertBuf *vbo = cache->pos_in_order = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = cache->pos_in_order = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata); - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); if (rdata->edit_bmesh) { BMesh *bm = rdata->edit_bmesh->bm; @@ -2867,15 +2867,15 @@ static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order( static short no_short[4]; normal_float_to_short_v3(no_short, eve->no); - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, eve->co); - GWN_vertbuf_attr_set(vbo, attr_id.nor, i, no_short); + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, eve->co); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, no_short); } BLI_assert(i == vbo_len_capacity); } else { for (int i = 0; i < vbo_len_capacity; ++i) { - GWN_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->mvert[i].co); - GWN_vertbuf_attr_set(vbo, attr_id.nor, i, rdata->mvert[i].no); /* XXX actually reading 4 shorts */ + GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->mvert[i].co); + GPU_vertbuf_attr_set(vbo, attr_id.nor, i, rdata->mvert[i].no); /* XXX actually reading 4 shorts */ } } } @@ -2883,26 +2883,26 @@ static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order( return cache->pos_in_order; } -static Gwn_VertFormat *edit_mesh_overlay_pos_format(uint *r_pos_id) +static GPUVertFormat *edit_mesh_overlay_pos_format(uint *r_pos_id) { - static Gwn_VertFormat format_pos = { 0 }; + static GPUVertFormat format_pos = { 0 }; static uint pos_id; if (format_pos.attr_len == 0) { - pos_id = GWN_vertformat_attr_add(&format_pos, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } *r_pos_id = pos_id; return &format_pos; } -static Gwn_VertFormat *edit_mesh_overlay_nor_format(uint *r_vnor_id, uint *r_lnor_id) +static GPUVertFormat *edit_mesh_overlay_nor_format(uint *r_vnor_id, uint *r_lnor_id) { - static Gwn_VertFormat format_nor = { 0 }; - static Gwn_VertFormat format_nor_loop = { 0 }; + static GPUVertFormat format_nor = { 0 }; + static GPUVertFormat format_nor_loop = { 0 }; static uint vnor_id, vnor_loop_id, lnor_id; if (format_nor.attr_len == 0) { - vnor_id = GWN_vertformat_attr_add(&format_nor, "vnor", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - vnor_loop_id = GWN_vertformat_attr_add(&format_nor_loop, "vnor", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - lnor_id = GWN_vertformat_attr_add(&format_nor_loop, "lnor", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + vnor_id = GPU_vertformat_attr_add(&format_nor, "vnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + vnor_loop_id = GPU_vertformat_attr_add(&format_nor_loop, "vnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + lnor_id = GPU_vertformat_attr_add(&format_nor_loop, "lnor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } if (r_lnor_id) { *r_vnor_id = vnor_loop_id; @@ -2915,12 +2915,12 @@ static Gwn_VertFormat *edit_mesh_overlay_nor_format(uint *r_vnor_id, uint *r_lno } } -static Gwn_VertFormat *edit_mesh_overlay_data_format(uint *r_data_id) +static GPUVertFormat *edit_mesh_overlay_data_format(uint *r_data_id) { - static Gwn_VertFormat format_flag = { 0 }; + static GPUVertFormat format_flag = { 0 }; static uint data_id; if (format_flag.attr_len == 0) { - data_id = GWN_vertformat_attr_add(&format_flag, "data", GWN_COMP_U8, 4, GWN_FETCH_INT); + data_id = GPU_vertformat_attr_add(&format_flag, "data", GPU_COMP_U8, 4, GPU_FETCH_INT); } *r_data_id = data_id; return &format_flag; @@ -2937,28 +2937,28 @@ static void mesh_batch_cache_create_overlay_tri_buffers( int vbo_len_used = 0; /* Positions */ - Gwn_VertBuf *vbo_pos = NULL; + GPUVertBuf *vbo_pos = NULL; static struct { uint pos, vnor, lnor, data; } attr_id; if (cache->ed_tri_pos == NULL) { vbo_pos = cache->ed_tri_pos = - GWN_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); - GWN_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); + GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); } /* Normals */ - Gwn_VertBuf *vbo_nor = NULL; + GPUVertBuf *vbo_nor = NULL; if (cache->ed_tri_nor == NULL) { vbo_nor = cache->ed_tri_nor = - GWN_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, &attr_id.lnor)); - GWN_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, &attr_id.lnor)); + GPU_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); } /* Data */ - Gwn_VertBuf *vbo_data = NULL; + GPUVertBuf *vbo_data = NULL; if (cache->ed_tri_data == NULL) { vbo_data = cache->ed_tri_data = - GWN_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); - GWN_vertbuf_data_alloc(vbo_data, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); + GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } for (int i = 0; i < tri_len; i++) { @@ -2976,13 +2976,13 @@ static void mesh_batch_cache_create_overlay_tri_buffers( /* Finish */ if (vbo_len_used != vbo_len_capacity) { if (vbo_pos != NULL) { - GWN_vertbuf_data_resize(vbo_pos, vbo_len_used); + GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } if (vbo_nor != NULL) { - GWN_vertbuf_data_resize(vbo_nor, vbo_len_used); + GPU_vertbuf_data_resize(vbo_nor, vbo_len_used); } if (vbo_data != NULL) { - GWN_vertbuf_data_resize(vbo_data, vbo_len_used); + GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } } } @@ -2998,28 +2998,28 @@ static void mesh_batch_cache_create_overlay_ledge_buffers( int vbo_len_used = 0; /* Positions */ - Gwn_VertBuf *vbo_pos = NULL; + GPUVertBuf *vbo_pos = NULL; static struct { uint pos, vnor, data; } attr_id; if (cache->ed_ledge_pos == NULL) { vbo_pos = cache->ed_ledge_pos = - GWN_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); - GWN_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); + GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); } /* Normals */ - Gwn_VertBuf *vbo_nor = NULL; + GPUVertBuf *vbo_nor = NULL; if (cache->ed_ledge_nor == NULL) { vbo_nor = cache->ed_ledge_nor = - GWN_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL)); - GWN_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL)); + GPU_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); } /* Data */ - Gwn_VertBuf *vbo_data = NULL; + GPUVertBuf *vbo_data = NULL; if (cache->ed_ledge_data == NULL) { vbo_data = cache->ed_ledge_data = - GWN_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); - GWN_vertbuf_data_alloc(vbo_data, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); + GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } if (rdata->edit_bmesh) { @@ -3039,13 +3039,13 @@ static void mesh_batch_cache_create_overlay_ledge_buffers( /* Finish */ if (vbo_len_used != vbo_len_capacity) { if (vbo_pos != NULL) { - GWN_vertbuf_data_resize(vbo_pos, vbo_len_used); + GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } if (vbo_nor != NULL) { - GWN_vertbuf_data_resize(vbo_nor, vbo_len_used); + GPU_vertbuf_data_resize(vbo_nor, vbo_len_used); } if (vbo_data != NULL) { - GWN_vertbuf_data_resize(vbo_data, vbo_len_used); + GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } } } @@ -3064,27 +3064,27 @@ static void mesh_batch_cache_create_overlay_lvert_buffers( static struct { uint pos, vnor, data; } attr_id; /* Positions */ - Gwn_VertBuf *vbo_pos = NULL; + GPUVertBuf *vbo_pos = NULL; if (cache->ed_lvert_pos == NULL) { vbo_pos = cache->ed_lvert_pos = - GWN_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); - GWN_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_pos_format(&attr_id.pos)); + GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity); } /* Normals */ - Gwn_VertBuf *vbo_nor = NULL; + GPUVertBuf *vbo_nor = NULL; if (cache->ed_lvert_nor == NULL) { vbo_nor = cache->ed_lvert_nor = - GWN_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL)); - GWN_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_nor_format(&attr_id.vnor, NULL)); + GPU_vertbuf_data_alloc(vbo_nor, vbo_len_capacity); } /* Data */ - Gwn_VertBuf *vbo_data = NULL; + GPUVertBuf *vbo_data = NULL; if (cache->ed_lvert_data == NULL) { vbo_data = cache->ed_lvert_data = - GWN_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); - GWN_vertbuf_data_alloc(vbo_data, vbo_len_capacity); + GPU_vertbuf_create_with_format(edit_mesh_overlay_data_format(&attr_id.data)); + GPU_vertbuf_data_alloc(vbo_data, vbo_len_capacity); } for (uint i = 0; i < lvert_len; i++) { @@ -3099,19 +3099,19 @@ static void mesh_batch_cache_create_overlay_lvert_buffers( /* Finish */ if (vbo_len_used != vbo_len_capacity) { if (vbo_pos != NULL) { - GWN_vertbuf_data_resize(vbo_pos, vbo_len_used); + GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } if (vbo_nor != NULL) { - GWN_vertbuf_data_resize(vbo_nor, vbo_len_used); + GPU_vertbuf_data_resize(vbo_nor, vbo_len_used); } if (vbo_data != NULL) { - GWN_vertbuf_data_resize(vbo_data, vbo_len_used); + GPU_vertbuf_data_resize(vbo_data, vbo_len_used); } } } /* Position */ -static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_pos( +static GPUVertBuf *mesh_batch_cache_get_edit_tri_pos( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3123,7 +3123,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_pos( return cache->ed_tri_pos; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_pos( +static GPUVertBuf *mesh_batch_cache_get_edit_ledge_pos( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3135,7 +3135,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_pos( return cache->ed_ledge_pos; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_pos( +static GPUVertBuf *mesh_batch_cache_get_edit_lvert_pos( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3148,7 +3148,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_pos( } /* Normal */ -static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_nor( +static GPUVertBuf *mesh_batch_cache_get_edit_tri_nor( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3160,7 +3160,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_nor( return cache->ed_tri_nor; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_nor( +static GPUVertBuf *mesh_batch_cache_get_edit_ledge_nor( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3172,7 +3172,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_nor( return cache->ed_ledge_nor; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_nor( +static GPUVertBuf *mesh_batch_cache_get_edit_lvert_nor( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3185,7 +3185,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_nor( } /* Data */ -static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_data( +static GPUVertBuf *mesh_batch_cache_get_edit_tri_data( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3197,7 +3197,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_tri_data( return cache->ed_tri_data; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_data( +static GPUVertBuf *mesh_batch_cache_get_edit_ledge_data( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3209,7 +3209,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_ledge_data( return cache->ed_ledge_data; } -static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_data( +static GPUVertBuf *mesh_batch_cache_get_edit_lvert_data( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & MR_DATATYPE_VERT); @@ -3221,7 +3221,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edit_lvert_data( return cache->ed_lvert_data; } -static Gwn_IndexBuf *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, MeshBatchCache *cache) +static GPUIndexBuf *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE)); @@ -3229,8 +3229,8 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, const int vert_len = mesh_render_data_verts_len_get(rdata); const int edge_len = mesh_render_data_edges_len_get(rdata); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); BLI_assert(rdata->types & MR_DATATYPE_EDGE); @@ -3240,24 +3240,24 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_in_order(MeshRenderData *rdata, BMEdge *eed; BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - GWN_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); + GPU_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); } } } else { const MEdge *ed = rdata->medge; for (int i = 0; i < edge_len; i++, ed++) { - GWN_indexbuf_add_line_verts(&elb, ed->v1, ed->v2); + GPU_indexbuf_add_line_verts(&elb, ed->v1, ed->v2); } } - cache->edges_in_order = GWN_indexbuf_build(&elb); + cache->edges_in_order = GPU_indexbuf_build(&elb); } return cache->edges_in_order; } #define NO_EDGE INT_MAX -static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, MeshBatchCache *cache) +static GPUIndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI)); @@ -3268,8 +3268,8 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, cache->is_manifold = true; /* Allocate max but only used indices are sent to GPU. */ - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, tri_len * 3, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, tri_len * 3, vert_len); EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3); /* Create edges for each pair of triangles sharing an edge. */ @@ -3310,12 +3310,12 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, if (inv_opposite == inv_indices) { /* Don't share edge if triangles have non matching winding. */ - GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); - GWN_indexbuf_add_line_adj_verts(&elb, v_opposite, v1, v2, v_opposite); + GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); + GPU_indexbuf_add_line_adj_verts(&elb, v_opposite, v1, v2, v_opposite); cache->is_manifold = false; } else { - GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v_opposite); + GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v_opposite); } } } @@ -3336,13 +3336,13 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, if (v_data < 0) { /* inv_opposite */ SWAP(uint, v1, v2); } - GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); + GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0); cache->is_manifold = false; } BLI_edgehashIterator_free(ehi); BLI_edgehash_free(eh, NULL); - cache->edges_adjacency = GWN_indexbuf_build(&elb); + cache->edges_adjacency = GPU_indexbuf_build(&elb); } return cache->edges_adjacency; @@ -3395,16 +3395,16 @@ static EdgeHash *create_looptri_edge_adjacency_hash(MeshRenderData *rdata) return eh; } -static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderData *rdata) +static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRenderData *rdata) { const int tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_VertFormat format = {0}; - uint index_id = GWN_vertformat_attr_add(&format, "index", GWN_COMP_U32, 1, GWN_FETCH_INT); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertFormat format = {0}; + uint index_id = GPU_vertformat_attr_add(&format, "index", GPU_COMP_U32, 1, GPU_FETCH_INT); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); int vbo_len_capacity = tri_len * 3; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); int vidx = 0; EdgeHash *eh = NULL; @@ -3442,7 +3442,7 @@ static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRender if (eav->vert_index[1] == -1) { value |= (1 << 31); } - GWN_vertbuf_attr_set(vbo, index_id, vidx++, &value); + GPU_vertbuf_attr_set(vbo, index_id, vidx++, &value); } } @@ -3451,7 +3451,7 @@ static Gwn_VertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(MeshRender int vbo_len_used = vidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } return vbo; @@ -3467,10 +3467,10 @@ static GPUTexture *mesh_batch_cache_get_edges_overlay_texture_buf(MeshRenderData return cache->edges_face_overlay_tx; } - Gwn_VertBuf *vbo = cache->edges_face_overlay = mesh_batch_cache_create_edges_overlay_texture_buf(rdata); + GPUVertBuf *vbo = cache->edges_face_overlay = mesh_batch_cache_create_edges_overlay_texture_buf(rdata); /* Upload data early because we need to create the texture for it. */ - GWN_vertbuf_use(vbo); + GPU_vertbuf_use(vbo); cache->edges_face_overlay_tx = GPU_texture_create_from_vertbuf(vbo); cache->edges_face_overlay_tri_count = vbo->vertex_alloc / 3; @@ -3482,15 +3482,15 @@ static GPUTexture *mesh_batch_cache_get_vert_pos_and_nor_in_order_buf(MeshRender BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI)); if (cache->pos_in_order_tx == NULL) { - Gwn_VertBuf *pos_in_order = mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache); - GWN_vertbuf_use(pos_in_order); /* Upload early for buffer texture creation. */ + GPUVertBuf *pos_in_order = mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache); + GPU_vertbuf_use(pos_in_order); /* Upload early for buffer texture creation. */ cache->pos_in_order_tx = GPU_texture_create_buffer(GPU_R32F, pos_in_order->vbo_id); } return cache->pos_in_order_tx; } -static Gwn_IndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache) +static GPUIndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); @@ -3498,15 +3498,15 @@ static Gwn_IndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rda const int vert_len = mesh_render_data_verts_len_get(rdata); const int tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); if (rdata->edit_bmesh) { for (int i = 0; i < tri_len; ++i) { const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GWN_indexbuf_add_generic_vert(&elb, BM_elem_index_get(ltri[tri_corner]->v)); + GPU_indexbuf_add_generic_vert(&elb, BM_elem_index_get(ltri[tri_corner]->v)); } } } @@ -3515,18 +3515,18 @@ static Gwn_IndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rda for (int i = 0; i < tri_len; ++i) { const MLoopTri *mlt = &rdata->mlooptri[i]; for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GWN_indexbuf_add_generic_vert(&elb, mlt->tri[tri_corner]); + GPU_indexbuf_add_generic_vert(&elb, mlt->tri[tri_corner]); } } } - cache->triangles_in_order = GWN_indexbuf_build(&elb); + cache->triangles_in_order = GPU_indexbuf_build(&elb); } return cache->triangles_in_order; } -static Gwn_IndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, MeshBatchCache *cache) +static GPUIndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); @@ -3535,8 +3535,8 @@ static Gwn_IndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, Mes const int edge_len = mesh_render_data_edges_len_get(rdata); /* Alloc max (edge_len) and upload only needed range. */ - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_LINES, edge_len, vert_len); if (rdata->edit_bmesh) { /* No need to support since edit mesh already draw them. @@ -3546,7 +3546,7 @@ static Gwn_IndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, Mes BMEdge *eed; BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_edge_is_wire(eed)) { - GWN_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); + GPU_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); } } } @@ -3554,17 +3554,17 @@ static Gwn_IndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, Mes for (int i = 0; i < edge_len; ++i) { const MEdge *medge = &rdata->medge[i]; if (medge->flag & ME_LOOSEEDGE) { - GWN_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); + GPU_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); } } } - cache->ledges_in_order = GWN_indexbuf_build(&elb); + cache->ledges_in_order = GPU_indexbuf_build(&elb); } return cache->ledges_in_order; } -static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( +static GPUIndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( MeshRenderData *rdata, MeshBatchCache *cache) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_POLY)); @@ -3576,7 +3576,7 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( int *mat_tri_len = MEM_callocN(sizeof(*mat_tri_len) * mat_len, __func__); cache->shaded_triangles_in_order = MEM_callocN(sizeof(*cache->shaded_triangles) * mat_len, __func__); - Gwn_IndexBufBuilder *elb = MEM_callocN(sizeof(*elb) * mat_len, __func__); + GPUIndexBufBuilder *elb = MEM_callocN(sizeof(*elb) * mat_len, __func__); /* Note that polygons (not triangles) are used here. * This OK because result is _guaranteed_ to be the same. */ @@ -3602,7 +3602,7 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( /* Init ELBs. */ for (int i = 0; i < mat_len; ++i) { - GWN_indexbuf_init(&elb[i], GWN_PRIM_TRIS, mat_tri_len[i], tri_len * 3); + GPU_indexbuf_init(&elb[i], GPU_PRIM_TRIS, mat_tri_len[i], tri_len * 3); } /* Populate ELBs. */ @@ -3616,7 +3616,7 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { const short ma_id = efa->mat_nr < mat_len ? efa->mat_nr : 0; for (int j = 2; j < efa->len; j++) { - GWN_indexbuf_add_tri_verts(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2); + GPU_indexbuf_add_tri_verts(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2); nidx += 3; } } @@ -3627,7 +3627,7 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( const MPoly *mp = &rdata->mpoly[i]; ; const short ma_id = mp->mat_nr < mat_len ? mp->mat_nr : 0; for (int j = 2; j < mp->totloop; j++) { - GWN_indexbuf_add_tri_verts(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2); + GPU_indexbuf_add_tri_verts(&elb[ma_id], nidx + 0, nidx + 1, nidx + 2); nidx += 3; } } @@ -3635,7 +3635,7 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( /* Build ELBs. */ for (int i = 0; i < mat_len; ++i) { - cache->shaded_triangles_in_order[i] = GWN_indexbuf_build(&elb[i]); + cache->shaded_triangles_in_order[i] = GPU_indexbuf_build(&elb[i]); } MEM_freeN(mat_tri_len); @@ -3645,30 +3645,30 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( return cache->shaded_triangles_in_order; } -static Gwn_VertBuf *mesh_create_edge_pos_with_sel( +static GPUVertBuf *mesh_create_edge_pos_with_sel( MeshRenderData *rdata, bool use_wire, bool use_select_bool) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP)); BLI_assert(rdata->edit_bmesh == NULL); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { uint vidx = 0, cidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, sel; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.sel = GWN_vertformat_attr_add(&format, "select", GWN_COMP_U8, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.sel = GPU_vertformat_attr_add(&format, "select", GPU_COMP_U8, 1, GPU_FETCH_INT); } const int edge_len = mesh_render_data_edges_len_get(rdata); - vbo = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = edge_len * 2; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); if (use_select_bool) { mesh_render_data_ensure_edge_select_bool(rdata, use_wire); @@ -3689,23 +3689,23 @@ static Gwn_VertBuf *mesh_create_edge_pos_with_sel( continue; } - GWN_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel); - GWN_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel); + GPU_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel); + GPU_vertbuf_attr_set(vbo, attr_id.sel, cidx++, &edge_vert_sel); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v1].co); - GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v2].co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v1].co); + GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, rdata->mvert[ed->v2].co); } vbo_len_used = vidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; } -static Gwn_IndexBuf *mesh_create_tri_overlay_weight_faces( +static GPUIndexBuf *mesh_create_tri_overlay_weight_faces( MeshRenderData *rdata) { BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); @@ -3714,57 +3714,57 @@ static Gwn_IndexBuf *mesh_create_tri_overlay_weight_faces( const int vert_len = mesh_render_data_verts_len_get(rdata); const int tri_len = mesh_render_data_looptri_len_get(rdata); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); for (int i = 0; i < tri_len; ++i) { const MLoopTri *mlt = &rdata->mlooptri[i]; if (!(rdata->mpoly[mlt->poly].flag & (ME_FACE_SEL | ME_HIDE))) { for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { - GWN_indexbuf_add_generic_vert(&elb, rdata->mloop[mlt->tri[tri_corner]].v); + GPU_indexbuf_add_generic_vert(&elb, rdata->mloop[mlt->tri[tri_corner]].v); } } } - return GWN_indexbuf_build(&elb); + return GPU_indexbuf_build(&elb); } } /** * Non-edit mode vertices (only used for weight-paint mode). */ -static Gwn_VertBuf *mesh_create_vert_pos_with_overlay_data( +static GPUVertBuf *mesh_create_vert_pos_with_overlay_data( MeshRenderData *rdata) { BLI_assert(rdata->types & (MR_DATATYPE_VERT)); BLI_assert(rdata->edit_bmesh == NULL); - Gwn_VertBuf *vbo; + GPUVertBuf *vbo; { uint cidx = 0; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint data; } attr_id; if (format.attr_len == 0) { - attr_id.data = GWN_vertformat_attr_add(&format, "data", GWN_COMP_I8, 1, GWN_FETCH_INT); + attr_id.data = GPU_vertformat_attr_add(&format, "data", GPU_COMP_I8, 1, GPU_FETCH_INT); } const int vert_len = mesh_render_data_verts_len_get(rdata); - vbo = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); const int vbo_len_capacity = vert_len; int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); for (int i = 0; i < vert_len; i++) { const MVert *mv = &rdata->mvert[i]; const char data = mv->flag & (SELECT | ME_HIDE); - GWN_vertbuf_attr_set(vbo, attr_id.data, cidx++, &data); + GPU_vertbuf_attr_set(vbo, attr_id.data, cidx++, &data); } vbo_len_used = cidx; if (vbo_len_capacity != vbo_len_used) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } } return vbo; @@ -3778,7 +3778,7 @@ static Gwn_VertBuf *mesh_create_vert_pos_with_overlay_data( /** \name Public API * \{ */ -Gwn_Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3787,8 +3787,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->all_edges = GWN_batch_create( - GWN_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + cache->all_edges = GPU_batch_create( + GPU_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), mesh_batch_cache_get_edges_in_order(rdata, cache)); mesh_render_data_free(rdata); @@ -3797,7 +3797,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) return cache->all_edges; } -Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3806,8 +3806,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->all_triangles = GWN_batch_create( - GWN_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + cache->all_triangles = GPU_batch_create( + GPU_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), mesh_batch_cache_get_triangles_in_order(rdata, cache)); mesh_render_data_free(rdata); @@ -3816,7 +3816,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(Mesh *me) return cache->all_triangles; } -Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3824,8 +3824,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->triangles_with_normals = GWN_batch_create( - GWN_PRIM_TRIS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL); + cache->triangles_with_normals = GPU_batch_create( + GPU_PRIM_TRIS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL); mesh_render_data_free(rdata); } @@ -3833,7 +3833,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) return cache->triangles_with_normals; } -Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3841,8 +3841,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->ledges_with_normals = GWN_batch_create( - GWN_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + cache->ledges_with_normals = GPU_batch_create( + GPU_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), mesh_batch_cache_get_loose_edges(rdata, cache)); mesh_render_data_free(rdata); @@ -3851,7 +3851,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) return cache->ledges_with_normals; } -Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int defgroup) +GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int defgroup) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3861,14 +3861,14 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->triangles_with_weights = GWN_batch_create_ex( - GWN_PRIM_TRIS, mesh_create_tri_weights(rdata, use_hide, defgroup), NULL, GWN_BATCH_OWNS_VBO); + cache->triangles_with_weights = GPU_batch_create_ex( + GPU_PRIM_TRIS, mesh_create_tri_weights(rdata, use_hide, defgroup), NULL, GPU_BATCH_OWNS_VBO); - Gwn_VertBuf *vbo_tris = use_hide ? + GPUVertBuf *vbo_tris = use_hide ? mesh_create_tri_pos_and_normals_visible_only(rdata) : mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - GWN_batch_vertbuf_add_ex(cache->triangles_with_weights, vbo_tris, use_hide); + GPU_batch_vertbuf_add_ex(cache->triangles_with_weights, vbo_tris, use_hide); mesh_render_data_free(rdata); } @@ -3876,7 +3876,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, return cache->triangles_with_weights; } -Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3886,13 +3886,13 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->triangles_with_vert_colors = GWN_batch_create_ex( - GWN_PRIM_TRIS, mesh_create_tri_vert_colors(rdata, use_hide), NULL, GWN_BATCH_OWNS_VBO); + cache->triangles_with_vert_colors = GPU_batch_create_ex( + GPU_PRIM_TRIS, mesh_create_tri_vert_colors(rdata, use_hide), NULL, GPU_BATCH_OWNS_VBO); - Gwn_VertBuf *vbo_tris = use_hide ? + GPUVertBuf *vbo_tris = use_hide ? mesh_create_tri_pos_and_normals_visible_only(rdata) : mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - GWN_batch_vertbuf_add_ex(cache->triangles_with_vert_colors, vbo_tris, use_hide); + GPU_batch_vertbuf_add_ex(cache->triangles_with_vert_colors, vbo_tris, use_hide); mesh_render_data_free(rdata); } @@ -3901,14 +3901,14 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh } -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id( +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id( struct Mesh *me, bool use_hide, uint select_id_offset) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->triangles_with_select_id_offset != select_id_offset) { cache->triangles_with_select_id_offset = select_id_offset; - GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->triangles_with_select_id); } if (cache->triangles_with_select_id == NULL) { @@ -3916,13 +3916,13 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id( MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->triangles_with_select_id = GWN_batch_create_ex( - GWN_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GWN_BATCH_OWNS_VBO); + cache->triangles_with_select_id = GPU_batch_create_ex( + GPU_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GPU_BATCH_OWNS_VBO); - Gwn_VertBuf *vbo_tris = use_hide ? + GPUVertBuf *vbo_tris = use_hide ? mesh_create_tri_pos_and_normals_visible_only(rdata) : mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - GWN_batch_vertbuf_add_ex(cache->triangles_with_select_id, vbo_tris, use_hide); + GPU_batch_vertbuf_add_ex(cache->triangles_with_select_id, vbo_tris, use_hide); mesh_render_data_free(rdata); } @@ -3934,7 +3934,7 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id( * Same as #DRW_mesh_batch_cache_get_triangles_with_select_id * without the ID's, use to mask out geometry, eg - dont select face-dots behind other faces. */ -struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide) +struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->triangles_with_select_mask == NULL) { @@ -3942,12 +3942,12 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mes MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - Gwn_VertBuf *vbo_tris = use_hide ? + GPUVertBuf *vbo_tris = use_hide ? mesh_create_tri_pos_and_normals_visible_only(rdata) : mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - cache->triangles_with_select_mask = GWN_batch_create_ex( - GWN_PRIM_TRIS, vbo_tris, NULL, use_hide ? GWN_BATCH_OWNS_VBO : 0); + cache->triangles_with_select_mask = GPU_batch_create_ex( + GPU_PRIM_TRIS, vbo_tris, NULL, use_hide ? GPU_BATCH_OWNS_VBO : 0); mesh_render_data_free(rdata); } @@ -3955,7 +3955,7 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mes return cache->triangles_with_select_mask; } -Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3963,8 +3963,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->points_with_normals = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL); + cache->points_with_normals = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_tri_pos_and_normals(rdata, cache), NULL); mesh_render_data_free(rdata); } @@ -3972,7 +3972,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me) return cache->points_with_normals; } -Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -3980,8 +3980,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) /* create batch from DM */ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT); - cache->all_verts = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL); + cache->all_verts = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL); mesh_render_data_free(rdata); } @@ -3989,21 +3989,21 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) return cache->all_verts; } -Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->fancy_edges == NULL) { /* create batch from DM */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static struct { uint pos, n1, n2; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - attr_id.n1 = GWN_vertformat_attr_add(&format, "N1", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - attr_id.n2 = GWN_vertformat_attr_add(&format, "N2", GWN_COMP_I10, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + attr_id.n1 = GPU_vertformat_attr_add(&format, "N1", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + attr_id.n2 = GPU_vertformat_attr_add(&format, "N2", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); MeshRenderData *rdata = mesh_render_data_create( me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); @@ -4012,7 +4012,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) const int vbo_len_capacity = edge_len * 2; /* these are PRIM_LINE verts, not mesh verts */ int vbo_len_used = 0; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); for (int i = 0; i < edge_len; ++i) { float *vcos1, *vcos2; float *pnor1 = NULL, *pnor2 = NULL; @@ -4020,33 +4020,33 @@ Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) if (mesh_render_data_edge_vcos_manifold_pnors(rdata, i, &vcos1, &vcos2, &pnor1, &pnor2, &is_manifold)) { - Gwn_PackedNormal n1value = { .x = 0, .y = 0, .z = +511 }; - Gwn_PackedNormal n2value = { .x = 0, .y = 0, .z = -511 }; + GPUPackedNormal n1value = { .x = 0, .y = 0, .z = +511 }; + GPUPackedNormal n2value = { .x = 0, .y = 0, .z = -511 }; if (is_manifold) { - n1value = GWN_normal_convert_i10_v3(pnor1); - n2value = GWN_normal_convert_i10_v3(pnor2); + n1value = GPU_normal_convert_i10_v3(pnor1); + n2value = GPU_normal_convert_i10_v3(pnor2); } - const Gwn_PackedNormal *n1 = &n1value; - const Gwn_PackedNormal *n2 = &n2value; + const GPUPackedNormal *n1 = &n1value; + const GPUPackedNormal *n2 = &n2value; - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * i, vcos1); - GWN_vertbuf_attr_set(vbo, attr_id.n1, 2 * i, n1); - GWN_vertbuf_attr_set(vbo, attr_id.n2, 2 * i, n2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2 * i, vcos1); + GPU_vertbuf_attr_set(vbo, attr_id.n1, 2 * i, n1); + GPU_vertbuf_attr_set(vbo, attr_id.n2, 2 * i, n2); - GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * i + 1, vcos2); - GWN_vertbuf_attr_set(vbo, attr_id.n1, 2 * i + 1, n1); - GWN_vertbuf_attr_set(vbo, attr_id.n2, 2 * i + 1, n2); + GPU_vertbuf_attr_set(vbo, attr_id.pos, 2 * i + 1, vcos2); + GPU_vertbuf_attr_set(vbo, attr_id.n1, 2 * i + 1, n1); + GPU_vertbuf_attr_set(vbo, attr_id.n2, 2 * i + 1, n2); vbo_len_used += 2; } } if (vbo_len_used != vbo_len_capacity) { - GWN_vertbuf_data_resize(vbo, vbo_len_used); + GPU_vertbuf_data_resize(vbo, vbo_len_used); } - cache->fancy_edges = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + cache->fancy_edges = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); mesh_render_data_free(rdata); } @@ -4054,7 +4054,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me) return cache->fancy_edges; } -Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold) +GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4063,8 +4063,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold MeshRenderData *rdata = mesh_render_data_create(me, options); - cache->edge_detection = GWN_batch_create_ex( - GWN_PRIM_LINES_ADJ, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + cache->edge_detection = GPU_batch_create_ex( + GPU_PRIM_LINES_ADJ, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), mesh_batch_cache_get_edges_adjacency(rdata, cache), 0); mesh_render_data_free(rdata); @@ -4111,42 +4111,42 @@ static void mesh_batch_cache_create_overlay_batches(Mesh *me) MeshRenderData *rdata = mesh_render_data_create(me, options); if (cache->overlay_triangles == NULL) { - cache->overlay_triangles = GWN_batch_create( - GWN_PRIM_TRIS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); - GWN_batch_vertbuf_add(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_nor(rdata, cache)); - GWN_batch_vertbuf_add(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_data(rdata, cache)); + cache->overlay_triangles = GPU_batch_create( + GPU_PRIM_TRIS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); + GPU_batch_vertbuf_add(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_nor(rdata, cache)); + GPU_batch_vertbuf_add(cache->overlay_triangles, mesh_batch_cache_get_edit_tri_data(rdata, cache)); } if (cache->overlay_loose_edges == NULL) { - cache->overlay_loose_edges = GWN_batch_create( - GWN_PRIM_LINES, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL); - GWN_batch_vertbuf_add(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_nor(rdata, cache)); - GWN_batch_vertbuf_add(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_data(rdata, cache)); + cache->overlay_loose_edges = GPU_batch_create( + GPU_PRIM_LINES, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL); + GPU_batch_vertbuf_add(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_nor(rdata, cache)); + GPU_batch_vertbuf_add(cache->overlay_loose_edges, mesh_batch_cache_get_edit_ledge_data(rdata, cache)); } if (cache->overlay_loose_verts == NULL) { - cache->overlay_loose_verts = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_edit_lvert_pos(rdata, cache), NULL); - GWN_batch_vertbuf_add(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_nor(rdata, cache)); - GWN_batch_vertbuf_add(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_data(rdata, cache)); + cache->overlay_loose_verts = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_edit_lvert_pos(rdata, cache), NULL); + GPU_batch_vertbuf_add(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_nor(rdata, cache)); + GPU_batch_vertbuf_add(cache->overlay_loose_verts, mesh_batch_cache_get_edit_lvert_data(rdata, cache)); } if (cache->overlay_triangles_nor == NULL) { - cache->overlay_triangles_nor = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); - GWN_batch_vertbuf_add(cache->overlay_triangles_nor, mesh_batch_cache_get_edit_tri_nor(rdata, cache)); + cache->overlay_triangles_nor = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_edit_tri_pos(rdata, cache), NULL); + GPU_batch_vertbuf_add(cache->overlay_triangles_nor, mesh_batch_cache_get_edit_tri_nor(rdata, cache)); } if (cache->overlay_loose_edges_nor == NULL) { - cache->overlay_loose_edges_nor = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL); - GWN_batch_vertbuf_add(cache->overlay_loose_edges_nor, mesh_batch_cache_get_edit_ledge_nor(rdata, cache)); + cache->overlay_loose_edges_nor = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_edit_ledge_pos(rdata, cache), NULL); + GPU_batch_vertbuf_add(cache->overlay_loose_edges_nor, mesh_batch_cache_get_edit_ledge_nor(rdata, cache)); } mesh_render_data_free(rdata); } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4157,7 +4157,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles(Mesh *me) return cache->overlay_triangles; } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4168,7 +4168,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(Mesh *me) return cache->overlay_loose_edges; } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_verts(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4179,7 +4179,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(Mesh *me) return cache->overlay_loose_verts; } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_triangles_nor(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4190,7 +4190,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(Mesh *me) return cache->overlay_triangles_nor; } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4201,15 +4201,15 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(Mesh *me) return cache->overlay_loose_edges_nor; } -Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->overlay_facedots == NULL) { MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY); - cache->overlay_facedots = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL); + cache->overlay_facedots = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL); mesh_render_data_free(rdata); } @@ -4217,13 +4217,13 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me) return cache->overlay_facedots; } -Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint select_id_offset) +GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint select_id_offset) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->facedot_with_select_id_offset != select_id_offset) { cache->facedot_with_select_id_offset = select_id_offset; - GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id); } if (cache->facedot_with_select_id == NULL) { @@ -4231,10 +4231,10 @@ Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint selec /* We only want the 'pos', not the normals or flag. * Use since this is almost certainly already created. */ - cache->facedot_with_select_id = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL); + cache->facedot_with_select_id = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL); - GWN_batch_vertbuf_add_ex( + GPU_batch_vertbuf_add_ex( cache->facedot_with_select_id, mesh_create_facedot_select_id(rdata, select_id_offset), true); @@ -4244,22 +4244,22 @@ Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint selec return cache->facedot_with_select_id; } -Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id_offset) +GPUBatch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id_offset) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->edges_with_select_id_offset != select_id_offset) { cache->edges_with_select_id_offset = select_id_offset; - GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->edges_with_select_id); } if (cache->edges_with_select_id == NULL) { MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE); - cache->edges_with_select_id = GWN_batch_create( - GWN_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL); + cache->edges_with_select_id = GPU_batch_create( + GPU_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL); - GWN_batch_vertbuf_add_ex( + GPU_batch_vertbuf_add_ex( cache->edges_with_select_id, mesh_create_edges_select_id(rdata, select_id_offset), true); @@ -4269,22 +4269,22 @@ Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_i return cache->edges_with_select_id; } -Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id_offset) +GPUBatch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id_offset) { MeshBatchCache *cache = mesh_batch_cache_get(me); if (cache->verts_with_select_id_offset != select_id_offset) { cache->verts_with_select_id_offset = select_id_offset; - GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id); + GPU_BATCH_DISCARD_SAFE(cache->verts_with_select_id); } if (cache->verts_with_select_id == NULL) { MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT); - cache->verts_with_select_id = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL); + cache->verts_with_select_id = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL); - GWN_batch_vertbuf_add_ex( + GPU_batch_vertbuf_add_ex( cache->verts_with_select_id, mesh_create_verts_select_id(rdata, select_id_offset), true); @@ -4294,7 +4294,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_i return cache->verts_with_select_id; } -Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded( +GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count) { @@ -4311,16 +4311,16 @@ Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded( cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * mat_len, __func__); - Gwn_IndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache); + GPUIndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache); - Gwn_VertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - Gwn_VertBuf *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache); + GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); + GPUVertBuf *vbo_shading = mesh_batch_cache_get_tri_shading_data(rdata, cache); for (int i = 0; i < mat_len; ++i) { - cache->shaded_triangles[i] = GWN_batch_create( - GWN_PRIM_TRIS, vbo, el[i]); + cache->shaded_triangles[i] = GPU_batch_create( + GPU_PRIM_TRIS, vbo, el[i]); if (vbo_shading) { - GWN_batch_vertbuf_add(cache->shaded_triangles[i], vbo_shading); + GPU_batch_vertbuf_add(cache->shaded_triangles[i], vbo_shading); } } @@ -4336,7 +4336,7 @@ Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded( return cache->shaded_triangles; } -Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) +GPUBatch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4350,15 +4350,15 @@ Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) cache->texpaint_triangles = MEM_callocN(sizeof(*cache->texpaint_triangles) * mat_len, __func__); - Gwn_IndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache); + GPUIndexBuf **el = mesh_batch_cache_get_triangles_in_order_split_by_material(rdata, cache); - Gwn_VertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); + GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); for (int i = 0; i < mat_len; ++i) { - cache->texpaint_triangles[i] = GWN_batch_create( - GWN_PRIM_TRIS, vbo, el[i]); - Gwn_VertBuf *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); + cache->texpaint_triangles[i] = GPU_batch_create( + GPU_PRIM_TRIS, vbo, el[i]); + GPUVertBuf *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); if (vbo_uv) { - GWN_batch_vertbuf_add(cache->texpaint_triangles[i], vbo_uv); + GPU_batch_vertbuf_add(cache->texpaint_triangles[i], vbo_uv); } } mesh_render_data_free(rdata); @@ -4367,7 +4367,7 @@ Gwn_Batch **DRW_mesh_batch_cache_get_surface_texpaint(Mesh *me) return cache->texpaint_triangles; } -Gwn_Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4377,20 +4377,20 @@ Gwn_Batch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me) MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOPUV; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - Gwn_VertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); + GPUVertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache); - cache->texpaint_triangles_single = GWN_batch_create( - GWN_PRIM_TRIS, vbo, NULL); - Gwn_VertBuf *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); + cache->texpaint_triangles_single = GPU_batch_create( + GPU_PRIM_TRIS, vbo, NULL); + GPUVertBuf *vbo_uv = mesh_batch_cache_get_tri_uv_active(rdata, cache); if (vbo_uv) { - GWN_batch_vertbuf_add(cache->texpaint_triangles_single, vbo_uv); + GPU_batch_vertbuf_add(cache->texpaint_triangles_single, vbo_uv); } mesh_render_data_free(rdata); } return cache->texpaint_triangles_single; } -Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel) +GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4399,8 +4399,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->overlay_paint_edges = GWN_batch_create_ex( - GWN_PRIM_LINES, mesh_create_edge_pos_with_sel(rdata, use_wire, use_sel), NULL, GWN_BATCH_OWNS_VBO); + cache->overlay_paint_edges = GPU_batch_create_ex( + GPU_PRIM_LINES, mesh_create_edge_pos_with_sel(rdata, use_wire, use_sel), NULL, GPU_BATCH_OWNS_VBO); mesh_render_data_free(rdata); } @@ -4408,7 +4408,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire return cache->overlay_paint_edges; } -Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4417,9 +4417,9 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me) const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI; MeshRenderData *rdata = mesh_render_data_create(me, datatype); - cache->overlay_weight_faces = GWN_batch_create_ex( - GWN_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), - mesh_create_tri_overlay_weight_faces(rdata), GWN_BATCH_OWNS_INDEX); + cache->overlay_weight_faces = GPU_batch_create_ex( + GPU_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + mesh_create_tri_overlay_weight_faces(rdata), GPU_BATCH_OWNS_INDEX); mesh_render_data_free(rdata); } @@ -4427,7 +4427,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me) return cache->overlay_weight_faces; } -Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); @@ -4435,10 +4435,10 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me) /* create batch from Mesh */ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT); - cache->overlay_weight_verts = GWN_batch_create( - GWN_PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL); + cache->overlay_weight_verts = GPU_batch_create( + GPU_PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL); - GWN_batch_vertbuf_add_ex( + GPU_batch_vertbuf_add_ex( cache->overlay_weight_verts, mesh_create_vert_pos_with_overlay_data(rdata), true); mesh_render_data_free(rdata); @@ -4458,7 +4458,7 @@ void DRW_mesh_cache_sculpt_coords_ensure(Mesh *me) /* XXX Force update of all the batches that contains the pos_with_normals buffer. * TODO(fclem): Ideally, Gawain should provide a way to update a buffer without destroying it. */ mesh_batch_cache_clear_selective(me, cache->pos_with_normals); - GWN_VERTBUF_DISCARD_SAFE(cache->pos_with_normals); + GPU_VERTBUF_DISCARD_SAFE(cache->pos_with_normals); } cache->is_sculpt_points_tag = false; } diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c index 24930921bee..375b0ba6bb2 100644 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ b/source/blender/draw/intern/draw_cache_impl_metaball.c @@ -45,18 +45,18 @@ static void metaball_batch_cache_clear(MetaBall *mb); /* ---------------------------------------------------------------------- */ -/* MetaBall Gwn_Batch Cache */ +/* MetaBall GPUBatch Cache */ typedef struct MetaBallBatchCache { - Gwn_Batch *batch; - Gwn_Batch **shaded_triangles; + GPUBatch *batch; + GPUBatch **shaded_triangles; int mat_len; /* settings to determine if cache is invalid */ bool is_dirty; } MetaBallBatchCache; -/* Gwn_Batch cache management. */ +/* GPUBatch cache management. */ static bool metaball_batch_cache_valid(MetaBall *mb) { @@ -113,7 +113,7 @@ static void metaball_batch_cache_clear(MetaBall *mb) return; } - GWN_BATCH_DISCARD_SAFE(cache->batch); + GPU_BATCH_DISCARD_SAFE(cache->batch); /* Note: shaded_triangles[0] is already freed by cache->batch */ MEM_SAFE_FREE(cache->shaded_triangles); cache->mat_len = 0; @@ -130,7 +130,7 @@ void DRW_mball_batch_cache_free(MetaBall *mb) /** \name Public Object/MetaBall API * \{ */ -Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) +GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) { if (!BKE_mball_is_basis(ob)) { return NULL; @@ -141,17 +141,17 @@ Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) if (cache->batch == NULL) { ListBase *lb = &ob->curve_cache->disp; - cache->batch = GWN_batch_create_ex( - GWN_PRIM_TRIS, + cache->batch = GPU_batch_create_ex( + GPU_PRIM_TRIS, DRW_displist_vertbuf_calc_pos_with_normals(lb), DRW_displist_indexbuf_calc_triangles_in_order(lb), - GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } return cache->batch; } -Gwn_Batch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, MetaBall *mb, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) +GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, MetaBall *mb, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len) { if (!BKE_mball_is_basis(ob)) { return NULL; diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index df67d34d566..b56396261d3 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -61,11 +61,11 @@ static void particle_batch_cache_clear(ParticleSystem *psys); /* ---------------------------------------------------------------------- */ -/* Particle Gwn_Batch Cache */ +/* Particle GPUBatch Cache */ typedef struct ParticlePointCache { - Gwn_VertBuf *pos; - Gwn_Batch *points; + GPUVertBuf *pos; + GPUBatch *points; int elems_len; int point_len; } ParticlePointCache; @@ -80,19 +80,19 @@ typedef struct ParticleBatchCache { /* Control points when in edit mode. */ ParticleHairCache edit_hair; - Gwn_VertBuf *edit_inner_pos; - Gwn_Batch *edit_inner_points; + GPUVertBuf *edit_inner_pos; + GPUBatch *edit_inner_points; int edit_inner_point_len; - Gwn_VertBuf *edit_tip_pos; - Gwn_Batch *edit_tip_points; + GPUVertBuf *edit_tip_pos; + GPUBatch *edit_tip_points; int edit_tip_point_len; /* Settings to determine if cache is invalid. */ bool is_dirty; } ParticleBatchCache; -/* Gwn_Batch cache management. */ +/* GPUBatch cache management. */ typedef struct HairAttributeID { uint pos; @@ -158,39 +158,39 @@ void DRW_particle_batch_cache_dirty(ParticleSystem *psys, int mode) static void particle_batch_cache_clear_point(ParticlePointCache *point_cache) { - GWN_BATCH_DISCARD_SAFE(point_cache->points); - GWN_VERTBUF_DISCARD_SAFE(point_cache->pos); + GPU_BATCH_DISCARD_SAFE(point_cache->points); + GPU_VERTBUF_DISCARD_SAFE(point_cache->pos); } static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache) { /* TODO more granular update tagging. */ - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf); DRW_TEXTURE_FREE_SAFE(hair_cache->point_tex); - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_strand_buf); DRW_TEXTURE_FREE_SAFE(hair_cache->strand_tex); for (int i = 0; i < MAX_MTFACE; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_uv_buf[i]); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_uv_buf[i]); DRW_TEXTURE_FREE_SAFE(hair_cache->uv_tex[i]); } for (int i = 0; i < MAX_MCOL; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->proc_col_buf[i]); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_col_buf[i]); DRW_TEXTURE_FREE_SAFE(hair_cache->col_tex[i]); } for (int i = 0; i < MAX_HAIR_SUBDIV; ++i) { - GWN_VERTBUF_DISCARD_SAFE(hair_cache->final[i].proc_buf); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->final[i].proc_buf); DRW_TEXTURE_FREE_SAFE(hair_cache->final[i].proc_tex); for (int j = 0; j < MAX_THICKRES; ++j) { - GWN_BATCH_DISCARD_SAFE(hair_cache->final[i].proc_hairs[j]); + GPU_BATCH_DISCARD_SAFE(hair_cache->final[i].proc_hairs[j]); } } /* "Normal" legacy hairs */ - GWN_BATCH_DISCARD_SAFE(hair_cache->hairs); - GWN_VERTBUF_DISCARD_SAFE(hair_cache->pos); - GWN_INDEXBUF_DISCARD_SAFE(hair_cache->indices); + GPU_BATCH_DISCARD_SAFE(hair_cache->hairs); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->pos); + GPU_INDEXBUF_DISCARD_SAFE(hair_cache->indices); } static void particle_batch_cache_clear(ParticleSystem *psys) @@ -205,10 +205,10 @@ static void particle_batch_cache_clear(ParticleSystem *psys) particle_batch_cache_clear_hair(&cache->edit_hair); - GWN_BATCH_DISCARD_SAFE(cache->edit_inner_points); - GWN_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); - GWN_BATCH_DISCARD_SAFE(cache->edit_tip_points); - GWN_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); + GPU_BATCH_DISCARD_SAFE(cache->edit_inner_points); + GPU_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); + GPU_BATCH_DISCARD_SAFE(cache->edit_tip_points); + GPU_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); } void DRW_particle_batch_cache_free(ParticleSystem *psys) @@ -514,7 +514,7 @@ static int particle_batch_cache_fill_segments( uint *col_id, float (***r_parent_uvs)[2], MCol ***r_parent_mcol, - Gwn_IndexBufBuilder *elb, + GPUIndexBufBuilder *elb, HairAttributeID *attr_id, ParticleHairCache *hair_cache) { @@ -561,12 +561,12 @@ static int particle_batch_cache_fill_segments( else { sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co); } - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, path[j].co); - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->tan, curr_point, tangent); - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->ind, curr_point, &i); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, path[j].co); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->tan, curr_point, tangent); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->ind, curr_point, &i); if (psmd != NULL) { for (int k = 0; k < num_uv_layers; k++) { - GWN_vertbuf_attr_set( + GPU_vertbuf_attr_set( hair_cache->pos, uv_id[k], curr_point, (is_simple && is_child) ? (*r_parent_uvs)[psys->child[i].parent][k] : uv[k]); @@ -578,22 +578,22 @@ static int particle_batch_cache_fill_segments( (is_simple && is_child) ? &(*r_parent_mcol)[psys->child[i].parent][k] : &mcol[k], scol); - GWN_vertbuf_attr_set(hair_cache->pos, col_id[k], curr_point, scol); + GPU_vertbuf_attr_set(hair_cache->pos, col_id[k], curr_point, scol); } } - GWN_indexbuf_add_generic_vert(elb, curr_point); + GPU_indexbuf_add_generic_vert(elb, curr_point); curr_point++; } sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co); int global_index = i + global_offset; - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, path[path->segments].co); - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->tan, curr_point, tangent); - GWN_vertbuf_attr_set(hair_cache->pos, attr_id->ind, curr_point, &global_index); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, path[path->segments].co); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->tan, curr_point, tangent); + GPU_vertbuf_attr_set(hair_cache->pos, attr_id->ind, curr_point, &global_index); if (psmd != NULL) { for (int k = 0; k < num_uv_layers; k++) { - GWN_vertbuf_attr_set( + GPU_vertbuf_attr_set( hair_cache->pos, uv_id[k], curr_point, (is_simple && is_child) ? (*r_parent_uvs)[psys->child[i].parent][k] : uv[k]); @@ -605,7 +605,7 @@ static int particle_batch_cache_fill_segments( (is_simple && is_child) ? &(*r_parent_mcol)[psys->child[i].parent][k] : &mcol[k], scol); - GWN_vertbuf_attr_set(hair_cache->pos, col_id[k], curr_point, scol); + GPU_vertbuf_attr_set(hair_cache->pos, col_id[k], curr_point, scol); } if (!is_simple) { MEM_freeN(uv); @@ -613,8 +613,8 @@ static int particle_batch_cache_fill_segments( } } /* Finish the segment and add restart primitive. */ - GWN_indexbuf_add_generic_vert(elb, curr_point); - GWN_indexbuf_add_primitive_restart(elb); + GPU_indexbuf_add_generic_vert(elb, curr_point); + GPU_indexbuf_add_primitive_restart(elb); curr_point++; } return curr_point; @@ -623,7 +623,7 @@ static int particle_batch_cache_fill_segments( static void particle_batch_cache_fill_segments_proc_pos( ParticleCacheKey **path_cache, const int num_path_keys, - Gwn_VertBufRaw *attr_step) + GPUVertBufRaw *attr_step) { for (int i = 0; i < num_path_keys; i++) { ParticleCacheKey *path = path_cache[i]; @@ -633,7 +633,7 @@ static void particle_batch_cache_fill_segments_proc_pos( float total_len = 0.0f; float *co_prev = NULL, *seg_data_first; for (int j = 0; j <= path->segments; j++) { - float *seg_data = (float *)GWN_vertbuf_raw_step(attr_step); + float *seg_data = (float *)GPU_vertbuf_raw_step(attr_step); copy_v3_v3(seg_data, path[j].co); if (co_prev) { total_len += len_v3v3(co_prev, path[j].co); @@ -658,7 +658,7 @@ static int particle_batch_cache_fill_segments_indices( const int start_index, const int num_path_keys, const int res, - Gwn_IndexBufBuilder *elb) + GPUIndexBufBuilder *elb) { int curr_point = start_index; for (int i = 0; i < num_path_keys; i++) { @@ -667,9 +667,9 @@ static int particle_batch_cache_fill_segments_indices( continue; } for (int k = 0; k < res; k++) { - GWN_indexbuf_add_generic_vert(elb, curr_point++); + GPU_indexbuf_add_generic_vert(elb, curr_point++); } - GWN_indexbuf_add_primitive_restart(elb); + GPU_indexbuf_add_primitive_restart(elb); } return curr_point; } @@ -681,9 +681,9 @@ static int particle_batch_cache_fill_strands_data( const ParticleSource particle_source, const int start_index, const int num_path_keys, - Gwn_VertBufRaw *data_step, - float (***r_parent_uvs)[2], Gwn_VertBufRaw *uv_step, MTFace **mtfaces, int num_uv_layers, - MCol ***r_parent_mcol, Gwn_VertBufRaw *col_step, MCol **mcols, int num_col_layers) + GPUVertBufRaw *data_step, + float (***r_parent_uvs)[2], GPUVertBufRaw *uv_step, MTFace **mtfaces, int num_uv_layers, + MCol ***r_parent_mcol, GPUVertBufRaw *col_step, MCol **mcols, int num_col_layers) { const bool is_simple = (psys->part->childtype == PART_CHILD_PARTICLES); const bool is_child = (particle_source == PARTICLE_SOURCE_CHILDREN); @@ -705,7 +705,7 @@ static int particle_batch_cache_fill_strands_data( continue; } - uint *seg_data = (uint *)GWN_vertbuf_raw_step(data_step); + uint *seg_data = (uint *)GPU_vertbuf_raw_step(data_step); *seg_data = (curr_point & 0xFFFFFF) | (path->segments << 24); curr_point += path->segments + 1; @@ -730,11 +730,11 @@ static int particle_batch_cache_fill_strands_data( *r_parent_mcol, &mcol); for (int k = 0; k < num_uv_layers; k++) { - float *t_uv = (float *)GWN_vertbuf_raw_step(uv_step + k); + float *t_uv = (float *)GPU_vertbuf_raw_step(uv_step + k); copy_v2_v2(t_uv, uv[k]); } for (int k = 0; k < num_col_layers; k++) { - ushort *scol = (ushort *)GWN_vertbuf_raw_step(col_step + k); + ushort *scol = (ushort *)GPU_vertbuf_raw_step(col_step + k); particle_pack_mcol( (is_simple && is_child) ? &(*r_parent_mcol)[psys->child[i].parent][k] : &mcol[k], @@ -754,17 +754,17 @@ static void particle_batch_cache_ensure_procedural_final_points( int subdiv) { /* Same format as point_tex. */ - Gwn_VertFormat format = { 0 }; - GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat format = { 0 }; + GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - cache->final[subdiv].proc_buf = GWN_vertbuf_create_with_format(&format); + cache->final[subdiv].proc_buf = GPU_vertbuf_create_with_format(&format); /* Create a destination buffer for the tranform feedback. Sized appropriately */ /* Thoses are points! not line segments. */ - GWN_vertbuf_data_alloc(cache->final[subdiv].proc_buf, cache->final[subdiv].strands_res * cache->strands_len); + GPU_vertbuf_data_alloc(cache->final[subdiv].proc_buf, cache->final[subdiv].strands_res * cache->strands_len); /* Create vbo immediatly to bind to texture buffer. */ - GWN_vertbuf_use(cache->final[subdiv].proc_buf); + GPU_vertbuf_use(cache->final[subdiv].proc_buf); cache->final[subdiv].proc_tex = GPU_texture_create_from_vertbuf(cache->final[subdiv].proc_buf); } @@ -791,37 +791,37 @@ static void particle_batch_cache_ensure_procedural_strand_data( } } - Gwn_VertBufRaw data_step; - Gwn_VertBufRaw uv_step[MAX_MTFACE]; - Gwn_VertBufRaw col_step[MAX_MCOL]; + GPUVertBufRaw data_step; + GPUVertBufRaw uv_step[MAX_MTFACE]; + GPUVertBufRaw col_step[MAX_MCOL]; MTFace *mtfaces[MAX_MTFACE] = {NULL}; MCol *mcols[MAX_MCOL] = {NULL}; float (**parent_uvs)[2] = NULL; MCol **parent_mcol = NULL; - Gwn_VertFormat format_data = {0}; - uint data_id = GWN_vertformat_attr_add(&format_data, "data", GWN_COMP_U32, 1, GWN_FETCH_INT); + GPUVertFormat format_data = {0}; + uint data_id = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U32, 1, GPU_FETCH_INT); - Gwn_VertFormat format_uv = {0}; - uint uv_id = GWN_vertformat_attr_add(&format_uv, "uv", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat format_uv = {0}; + uint uv_id = GPU_vertformat_attr_add(&format_uv, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - Gwn_VertFormat format_col = {0}; - uint col_id = GWN_vertformat_attr_add(&format_col, "col", GWN_COMP_U16, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat format_col = {0}; + uint col_id = GPU_vertformat_attr_add(&format_col, "col", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); memset(cache->uv_layer_names, 0, sizeof(cache->uv_layer_names)); memset(cache->col_layer_names, 0, sizeof(cache->col_layer_names)); /* Strand Data */ - cache->proc_strand_buf = GWN_vertbuf_create_with_format(&format_data); - GWN_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); - GWN_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); + cache->proc_strand_buf = GPU_vertbuf_create_with_format(&format_data); + GPU_vertbuf_data_alloc(cache->proc_strand_buf, cache->strands_len); + GPU_vertbuf_attr_get_raw_data(cache->proc_strand_buf, data_id, &data_step); /* UV layers */ for (int i = 0; i < cache->num_uv_layers; i++) { - cache->proc_uv_buf[i] = GWN_vertbuf_create_with_format(&format_uv); - GWN_vertbuf_data_alloc(cache->proc_uv_buf[i], cache->strands_len); - GWN_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); + cache->proc_uv_buf[i] = GPU_vertbuf_create_with_format(&format_uv); + GPU_vertbuf_data_alloc(cache->proc_uv_buf[i], cache->strands_len); + GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); uint hash = BLI_ghashutil_strhash_p(name); @@ -835,9 +835,9 @@ static void particle_batch_cache_ensure_procedural_strand_data( } /* Vertex colors */ for (int i = 0; i < cache->num_col_layers; i++) { - cache->proc_col_buf[i] = GWN_vertbuf_create_with_format(&format_col); - GWN_vertbuf_data_alloc(cache->proc_col_buf[i], cache->strands_len); - GWN_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); + cache->proc_col_buf[i] = GPU_vertbuf_create_with_format(&format_col); + GPU_vertbuf_data_alloc(cache->proc_col_buf[i], cache->strands_len); + GPU_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); uint hash = BLI_ghashutil_strhash_p(name); @@ -914,15 +914,15 @@ static void particle_batch_cache_ensure_procedural_strand_data( } /* Create vbo immediatly to bind to texture buffer. */ - GWN_vertbuf_use(cache->proc_strand_buf); + GPU_vertbuf_use(cache->proc_strand_buf); cache->strand_tex = GPU_texture_create_from_vertbuf(cache->proc_strand_buf); for (int i = 0; i < cache->num_uv_layers; i++) { - GWN_vertbuf_use(cache->proc_uv_buf[i]); + GPU_vertbuf_use(cache->proc_uv_buf[i]); cache->uv_tex[i] = GPU_texture_create_from_vertbuf(cache->proc_uv_buf[i]); } for (int i = 0; i < cache->num_col_layers; i++) { - GWN_vertbuf_use(cache->proc_col_buf[i]); + GPU_vertbuf_use(cache->proc_col_buf[i]); cache->col_tex[i] = GPU_texture_create_from_vertbuf(cache->proc_col_buf[i]); } } @@ -943,19 +943,19 @@ static void particle_batch_cache_ensure_procedural_indices( int verts_per_hair = cache->final[subdiv].strands_res * thickness_res; /* +1 for primitive restart */ int element_count = (verts_per_hair + 1) * cache->strands_len; - Gwn_PrimType prim_type = (thickness_res == 1) ? GWN_PRIM_LINE_STRIP : GWN_PRIM_TRI_STRIP; + GPUPrimType prim_type = (thickness_res == 1) ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP; - static Gwn_VertFormat format = { 0 }; - GWN_vertformat_clear(&format); + static GPUVertFormat format = { 0 }; + GPU_vertformat_clear(&format); /* initialize vertex format */ - GWN_vertformat_attr_add(&format, "dummy", GWN_COMP_U8, 1, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, 1); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 1); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init_ex(&elb, prim_type, element_count, element_count, true); + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, prim_type, element_count, element_count, true); if (edit != NULL && edit->pathcache != NULL) { particle_batch_cache_fill_segments_indices( @@ -976,11 +976,11 @@ static void particle_batch_cache_ensure_procedural_indices( } } - cache->final[subdiv].proc_hairs[thickness_res - 1] = GWN_batch_create_ex( + cache->final[subdiv].proc_hairs[thickness_res - 1] = GPU_batch_create_ex( prim_type, vbo, - GWN_indexbuf_build(&elb), - GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + GPU_indexbuf_build(&elb), + GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } static void particle_batch_cache_ensure_procedural_pos( @@ -993,14 +993,14 @@ static void particle_batch_cache_ensure_procedural_pos( } /* initialize vertex format */ - Gwn_VertFormat format = {0}; - uint pos_id = GWN_vertformat_attr_add(&format, "posTime", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat format = {0}; + uint pos_id = GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - cache->proc_point_buf = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->proc_point_buf, cache->point_len); + cache->proc_point_buf = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache->proc_point_buf, cache->point_len); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &pos_step); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(cache->proc_point_buf, pos_id, &pos_step); if (edit != NULL && edit->pathcache != NULL) { particle_batch_cache_fill_segments_proc_pos( @@ -1027,7 +1027,7 @@ static void particle_batch_cache_ensure_procedural_pos( } /* Create vbo immediatly to bind to texture buffer. */ - GWN_vertbuf_use(cache->proc_point_buf); + GPU_vertbuf_use(cache->proc_point_buf); cache->point_tex = GPU_texture_create_from_vertbuf(cache->proc_point_buf); } @@ -1045,10 +1045,10 @@ static void particle_batch_cache_ensure_pos_and_seg( int curr_point = 0; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - GWN_VERTBUF_DISCARD_SAFE(hair_cache->pos); - GWN_INDEXBUF_DISCARD_SAFE(hair_cache->indices); + GPU_VERTBUF_DISCARD_SAFE(hair_cache->pos); + GPU_INDEXBUF_DISCARD_SAFE(hair_cache->indices); - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; HairAttributeID attr_id; uint *uv_id = NULL; uint *col_id = NULL; @@ -1072,12 +1072,12 @@ static void particle_batch_cache_ensure_pos_and_seg( } } - GWN_vertformat_clear(&format); + GPU_vertformat_clear(&format); /* initialize vertex format */ - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.tan = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - attr_id.ind = GWN_vertformat_attr_add(&format, "ind", GWN_COMP_I32, 1, GWN_FETCH_INT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.tan = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + attr_id.ind = GPU_vertformat_attr_add(&format, "ind", GPU_COMP_I32, 1, GPU_FETCH_INT); if (psmd) { uv_id = MEM_mallocN(sizeof(*uv_id) * num_uv_layers, "UV attrib format"); @@ -1088,10 +1088,10 @@ static void particle_batch_cache_ensure_pos_and_seg( char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name)); - uv_id[i] = GWN_vertformat_attr_add(&format, uuid, GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uv_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (i == active_uv) { - GWN_vertformat_alias_add(&format, "u"); + GPU_vertformat_alias_add(&format, "u"); } } @@ -1100,21 +1100,21 @@ static void particle_batch_cache_ensure_pos_and_seg( char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "c%u", BLI_ghashutil_strhash_p(name)); - col_id[i] = GWN_vertformat_attr_add(&format, uuid, GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + col_id[i] = GPU_vertformat_attr_add(&format, uuid, GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (i == active_col) { - GWN_vertformat_alias_add(&format, "c"); + GPU_vertformat_alias_add(&format, "c"); } } } - hair_cache->pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(hair_cache->pos, hair_cache->point_len); + hair_cache->pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(hair_cache->pos, hair_cache->point_len); - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init_ex( + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex( &elb, - GWN_PRIM_LINE_STRIP, + GPU_PRIM_LINE_STRIP, hair_cache->elems_len, hair_cache->point_len, true); @@ -1183,7 +1183,7 @@ static void particle_batch_cache_ensure_pos_and_seg( if (psmd != NULL) { MEM_freeN(uv_id); } - hair_cache->indices = GWN_indexbuf_build(&elb); + hair_cache->indices = GPU_indexbuf_build(&elb); } static void particle_batch_cache_ensure_pos( @@ -1195,7 +1195,7 @@ static void particle_batch_cache_ensure_pos( return; } - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, rot_id, val_id; int i, curr_point; ParticleData *pa; @@ -1217,17 +1217,17 @@ static void particle_batch_cache_ensure_pos( } } - GWN_VERTBUF_DISCARD_SAFE(point_cache->pos); + GPU_VERTBUF_DISCARD_SAFE(point_cache->pos); if (format.attr_len == 0) { /* initialize vertex format */ - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - rot_id = GWN_vertformat_attr_add(&format, "rot", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - val_id = GWN_vertformat_attr_add(&format, "val", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + rot_id = GPU_vertformat_attr_add(&format, "rot", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + val_id = GPU_vertformat_attr_add(&format, "val", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } - point_cache->pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(point_cache->pos, psys->totpart); + point_cache->pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(point_cache->pos, psys->totpart); for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { state.time = DEG_get_ctime(draw_ctx->depsgraph); @@ -1237,8 +1237,8 @@ static void particle_batch_cache_ensure_pos( float val; - GWN_vertbuf_attr_set(point_cache->pos, pos_id, curr_point, pa->state.co); - GWN_vertbuf_attr_set(point_cache->pos, rot_id, curr_point, pa->state.rot); + GPU_vertbuf_attr_set(point_cache->pos, pos_id, curr_point, pa->state.co); + GPU_vertbuf_attr_set(point_cache->pos, rot_id, curr_point, pa->state.rot); switch (psys->part->draw_col) { case PART_DRAW_COL_VEL: @@ -1254,13 +1254,13 @@ static void particle_batch_cache_ensure_pos( break; } - GWN_vertbuf_attr_set(point_cache->pos, val_id, curr_point, &val); + GPU_vertbuf_attr_set(point_cache->pos, val_id, curr_point, &val); curr_point++; } if (curr_point != psys->totpart) { - GWN_vertbuf_data_resize(point_cache->pos, curr_point); + GPU_vertbuf_data_resize(point_cache->pos, curr_point); } } @@ -1334,7 +1334,7 @@ static void drw_particle_get_hair_source( } } -Gwn_Batch *DRW_particles_batch_cache_get_hair( +GPUBatch *DRW_particles_batch_cache_get_hair( Object *object, ParticleSystem *psys, ModifierData *md) @@ -1346,27 +1346,27 @@ Gwn_Batch *DRW_particles_batch_cache_get_hair( drw_particle_get_hair_source(object, psys, md, NULL, &source); ensure_seg_pt_count(source.edit, source.psys, &cache->hair); particle_batch_cache_ensure_pos_and_seg(source.edit, source.psys, source.md, &cache->hair); - cache->hair.hairs = GWN_batch_create( - GWN_PRIM_LINE_STRIP, + cache->hair.hairs = GPU_batch_create( + GPU_PRIM_LINE_STRIP, cache->hair.pos, cache->hair.indices); } return cache->hair.hairs; } -Gwn_Batch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *psys) +GPUBatch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *psys) { ParticleBatchCache *cache = particle_batch_cache_get(psys); if (cache->point.points == NULL) { particle_batch_cache_ensure_pos(object, psys, &cache->point); - cache->point.points = GWN_batch_create(GWN_PRIM_POINTS, cache->point.pos, NULL); + cache->point.points = GPU_batch_create(GPU_PRIM_POINTS, cache->point.pos, NULL); } return cache->point.points; } -Gwn_Batch *DRW_particles_batch_cache_get_edit_strands( +GPUBatch *DRW_particles_batch_cache_get_edit_strands( Object *object, ParticleSystem *psys, PTCacheEdit *edit) @@ -1378,8 +1378,8 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_strands( drw_particle_update_ptcache_edit(object, psys, edit); ensure_seg_pt_count(edit, psys, &cache->edit_hair); particle_batch_cache_ensure_pos_and_seg(edit, psys, NULL, &cache->edit_hair); - cache->edit_hair.hairs = GWN_batch_create( - GWN_PRIM_LINE_STRIP, + cache->edit_hair.hairs = GPU_batch_create( + GPU_PRIM_LINE_STRIP, cache->edit_hair.pos, cache->edit_hair.indices); return cache->edit_hair.hairs; @@ -1419,19 +1419,19 @@ static void particle_batch_cache_ensure_edit_inner_pos( return; } - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, color_id; - GWN_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->edit_inner_pos); if (format.attr_len == 0) { /* initialize vertex format */ - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - color_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } - cache->edit_inner_pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->edit_inner_pos, cache->edit_inner_point_len); + cache->edit_inner_pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache->edit_inner_pos, cache->edit_inner_point_len); float selected_color[4], normal_color[4]; edit_colors_get(edit, selected_color, normal_color); @@ -1441,19 +1441,19 @@ static void particle_batch_cache_ensure_edit_inner_pos( const PTCacheEditPoint *point = &edit->points[point_index]; for (int key_index = 0; key_index < point->totkey - 1; key_index++) { PTCacheEditKey *key = &point->keys[key_index]; - GWN_vertbuf_attr_set(cache->edit_inner_pos, pos_id, global_key_index, key->world_co); + GPU_vertbuf_attr_set(cache->edit_inner_pos, pos_id, global_key_index, key->world_co); if (key->flag & PEK_SELECT) { - GWN_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, selected_color); + GPU_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, selected_color); } else { - GWN_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, normal_color); + GPU_vertbuf_attr_set(cache->edit_inner_pos, color_id, global_key_index, normal_color); } global_key_index++; } } } -Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points( +GPUBatch *DRW_particles_batch_cache_get_edit_inner_points( Object *object, ParticleSystem *psys, PTCacheEdit *edit) @@ -1465,8 +1465,8 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points( drw_particle_update_ptcache_edit(object, psys, edit); ensure_edit_inner_points_count(edit, cache); particle_batch_cache_ensure_edit_inner_pos(edit, cache); - cache->edit_inner_points = GWN_batch_create( - GWN_PRIM_POINTS, + cache->edit_inner_points = GPU_batch_create( + GPU_PRIM_POINTS, cache->edit_inner_pos, NULL); return cache->edit_inner_points; @@ -1490,19 +1490,19 @@ static void particle_batch_cache_ensure_edit_tip_pos( return; } - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint pos_id, color_id; - GWN_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->edit_tip_pos); if (format.attr_len == 0) { /* initialize vertex format */ - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - color_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } - cache->edit_tip_pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->edit_tip_pos, cache->edit_tip_point_len); + cache->edit_tip_pos = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(cache->edit_tip_pos, cache->edit_tip_point_len); float selected_color[4], normal_color[4]; edit_colors_get(edit, selected_color, normal_color); @@ -1510,17 +1510,17 @@ static void particle_batch_cache_ensure_edit_tip_pos( for (int point_index = 0; point_index < edit->totpoint; point_index++) { const PTCacheEditPoint *point = &edit->points[point_index]; PTCacheEditKey *key = &point->keys[point->totkey - 1]; - GWN_vertbuf_attr_set(cache->edit_tip_pos, pos_id, point_index, key->world_co); + GPU_vertbuf_attr_set(cache->edit_tip_pos, pos_id, point_index, key->world_co); if (key->flag & PEK_SELECT) { - GWN_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, selected_color); + GPU_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, selected_color); } else { - GWN_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, normal_color); + GPU_vertbuf_attr_set(cache->edit_tip_pos, color_id, point_index, normal_color); } } } -Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points( +GPUBatch *DRW_particles_batch_cache_get_edit_tip_points( Object *object, ParticleSystem *psys, PTCacheEdit *edit) @@ -1532,8 +1532,8 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points( drw_particle_update_ptcache_edit(object, psys, edit); ensure_edit_tip_points_count(edit, cache); particle_batch_cache_ensure_edit_tip_pos(edit, cache); - cache->edit_tip_points = GWN_batch_create( - GWN_PRIM_POINTS, + cache->edit_tip_points = GPU_batch_create( + GPU_PRIM_POINTS, cache->edit_tip_pos, NULL); return cache->edit_tip_points; diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index df80300417e..c9fc5eba079 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -208,29 +208,29 @@ static struct { } g_shaders = {NULL}; static struct { - struct Gwn_VertFormat *instance_screenspace; - struct Gwn_VertFormat *instance_color; - struct Gwn_VertFormat *instance_screen_aligned; - struct Gwn_VertFormat *instance_scaled; - struct Gwn_VertFormat *instance_sized; - struct Gwn_VertFormat *instance_outline; - struct Gwn_VertFormat *instance; - struct Gwn_VertFormat *instance_camera; - struct Gwn_VertFormat *instance_distance_lines; - struct Gwn_VertFormat *instance_spot; - struct Gwn_VertFormat *instance_bone; - struct Gwn_VertFormat *instance_bone_stick; - struct Gwn_VertFormat *instance_bone_outline; - struct Gwn_VertFormat *instance_bone_envelope; - struct Gwn_VertFormat *instance_bone_envelope_distance; - struct Gwn_VertFormat *instance_bone_envelope_outline; - struct Gwn_VertFormat *instance_mball_handles; - struct Gwn_VertFormat *dynlines_color; + struct GPUVertFormat *instance_screenspace; + struct GPUVertFormat *instance_color; + struct GPUVertFormat *instance_screen_aligned; + struct GPUVertFormat *instance_scaled; + struct GPUVertFormat *instance_sized; + struct GPUVertFormat *instance_outline; + struct GPUVertFormat *instance; + struct GPUVertFormat *instance_camera; + struct GPUVertFormat *instance_distance_lines; + struct GPUVertFormat *instance_spot; + struct GPUVertFormat *instance_bone; + struct GPUVertFormat *instance_bone_stick; + struct GPUVertFormat *instance_bone_outline; + struct GPUVertFormat *instance_bone_envelope; + struct GPUVertFormat *instance_bone_envelope_distance; + struct GPUVertFormat *instance_bone_envelope_outline; + struct GPUVertFormat *instance_mball_handles; + struct GPUVertFormat *dynlines_color; } g_formats = {NULL}; void DRW_globals_free(void) { - struct Gwn_VertFormat **format = &g_formats.instance_screenspace; + struct GPUVertFormat **format = &g_formats.instance_screenspace; for (int i = 0; i < sizeof(g_formats) / sizeof(void *); ++i, ++format) { MEM_SAFE_FREE(*format); } @@ -304,7 +304,7 @@ DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4 return grp; } -DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *geom, float *size) +DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct GPUBatch *geom, float *size) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR); @@ -322,7 +322,7 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *g return grp; } -DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct GPUBatch *geom) { static float light[3] = {0.0f, 0.0f, 1.0f}; GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR); @@ -338,7 +338,7 @@ DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR); @@ -352,7 +352,7 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED); @@ -368,7 +368,7 @@ DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Gwn_Batch return grp; } -DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS); @@ -384,7 +384,7 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Gwn_Batch *ge return grp; } -DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE); @@ -399,7 +399,7 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); @@ -414,7 +414,7 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct Gwn_Batch *geom, int *baseid) +DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct GPUBatch *geom, int *baseid) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE); @@ -430,7 +430,7 @@ DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct Gwn_Batch *geom, return grp; } -DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA); @@ -447,7 +447,7 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom) return grp; } -DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES); static float point_size = 4.0f; @@ -465,7 +465,7 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Gwn_Batch return grp; } -DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR); static const int True = true; @@ -600,7 +600,7 @@ DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass) } /* Only works with batches with adjacency infos. */ -DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct GPUBatch *geom) { if (g_shaders.shape_outline == NULL) { g_shaders.shape_outline = DRW_shader_create( @@ -623,7 +623,7 @@ DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct Gwn_B return grp; } -DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct Gwn_Batch *geom) +DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatch *geom) { if (g_shaders.shape_solid == NULL) { g_shaders.shape_solid = DRW_shader_create( diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index b4ae0600f02..80b2ec8db71 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -28,7 +28,7 @@ struct DRWPass; struct DRWShadingGroup; -struct Gwn_Batch; +struct GPUBatch; struct GPUMaterial; struct Object; struct ViewLayer; @@ -112,25 +112,25 @@ struct DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(struct DRWPass *pa struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size); struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, float color[4]); struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, float color[4]); -struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Gwn_Batch *geom, float *size); -struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct Gwn_Batch *geom, int *baseid); -struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct GPUBatch *geom, float *size); +struct DRWShadingGroup *shgroup_instance_solid(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_wire(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct GPUBatch *geom, int *baseid); +struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_axes(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_distance(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_outline(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass); -struct DRWShadingGroup *shgroup_instance_bone_shape_outline(struct DRWPass *pass, struct Gwn_Batch *geom); -struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass, struct Gwn_Batch *geom); +struct DRWShadingGroup *shgroup_instance_bone_shape_outline(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass); diff --git a/source/blender/draw/intern/draw_debug.c b/source/blender/draw/intern/draw_debug.c index 64e76a339c1..8af13d66c28 100644 --- a/source/blender/draw/intern/draw_debug.c +++ b/source/blender/draw/intern/draw_debug.c @@ -147,13 +147,13 @@ static void drw_debug_draw_lines(void) return; } - Gwn_VertFormat *vert_format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(vert_format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *vert_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(vert_format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, count * 2); + immBegin(GPU_PRIM_LINES, count * 2); while (DST.debug.lines) { void *next = DST.debug.lines->next; @@ -181,36 +181,36 @@ static void drw_debug_draw_spheres(void) } float one = 1.0f; - Gwn_VertFormat vert_format = {0}; - uint mat = GWN_vertformat_attr_add(&vert_format, "InstanceModelMatrix", GWN_COMP_F32, 16, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(&vert_format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint siz = GWN_vertformat_attr_add(&vert_format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + GPUVertFormat vert_format = {0}; + uint mat = GPU_vertformat_attr_add(&vert_format, "InstanceModelMatrix", GPU_COMP_F32, 16, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(&vert_format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint siz = GPU_vertformat_attr_add(&vert_format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - Gwn_VertBuf *inst_vbo = GWN_vertbuf_create_with_format(&vert_format); + GPUVertBuf *inst_vbo = GPU_vertbuf_create_with_format(&vert_format); - GWN_vertbuf_data_alloc(inst_vbo, count); + GPU_vertbuf_data_alloc(inst_vbo, count); int v = 0; while (DST.debug.spheres) { void *next = DST.debug.spheres->next; - GWN_vertbuf_attr_set(inst_vbo, mat, v, DST.debug.spheres->mat[0]); - GWN_vertbuf_attr_set(inst_vbo, col, v, DST.debug.spheres->color); - GWN_vertbuf_attr_set(inst_vbo, siz, v, &one); + GPU_vertbuf_attr_set(inst_vbo, mat, v, DST.debug.spheres->mat[0]); + GPU_vertbuf_attr_set(inst_vbo, col, v, DST.debug.spheres->color); + GPU_vertbuf_attr_set(inst_vbo, siz, v, &one); v++; MEM_freeN(DST.debug.spheres); DST.debug.spheres = next; } - Gwn_Batch *empty_sphere = DRW_cache_empty_sphere_get(); + GPUBatch *empty_sphere = DRW_cache_empty_sphere_get(); - Gwn_Batch *draw_batch = GWN_batch_create(GWN_PRIM_LINES, empty_sphere->verts[0], NULL); - GWN_batch_instbuf_set(draw_batch, inst_vbo, true); - GWN_batch_program_set_builtin(draw_batch, GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); + GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_LINES, empty_sphere->verts[0], NULL); + GPU_batch_instbuf_set(draw_batch, inst_vbo, true); + GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); - GWN_batch_draw(draw_batch); - GWN_batch_discard(draw_batch); + GPU_batch_draw(draw_batch); + GPU_batch_discard(draw_batch); } void drw_debug_draw(void) diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h index 17acd7e6259..41f91e02459 100644 --- a/source/blender/draw/intern/draw_hair_private.h +++ b/source/blender/draw/intern/draw_hair_private.h @@ -42,32 +42,32 @@ struct ParticleHairCache; typedef struct ParticleHairFinalCache { /* Output of the subdivision stage: vertex buff sized to subdiv level. */ - Gwn_VertBuf *proc_buf; + GPUVertBuf *proc_buf; GPUTexture *proc_tex; /* Just contains a huge index buffer used to draw the final hair. */ - Gwn_Batch *proc_hairs[MAX_THICKRES]; + GPUBatch *proc_hairs[MAX_THICKRES]; int strands_res; /* points per hair, at least 2 */ } ParticleHairFinalCache; typedef struct ParticleHairCache { - Gwn_VertBuf *pos; - Gwn_IndexBuf *indices; - Gwn_Batch *hairs; + GPUVertBuf *pos; + GPUIndexBuf *indices; + GPUBatch *hairs; /* Hair Procedural display: Interpolation is done on the GPU. */ - Gwn_VertBuf *proc_point_buf; /* Input control points */ + GPUVertBuf *proc_point_buf; /* Input control points */ GPUTexture *point_tex; - Gwn_VertBuf *proc_strand_buf; /* Infos of control points strands (segment count and base index) */ + GPUVertBuf *proc_strand_buf; /* Infos of control points strands (segment count and base index) */ GPUTexture *strand_tex; - Gwn_VertBuf *proc_uv_buf[MAX_MTFACE]; + GPUVertBuf *proc_uv_buf[MAX_MTFACE]; GPUTexture *uv_tex[MAX_MTFACE]; char uv_layer_names[MAX_MTFACE][MAX_LAYER_NAME_CT][MAX_LAYER_NAME_LEN]; - Gwn_VertBuf *proc_col_buf[MAX_MCOL]; + GPUVertBuf *proc_col_buf[MAX_MCOL]; GPUTexture *col_tex[MAX_MCOL]; char col_layer_names[MAX_MCOL][MAX_LAYER_NAME_CT][MAX_LAYER_NAME_LEN]; diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index e322d4780d5..89cffd6c19c 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -45,17 +45,17 @@ typedef struct DRWBatchingBuffer { struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */ - Gwn_VertFormat *format; /* Identifier. */ - Gwn_VertBuf *vert; /* Gwn_VertBuf contained in the Gwn_Batch. */ - Gwn_Batch *batch; /* Gwn_Batch containing the Gwn_VertBuf. */ + GPUVertFormat *format; /* Identifier. */ + GPUVertBuf *vert; /* GPUVertBuf contained in the GPUBatch. */ + GPUBatch *batch; /* GPUBatch containing the GPUVertBuf. */ } DRWBatchingBuffer; typedef struct DRWInstancingBuffer { struct DRWShadingGroup *shgroup; /* Link back to the owning shGroup. Also tells if it's used */ - Gwn_VertFormat *format; /* Identifier. */ - Gwn_Batch *instance; /* Identifier. */ - Gwn_VertBuf *vert; /* Gwn_VertBuf contained in the Gwn_Batch. */ - Gwn_Batch *batch; /* Gwn_Batch containing the Gwn_VertBuf. */ + GPUVertFormat *format; /* Identifier. */ + GPUBatch *instance; /* Identifier. */ + GPUVertBuf *vert; /* GPUVertBuf contained in the GPUBatch. */ + GPUBatch *batch; /* GPUBatch containing the GPUVertBuf. */ } DRWInstancingBuffer; typedef struct DRWInstanceChunk { @@ -100,7 +100,7 @@ static ListBase g_idatalists = {NULL, NULL}; * that would be too slow]). **/ -static void instance_batch_free(Gwn_Batch *batch, void *UNUSED(user_data)) +static void instance_batch_free(GPUBatch *batch, void *UNUSED(user_data)) { /* Free all batches that have the same key before they are reused. */ /* TODO: Make it thread safe! Batch freeing can happen from another thread. */ @@ -111,8 +111,8 @@ static void instance_batch_free(Gwn_Batch *batch, void *UNUSED(user_data)) for (int i = 0; i < idatalist->instancing.alloc_size; i++, ibuf++) { if (ibuf->instance == batch) { BLI_assert(ibuf->shgroup == NULL); /* Make sure it has no other users. */ - GWN_VERTBUF_DISCARD_SAFE(ibuf->vert); - GWN_BATCH_DISCARD_SAFE(ibuf->batch); + GPU_VERTBUF_DISCARD_SAFE(ibuf->vert); + GPU_BATCH_DISCARD_SAFE(ibuf->batch); /* Tag as non alloced. */ ibuf->format = NULL; } @@ -121,8 +121,8 @@ static void instance_batch_free(Gwn_Batch *batch, void *UNUSED(user_data)) } void DRW_batching_buffer_request( - DRWInstanceDataList *idatalist, Gwn_VertFormat *format, Gwn_PrimType type, struct DRWShadingGroup *shgroup, - Gwn_Batch **r_batch, Gwn_VertBuf **r_vert) + DRWInstanceDataList *idatalist, GPUVertFormat *format, GPUPrimType type, struct DRWShadingGroup *shgroup, + GPUBatch **r_batch, GPUVertBuf **r_vert) { DRWInstanceChunk *chunk = &idatalist->batching; DRWBatchingBuffer *bbuf = idatalist->batching.bbufs; @@ -152,16 +152,16 @@ void DRW_batching_buffer_request( } /* Create the batch. */ bbuf = chunk->bbufs + new_id; - bbuf->vert = *r_vert = GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_DYNAMIC); - bbuf->batch = *r_batch = GWN_batch_create_ex(type, bbuf->vert, NULL, 0); + bbuf->vert = *r_vert = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_DYNAMIC); + bbuf->batch = *r_batch = GPU_batch_create_ex(type, bbuf->vert, NULL, 0); bbuf->format = format; bbuf->shgroup = shgroup; - GWN_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK); + GPU_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK); } void DRW_instancing_buffer_request( - DRWInstanceDataList *idatalist, Gwn_VertFormat *format, Gwn_Batch *instance, struct DRWShadingGroup *shgroup, - Gwn_Batch **r_batch, Gwn_VertBuf **r_vert) + DRWInstanceDataList *idatalist, GPUVertFormat *format, GPUBatch *instance, struct DRWShadingGroup *shgroup, + GPUBatch **r_batch, GPUVertBuf **r_vert) { DRWInstanceChunk *chunk = &idatalist->instancing; DRWInstancingBuffer *ibuf = idatalist->instancing.ibufs; @@ -193,15 +193,15 @@ void DRW_instancing_buffer_request( } /* Create the batch. */ ibuf = chunk->ibufs + new_id; - ibuf->vert = *r_vert = GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_DYNAMIC); - ibuf->batch = *r_batch = GWN_batch_duplicate(instance); + ibuf->vert = *r_vert = GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_DYNAMIC); + ibuf->batch = *r_batch = GPU_batch_duplicate(instance); ibuf->format = format; ibuf->shgroup = shgroup; ibuf->instance = instance; - GWN_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK); - GWN_batch_instbuf_set(ibuf->batch, ibuf->vert, false); + GPU_vertbuf_data_alloc(*r_vert, BUFFER_VERTS_CHUNK); + GPU_batch_instbuf_set(ibuf->batch, ibuf->vert, false); /* Make sure to free this ibuf if the instance batch gets free. */ - GWN_batch_callback_free_set(instance, &instance_batch_free, NULL); + GPU_batch_callback_free_set(instance, &instance_batch_free, NULL); } void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) @@ -218,14 +218,14 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) if (vert_len + BUFFER_VERTS_CHUNK <= bbuf->vert->vertex_len) { uint size = vert_len + BUFFER_VERTS_CHUNK - 1; size = size - size % BUFFER_VERTS_CHUNK; - GWN_vertbuf_data_resize(bbuf->vert, size); + GPU_vertbuf_data_resize(bbuf->vert, size); } - GWN_vertbuf_use(bbuf->vert); /* Send data. */ + GPU_vertbuf_use(bbuf->vert); /* Send data. */ bbuf->shgroup = NULL; /* Set as non used for the next round. */ } else { - GWN_VERTBUF_DISCARD_SAFE(bbuf->vert); - GWN_BATCH_DISCARD_SAFE(bbuf->batch); + GPU_VERTBUF_DISCARD_SAFE(bbuf->vert); + GPU_BATCH_DISCARD_SAFE(bbuf->batch); bbuf->format = NULL; /* Tag as non alloced. */ } } @@ -250,14 +250,14 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist) if (vert_len + BUFFER_VERTS_CHUNK <= ibuf->vert->vertex_len) { uint size = vert_len + BUFFER_VERTS_CHUNK - 1; size = size - size % BUFFER_VERTS_CHUNK; - GWN_vertbuf_data_resize(ibuf->vert, size); + GPU_vertbuf_data_resize(ibuf->vert, size); } - GWN_vertbuf_use(ibuf->vert); /* Send data. */ + GPU_vertbuf_use(ibuf->vert); /* Send data. */ ibuf->shgroup = NULL; /* Set as non used for the next round. */ } else { - GWN_VERTBUF_DISCARD_SAFE(ibuf->vert); - GWN_BATCH_DISCARD_SAFE(ibuf->batch); + GPU_VERTBUF_DISCARD_SAFE(ibuf->vert); + GPU_BATCH_DISCARD_SAFE(ibuf->batch); ibuf->format = NULL; /* Tag as non alloced. */ } } @@ -366,15 +366,15 @@ void DRW_instance_data_list_free(DRWInstanceDataList *idatalist) DRWBatchingBuffer *bbuf = idatalist->batching.bbufs; for (int i = 0; i < idatalist->batching.alloc_size; i++, bbuf++) { - GWN_VERTBUF_DISCARD_SAFE(bbuf->vert); - GWN_BATCH_DISCARD_SAFE(bbuf->batch); + GPU_VERTBUF_DISCARD_SAFE(bbuf->vert); + GPU_BATCH_DISCARD_SAFE(bbuf->batch); } MEM_freeN(idatalist->batching.bbufs); DRWInstancingBuffer *ibuf = idatalist->instancing.ibufs; for (int i = 0; i < idatalist->instancing.alloc_size; i++, ibuf++) { - GWN_VERTBUF_DISCARD_SAFE(ibuf->vert); - GWN_BATCH_DISCARD_SAFE(ibuf->batch); + GPU_VERTBUF_DISCARD_SAFE(ibuf->vert); + GPU_BATCH_DISCARD_SAFE(ibuf->batch); } MEM_freeN(idatalist->instancing.ibufs); diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h index 0ea40a50a6b..174f03e3bc7 100644 --- a/source/blender/draw/intern/draw_instance_data.h +++ b/source/blender/draw/intern/draw_instance_data.h @@ -43,11 +43,11 @@ DRWInstanceData *DRW_instance_data_request( DRWInstanceDataList *idatalist, uint attrib_size); void DRW_batching_buffer_request( - DRWInstanceDataList *idatalist, Gwn_VertFormat *format, Gwn_PrimType type, struct DRWShadingGroup *shgroup, - Gwn_Batch **r_batch, Gwn_VertBuf **r_vert); + DRWInstanceDataList *idatalist, GPUVertFormat *format, GPUPrimType type, struct DRWShadingGroup *shgroup, + GPUBatch **r_batch, GPUVertBuf **r_vert); void DRW_instancing_buffer_request( - DRWInstanceDataList *idatalist, Gwn_VertFormat *format, Gwn_Batch *instance, struct DRWShadingGroup *shgroup, - Gwn_Batch **r_batch, Gwn_VertBuf **r_vert); + DRWInstanceDataList *idatalist, GPUVertFormat *format, GPUBatch *instance, struct DRWShadingGroup *shgroup, + GPUBatch **r_batch, GPUVertBuf **r_vert); /* Upload all instance data to the GPU as soon as possible. */ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 4c6f8962d82..92603a0ce53 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -228,9 +228,9 @@ void DRW_transform_to_display(GPUTexture *tex) { drw_state_set(DRW_STATE_WRITE_COLOR); - Gwn_VertFormat *vert_format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint texco = GWN_vertformat_attr_add(vert_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *vert_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); const float dither = 1.0f; @@ -262,7 +262,7 @@ void DRW_transform_to_display(GPUTexture *tex) immUniformMatrix4fv("ModelViewProjectionMatrix", mat); /* Full screen triangle */ - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immAttrib2f(texco, 0.0f, 0.0f); immVertex2f(pos, -1.0f, -1.0f); @@ -287,21 +287,21 @@ void DRW_transform_to_display(GPUTexture *tex) void DRW_transform_none(GPUTexture *tex) { /* Draw as texture for final render (without immediate mode). */ - Gwn_Batch *geom = DRW_cache_fullscreen_quad_texcoord_get(); - GWN_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); + GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); GPU_texture_bind(tex, 0); const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - GWN_batch_uniform_4fv(geom, "color", white); + GPU_batch_uniform_4fv(geom, "color", white); float mat[4][4]; unit_m4(mat); - GWN_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); + GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); - GWN_batch_program_use_begin(geom); - GWN_batch_draw_range_ex(geom, 0, 0, false); - GWN_batch_program_use_end(geom); + GPU_batch_program_use_begin(geom); + GPU_batch_draw_range_ex(geom, 0, 0, false); + GPU_batch_program_use_end(geom); GPU_texture_unbind(tex); } @@ -327,7 +327,7 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color) BLI_assert(samples > 0); BLI_assert(GPU_texture_samples(src_color) == samples); - Gwn_Batch *geom = DRW_cache_fullscreen_quad_get(); + GPUBatch *geom = DRW_cache_fullscreen_quad_get(); int builtin; switch (samples) { @@ -341,21 +341,21 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color) break; } - GWN_batch_program_set_builtin(geom, builtin); + GPU_batch_program_set_builtin(geom, builtin); GPU_texture_bind(src_depth, 0); GPU_texture_bind(src_color, 1); - GWN_batch_uniform_1i(geom, "depthMulti", 0); - GWN_batch_uniform_1i(geom, "colorMulti", 1); + GPU_batch_uniform_1i(geom, "depthMulti", 0); + GPU_batch_uniform_1i(geom, "colorMulti", 1); float mat[4][4]; unit_m4(mat); - GWN_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); + GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); /* avoid gpuMatrix calls */ - GWN_batch_program_use_begin(geom); - GWN_batch_draw_range_ex(geom, 0, 0, false); - GWN_batch_program_use_end(geom); + GPU_batch_program_use_begin(geom); + GPU_batch_draw_range_ex(geom, 0, 0, false); + GPU_batch_program_use_end(geom); } /** \} */ @@ -1573,14 +1573,14 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) } void *re_gl_context = RE_gl_context_get(render); - void *re_gwn_context = NULL; + void *re_gpu_context = NULL; /* Changing Context */ if (re_gl_context != NULL) { DRW_opengl_render_context_enable(re_gl_context); - /* We need to query gwn context after a gl context has been bound. */ - re_gwn_context = RE_gwn_context_get(render); - DRW_gawain_render_context_enable(re_gwn_context); + /* We need to query gpu context after a gl context has been bound. */ + re_gpu_context = RE_gpu_context_get(render); + DRW_gawain_render_context_enable(re_gpu_context); } else { DRW_opengl_context_enable(); @@ -1659,7 +1659,7 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) /* Changing Context */ if (re_gl_context != NULL) { - DRW_gawain_render_context_disable(re_gwn_context); + DRW_gawain_render_context_disable(re_gpu_context); DRW_opengl_render_context_disable(re_gl_context); } else { @@ -1967,9 +1967,9 @@ static void draw_depth_texture_to_screen(GPUTexture *texture) const float w = (float)GPU_texture_width(texture); const float h = (float)GPU_texture_height(texture); - Gwn_VertFormat *format = immVertexFormat(); - uint texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY); @@ -1977,7 +1977,7 @@ static void draw_depth_texture_to_screen(GPUTexture *texture) immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ - immBegin(GWN_PRIM_TRI_STRIP, 4); + immBegin(GPU_PRIM_TRI_STRIP, 4); immAttrib2f(texcoord, 0.0f, 0.0f); immVertex2f(pos, 0.0f, 0.0f); @@ -2298,7 +2298,7 @@ void DRW_engines_register(void) } } -extern struct Gwn_VertFormat *g_pos_format; /* draw_shgroup.c */ +extern struct GPUVertFormat *g_pos_format; /* draw_shgroup.c */ extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ extern struct GPUTexture *globals_ramp; /* draw_common.c */ void DRW_engines_free(void) @@ -2352,7 +2352,7 @@ void DRW_opengl_context_create(void) /* This changes the active context. */ DST.gl_context = WM_opengl_context_create(); /* Be sure to create gawain.context too. */ - DST.gwn_context = GWN_context_create(); + DST.gpu_context = GPU_context_create(); if (!G.background) { immActivate(); } @@ -2367,8 +2367,8 @@ void DRW_opengl_context_destroy(void) BLI_assert(BLI_thread_is_main()); if (DST.gl_context != NULL) { WM_opengl_context_activate(DST.gl_context); - GWN_context_active_set(DST.gwn_context); - GWN_context_discard(DST.gwn_context); + GPU_context_active_set(DST.gpu_context); + GPU_context_discard(DST.gpu_context); WM_opengl_context_dispose(DST.gl_context); BLI_ticket_mutex_free(DST.gl_context_mutex); } @@ -2387,7 +2387,7 @@ void DRW_opengl_context_enable(void) } } WM_opengl_context_activate(DST.gl_context); - GWN_context_active_set(DST.gwn_context); + GPU_context_active_set(DST.gpu_context); if (BLI_thread_is_main()) { if (!G.background) { immActivate(); @@ -2411,7 +2411,7 @@ void DRW_opengl_context_disable(void) } else { WM_opengl_context_release(DST.gl_context); - GWN_context_active_set(NULL); + GPU_context_active_set(NULL); } BLI_ticket_mutex_unlock(DST.gl_context_mutex); @@ -2437,20 +2437,20 @@ void DRW_opengl_render_context_disable(void *re_gl_context) } /* Needs to be called AFTER DRW_opengl_render_context_enable() */ -void DRW_gawain_render_context_enable(void *re_gwn_context) +void DRW_gawain_render_context_enable(void *re_gpu_context) { /* If thread is main you should use DRW_opengl_context_enable(). */ BLI_assert(!BLI_thread_is_main()); - GWN_context_active_set(re_gwn_context); + GPU_context_active_set(re_gpu_context); DRW_shape_cache_reset(); /* XXX fix that too. */ } /* Needs to be called BEFORE DRW_opengl_render_context_disable() */ -void DRW_gawain_render_context_disable(void *UNUSED(re_gwn_context)) +void DRW_gawain_render_context_disable(void *UNUSED(re_gpu_context)) { DRW_shape_cache_reset(); /* XXX fix that too. */ - GWN_context_active_set(NULL); + GPU_context_active_set(NULL); } /** \} */ diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 2d44fb5b6d8..9b01f17649c 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -130,7 +130,7 @@ typedef enum { DRW_CALL_RANGE, /* Like single but only draw a range of vertices/indices. */ DRW_CALL_INSTANCES, /* Draw instances without any instancing attribs. */ DRW_CALL_GENERATE, /* Uses a callback to draw with any number of batches. */ - DRW_CALL_PROCEDURAL, /* Generate a drawcall without any Gwn_Batch. */ + DRW_CALL_PROCEDURAL, /* Generate a drawcall without any GPUBatch. */ } DRWCallType; typedef struct DRWCall { @@ -139,14 +139,14 @@ typedef struct DRWCall { union { struct { /* type == DRW_CALL_SINGLE */ - Gwn_Batch *geometry; + GPUBatch *geometry; } single; struct { /* type == DRW_CALL_RANGE */ - Gwn_Batch *geometry; + GPUBatch *geometry; uint start, count; } range; struct { /* type == DRW_CALL_INSTANCES */ - Gwn_Batch *geometry; + GPUBatch *geometry; /* Count can be adjusted between redraw. If needed, we can add fixed count. */ uint *count; } instances; @@ -156,7 +156,7 @@ typedef struct DRWCall { } generate; struct { /* type == DRW_CALL_PROCEDURAL */ uint vert_count; - Gwn_PrimType prim_type; + GPUPrimType prim_type; } procedural; }; @@ -226,16 +226,16 @@ struct DRWShadingGroup { } calls; struct { /* DRW_SHG_FEEDBACK_TRANSFORM */ DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */ - struct Gwn_VertBuf *tfeedback_target; /* Transform Feedback target. */ + struct GPUVertBuf *tfeedback_target; /* Transform Feedback target. */ }; struct { /* DRW_SHG_***_BATCH */ - struct Gwn_Batch *batch_geom; /* Result of call batching */ - struct Gwn_VertBuf *batch_vbo; + struct GPUBatch *batch_geom; /* Result of call batching */ + struct GPUVertBuf *batch_vbo; uint primitive_count; }; struct { /* DRW_SHG_INSTANCE[_EXTERNAL] */ - struct Gwn_Batch *instance_geom; - struct Gwn_VertBuf *instance_vbo; + struct GPUBatch *instance_geom; + struct GPUVertBuf *instance_vbo; uint instance_count; float instance_orcofac[2][3]; /* TODO find a better place. */ }; @@ -264,7 +264,7 @@ struct DRWShadingGroup { #endif #ifdef USE_GPU_SELECT - Gwn_VertBuf *inst_selectid; + GPUVertBuf *inst_selectid; DRWPass *pass_parent; /* backlink to pass we're in */ int override_selectid; /* Override for single object instances. */ #endif @@ -379,7 +379,7 @@ typedef struct DRWManager { /* gl_context serves as the offset for clearing only * the top portion of the struct so DO NOT MOVE IT! */ void *gl_context; /* Unique ghost context used by the draw manager. */ - Gwn_Context *gwn_context; + GPUContext *gpu_context; TicketMutex *gl_context_mutex; /* Mutex to lock the drw manager and avoid concurent context usage. */ /** GPU Resource State: Memory storage between drawing. */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index c259633982e..dccb869c133 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -41,7 +41,7 @@ #include "intern/gpu_codegen.h" -struct Gwn_VertFormat *g_pos_format = NULL; +struct GPUVertFormat *g_pos_format = NULL; extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */ @@ -355,7 +355,7 @@ static DRWCallState *drw_call_state_object(DRWShadingGroup *shgroup, float (*obm return DST.ob_state; } -void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4]) +void DRW_shgroup_call_add(DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4]) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -371,7 +371,7 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obm BLI_LINKS_APPEND(&shgroup->calls, call); } -void DRW_shgroup_call_range_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], uint v_sta, uint v_count) +void DRW_shgroup_call_range_add(DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4], uint v_sta, uint v_count) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -391,7 +391,7 @@ void DRW_shgroup_call_range_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float } static void drw_shgroup_call_procedural_add_ex( - DRWShadingGroup *shgroup, Gwn_PrimType prim_type, uint vert_count, float (*obmat)[4], Object *ob) + DRWShadingGroup *shgroup, GPUPrimType prim_type, uint vert_count, float (*obmat)[4], Object *ob) { BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -414,28 +414,28 @@ static void drw_shgroup_call_procedural_add_ex( void DRW_shgroup_call_procedural_points_add(DRWShadingGroup *shgroup, uint point_len, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_POINTS, point_len, obmat, NULL); + drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_POINTS, point_len, obmat, NULL); } void DRW_shgroup_call_procedural_lines_add(DRWShadingGroup *shgroup, uint line_count, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_LINES, line_count * 2, obmat, NULL); + drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_LINES, line_count * 2, obmat, NULL); } void DRW_shgroup_call_procedural_triangles_add(DRWShadingGroup *shgroup, uint tria_count, float (*obmat)[4]) { - drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, obmat, NULL); + drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_TRIS, tria_count * 3, obmat, NULL); } /* TODO (fclem): this is a sign that the api is starting to be limiting. * Maybe add special function that general purpose for special cases. */ void DRW_shgroup_call_object_procedural_triangles_culled_add(DRWShadingGroup *shgroup, uint tria_count, Object *ob) { - drw_shgroup_call_procedural_add_ex(shgroup, GWN_PRIM_TRIS, tria_count * 3, NULL, ob); + drw_shgroup_call_procedural_add_ex(shgroup, GPU_PRIM_TRIS, tria_count * 3, NULL, ob); } /* These calls can be culled and are optimized for redraw */ -void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, bool bypass_culling) +void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, bool bypass_culling) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -455,7 +455,7 @@ void DRW_shgroup_call_object_add_ex(DRWShadingGroup *shgroup, Gwn_Batch *geom, O } void DRW_shgroup_call_object_add_with_callback( - DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, + DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, DRWCallVisibilityFn *callback, void *user_data) { BLI_assert(geom != NULL); @@ -474,7 +474,7 @@ void DRW_shgroup_call_object_add_with_callback( BLI_LINKS_APPEND(&shgroup->calls, call); } -void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], uint *count) +void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, GPUBatch *geom, float (*obmat)[4], uint *count) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -492,7 +492,7 @@ void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, f } /* These calls can be culled and are optimized for redraw */ -void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob, uint *count) +void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup, GPUBatch *geom, Object *ob, uint *count) { BLI_assert(geom != NULL); BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)); @@ -531,7 +531,7 @@ void DRW_shgroup_call_generate_add( static void sculpt_draw_cb( DRWShadingGroup *shgroup, - void (*draw_fn)(DRWShadingGroup *shgroup, Gwn_Batch *geom), + void (*draw_fn)(DRWShadingGroup *shgroup, GPUBatch *geom), void *user_data) { Object *ob = user_data; @@ -540,7 +540,7 @@ static void sculpt_draw_cb( if (pbvh) { BKE_pbvh_draw_cb( pbvh, NULL, NULL, false, - (void (*)(void *, Gwn_Batch *))draw_fn, shgroup); + (void (*)(void *, GPUBatch *))draw_fn, shgroup); } } @@ -554,9 +554,9 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at #ifdef USE_GPU_SELECT if (G.f & G_PICKSEL) { if (shgroup->instance_count == shgroup->inst_selectid->vertex_len) { - GWN_vertbuf_data_resize(shgroup->inst_selectid, shgroup->instance_count + 32); + GPU_vertbuf_data_resize(shgroup->inst_selectid, shgroup->instance_count + 32); } - GWN_vertbuf_attr_set(shgroup->inst_selectid, 0, shgroup->instance_count, &DST.select_id); + GPU_vertbuf_attr_set(shgroup->inst_selectid, 0, shgroup->instance_count, &DST.select_id); } #endif @@ -565,9 +565,9 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at for (int i = 0; i < attr_len; ++i) { if (shgroup->instance_count == shgroup->instance_vbo->vertex_len) { - GWN_vertbuf_data_resize(shgroup->instance_vbo, shgroup->instance_count + 32); + GPU_vertbuf_data_resize(shgroup->instance_vbo, shgroup->instance_count + 32); } - GWN_vertbuf_attr_set(shgroup->instance_vbo, i, shgroup->instance_count, attr[i]); + GPU_vertbuf_attr_set(shgroup->instance_vbo, i, shgroup->instance_count, attr[i]); } shgroup->instance_count += 1; @@ -601,25 +601,25 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) } else { /* Only here to support builtin shaders. This should not be used by engines. */ - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_VIEW, DST.view_data.matstate.mat[DRW_MAT_VIEW], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_VIEW_INV, DST.view_data.matstate.mat[DRW_MAT_VIEWINV], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION, DST.view_data.matstate.mat[DRW_MAT_PERS], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_VIEWPROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_PERSINV], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION, DST.view_data.matstate.mat[DRW_MAT_WIN], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_PROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_WININV], 16, 1); - drw_shgroup_builtin_uniform(shgroup, GWN_UNIFORM_CAMERATEXCO, DST.view_data.viewcamtexcofac, 3, 2); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_VIEW, DST.view_data.matstate.mat[DRW_MAT_VIEW], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_VIEW_INV, DST.view_data.matstate.mat[DRW_MAT_VIEWINV], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_VIEWPROJECTION, DST.view_data.matstate.mat[DRW_MAT_PERS], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_VIEWPROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_PERSINV], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_PROJECTION, DST.view_data.matstate.mat[DRW_MAT_WIN], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_PROJECTION_INV, DST.view_data.matstate.mat[DRW_MAT_WININV], 16, 1); + drw_shgroup_builtin_uniform(shgroup, GPU_UNIFORM_CAMERATEXCO, DST.view_data.viewcamtexcofac, 3, 2); } - shgroup->model = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL); - shgroup->modelinverse = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODEL_INV); - shgroup->modelview = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODELVIEW); - shgroup->modelviewinverse = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MODELVIEW_INV); - shgroup->modelviewprojection = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_MVP); - shgroup->normalview = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_NORMAL); - shgroup->normalworld = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_WORLDNORMAL); - shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_ORCO); - shgroup->eye = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_EYE); - shgroup->callid = GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_CALLID); + shgroup->model = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL); + shgroup->modelinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODEL_INV); + shgroup->modelview = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW); + shgroup->modelviewinverse = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV); + shgroup->modelviewprojection = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MVP); + shgroup->normalview = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_NORMAL); + shgroup->normalworld = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_WORLDNORMAL); + shgroup->orcotexfac = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_ORCO); + shgroup->eye = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_EYE); + shgroup->callid = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_CALLID); shgroup->matflag = 0; if (shgroup->modelinverse > -1) @@ -641,7 +641,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) } static void drw_shgroup_instance_init( - DRWShadingGroup *shgroup, GPUShader *shader, Gwn_Batch *batch, Gwn_VertFormat *format) + DRWShadingGroup *shgroup, GPUShader *shader, GPUBatch *batch, GPUVertFormat *format) { BLI_assert(shgroup->type == DRW_SHG_INSTANCE); BLI_assert(batch != NULL); @@ -661,20 +661,20 @@ static void drw_shgroup_instance_init( if (G.f & G_PICKSEL) { /* Not actually used for rendering but alloced in one chunk. * Plus we don't have to care about ownership. */ - static Gwn_VertFormat inst_select_format = {0}; + static GPUVertFormat inst_select_format = {0}; if (inst_select_format.attr_len == 0) { - GWN_vertformat_attr_add(&inst_select_format, "selectId", GWN_COMP_I32, 1, GWN_FETCH_INT); + GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT); } - Gwn_Batch *batch_dummy; /* Not used */ + GPUBatch *batch_dummy; /* Not used */ DRW_batching_buffer_request(DST.idatalist, &inst_select_format, - GWN_PRIM_POINTS, shgroup, + GPU_PRIM_POINTS, shgroup, &batch_dummy, &shgroup->inst_selectid); } #endif } static void drw_shgroup_batching_init( - DRWShadingGroup *shgroup, GPUShader *shader, Gwn_VertFormat *format) + DRWShadingGroup *shgroup, GPUShader *shader, GPUVertFormat *format) { drw_shgroup_init(shgroup, shader); @@ -683,12 +683,12 @@ static void drw_shgroup_batching_init( #endif BLI_assert(format != NULL); - Gwn_PrimType type; + GPUPrimType type; switch (shgroup->type) { - case DRW_SHG_POINT_BATCH: type = GWN_PRIM_POINTS; break; - case DRW_SHG_LINE_BATCH: type = GWN_PRIM_LINES; break; - case DRW_SHG_TRIANGLE_BATCH: type = GWN_PRIM_TRIS; break; - default: type = GWN_PRIM_NONE; BLI_assert(0); break; + case DRW_SHG_POINT_BATCH: type = GPU_PRIM_POINTS; break; + case DRW_SHG_LINE_BATCH: type = GPU_PRIM_LINES; break; + case DRW_SHG_TRIANGLE_BATCH: type = GPU_PRIM_TRIS; break; + default: type = GPU_PRIM_NONE; BLI_assert(0); break; } DRW_batching_buffer_request(DST.idatalist, format, type, shgroup, @@ -697,13 +697,13 @@ static void drw_shgroup_batching_init( #ifdef USE_GPU_SELECT if (G.f & G_PICKSEL) { /* Not actually used for rendering but alloced in one chunk. */ - static Gwn_VertFormat inst_select_format = {0}; + static GPUVertFormat inst_select_format = {0}; if (inst_select_format.attr_len == 0) { - GWN_vertformat_attr_add(&inst_select_format, "selectId", GWN_COMP_I32, 1, GWN_FETCH_INT); + GPU_vertformat_attr_add(&inst_select_format, "selectId", GPU_COMP_I32, 1, GPU_FETCH_INT); } - Gwn_Batch *batch; /* Not used */ + GPUBatch *batch; /* Not used */ DRW_batching_buffer_request(DST.idatalist, &inst_select_format, - GWN_PRIM_POINTS, shgroup, + GPU_PRIM_POINTS, shgroup, &batch, &shgroup->inst_selectid); } #endif @@ -807,15 +807,15 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp, struct return grp; } -Gwn_VertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize) +GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttribFormat attribs[], int arraysize) { - Gwn_VertFormat *format = MEM_callocN(sizeof(Gwn_VertFormat), "Gwn_VertFormat"); + GPUVertFormat *format = MEM_callocN(sizeof(GPUVertFormat), "GPUVertFormat"); for (int i = 0; i < arraysize; ++i) { - GWN_vertformat_attr_add(format, attribs[i].name, - (attribs[i].type == DRW_ATTRIB_INT) ? GWN_COMP_I32 : GWN_COMP_F32, + GPU_vertformat_attr_add(format, attribs[i].name, + (attribs[i].type == DRW_ATTRIB_INT) ? GPU_COMP_I32 : GPU_COMP_F32, attribs[i].components, - (attribs[i].type == DRW_ATTRIB_INT) ? GWN_FETCH_INT : GWN_FETCH_FLOAT); + (attribs[i].type == DRW_ATTRIB_INT) ? GPU_FETCH_INT : GPU_FETCH_FLOAT); } return format; } @@ -835,7 +835,7 @@ DRWShadingGroup *DRW_shgroup_material_create( } DRWShadingGroup *DRW_shgroup_material_instance_create( - struct GPUMaterial *material, DRWPass *pass, Gwn_Batch *geom, Object *ob, Gwn_VertFormat *format) + struct GPUMaterial *material, DRWPass *pass, GPUBatch *geom, Object *ob, GPUVertFormat *format) { GPUPass *gpupass = GPU_material_get_pass(material); DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass); @@ -861,7 +861,7 @@ DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create( DRWShadingGroup *shgroup = drw_shgroup_material_create_ex(gpupass, pass); if (shgroup) { - /* Calling drw_shgroup_init will cause it to call GWN_draw_primitive(). */ + /* Calling drw_shgroup_init will cause it to call GPU_draw_primitive(). */ drw_shgroup_init(shgroup, GPU_pass_shader_get(gpupass)); shgroup->type = DRW_SHG_TRIANGLE_BATCH; shgroup->instance_count = tri_count * 3; @@ -879,7 +879,7 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) } DRWShadingGroup *DRW_shgroup_instance_create( - struct GPUShader *shader, DRWPass *pass, Gwn_Batch *geom, Gwn_VertFormat *format) + struct GPUShader *shader, DRWPass *pass, GPUBatch *geom, GPUVertFormat *format) { DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_INSTANCE; @@ -903,7 +903,7 @@ DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPas } DRWShadingGroup *DRW_shgroup_line_batch_create_with_format( - struct GPUShader *shader, DRWPass *pass, Gwn_VertFormat *format) + struct GPUShader *shader, DRWPass *pass, GPUVertFormat *format) { DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); shgroup->type = DRW_SHG_LINE_BATCH; @@ -930,7 +930,7 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR #endif DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); - /* Calling drw_shgroup_init will cause it to call GWN_draw_primitive(). */ + /* Calling drw_shgroup_init will cause it to call GPU_draw_primitive(). */ drw_shgroup_init(shgroup, shader); shgroup->type = DRW_SHG_TRIANGLE_BATCH; @@ -939,7 +939,7 @@ DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DR return shgroup; } -DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, Gwn_VertBuf *tf_target) +DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, GPUVertBuf *tf_target) { BLI_assert(tf_target != NULL); DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass); @@ -953,7 +953,7 @@ DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, } /* Specify an external batch instead of adding each attrib one by one. */ -void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batch) +void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct GPUBatch *batch) { BLI_assert(shgroup->type == DRW_SHG_INSTANCE); BLI_assert(shgroup->instance_count == 0); @@ -966,7 +966,7 @@ void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batc /* Note: This WILL break if batch->verts[0] is destroyed and reallocated * at the same adress. Bindings/VAOs would remain obsolete. */ //if (shgroup->instancing_geom->inst != batch->verts[0]) - GWN_batch_instbuf_set(shgroup->instance_geom, batch->verts[0], false); + GPU_batch_instbuf_set(shgroup->instance_geom, batch->verts[0], false); #ifdef USE_GPU_SELECT shgroup->override_selectid = DST.select_id; diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 5957643d090..1134f421c16 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -827,29 +827,29 @@ static void draw_geometry_prepare(DRWShadingGroup *shgroup, DRWCallState *state) } static void draw_geometry_execute_ex( - DRWShadingGroup *shgroup, Gwn_Batch *geom, uint start, uint count, bool draw_instance) + DRWShadingGroup *shgroup, GPUBatch *geom, uint start, uint count, bool draw_instance) { /* Special case: empty drawcall, placement is done via shader, don't bind anything. */ /* TODO use DRW_CALL_PROCEDURAL instead */ if (geom == NULL) { BLI_assert(shgroup->type == DRW_SHG_TRIANGLE_BATCH); /* Add other type if needed. */ /* Shader is already bound. */ - GWN_draw_primitive(GWN_PRIM_TRIS, count); + GPU_draw_primitive(GPU_PRIM_TRIS, count); return; } /* step 2 : bind vertex array & draw */ - GWN_batch_program_set_no_use( + GPU_batch_program_set_no_use( geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader)); /* XXX hacking gawain. we don't want to call glUseProgram! (huge performance loss) */ geom->program_in_use = true; - GWN_batch_draw_range_ex(geom, start, count, draw_instance); + GPU_batch_draw_range_ex(geom, start, count, draw_instance); geom->program_in_use = false; /* XXX hacking gawain */ } -static void draw_geometry_execute(DRWShadingGroup *shgroup, Gwn_Batch *geom) +static void draw_geometry_execute(DRWShadingGroup *shgroup, GPUBatch *geom) { draw_geometry_execute_ex(shgroup, geom, 0, 0, false); } @@ -1055,9 +1055,9 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) if (G.f & G_PICKSEL) { \ if (_shgroup->override_selectid == -1) { \ /* Hack : get vbo data without actually drawing. */ \ - Gwn_VertBufRaw raw; \ - GWN_vertbuf_attr_get_raw_data(_shgroup->inst_selectid, 0, &raw); \ - select_id = GWN_vertbuf_raw_step(&raw); \ + GPUVertBufRaw raw; \ + GPU_vertbuf_attr_get_raw_data(_shgroup->inst_selectid, 0, &raw); \ + select_id = GPU_vertbuf_raw_step(&raw); \ switch (_shgroup->type) { \ case DRW_SHG_TRIANGLE_BATCH: _count = 3; break; \ case DRW_SHG_LINE_BATCH: _count = 2; break; \ @@ -1168,7 +1168,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) call->generate.geometry_fn(shgroup, draw_geometry_execute, call->generate.user_data); break; case DRW_CALL_PROCEDURAL: - GWN_draw_primitive(call->procedural.prim_type, call->procedural.vert_count); + GPU_draw_primitive(call->procedural.prim_type, call->procedural.vert_count); break; default: BLI_assert(0); diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c index e4c0877b907..edeb6c07733 100644 --- a/source/blender/draw/intern/draw_manager_profiling.c +++ b/source/blender/draw/intern/draw_manager_profiling.c @@ -305,7 +305,7 @@ void DRW_stats_draw(rcti *rect) /* Memory Stats */ uint tex_mem = GPU_texture_memory_usage_get(); - uint vbo_mem = GWN_vertbuf_get_memory_usage(); + uint vbo_mem = GPU_vertbuf_get_memory_usage(); sprintf(stat_string, "GPU Memory"); draw_stat(rect, 0, v, stat_string, sizeof(stat_string)); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 688712a97b6..05aecea1d7a 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -214,9 +214,9 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** glDepthMask(GL_FALSE); /* disable write in zbuffer */ #endif - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); @@ -253,7 +253,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** if (gridline_len == 0) goto drawgrid_cleanup; /* nothing to draw */ - immBegin(GWN_PRIM_LINES, gridline_len * 2); + immBegin(GPU_PRIM_LINES, gridline_len * 2); } float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar); @@ -306,7 +306,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** if (gridline_len == 0) goto drawgrid_cleanup; /* nothing to draw */ - immBegin(GWN_PRIM_LINES, gridline_len * 2); + immBegin(GPU_PRIM_LINES, gridline_len * 2); if (grids_to_draw == 2) { UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2); @@ -381,13 +381,13 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) uchar col_bg[3], col_grid_emphasise[3], col_grid_light[3]; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, vertex_len); + immBegin(GPU_PRIM_LINES, vertex_len); /* draw normal grid lines */ UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10); @@ -469,12 +469,12 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) 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(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_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); + immBegin(GPU_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'); @@ -582,9 +582,9 @@ void DRW_draw_background(void) /* Gradient background Color */ glDisable(GL_DEPTH_TEST); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); uchar col_hi[3], col_lo[3]; GPU_matrix_push(); @@ -596,7 +596,7 @@ void DRW_draw_background(void) UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo); UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi); - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib3ubv(color, col_lo); immVertex2f(pos, -1.0f, -1.0f); immVertex2f(pos, 1.0f, -1.0f); @@ -689,10 +689,10 @@ void DRW_draw_cursor(void) /* Draw lines */ if (is_aligned == false) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor3(TH_VIEW_OVERLAY); - immBegin(GWN_PRIM_LINES, 12); + immBegin(GPU_PRIM_LINES, 12); const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) * U.widget_unit; @@ -727,11 +727,11 @@ void DRW_draw_cursor(void) GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f); GPU_matrix_scale_2f(U.widget_unit, U.widget_unit); - Gwn_Batch *cursor_batch = DRW_cache_cursor_get(is_aligned); + GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned); GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR); - GWN_batch_program_set(cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); + GPU_batch_program_set(cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader)); - GWN_batch_draw(cursor_batch); + GPU_batch_draw(cursor_batch); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 50ce29b7b1a..c8b8f678ca6 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -244,7 +244,7 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) { Curve *cu = ob->data; /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; geom = DRW_cache_curve_edge_wire_get(ob); DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index 870dd14d677..ca7903c555b 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -196,7 +196,7 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob) if (ob->type == OB_LATTICE) { if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) { /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; geom = DRW_cache_lattice_wire_get(ob, true); DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index b402494dfb5..67a424b8081 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -432,7 +432,7 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo); /* we need a full screen pass to combine the result */ - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); psl->mix_occlude = DRW_pass_create( "Mix Occluded Wires", @@ -450,7 +450,7 @@ static void edit_mesh_add_ob_to_pass( Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp, DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp) { - struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter; + struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter; ToolSettings *tsettings = scene->toolsettings; DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts); @@ -477,7 +477,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); View3D *v3d = draw_ctx->v3d; Scene *scene = draw_ctx->scene; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (ob->type == OB_MESH) { if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) { @@ -512,7 +512,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) } if (vnormals_do || lnormals_do) { - struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts; + struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts; DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts); if (vnormals_do) { diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c index 7074ba3d024..3c5d0dbf5a1 100644 --- a/source/blender/draw/modes/edit_surface_mode.c +++ b/source/blender/draw/modes/edit_surface_mode.c @@ -180,7 +180,7 @@ static void EDIT_SURFACE_cache_populate(void *vedata, Object *ob) if (ob->type == OB_MESH) { /* Get geometry cache */ - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); /* Add geom to a shading group */ DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index 5750dc8a0b9..f21715ef399 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -197,7 +197,7 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob) if (ob == draw_ctx->object_edit) { const Curve *cu = ob->data; /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (cu->flag & CU_FAST) { geom = DRW_cache_text_edge_wire_get(ob); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 386261b64d7..dc499987c8a 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -255,9 +255,9 @@ typedef struct OBJECT_PrivateData { static struct { /* Instance Data format */ - struct Gwn_VertFormat *particle_format; - struct Gwn_VertFormat *empty_image_format; - struct Gwn_VertFormat *empty_image_wire_format; + struct GPUVertFormat *particle_format; + struct GPUVertFormat *empty_image_format; + struct GPUVertFormat *empty_image_wire_format; /* fullscreen shaders */ GPUShader *outline_prepass_sh; @@ -851,7 +851,7 @@ static void DRW_shgroup_empty_image( {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}, }); - struct Gwn_Batch *geom = DRW_cache_image_plane_get(); + struct GPUBatch *geom = DRW_cache_image_plane_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( e_data.object_empty_image_sh, psl->non_meshes, geom, e_data.empty_image_format); DRW_shgroup_uniform_texture(grp, "image", tex); @@ -871,7 +871,7 @@ static void DRW_shgroup_empty_image( {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} }); - struct Gwn_Batch *geom = DRW_cache_image_plane_wire_get(); + struct GPUBatch *geom = DRW_cache_image_plane_wire_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( e_data.object_empty_image_wire_sh, psl->non_meshes, geom, e_data.empty_image_wire_format); DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1); @@ -940,8 +940,8 @@ static void OBJECT_cache_init(void *vedata) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_POINT; DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state); - struct Gwn_Batch *sphere = DRW_cache_sphere_get(); - struct Gwn_Batch *quad = DRW_cache_quad_get(); + struct GPUBatch *sphere = DRW_cache_sphere_get(); + struct GPUBatch *quad = DRW_cache_quad_get(); /* Cubemap */ g_data->lightprobes_cube_select = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_select); @@ -960,7 +960,7 @@ static void OBJECT_cache_init(void *vedata) { DRWState state = DRW_STATE_WRITE_COLOR; - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); /* Don't occlude the "outline" detection pass if in xray mode (too much flickering). */ float alphaOcclu = (xray_enabled) ? 1.0f : 0.35f; /* Reminder : bool uniforms need to be 4 bytes. */ @@ -1000,7 +1000,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND; psl->outlines_resolve = DRW_pass_create("Outlines Resolve Pass", state); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); GPUTexture **outline_tx = (do_outline_expand) ? &e_data.outlines_blur_tx : &e_data.outlines_color_tx; DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_aa_sh, psl->outlines_resolve); @@ -1014,7 +1014,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND; psl->grid = DRW_pass_create("Infinite Grid Pass", state); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); static float mat[4][4]; unit_m4(mat); @@ -1075,7 +1075,7 @@ static void OBJECT_cache_init(void *vedata) { /* Non Meshes Pass (Camera, empties, lamps ...) */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | @@ -1221,7 +1221,7 @@ static void OBJECT_cache_init(void *vedata) /* TODO * for now we create multiple times the same VBO with only lamp center coordinates * but ideally we would only create it once */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* start with buflimit because we don't want stipples */ geom = DRW_cache_single_line_get(); @@ -1273,7 +1273,7 @@ static void OBJECT_cache_init(void *vedata) { /* -------- STIPPLES ------- */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* Relationship Lines */ stl->g_data->relationship_lines = shgroup_dynlines_dashed_uniform_color(psl->non_meshes, ts.colorWire); @@ -2252,7 +2252,7 @@ static void OBJECT_cache_populate_particles(Object *ob, unit_m4(mat); if (draw_as != PART_DRAW_PATH) { - struct Gwn_Batch *geom = DRW_cache_particles_get_dots(ob, psys); + struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys); DRWShadingGroup *shgrp = NULL; static int screen_space[2] = {0, 1}; static float def_prim_col[3] = {0.5f, 0.5f, 0.5f}; @@ -2335,7 +2335,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (do_outlines) { if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) { - struct Gwn_Batch *geom; + struct GPUBatch *geom; const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) && (v3d->shading.type < OB_MATERIAL); if (xray_enabled) { @@ -2363,7 +2363,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (ob != draw_ctx->object_edit) { Mesh *me = ob->data; if (me->totedge == 0) { - struct Gwn_Batch *geom = DRW_cache_mesh_verts_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_verts_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -2374,7 +2374,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } } else { - struct Gwn_Batch *geom = DRW_cache_mesh_loose_edges_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_loose_edges_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -2395,7 +2395,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (hide_object_extra) { break; } - struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false); + struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } @@ -2411,7 +2411,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (hide_object_extra) { break; } - struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob); + struct GPUBatch *geom = DRW_cache_curve_edge_wire_get(ob); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index a67c7ffb131..e3c986bde5a 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -175,7 +175,7 @@ static void overlay_cache_populate(void *vedata, Object *ob) return; if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat); } diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 85cff28b313..8256bb4d0d7 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -293,9 +293,9 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) if (use_surface) { if (me->mloopuv != NULL) { if (use_material_slots) { - struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; + struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; if ((me->totcol == 0) || (geom_array == NULL)) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); ok = true; } @@ -312,7 +312,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) } } else { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); if (geom && stl->g_data->shgroup_image_array[0]) { DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat); ok = true; @@ -321,7 +321,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) } if (!ok) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); } } @@ -329,7 +329,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) /* Face Mask */ const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; if (use_face_sel) { - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* Note: ideally selected faces wouldn't show interior wire. */ const bool use_wire = true; geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel); diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index 9cf6ea52d33..33af72e8616 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -150,7 +150,7 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob) const bool use_wire = (v3d->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0; const bool use_surface = v3d->overlay.vertex_paint_mode_opacity != 0.0f; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (use_surface) { geom = DRW_cache_mesh_surface_vert_colors_get(ob); diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index 14fae743d8c..d4fc73e7f88 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -190,7 +190,7 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob) const bool use_surface = v3d->overlay.weight_paint_mode_opacity != 0.0f; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (use_surface) { geom = DRW_cache_mesh_surface_weights_get(ob); diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index 19c3ddd4b50..f4879483540 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -148,17 +148,17 @@ static void particle_edit_cache_populate(void *vedata, const DRWContextState *draw_ctx = DRW_context_state_get(); ParticleEditSettings *pset = PE_settings(draw_ctx->scene); { - struct Gwn_Batch *strands = + struct GPUBatch *strands = DRW_cache_particles_get_edit_strands(object, psys, edit); DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); } if (pset->selectmode == SCE_SELECT_POINT) { - struct Gwn_Batch *points = + struct GPUBatch *points = DRW_cache_particles_get_edit_inner_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL); } if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) { - struct Gwn_Batch *points = + struct GPUBatch *points = DRW_cache_particles_get_edit_tip_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL); } diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 57efc65542c..040195b889b 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -221,7 +221,7 @@ static void POSE_cache_populate(void *vedata, Object *ob) !DRW_state_is_select() && POSE_is_bone_selection_overlay_active()) { - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { if (POSE_is_driven_by_active_armature(ob)) { DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob); diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c70790e0550..3c10cda6456 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -146,7 +146,7 @@ static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; float color[3]; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* set backdrop drawing color */ acf->get_backdrop_color(ac, ale, color); @@ -235,7 +235,7 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0; float color[3]; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* set backdrop drawing color */ acf->get_backdrop_color(ac, ale, color); @@ -3868,7 +3868,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* for F-Curves, draw color-preview of curve behind checkbox */ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) { FCurve *fcu = (FCurve *)ale->data; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -3924,7 +3924,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float /* draw red underline if channel is disabled */ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -3933,7 +3933,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float GPU_line_width(2.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, (float)offset, yminc); immVertex2f(pos, (float)v2d->cur.xmax, yminc); immEnd(); @@ -3952,7 +3952,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float short draw_sliders = 0; float ymin_ofs = 0.0f; float color[3]; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 129cf07b7c4..780e984f870 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -141,15 +141,15 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag) GPU_line_width((flag & DRAWCFRA_WIDE) ? 3.0 : 2.0); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* Draw a light green line to indicate current frame */ immUniformThemeColor(TH_CFRAME); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */ immVertex2f(pos, x, v2d->cur.ymax); immEnd(); @@ -170,8 +170,8 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_ANIM_ACTIVE, -25, -30); @@ -203,8 +203,8 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d) GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_BACK, -25, -100); @@ -222,7 +222,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d) /* thin lines where the actual frames are */ immUniformThemeColorShade(TH_BACK, -60); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, (float)SFRA, v2d->cur.ymin); immVertex2f(pos, (float)SFRA, v2d->cur.ymax); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index f809bff536f..e1f4092c494 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -400,8 +400,8 @@ static void draw_marker( if (flag & DRAW_MARKERS_LINES) #endif { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -418,7 +418,7 @@ static void draw_marker( immUniform1f("dash_width", 6.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, xpos + 0.5f, 12.0f); immVertex2f(pos, xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale); immEnd(); @@ -486,7 +486,7 @@ void ED_markers_draw(const bContext *C, int flag) v2d = UI_view2d_fromcontext(C); if (flag & DRAW_MARKERS_MARGIN) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); const unsigned char shade[4] = {0, 0, 0, 16}; diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 78ce24db503..30130ce4dac 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -593,12 +593,12 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa } if (block_len > 0) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_TRIS, 6 * block_len); + immBegin(GPU_PRIM_TRIS, 6 * block_len); for (ActKeyBlock *ab = blocks->first; ab; ab = ab->next) { if (actkeyblock_is_valid(ab, keys)) { if (ab->flag & ACTKEYBLOCK_FLAG_MOVING_HOLD) { @@ -633,14 +633,14 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa if (key_len > 0) { /* draw keys */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, key_len); + immBegin(GPU_PRIM_POINTS, key_len); for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) { if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) { diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 927b8b8514d..dd0430f4f65 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -387,9 +387,9 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS float color[3]; UI_GetThemeColor3fv(TH_WIRE, color); - Gwn_Batch *sphere = GPU_batch_preset_sphere(0); - GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_3fv(sphere, "color", color); + GPUBatch *sphere = GPU_batch_preset_sphere(0); + GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); + GPU_batch_uniform_3fv(sphere, "color", color); /* scale to edit-mode space */ GPU_matrix_push(); @@ -407,7 +407,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS GPU_matrix_push(); GPU_matrix_scale_1f(radius); - GWN_batch_draw(sphere); + GPU_batch_draw(sphere); GPU_matrix_pop(); location_prev = selem->location_local; @@ -430,8 +430,8 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS } { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); GPU_depth_test(false); @@ -440,7 +440,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS GPU_line_width(3.0f); imm_cpack(0x0); - immBegin(GWN_PRIM_LINE_STRIP, stroke_len); + immBegin(GPU_PRIM_LINE_STRIP, stroke_len); for (int i = 0; i < stroke_len; i++) { immVertex3fv(pos, coord_array[i]); } @@ -449,7 +449,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS GPU_line_width(1.0f); imm_cpack(0xffffffff); - immBegin(GWN_PRIM_LINE_STRIP, stroke_len); + immBegin(GPU_PRIM_LINE_STRIP, stroke_len); for (int i = 0; i < stroke_len; i++) { immVertex3fv(pos, coord_array[i]); } diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c index aaaee182c71..5ccb1fa1f6d 100644 --- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c +++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c @@ -64,31 +64,31 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel /* TODO store the Batches inside the GizmoGeomInfo and updated it when geom changes * So we don't need to re-created and discard it every time */ - Gwn_VertBuf *vbo; - Gwn_IndexBuf *el; - Gwn_Batch *batch; - Gwn_IndexBufBuilder elb = {0}; + GPUVertBuf *vbo; + GPUIndexBuf *el; + GPUBatch *batch; + GPUIndexBufBuilder elb = {0}; - Gwn_VertFormat format = {0}; - uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat format = {0}; + uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); /* Elements */ - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, info->ntris, info->nverts); + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, info->ntris, info->nverts); for (int i = 0; i < info->ntris; ++i) { const unsigned short *idx = &info->indices[i * 3]; - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); + GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); } - el = GWN_indexbuf_build(&elb); + el = GPU_indexbuf_build(&elb); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, info->nverts); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, info->nverts); - GWN_vertbuf_attr_fill(vbo, pos_id, info->verts); + GPU_vertbuf_attr_fill(vbo, pos_id, info->verts); - batch = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, el, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); + batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, el, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4fv(batch, "color", color); + GPU_batch_uniform_4fv(batch, "color", color); /* We may want to re-visit this, for now disable * since it causes issues leaving the GL state modified. */ @@ -97,7 +97,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel GPU_depth_test(true); #endif - GWN_batch_draw(batch); + GPU_batch_draw(batch); #if 0 GPU_depth_test(false); @@ -105,7 +105,7 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, const bool UNUSED(sel #endif - GWN_batch_discard(batch); + GPU_batch_discard(batch); } void wm_gizmo_vec_draw( diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c index 673e38e4a1a..cb8e2a90b07 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c @@ -70,7 +70,7 @@ static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float const float arrow_length = RNA_float_get(gz->ptr, "length") - size_length; const float arrow_angle = RNA_float_get(gz->ptr, "angle"); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_matrix_push(); GPU_matrix_mul(matrix); @@ -80,12 +80,12 @@ static void arrow2d_draw_geom(wmGizmo *gz, const float matrix[4][4], const float immUniformColor4fv(color); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, 0.0f, 0.0f); immVertex2f(pos, 0.0f, arrow_length); immEnd(); - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immVertex2f(pos, size_breadth, arrow_length); immVertex2f(pos, -size_breadth, arrow_length); immVertex2f(pos, 0.0f, arrow_length + size_length); diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index da4bce680b8..0f8389af17d 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -90,7 +90,7 @@ static void gizmo_arrow_matrix_basis_get(const wmGizmo *gz, float r_matrix[4][4] static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const float color[4]) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); bool unbind_shader = true; const int draw_style = RNA_enum_get(arrow->gizmo.ptr, "draw_style"); const int draw_options = RNA_enum_get(arrow->gizmo.ptr, "draw_options"); @@ -100,7 +100,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const if (draw_style == ED_GIZMO_ARROW_STYLE_CROSS) { immUniformColor4fv(color); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex3f(pos, -1.0f, 0.0f, 0.0f); immVertex3f(pos, 1.0f, 0.0f, 0.0f); immVertex3f(pos, 0.0f, -1.0f, 0.0f); @@ -120,7 +120,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const }; GPU_line_width(arrow->gizmo.line_width); - wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GWN_PRIM_LINE_LOOP); + wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_LOOP); } else { #ifdef USE_GIZMO_CUSTOM_ARROWS @@ -135,7 +135,7 @@ static void arrow_draw_geom(const ArrowGizmo3D *arrow, const bool select, const if (draw_options & ED_GIZMO_ARROW_DRAW_FLAG_STEM) { GPU_line_width(arrow->gizmo.line_width); - wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GWN_PRIM_LINE_STRIP); + wm_gizmo_vec_draw(color, vec, ARRAY_SIZE(vec), pos, GPU_PRIM_LINE_STRIP); } else { immUniformColor4fv(color); diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index 13711325038..d976adc06bf 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -72,7 +72,7 @@ typedef struct ButtonGizmo2D { bool is_init; /* Use an icon or shape */ int icon; - Gwn_Batch *shape_batch[2]; + GPUBatch *shape_batch[2]; } ButtonGizmo2D; #define CIRCLE_RESOLUTION 32 @@ -84,8 +84,8 @@ static void button2d_geom_draw_backdrop( { GPU_line_width(gz->line_width); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -137,12 +137,12 @@ static void button2d_draw_intern( if (draw_options & ED_GIZMO_BUTTON_SHOW_HELPLINE) { float matrix_final_no_offset[4][4]; WM_gizmo_calc_matrix_final_no_offset(gz, matrix_final_no_offset); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(color); GPU_line_width(gz->line_width); immUniformColor4fv(color); - immBegin(GWN_PRIM_LINE_STRIP, 2); + immBegin(GPU_PRIM_LINE_STRIP, 2); immVertex3fv(pos, matrix_final[3]); immVertex3fv(pos, matrix_final_no_offset[3]); immEnd(); @@ -177,9 +177,9 @@ static void button2d_draw_intern( GPU_line_width(1.0f); for (uint i = 0; i < ARRAY_SIZE(button->shape_batch) && button->shape_batch[i]; i++) { /* Invert line color for wire. */ - GWN_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR); - GWN_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color)); - GWN_batch_draw(button->shape_batch[i]); + GPU_batch_program_set_builtin(button->shape_batch[i], GPU_SHADER_2D_UNIFORM_COLOR); + GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color)); + GPU_batch_draw(button->shape_batch[i]); if (draw_options & ED_GIZMO_BUTTON_SHOW_OUTLINE) { color[0] = 1.0f - color[0]; @@ -270,7 +270,7 @@ static void gizmo_button2d_free(wmGizmo *gz) ButtonGizmo2D *shape = (ButtonGizmo2D *)gz; for (uint i = 0; i < ARRAY_SIZE(shape->shape_batch); i++) { - GWN_BATCH_DISCARD_SAFE(shape->shape_batch[i]); + GPU_BATCH_DISCARD_SAFE(shape->shape_batch[i]); } } diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 5e3b7bb21c6..2869b93a790 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -136,12 +136,12 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_con static void cage2d_draw_box_corners( const rctf *r, const float margin[2], const float color[3]) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3fv(color); - immBegin(GWN_PRIM_LINES, 16); + immBegin(GPU_PRIM_LINES, 16); immVertex2f(pos, r->xmin, r->ymin + margin[1]); immVertex2f(pos, r->xmin, r->ymin); @@ -176,7 +176,7 @@ static void cage2d_draw_box_interaction( /* 4 verts for translate, otherwise only 3 are used. */ float verts[4][2]; uint verts_len = 0; - Gwn_PrimType prim_type = GWN_PRIM_NONE; + GPUPrimType prim_type = GPU_PRIM_NONE; switch (highlighted) { case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X: @@ -192,10 +192,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax); ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin); verts_len += 2; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -212,10 +212,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[2], r.xmin, r.ymax); ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin); verts_len += 2; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -232,10 +232,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymax); ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax); verts_len += 2; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -252,10 +252,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[2], r.xmax, r.ymin); ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin); verts_len += 2; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -272,10 +272,10 @@ static void cage2d_draw_box_interaction( if (is_solid) { ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymin); verts_len += 1; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -292,10 +292,10 @@ static void cage2d_draw_box_interaction( if (is_solid) { ARRAY_SET_ITEMS(verts[3], r.xmin, r.ymax); verts_len += 1; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -312,10 +312,10 @@ static void cage2d_draw_box_interaction( if (is_solid) { ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymin); verts_len += 1; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -332,10 +332,10 @@ static void cage2d_draw_box_interaction( if (is_solid) { ARRAY_SET_ITEMS(verts[3], r.xmax, r.ymax); verts_len += 1; - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -355,10 +355,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[3], r_rotate.xmax, r_rotate.ymin); verts_len = 4; if (is_solid) { - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } break; } @@ -371,10 +371,10 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[3], margin[0] / 2, -margin[1] / 2); verts_len = 4; if (is_solid) { - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { - prim_type = GWN_PRIM_LINES; + prim_type = GPU_PRIM_LINES; } } else { @@ -385,12 +385,12 @@ static void cage2d_draw_box_interaction( ARRAY_SET_ITEMS(verts[3], size[0], -size[1]); verts_len = 4; if (is_solid) { - prim_type = GWN_PRIM_TRI_FAN; + prim_type = GPU_PRIM_TRI_FAN; } else { /* unreachable */ BLI_assert(0); - prim_type = GWN_PRIM_LINE_STRIP; + prim_type = GPU_PRIM_LINE_STRIP; } } break; @@ -398,20 +398,20 @@ static void cage2d_draw_box_interaction( return; } - BLI_assert(prim_type != GWN_PRIM_NONE); + BLI_assert(prim_type != GPU_PRIM_NONE); - Gwn_VertFormat *format = immVertexFormat(); + GPUVertFormat *format = immVertexFormat(); struct { uint pos, col; } attr_id = { - .pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT), - .col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT), + .pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT), + .col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT), }; immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); { if (is_solid) { - BLI_assert(ELEM(prim_type, GWN_PRIM_TRI_FAN)); + BLI_assert(ELEM(prim_type, GPU_PRIM_TRI_FAN)); immBegin(prim_type, verts_len); immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f); for (uint i = 0; i < verts_len; i++) { @@ -420,7 +420,7 @@ static void cage2d_draw_box_interaction( immEnd(); } else { - BLI_assert(ELEM(prim_type, GWN_PRIM_LINE_STRIP, GWN_PRIM_LINES)); + BLI_assert(ELEM(prim_type, GPU_PRIM_LINE_STRIP, GPU_PRIM_LINES)); GPU_line_width(line_width + 3.0f); immBegin(prim_type, verts_len); @@ -455,7 +455,7 @@ static void cage2d_draw_box_interaction( static void imm_draw_point_aspect_2d( uint pos, float x, float y, float rad_x, float rad_y, bool solid) { - immBegin(solid ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4); + immBegin(solid ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, x - rad_x, y - rad_y); immVertex2f(pos, x - rad_x, y + rad_y); immVertex2f(pos, x + rad_x, y + rad_y); @@ -467,12 +467,12 @@ static void cage2d_draw_circle_wire( const rctf *r, const float margin[2], const float color[3], const int transform_flag, const int draw_options) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3fv(color); - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, r->xmin, r->ymin); immVertex2f(pos, r->xmax, r->ymin); immVertex2f(pos, r->xmax, r->ymax); @@ -480,7 +480,7 @@ static void cage2d_draw_circle_wire( immEnd(); if (transform_flag & ED_GIZMO_CAGE2D_XFORM_FLAG_ROTATE) { - immBegin(GWN_PRIM_LINE_LOOP, 2); + immBegin(GPU_PRIM_LINE_LOOP, 2); immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax); immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]); immEnd(); @@ -491,7 +491,7 @@ static void cage2d_draw_circle_wire( const float rad[2] = {margin[0] / 2, margin[1] / 2}; const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)}; - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]); immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]); immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]); @@ -508,7 +508,7 @@ static void cage2d_draw_circle_handles( const int transform_flag, bool solid) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); void (*circle_fn)(uint, float, float, float, float, int) = (solid) ? imm_draw_circle_fill_aspect_2d : imm_draw_circle_wire_aspect_2d; const int resolu = 12; @@ -560,7 +560,7 @@ static void gizmo_cage2d_draw_intern( /* Handy for quick testing draw (if it's outside bounds). */ if (false) { GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index 9cad82619ba..0f1d309c927 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -150,7 +150,7 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con static void cage3d_draw_box_corners( const float r[3], const float margin[3], const float color[3]) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); UNUSED_VARS(margin); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -185,7 +185,7 @@ static void cage3d_draw_box_interaction( const float rad[3] = {margin[0] / 3, margin[1] / 3, margin[2] / 3}; { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3fv(color); imm_draw_cube_fill_3d(pos, co, rad); @@ -217,7 +217,7 @@ static void cage3d_draw_circle_wire( const float r[3], const float margin[3], const float color[3], const int transform_flag, const int draw_options) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3fv(color); @@ -230,7 +230,7 @@ static void cage3d_draw_circle_wire( const float rad[2] = {margin[0] / 2, margin[1] / 2}; const float center[2] = {0.0f, 0.0f}; - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]); immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]); immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]); @@ -251,7 +251,7 @@ static void cage3d_draw_circle_handles( const float r[3], const float margin[3], const float color[3], bool solid, float scale) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); const float rad[3] = {margin[0] / 3, margin[1] / 3, margin[2] / 3}; immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -305,7 +305,7 @@ static void gizmo_cage3d_draw_intern( /* Handy for quick testing draw (if it's outside bounds). */ if (false) { GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c index 300ae222189..8e04703c14e 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c @@ -126,8 +126,8 @@ static void dial_geom_draw( GPU_line_width(gz->line_width); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (clip_plane) { immBindBuiltinProgram(GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR); @@ -164,13 +164,13 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[ GPU_matrix_push(); GPU_matrix_rotate_3f(RAD2DEGF(angle), 0.0f, 0.0f, -1.0f); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(color); - immBegin(GWN_PRIM_LINE_STRIP, 2); + immBegin(GPU_PRIM_LINE_STRIP, 2); immVertex3f(pos, 0.0f, 0.0f, 0.0f); immVertex3fv(pos, co_outer); immEnd(); @@ -185,8 +185,8 @@ static void dial_ghostarc_draw( { const float width_inner = DIAL_WIDTH - gz->line_width * 0.5f / U.gizmo_size; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(color); imm_draw_disk_partial_fill_2d( diff --git a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c index 840ea793b89..8d4db81c11f 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c @@ -105,8 +105,8 @@ static void grab_geom_draw( GPU_line_width(gz->line_width); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -121,7 +121,7 @@ static void grab_geom_draw( } } else if (draw_style == ED_GIZMO_GRAB_STYLE_CROSS_2D) { - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, 1.0f, 1.0f); immVertex2f(pos, -1.0f, -1.0f); diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c index b61c16b8d65..6443a6bf038 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c @@ -77,10 +77,10 @@ static void gizmo_primitive_draw_geom( } if (vert_count > 0) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GWN_PRIM_TRI_FAN); - wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GWN_PRIM_LINE_LOOP); + wm_gizmo_vec_draw(col_inner, verts, vert_count, pos, GPU_PRIM_TRI_FAN); + wm_gizmo_vec_draw(col_outer, verts, vert_count, pos, GPU_PRIM_LINE_LOOP); immUnbindProgram(); } } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index ec4310213ef..29b24886017 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -150,14 +150,14 @@ static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, f /* draw triangulation data */ if (tot_triangles > 0) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* Draw all triangles for filling the polygon */ - immBegin(GWN_PRIM_TRIS, tot_triangles * 3); + immBegin(GPU_PRIM_TRIS, tot_triangles * 3); /* TODO: use batch instead of immediate mode, to share vertices */ const tGPspoint *pt; @@ -208,9 +208,9 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short return; } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); const tGPspoint *pt = points; @@ -218,7 +218,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short /* if drawing a single point, draw it larger */ GPU_point_size((float)(thickness + 2) * points->pressure); immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); gp_set_tpoint_varying_color(pt, ink, color); immVertex2iv(pos, &pt->x); } @@ -228,7 +228,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short /* draw stroke curve */ GPU_line_width(max_ff(oldpressure * thickness, 1.0)); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints); /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ @@ -247,7 +247,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short draw_points = 0; GPU_line_width(max_ff(pt->pressure * thickness, 1.0f)); - immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1); /* need to roll-back one point to ensure that there are no gaps in the stroke */ if (i != 0) { @@ -319,14 +319,14 @@ static void gp_draw_stroke_volumetric_buffer(const tGPspoint *points, int totpoi if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D)) return; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, totpoints); + immBegin(GPU_PRIM_POINTS, totpoints); const tGPspoint *pt = points; for (int i = 0; i < totpoints; i++, pt++) { @@ -346,14 +346,14 @@ static void gp_draw_stroke_volumetric_2d(const bGPDspoint *points, int totpoints int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4]) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, totpoints); + immBegin(GPU_PRIM_POINTS, totpoints); const bGPDspoint *pt = points; for (int i = 0; i < totpoints; i++, pt++) { @@ -379,14 +379,14 @@ static void gp_draw_stroke_volumetric_3d( const bGPDspoint *points, int totpoints, short thickness, const float ink[4]) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, totpoints); + immBegin(GPU_PRIM_POINTS, totpoints); const bGPDspoint *pt = points; for (int i = 0; i < totpoints && pt; i++, pt++) { @@ -519,18 +519,18 @@ static void gp_draw_stroke_fill( uint pos; if (gps->flag & GP_STROKE_3DSPACE) { - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); } else { - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); } immUniformColor4fv(color); /* Draw all triangles for filling the polygon (cache must be calculated before) */ - immBegin(GWN_PRIM_TRIS, gps->tot_triangles * 3); + immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3); /* TODO: use batch instead of immediate mode, to share vertices */ bGPDtriangle *stroke_triangle = gps->triangles; @@ -575,8 +575,8 @@ static void gp_draw_stroke_point( float fpt[3]; mul_v3_m4v3(fpt, diff_mat, &pt->x); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); if (sflag & GP_STROKE_3DSPACE) { immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); @@ -594,7 +594,7 @@ static void gp_draw_stroke_point( /* set point thickness (since there's only one of these) */ immUniform1f("size", (float)(thickness + 2) * pt->pressure); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(pos, fpt); immEnd(); @@ -617,9 +617,9 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); @@ -627,7 +627,7 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi /* draw stroke curve */ GPU_line_width(max_ff(curpressure * thickness, 1.0f)); - immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints + cyclic_add); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add); const bGPDspoint *pt = points; for (int i = 0; i < totpoints; i++, pt++) { gp_set_point_varying_color(pt, ink, color); @@ -648,7 +648,7 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi curpressure = pt->pressure; GPU_line_width(max_ff(curpressure * thickness, 1.0f)); - immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add); /* need to roll-back one point to ensure that there are no gaps in the stroke */ if (i != 0) { @@ -716,12 +716,12 @@ static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thi int i; float fpt[3]; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_TRI_STRIP, totpoints * 2 + 4); + immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4); /* get x and y coordinates from first point */ mul_v3_m4v3(fpt, diff_mat, &points->x); @@ -1150,21 +1150,21 @@ static void gp_draw_strokes_edit( UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); selectColor[3] = alpha; - Gwn_VertFormat *format = immVertexFormat(); + GPUVertFormat *format = immVertexFormat(); uint pos; /* specified later */ - uint size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); if (gps->flag & GP_STROKE_3DSPACE) { - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); } else { - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR); } - immBegin(GWN_PRIM_POINTS, gps->totpoints); + immBegin(GPU_PRIM_POINTS, gps->totpoints); /* Draw start and end point differently if enabled stroke direction hint */ bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1); diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index a8810df35ff..bd9bfcf7025 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -985,8 +985,8 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customda GP_EditBrush_Data *brush = gpsculpt_get_brush(CTX_data_scene(C)); if (brush) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index ec8a213301f..789e9865ae4 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1875,8 +1875,8 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) tGPsdata *p = (tGPsdata *)p_ptr; if (p->paintmode == GP_PAINTMODE_ERASER) { - Gwn_VertFormat *format = immVertexFormat(); - const uint shdr_pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 9b0b2c970b2..64dee410526 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -109,7 +109,7 @@ typedef enum eKeyframeShapeDrawOpts { } eKeyframeShapeDrawOpts; /* draw simple diamond-shape keyframe */ -/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(GWN_PRIM_POINTS, n), then call this n times */ +/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(GPU_PRIM_POINTS, n), then call this n times */ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha, unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index b1c3795b1af..6a304a8150e 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -130,19 +130,19 @@ void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space. * If it has been scaled, then it's no longer valid. */ - Gwn_Batch *batch = ui_batch_roundbox_get(filled, true); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); - GWN_batch_draw(batch); + GPUBatch *batch = ui_batch_roundbox_get(filled, true); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_draw(batch); } else { /* plain antialiased unfilled box */ GPU_line_smooth(true); - Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); - GWN_batch_draw(batch); + GPUBatch *batch = ui_batch_roundbox_get(filled, false); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_draw(batch); GPU_line_smooth(false); } @@ -159,8 +159,8 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float }; int a; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* mult */ for (a = 0; a < 7; a++) { @@ -176,7 +176,7 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(col); - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_len); + immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { immVertex2f(pos, maxx - rad, miny); @@ -244,10 +244,10 @@ void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float .alpha_discard = 1.0f, }; - Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); - GWN_batch_draw(batch); + GPUBatch *batch = ui_batch_roundbox_get(filled, false); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_draw(batch); } #if 0 @@ -280,9 +280,9 @@ void UI_draw_roundbox_shade_x( int vert_count = 0; int a; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); @@ -304,7 +304,7 @@ void UI_draw_roundbox_shade_x( vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1; vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1; - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count); + immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { @@ -404,10 +404,10 @@ void UI_draw_roundbox_shade_x( .alpha_discard = 1.0f, }; - Gwn_Batch *batch = ui_batch_roundbox_get(filled, false); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); - GWN_batch_draw(batch); + GPUBatch *batch = ui_batch_roundbox_get(filled, false); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_draw(batch); } #if 0 /* unused */ @@ -432,9 +432,9 @@ void UI_draw_roundbox_shade_y( mul_v2_fl(vec[a], rad); } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); @@ -452,7 +452,7 @@ void UI_draw_roundbox_shade_y( vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1; vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1; - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, vert_count); + immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count); /* start with corner right-bottom */ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { @@ -535,8 +535,8 @@ void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const flo { int ofs_y = 4 * U.pixelsize; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); @@ -550,9 +550,9 @@ void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const flo /* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */ void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highlight[3], unsigned char highlight_fade[3]) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); /* add a 1px offset, looks nicer */ const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize; const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize; @@ -571,7 +571,7 @@ void ui_draw_but_TAB_outline(const rcti *rect, float rad, unsigned char highligh } immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBeginAtMost(GWN_PRIM_LINE_STRIP, 25); + immBeginAtMost(GPU_PRIM_LINE_STRIP, 25); immAttrib3ubv(col, highlight); @@ -685,8 +685,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w * * \Note This functionn is to be used with the 2D dashed shader enabled. * - * \param pos is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib - * \param line_origin is a PRIM_FLOAT, 2, GWN_FETCH_FLOAT vertex attrib + * \param pos is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attrib + * \param line_origin is a PRIM_FLOAT, 2, GPU_FETCH_FLOAT vertex attrib * * The next 4 parameters are the offsets for the view, not the zones. */ @@ -749,7 +749,7 @@ static void histogram_draw_one( /* curve outline */ GPU_line_width(1.5); - immBegin(GWN_PRIM_LINE_STRIP, res); + immBegin(GPU_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); immVertex2f(pos_attrib, x2, y + (data[i] * h)); @@ -758,7 +758,7 @@ static void histogram_draw_one( } else { /* under the curve */ - immBegin(GWN_PRIM_TRI_STRIP, res * 2); + immBegin(GPU_PRIM_TRI_STRIP, res * 2); immVertex2f(pos_attrib, x, y); immVertex2f(pos_attrib, x, y + (data[0] * h)); for (int i = 1; i < res; i++) { @@ -772,7 +772,7 @@ static void histogram_draw_one( immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - immBegin(GWN_PRIM_LINE_STRIP, res); + immBegin(GPU_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { float x2 = x + i * (w / (float)res); immVertex2f(pos_attrib, x2, y + (data[i] * h)); @@ -818,8 +818,8 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -833,7 +833,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); } - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, rect.xmin, rect.ymin + fac * h); immVertex2f(pos, rect.xmax, rect.ymin + fac * h); @@ -869,21 +869,21 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUS static void waveform_draw_one(float *waveform, int nbr, const float col[3]) { - Gwn_VertFormat format = {0}; - uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat format = {0}; + uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, nbr); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, nbr); - GWN_vertbuf_attr_fill(vbo, pos_id, waveform); + GPU_vertbuf_attr_fill(vbo, pos_id, waveform); - /* TODO store the Gwn_Batch inside the scope */ - Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); - GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f); - GWN_batch_draw(batch); + /* TODO store the GPUBatch inside the scope */ + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); + GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f); + GPU_batch_draw(batch); - GWN_batch_discard(batch); + GPU_batch_discard(batch); } void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) @@ -957,15 +957,15 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f); /* draw grid lines here */ - immBegin(GWN_PRIM_LINES, 12); + immBegin(GPU_PRIM_LINES, 12); for (int i = 0; i < 6; i++) { immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h); @@ -976,7 +976,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE /* 3 vertical separation */ if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) { - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); for (int i = 1; i < 3; i++) { immVertex2f(pos, rect.xmin + i * w3, rect.ymin); @@ -987,7 +987,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE } /* separate min max zone on the right */ - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect.xmin + w, rect.ymin); immVertex2f(pos, rect.xmin + w, rect.ymax); immEnd(); @@ -995,7 +995,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE /* 16-235-240 level in case of ITU-R BT601/709 */ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f); if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) { - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f); immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f); @@ -1013,7 +1013,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE } /* 7.5 IRE black point level for NTSC */ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) { - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect.xmin, yofs + h * 0.075f); immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f); immEnd(); @@ -1042,7 +1042,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE CLAMP(min, rect.ymin, rect.ymax); CLAMP(max, rect.ymin, rect.ymax); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect.xmax - 3, min); immVertex2f(pos, rect.xmax - 3, max); immEnd(); @@ -1096,7 +1096,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSE CLAMP(min, rect.ymin, rect.ymax); CLAMP(max, rect.ymin, rect.ymax); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect.xmin + w + 2 + c * 2, min); immVertex2f(pos, rect.xmin + w + 2 + c * 2, max); immEnd(); @@ -1140,7 +1140,7 @@ static void vectorscope_draw_target(unsigned int pos, float centerx, float cente immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f); dangle = DEG2RADF(2.5f); dampli = 2.5f / 200.0f; - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); @@ -1152,22 +1152,22 @@ static void vectorscope_draw_target(unsigned int pos, float centerx, float cente dampli = 0.2f * tampli; dangle2 = DEG2RADF(5.0f); dampli2 = 0.5f * dampli; - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2)); immEnd(); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2)); immEnd(); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2)); immEnd(); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle)); immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2)); @@ -1215,15 +1215,15 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f); /* draw grid elements */ /* cross */ - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery); immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery); @@ -1236,7 +1236,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN /* circles */ for (int j = 0; j < 5; j++) { const int increment = 15; - immBegin(GWN_PRIM_LINE_LOOP, (int)(360 / increment)); + immBegin(GPU_PRIM_LINE_LOOP, (int)(360 / increment)); for (int i = 0; i <= 360 - increment; i += increment) { const float a = DEG2RADF((float)i); const float r = (j + 1) * 0.1f; @@ -1247,7 +1247,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UN /* skin tone line */ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad)); immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad)); immEnd(); @@ -1284,7 +1284,7 @@ static void ui_draw_colorband_handle_tri_hlight(unsigned int pos, float x1, floa { GPU_line_smooth(true); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, x1 + halfwidth, y1); immVertex2f(pos, x1, y1 + height); immVertex2f(pos, x1 - halfwidth, y1); @@ -1297,7 +1297,7 @@ static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, f { glEnable(fill ? GL_POLYGON_SMOOTH : GL_LINE_SMOOTH); - immBegin(fill ? GWN_PRIM_TRIS : GWN_PRIM_LINE_LOOP, 3); + immBegin(fill ? GPU_PRIM_TRIS : GPU_PRIM_LINE_LOOP, 3); immVertex2f(pos, x1 + halfwidth, y1); immVertex2f(pos, x1, y1 + height); immVertex2f(pos, x1 - halfwidth, y1); @@ -1308,7 +1308,7 @@ static void ui_draw_colorband_handle_tri(unsigned int pos, float x1, float y1, f static void ui_draw_colorband_handle_box(unsigned int pos, float x1, float y1, float x2, float y2, bool fill) { - immBegin(fill ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4); + immBegin(fill ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x1, y2); immVertex2f(pos, x2, y2); @@ -1348,7 +1348,7 @@ static void ui_draw_colorband_handle( immUniformArray4fv("colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", active ? 4.0f : 2.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(shdr_pos, x, y1); immVertex2f(shdr_pos, x, y2); immEnd(); @@ -1419,8 +1419,8 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti float sizey_solid = sizey * 0.25f; float y1 = rect->ymin; - Gwn_VertFormat *format = immVertexFormat(); - pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); /* Drawing the checkerboard. */ @@ -1432,8 +1432,8 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti /* New format */ format = immVertexFormat(); - pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - col_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* layer: color ramp */ @@ -1447,7 +1447,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti v1[1] = y1 + sizey_solid; v2[1] = rect->ymax; - immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2); + immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); @@ -1466,7 +1466,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti v1[1] = y1; v2[1] = y1 + sizey_solid; - immBegin(GWN_PRIM_TRI_STRIP, (sizex + 1) * 2); + immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); @@ -1487,7 +1487,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti /* New format */ format = immVertexFormat(); - pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* layer: box outline */ @@ -1498,14 +1498,14 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti GPU_blend(true); immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos_id, x1, y1); immVertex2f(pos_id, x1 + sizex, y1); immEnd(); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos_id, x1, y1 - 1); immVertex2f(pos_id, x1 + sizex, y1 - 1); immEnd(); @@ -1558,18 +1558,18 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect) GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect)); GPU_matrix_scale_1f(size); - Gwn_Batch *sphere = GPU_batch_preset_sphere(2); - GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f); - GWN_batch_uniform_3fv(sphere, "light", light); - GWN_batch_draw(sphere); + GPUBatch *sphere = GPU_batch_preset_sphere(2); + GPU_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); + GPU_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f); + GPU_batch_uniform_3fv(sphere, "light", light); + GPU_batch_draw(sphere); /* restore */ glDisable(GL_CULL_FACE); /* AA circle */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv((unsigned char *)wcol->inner); @@ -1599,7 +1599,7 @@ static void ui_draw_but_curve_grid(unsigned int pos, const rcti *rect, float zoo floorf((rect->xmax - fx) / dx) + 1.0f + floorf((rect->ymax - fy) / dy) + 1.0f); - immBegin(GWN_PRIM_LINES, (int)line_count * 2); + immBegin(GPU_PRIM_LINES, (int)line_count * 2); while (fx < rect->xmax) { immVertex2f(pos, fx, rect->ymin); immVertex2f(pos, fx, rect->ymax); @@ -1675,8 +1675,8 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti GPU_line_width(1.0f); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* backdrop */ @@ -1712,7 +1712,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f); /* axes */ gl_shaded_color((unsigned char *)wcol->inner, -50); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy)); immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy)); immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin); @@ -1725,7 +1725,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti #if 0 if (cumap->flag & CUMA_DRAW_CFRA) { immUniformColor3ub(0x60, 0xc0, 0x40); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin); immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax); immEnd(); @@ -1734,7 +1734,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* sample option */ if (cumap->flag & CUMA_DRAW_SAMPLE) { - immBegin(GWN_PRIM_LINES, 2); /* will draw one of the following 3 lines */ + immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */ if (but->a1 == UI_GRAD_H) { float tsample[3]; float hsv[3]; @@ -1770,7 +1770,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti immUniformColor3ubv((unsigned char *)wcol->item); GPU_line_smooth(true); GPU_blend(true); - immBegin(GWN_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2); + immBegin(GPU_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2); if (cuma->table == NULL) curvemapping_changed(cumap, false); @@ -1807,13 +1807,13 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* the points, use aspect to make them visible on edges */ format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); cmp = cuma->curve; GPU_point_size(3.0f); - immBegin(GWN_PRIM_POINTS, cuma->totpoint); + immBegin(GPU_PRIM_POINTS, cuma->totpoint); for (int a = 0; a < cuma->totpoint; a++) { float color[4]; if (cmp[a].flag & CUMA_SELECT) @@ -1833,7 +1833,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti /* outline */ format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv((unsigned char *)wcol->outline); @@ -1926,16 +1926,16 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *U BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect)); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel); UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline); /* Do stipple cross with geometry */ - immBegin(GWN_PRIM_LINES, 7 * 2 * 2); + immBegin(GPU_PRIM_LINES, 7 * 2 * 2); float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f}; for (int axe = 0; axe < 2; ++axe) { for (int i = 0; i < 7; ++i) { @@ -2018,13 +2018,13 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol float x = 0.5f * (recti->xmin + recti->xmax); float y = 0.5f * (recti->ymin + recti->ymax); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv(but->col); GPU_blend(true); - immBegin(GWN_PRIM_TRI_FAN, 16); + immBegin(GPU_PRIM_TRI_FAN, 16); for (int a = 0; a < 16; a++) immVertex2f(pos, x + size * si[a], y + size * co[a]); immEnd(); @@ -2032,7 +2032,7 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol immUniformColor4ub(0, 0, 0, 150); GPU_line_width(1); GPU_line_smooth(true); - immBegin(GWN_PRIM_LINE_LOOP, 16); + immBegin(GPU_PRIM_LINE_LOOP, 16); for (int a = 0; a < 16; a++) immVertex2f(pos, x + size * si[a], y + size * co[a]); immEnd(); @@ -2115,13 +2115,13 @@ void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, { GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBegin(GWN_PRIM_TRIS, 54); + immBegin(GPU_PRIM_TRIS, 54); /* accumulated outline boxes to make shade not linear, is more pleasant */ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8); @@ -2186,11 +2186,11 @@ void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha .alpha_discard = 1.0f, }; - Gwn_Batch *batch = ui_batch_roundbox_shadow_get(); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); - GWN_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params); - GWN_batch_uniform_1f(batch, "alpha", 1.0f - visibility); - GWN_batch_draw(batch); + GPUBatch *batch = ui_batch_roundbox_shadow_get(); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); + GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params); + GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility); + GPU_batch_draw(batch); /* outline emphasis */ GPU_line_smooth(true); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index b9183461b4c..22b82898288 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -250,11 +250,11 @@ static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float viconutil_set_point(pts[1], cx - d2, cy - d); viconutil_set_point(pts[2], cx + d2, cy); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(0.2f, 0.2f, 0.2f, alpha); - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immVertex2iv(pos, pts[0]); immVertex2iv(pos, pts[1]); immVertex2iv(pos, pts[2]); @@ -280,15 +280,15 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, int xco = x + w / 2; int yco = y + h / 2; - Gwn_VertFormat *format = immVertexFormat(); - uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); /* draw keyframe * - size: 0.6 * h (found out experimentally... dunno why!) @@ -343,7 +343,7 @@ static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNU const int b = x + w / 3 * 2; const int c = x + w; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* XXX: Include alpha into this... */ @@ -1262,7 +1262,7 @@ static void icon_draw_cache_flush_ex(void) glUniform1i(img_loc, 0); glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)g_icon_draw_cache.drawcall_cache); - GWN_draw_primitive(GWN_PRIM_TRIS, 6 * g_icon_draw_cache.calls); + GPU_draw_primitive(GPU_PRIM_TRIS, 6 * g_icon_draw_cache.calls); glBindTexture(GL_TEXTURE_2D, 0); @@ -1342,14 +1342,14 @@ static void icon_draw_texture( GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); GPU_shader_bind(shader); - if (rgb) glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha); - else glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha); + if (rgb) glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha); + else glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha); glUniform1i(GPU_shader_get_uniform(shader, "image"), 0); glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2); glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x, y, x + w, y + h); - GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4); + GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c index dc444b98b2c..fabf5f9bf48 100644 --- a/source/blender/editors/interface/interface_icons_event.c +++ b/source/blender/editors/interface/interface_icons_event.c @@ -136,8 +136,8 @@ static void icon_draw_rect_input_line_prim( { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - BLI_assert(ELEM(prim, GWN_PRIM_LINE_LOOP, GWN_PRIM_LINE_STRIP)); - const uint pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + BLI_assert(ELEM(prim, GPU_PRIM_LINE_LOOP, GPU_PRIM_LINE_STRIP)); + const uint pos_id = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); immBegin(prim, lines_len); @@ -289,7 +289,7 @@ void icon_draw_rect_input( else if (event_type == SPACEKEY) { const uchar lines[] = {60, 118, 60, 60, 195, 60, 195, 118}; icon_draw_rect_input_line_prim( - &rect, color, GWN_PRIM_LINE_STRIP, + &rect, color, GPU_PRIM_LINE_STRIP, (const void *)lines, ARRAY_SIZE(lines) / 2); } } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index ffc389c6dfd..f0060cd5758 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -752,9 +752,9 @@ enum { ROUNDBOX_TRIA_MAX, /* don't use */ }; -struct Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased); -struct Gwn_Batch *ui_batch_roundbox_widget_get(int tria); -struct Gwn_Batch *ui_batch_roundbox_shadow_get(void); +struct GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased); +struct GPUBatch *ui_batch_roundbox_widget_get(int tria); +struct GPUBatch *ui_batch_roundbox_shadow_get(void); void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]); void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 79d92eedfa3..59fdf7e672d 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -478,7 +478,7 @@ static void ui_draw_anti_x(unsigned int pos, float x1, float y1, float x2, float GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x2, y2); @@ -519,7 +519,7 @@ static void ui_draw_panel_scalewidget(unsigned int pos, const rcti *rect) GPU_blend(true); immUniformColor4ub(255, 255, 255, 50); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, xmin, ymin); immVertex2f(pos, xmax, ymax); @@ -531,7 +531,7 @@ static void ui_draw_panel_scalewidget(unsigned int pos, const rcti *rect) immUniformColor4ub(0, 0, 0, 50); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, xmin, ymin + 1); immVertex2f(pos, xmax, ymax + 1); @@ -584,7 +584,7 @@ static void ui_draw_panel_dragwidget(unsigned int pos, unsigned int col, const r UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark); /* draw multiple boxes */ - immBegin(GWN_PRIM_TRIS, 4 * 2 * (6 * 2)); + immBegin(GPU_PRIM_TRIS, 4 * 2 * (6 * 2)); for (i_x = 0; i_x < 4; i_x++) { for (i_y = 0; i_y < 2; i_y++) { const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin)); @@ -677,7 +677,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con titlerect.xmin += 5.0f / block->aspect; } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); if (!is_subpanel) { @@ -691,7 +691,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con immUniformThemeColor(TH_PANEL_HEADER); immRectf(pos, minx, headrect.ymin, maxx, y); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, minx, y); immVertex2f(pos, maxx, y); @@ -729,9 +729,9 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con if (show_drag) { uint col; - Gwn_VertFormat *format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); /* itemrect smaller */ itemrect.xmax = headrect.xmax - 5.0f / block->aspect; @@ -745,7 +745,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con immUnbindProgram(); /* Restore format for the following draws. */ - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } } @@ -758,7 +758,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con else if (is_closed_x) { /* draw vertical title */ ui_draw_aligned_panel_header(style, block, &headrect, 'v'); - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } /* an open panel */ else { @@ -1700,9 +1700,9 @@ static void ui_panel_category_draw_tab( {0.98, 0.805}}; int a; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); /* mult */ for (a = 0; a < 4; a++) { @@ -1724,7 +1724,7 @@ static void ui_panel_category_draw_tab( immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_STRIP, vert_len); + immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len); /* start with corner right-top */ if (use_highlight) { @@ -1929,7 +1929,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) /* begin drawing */ GPU_line_smooth(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* draw the background */ @@ -1991,7 +1991,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) /* tab blackline */ if (!is_active) { - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv(theme_col_tab_divider); @@ -2022,7 +2022,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) GPU_blend(false); /* tab blackline remaining (last tab) */ - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); if (pc_dyn->prev == NULL) { immUniformColor3ubv(theme_col_tab_divider); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index aa3106b135b..52e6e237a58 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -247,22 +247,22 @@ static const int tria_vcount[ROUNDBOX_TRIA_MAX] = { }; static struct { - Gwn_Batch *roundbox_widget[ROUNDBOX_TRIA_MAX]; + GPUBatch *roundbox_widget[ROUNDBOX_TRIA_MAX]; - Gwn_Batch *roundbox_simple; - Gwn_Batch *roundbox_simple_aa; - Gwn_Batch *roundbox_simple_outline; - Gwn_Batch *roundbox_shadow; + GPUBatch *roundbox_simple; + GPUBatch *roundbox_simple_aa; + GPUBatch *roundbox_simple_outline; + GPUBatch *roundbox_shadow; - Gwn_VertFormat format; + GPUVertFormat format; uint vflag_id; } g_ui_batch_cache = {{0}}; -static Gwn_VertFormat *vflag_format(void) +static GPUVertFormat *vflag_format(void) { if (g_ui_batch_cache.format.attr_len == 0) { - Gwn_VertFormat *format = &g_ui_batch_cache.format; - g_ui_batch_cache.vflag_id = GWN_vertformat_attr_add(format, "vflag", GWN_COMP_U32, 1, GWN_FETCH_INT); + GPUVertFormat *format = &g_ui_batch_cache.format; + g_ui_batch_cache.vflag_id = GPU_vertformat_attr_add(format, "vflag", GPU_COMP_U32, 1, GPU_FETCH_INT); } return &g_ui_batch_cache.format; } @@ -273,17 +273,17 @@ static Gwn_VertFormat *vflag_format(void) #define NO_AA WIDGET_AA_JITTER static void set_roundbox_vertex_data( - Gwn_VertBufRaw *vflag_step, uint32_t d) + GPUVertBufRaw *vflag_step, uint32_t d) { - uint32_t *data = GWN_vertbuf_raw_step(vflag_step); + uint32_t *data = GPU_vertbuf_raw_step(vflag_step); *data = d; } static uint32_t set_roundbox_vertex( - Gwn_VertBufRaw *vflag_step, + GPUVertBufRaw *vflag_step, int corner_id, int corner_v, int jit_v, bool inner, bool emboss, int color) { - uint32_t *data = GWN_vertbuf_raw_step(vflag_step); + uint32_t *data = GPU_vertbuf_raw_step(vflag_step); *data = corner_id; *data |= corner_v << 2; *data |= jit_v << 6; @@ -294,10 +294,10 @@ static uint32_t set_roundbox_vertex( } static uint32_t set_tria_vertex( - Gwn_VertBufRaw *vflag_step, + GPUVertBufRaw *vflag_step, int tria_type, int tria_v, int tria_id, int jit_v) { - uint32_t *data = GWN_vertbuf_raw_step(vflag_step); + uint32_t *data = GPU_vertbuf_raw_step(vflag_step); if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS)) { tria_v += tria_id * tria_vcount[ROUNDBOX_TRIA_ARROWS]; } @@ -308,7 +308,7 @@ static uint32_t set_tria_vertex( return *data; } -static void roundbox_batch_add_tria(Gwn_VertBufRaw *vflag_step, int tria, uint32_t last_data) +static void roundbox_batch_add_tria(GPUVertBufRaw *vflag_step, int tria, uint32_t last_data) { const int tria_num = ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2; /* for each tria */ @@ -324,12 +324,12 @@ static void roundbox_batch_add_tria(Gwn_VertBufRaw *vflag_step, int tria, uint32 } } -Gwn_Batch *ui_batch_roundbox_widget_get(int tria) +GPUBatch *ui_batch_roundbox_widget_get(int tria) { if (g_ui_batch_cache.roundbox_widget[tria] == NULL) { uint32_t last_data; - Gwn_VertBufRaw vflag_step; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format()); + GPUVertBufRaw vflag_step; + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format()); int vcount = WIDGET_SIZE_MAX; /* inner */ vcount += 2; /* restart */ vcount += ((WIDGET_SIZE_MAX + 1) * 2) * WIDGET_AA_JITTER; /* outline (edges) */ @@ -341,8 +341,8 @@ Gwn_Batch *ui_batch_roundbox_widget_get(int tria) vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */ } } - GWN_vertbuf_data_alloc(vbo, vcount); - GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); + GPU_vertbuf_data_alloc(vbo, vcount); + GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); /* Inner */ for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) { for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU -1; a2 >= 0; a1++, a2--) { @@ -383,15 +383,15 @@ Gwn_Batch *ui_batch_roundbox_widget_get(int tria) if (tria) { roundbox_batch_add_tria(&vflag_step, tria, last_data); } - g_ui_batch_cache.roundbox_widget[tria] = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + g_ui_batch_cache.roundbox_widget[tria] = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); gpu_batch_presets_register(g_ui_batch_cache.roundbox_widget[tria]); } return g_ui_batch_cache.roundbox_widget[tria]; } -Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased) +GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased) { - Gwn_Batch **batch = NULL; + GPUBatch **batch = NULL; if (filled) { if (antialiased) @@ -408,13 +408,13 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased) if (*batch == NULL) { uint32_t last_data; - Gwn_VertBufRaw vflag_step; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format()); + GPUVertBufRaw vflag_step; + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format()); int vcount = WIDGET_SIZE_MAX; vcount += (filled) ? 2 : 0; vcount *= (antialiased) ? WIDGET_AA_JITTER : 1; - GWN_vertbuf_data_alloc(vbo, vcount); - GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); + GPU_vertbuf_data_alloc(vbo, vcount); + GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); if (filled) { for (int j = 0; j < WIDGET_AA_JITTER; j++) { @@ -435,7 +435,7 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased) break; } } - *batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + *batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); } else { for (int j = 0; j < WIDGET_AA_JITTER; j++) { @@ -451,7 +451,7 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased) break; } } - *batch = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO); + *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO); } gpu_batch_presets_register(*batch); @@ -459,15 +459,15 @@ Gwn_Batch *ui_batch_roundbox_get(bool filled, bool antialiased) return *batch; } -Gwn_Batch *ui_batch_roundbox_shadow_get(void) +GPUBatch *ui_batch_roundbox_shadow_get(void) { if (g_ui_batch_cache.roundbox_shadow == NULL) { uint32_t last_data; - Gwn_VertBufRaw vflag_step; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(vflag_format()); + GPUVertBufRaw vflag_step; + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format()); int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX; - GWN_vertbuf_data_alloc(vbo, vcount); - GWN_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); + GPU_vertbuf_data_alloc(vbo, vcount); + GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); for (int c = 0; c < 4; c++) { for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) { @@ -488,7 +488,7 @@ Gwn_Batch *ui_batch_roundbox_shadow_get(void) set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER); } } - g_ui_batch_cache.roundbox_shadow = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + g_ui_batch_cache.roundbox_shadow = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); gpu_batch_presets_register(g_ui_batch_cache.roundbox_shadow); } return g_ui_batch_cache.roundbox_shadow; @@ -513,11 +513,11 @@ void UI_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(draw_color); - immBegin(GWN_PRIM_TRIS, 3 * WIDGET_AA_JITTER); + immBegin(GPU_PRIM_TRIS, 3 * WIDGET_AA_JITTER); /* for each AA step */ for (int j = 0; j < WIDGET_AA_JITTER; j++) { @@ -556,14 +556,14 @@ void UI_draw_anti_fan(float tri_array[][2], unsigned int length, const float col GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(draw_color); /* for each AA step */ for (int j = 0; j < WIDGET_AA_JITTER; j++) { - immBegin(GWN_PRIM_TRI_FAN, length); + immBegin(GPU_PRIM_TRI_FAN, length); immVertex2f(pos, tri_array[0][0], tri_array[0][1]); immVertex2f(pos, tri_array[1][0], tri_array[1][1]); @@ -1084,7 +1084,7 @@ static void widgetbase_set_uniform_colors_ubv( #define MAX_WIDGET_PARAMETERS 11 struct { - Gwn_Batch *batch; /* Batch type */ + GPUBatch *batch; /* Batch type */ uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]; int count; bool enabled; @@ -1097,22 +1097,22 @@ void UI_widgetbase_draw_cache_flush(void) if (g_widget_base_batch.count == 0) return; - Gwn_Batch *batch = g_widget_base_batch.batch; + GPUBatch *batch = g_widget_base_batch.batch; if (g_widget_base_batch.count == 1) { /* draw single */ - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params); - GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params); + GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); + GPU_batch_draw(batch); } else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST); - GWN_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST); + GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, (float *)g_widget_base_batch.params); - GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); + GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_matrix_bind(batch->interface); - GWN_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true); - GWN_batch_program_use_end(batch); + GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true); + GPU_batch_program_use_end(batch); } g_widget_base_batch.count = 0; } @@ -1135,7 +1135,7 @@ void UI_widgetbase_draw_cache_end(void) GPU_blend(false); } -static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb) +static void draw_widgetbase_batch(GPUBatch *batch, uiWidgetBase *wtb) { wtb->uniform_params.tria1_size = wtb->tria1.size; wtb->uniform_params.tria2_size = wtb->tria2.size; @@ -1171,10 +1171,10 @@ static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb) else { float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f}; /* draw single */ - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&wtb->uniform_params); - GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&wtb->uniform_params); + GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); + GPU_batch_draw(batch); } } @@ -1228,7 +1228,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol) if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] || alpha_check) { widgetbase_set_uniform_colors_ubv(wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, alpha_check); - Gwn_Batch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type); + GPUBatch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type); draw_widgetbase_batch(roundbox_batch, wtb); } @@ -1836,7 +1836,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv((unsigned char *)wcol->item); @@ -1872,7 +1872,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b UI_widgetbase_draw_cache_flush(); GPU_blend(false); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(0.2f, 0.6f, 0.9f); @@ -2423,7 +2423,7 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r /* we draw a number of increasing size alpha quad strips */ alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2475,7 +2475,7 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir static void ui_hsv_cursor(float x, float y) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2571,13 +2571,13 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * ui_color_picker_to_rgb(0.0f, 0.0f, hsv[2], colcent, colcent + 1, colcent + 2); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBegin(GWN_PRIM_TRI_FAN, tot + 2); + immBegin(GPU_PRIM_TRI_FAN, tot + 2); immAttrib3fv(color, colcent); immVertex2f(pos, centx, centy); @@ -2598,7 +2598,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * /* fully rounded outline */ format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2682,12 +2682,12 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons } /* old below */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBegin(GWN_PRIM_TRIS, steps * 3 * 6); + immBegin(GPU_PRIM_TRIS, steps * 3 * 6); for (dx = 0.0f; dx < 0.999f; dx += color_step) { /* 0.999 = prevent float inaccuracy for steps */ const float dx_next = dx + color_step; @@ -2843,7 +2843,7 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) ui_hsv_cursor(x, y); /* outline */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ub(0, 0, 0); imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax)); @@ -2940,14 +2940,14 @@ static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol) 30 }; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_blend(true); immUniformColor4ubv(col); GPU_line_width(1.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, rect->xmin, y); immVertex2f(pos, rect->xmax, y); immEnd(); @@ -3402,11 +3402,11 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat UI_widgetbase_draw_cache_flush(); GPU_blend(false); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(bw, bw, bw); - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.9f * height); immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.5f * height); immVertex2f(pos, rect->xmin + 0.5f * width, rect->ymin + 0.9f * height); @@ -3783,7 +3783,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */ but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* make mask to draw over image */ @@ -4420,11 +4420,11 @@ static void ui_draw_popover_back_impl( /* Draw popover arrow (top/bottom) */ if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv((unsigned char *)wcol->inner); GPU_blend(true); - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); if (direction == UI_DIR_DOWN) { const float y = rect->ymax; immVertex2f(pos, cent_x - unit_half, y); @@ -4476,10 +4476,10 @@ static void draw_disk_shaded( unsigned char r_col[4]; unsigned int pos, col; - Gwn_VertFormat *format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (shaded) { - col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); } else { @@ -4487,7 +4487,7 @@ static void draw_disk_shaded( immUniformColor4ubv((unsigned char *)col1); } - immBegin(GWN_PRIM_TRI_STRIP, subd * 2); + immBegin(GPU_PRIM_TRI_STRIP, subd * 2); for (i = 0; i < subd; i++) { float a; @@ -4556,8 +4556,8 @@ void ui_draw_pie_center(uiBlock *block) } } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv((unsigned char *)btheme->tui.wcol_pie_menu.outline); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 7d9eb1181ed..3a527712367 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -1338,12 +1338,12 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) if (vertex_count == 0) return; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, vertex_count); + immBegin(GPU_PRIM_LINES, vertex_count); /* vertical lines */ if (flag & V2D_VERTICAL_LINES) { @@ -1480,15 +1480,15 @@ void UI_view2d_constant_grid_draw(View2D *v2d, float step) count_y = (v2d->cur.ymax - start_y) / step + 1; if (count_x > 0 || count_y > 0) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); float theme_color[3]; UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, count_x * 2 + count_y * 2 + 4); + immBegin(GPU_PRIM_LINES, count_x * 2 + count_y * 2 + 4); immAttrib3fv(color, theme_color); for (int i = 0; i < count_x ; start_x += step, i++) { @@ -1531,14 +1531,14 @@ void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_s vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1); vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); GPU_line_width(1.0f); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBeginAtMost(GWN_PRIM_LINES, vertex_count); + immBeginAtMost(GPU_PRIM_LINES, vertex_count); for (int level = 0; level < totlevels; ++level) { UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color); diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 14cec724168..506dec2aa3e 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -124,8 +124,8 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin return; } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff}; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -134,7 +134,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin /* this could be split into its own loop */ if (draw_type == MASK_DT_OUTLINE) { GPU_line_width(3.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(pos, point_pos); immVertex2fv(pos, handle_pos); immEnd(); @@ -154,7 +154,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin } GPU_line_width(1.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(pos, point_pos); immVertex2fv(pos, handle_pos); immEnd(); @@ -178,7 +178,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const MaskSplinePoin immUniform4fv("outlineColor", point_color); immUniformColor3fvAlpha(point_color, 0.25f); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2fv(pos, handle_pos); immEnd(); @@ -212,8 +212,8 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); immUniform1f("size", 0.7f * handle_size); @@ -251,7 +251,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline immUniformThemeColor(TH_HANDLE_VERTEX); } - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2fv(pos, feather_point); immEnd(); @@ -320,7 +320,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline else immUniformThemeColor(TH_HANDLE_VERTEX); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2fv(pos, vert); immEnd(); @@ -350,7 +350,7 @@ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f); immUniform1f("size", 12.0f); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(pos, x, y); immEnd(); @@ -371,7 +371,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r } } -static void mask_draw_array(unsigned int pos, Gwn_PrimType prim_type, const float (*points)[2], unsigned int vertex_len) +static void mask_draw_array(unsigned int pos, GPUPrimType prim_type, const float (*points)[2], unsigned int vertex_len) { immBegin(prim_type, vertex_len); for (unsigned int i = 0; i < vertex_len; ++i) { @@ -384,7 +384,7 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (* const bool is_feather, const bool is_active, const unsigned char rgb_spline[4], const char draw_type) { - const Gwn_PrimType draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GWN_PRIM_LINE_LOOP : GWN_PRIM_LINE_STRIP; + const GPUPrimType draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GPU_PRIM_LINE_LOOP : GPU_PRIM_LINE_STRIP; const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff}; unsigned char rgb_tmp[4]; SpaceClip *sc = CTX_wm_space_clip(C); @@ -402,8 +402,8 @@ static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (* } } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); switch (draw_type) { @@ -747,12 +747,12 @@ void ED_mask_draw_frames(Mask *mask, ARegion *ar, const int cfra, const int sfra unsigned int num_lines = BLI_listbase_count(&masklay->splines_shapes); if (num_lines > 0) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ub(255, 175, 0, 255); - immBegin(GWN_PRIM_LINES, 2 * num_lines); + immBegin(GPU_PRIM_LINES, 2 * num_lines); for (MaskLayerShape *masklay_shape = masklay->splines_shapes.first; masklay_shape; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index a2717e53358..99756269c1f 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1007,13 +1007,13 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd) copy_v3_v3(v2, ray_hit_best[1]); } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor(TH_TRANSFORM); GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(pos, v1); immVertex3fv(pos, v2); immEnd(); @@ -1048,7 +1048,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void GPU_matrix_push(); GPU_matrix_mul(kcd->ob->obmat); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -1059,7 +1059,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.line); GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(pos, kcd->prev.cage); immVertex3fv(pos, kcd->curr.cage); immEnd(); @@ -1069,7 +1069,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.point); GPU_point_size(11); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(pos, kcd->prev.cage); immEnd(); } @@ -1078,7 +1078,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.curpoint); GPU_point_size(9); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(pos, kcd->prev.cage); immEnd(); } @@ -1087,7 +1087,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.edge); GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(pos, kcd->curr.edge->v1->cageco); immVertex3fv(pos, kcd->curr.edge->v2->cageco); immEnd(); @@ -1096,7 +1096,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.point); GPU_point_size(11); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(pos, kcd->curr.cage); immEnd(); } @@ -1105,7 +1105,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.curpoint); GPU_point_size(9); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(pos, kcd->curr.cage); immEnd(); } @@ -1121,7 +1121,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor4ubv(kcd->colors.point_a); GPU_point_size(11); - immBeginAtMost(GWN_PRIM_POINTS, kcd->totlinehit); + immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { @@ -1136,7 +1136,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor4ubv(kcd->colors.curpoint_a); GPU_point_size(7); - immBeginAtMost(GWN_PRIM_POINTS, kcd->totlinehit); + immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { @@ -1157,7 +1157,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.line); GPU_line_width(1.0); - immBeginAtMost(GWN_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); + immBeginAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { @@ -1178,7 +1178,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.point); GPU_point_size(5.0); - immBeginAtMost(GWN_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); + immBeginAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); BLI_mempool_iternew(kcd->kverts, &iter); for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 9a58f1dcd08..95c94c146e4 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -116,13 +116,13 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a GPU_matrix_push(); GPU_matrix_mul(lcd->ob->obmat); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3ub(255, 0, 255); if (lcd->totedge > 0) { - immBegin(GWN_PRIM_LINES, lcd->totedge * 2); + immBegin(GPU_PRIM_LINES, lcd->totedge * 2); for (int i = 0; i < lcd->totedge; i++) { immVertex3fv(pos, lcd->edges[i][0]); @@ -135,7 +135,7 @@ static void ringsel_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *a if (lcd->totpoint > 0) { GPU_point_size(3.0f); - immBegin(GWN_PRIM_POINTS, lcd->totpoint); + immBegin(GPU_PRIM_POINTS, lcd->totpoint); for (int i = 0; i < lcd->totpoint; i++) { immVertex3fv(pos, lcd->points[i]); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 10d9c90aeb3..1b82e60b986 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2892,7 +2892,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) brush = &pset->brush[pset->brushtype]; if (brush) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ub(255, 255, 255, 128); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index cb8fdba0ae1..1a63bc1cd53 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -105,12 +105,12 @@ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides) float color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); - immBeginAtMost(GWN_PRIM_LINES, 8); + immBeginAtMost(GPU_PRIM_LINES, 8); /* right */ if (sides & REGION_EMBOSS_RIGHT) { @@ -262,8 +262,8 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -271,7 +271,7 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); immUniformColor4f(0.0f, 1.0f, 1.0f, alpha); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, click_rect.xmin, click_rect.ymin); immVertex2f(pos, click_rect.xmax, click_rect.ymax); immVertex2f(pos, click_rect.xmin, click_rect.ymax); @@ -295,8 +295,8 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2) float width = 0.1f * U.widget_unit; float pad = 0.2f * U.widget_unit; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_blend(true); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -500,8 +500,8 @@ void ED_region_do_draw(bContext *C, ARegion *ar) /* for debugging unneeded area redraws and partial redraw */ #if 0 GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(drand48(), drand48(), drand48(), 0.1f); immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin, @@ -2472,8 +2472,8 @@ void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(fill_color); immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1); @@ -2691,8 +2691,8 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, /* set up rect */ BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y); /* draw top box */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_METADATA_BG); immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); @@ -2716,8 +2716,8 @@ void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, /* set up box rect */ BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin); /* draw top box */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_METADATA_BG); immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); @@ -2745,8 +2745,8 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1); UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, 20); @@ -2778,12 +2778,12 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) int count_large = 1.0f / (4.0f * gridstep); if (count_fine > 0) { - GWN_vertformat_clear(format); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPU_vertformat_clear(format); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, 4 * count_fine + 4 * count_large); + immBegin(GPU_PRIM_LINES, 4 * count_fine + 4 * count_large); float theme_color[3]; UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color); @@ -2877,7 +2877,7 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect) void ED_region_cache_draw_background(const ARegion *ar) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ub(128, 128, 255, 64); immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC); @@ -2897,7 +2897,7 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_CFRAME); immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f); @@ -2911,7 +2911,7 @@ void ED_region_cache_draw_curfra_label(const int framenr, const float x, const f void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra) { if (num_segments) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ub(128, 128, 255, 128); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 41404aee9c9..7fa093106df 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -140,9 +140,9 @@ static int get_cached_work_texture(int *r_w, int *r_h) static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state) { - Gwn_VertFormat *vert_format = immVertexFormat(); - state->pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - state->texco = GWN_vertformat_attr_add(vert_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *vert_format = immVertexFormat(); + state->pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + state->texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } /* To be used before calling immDrawPixelsTex @@ -297,7 +297,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); } - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h); immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom); @@ -551,28 +551,28 @@ void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, flo delta_y = min_ff(delta_y, border->ymax - border->ymin); /* left bottom corner */ - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, border->xmin, border->ymin + delta_y); immVertex2f(pos, border->xmin, border->ymin); immVertex2f(pos, border->xmin + delta_x, border->ymin); immEnd(); /* left top corner */ - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, border->xmin, border->ymax - delta_y); immVertex2f(pos, border->xmin, border->ymax); immVertex2f(pos, border->xmin + delta_x, border->ymax); immEnd(); /* right bottom corner */ - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, border->xmax - delta_x, border->ymin); immVertex2f(pos, border->xmax, border->ymin); immVertex2f(pos, border->xmax, border->ymin + delta_y); immEnd(); /* right top corner */ - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2f(pos, border->xmax - delta_x, border->ymax); immVertex2f(pos, border->xmax, border->ymax); immVertex2f(pos, border->xmax, border->ymax - delta_y); diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 6e512d6d4df..10d72d74b22 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -99,7 +99,7 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos) } } - immBegin(GWN_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); for (i = 0; i < 5; i++) { immVertex2f(pos, points[i].x, points[i].y); @@ -107,7 +107,7 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos) immEnd(); - immBegin(GWN_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); for (i = 4; i < 8; i++) { immVertex2f(pos, points[i].x, points[i].y); @@ -180,7 +180,7 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos) } } - immBegin(GWN_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); for (i = 0; i < 5; i++) { immVertex2f(pos, points[i].x, points[i].y); @@ -188,7 +188,7 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos) immEnd(); - immBegin(GWN_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); for (i = 4; i < 8; i++) { immVertex2f(pos, points[i].x, points[i].y); @@ -323,11 +323,11 @@ static void drawscredge_corner(ScrArea *sa, int sizex, int sizey) /* Wrap up the corners with a nice embossing. */ rcti rect = sa->totrct; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); - immBeginAtMost(GWN_PRIM_LINES, 8); + immBeginAtMost(GPU_PRIM_LINES, 8); /* Right. */ immVertex2f(pos, rect.xmax, rect.ymax); @@ -386,7 +386,7 @@ static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, shor return; } - immBegin(GWN_PRIM_LINES, count); + immBegin(GPU_PRIM_LINES, count); /* right border area */ if (x2 < sizex - 1) { @@ -439,7 +439,7 @@ void ED_screen_draw_edges(wmWindow *win) ScrArea *sa; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* Note: first loop only draws if U.pixelsize > 1, skip otherwise */ @@ -477,7 +477,7 @@ void ED_screen_draw_edges(wmWindow *win) */ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_width(1); @@ -518,14 +518,14 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* splitpoint */ GPU_blend(true); immUniformColor4ub(255, 255, 255, 100); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); if (dir == 'h') { const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax; @@ -537,7 +537,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) immUniformColor4ub(0, 0, 0, 100); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, sa->totrct.xmin, y + 1); immVertex2f(pos, sa->totrct.xmax, y + 1); @@ -555,7 +555,7 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) immUniformColor4ub(0, 0, 0, 100); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x + 1, sa->totrct.ymin); immVertex2f(pos, x + 1, sa->totrct.ymax); @@ -594,7 +594,7 @@ static void screen_preview_draw_areas(const bScreen *screen, const float scale[2 const float ofs_between_areas) { const float ofs_h = ofs_between_areas * 0.5f; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(col); @@ -607,7 +607,7 @@ static void screen_preview_draw_areas(const bScreen *screen, const float scale[2 .ymax = sa->totrct.ymax * scale[1] - ofs_h }; - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immVertex2f(pos, rect.xmin, rect.ymin); immVertex2f(pos, rect.xmax, rect.ymin); immVertex2f(pos, rect.xmax, rect.ymax); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index e1de86910ff..997fe1282f9 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -680,9 +680,9 @@ static void paint_draw_tex_overlay( } /* set quad color. Colored overlay does not get blending */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (col) { immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -696,7 +696,7 @@ static void paint_draw_tex_overlay( /* draw textured quad */ immUniform1i("image", GL_TEXTURE0); - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texCoord, 0.0f, 0.0f); immVertex2f(pos, quad.xmin, quad.ymin); immAttrib2f(texCoord, 1.0f, 0.0f); @@ -769,9 +769,9 @@ static void paint_draw_cursor_overlay( GPU_matrix_translate_2f(-center[0], -center[1]); } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -782,7 +782,7 @@ static void paint_draw_cursor_overlay( /* draw textured quad */ immUniform1i("image", 0); - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texCoord, 0.0f, 0.0f); immVertex2f(pos, quad.xmin, quad.ymin); immAttrib2f(texCoord, 1.0f, 0.0f); @@ -844,7 +844,7 @@ BLI_INLINE void draw_tri_point( {co[0] + w, co[1] - w}, }; - immBegin(GWN_PRIM_LINE_LOOP, 3); + immBegin(GPU_PRIM_LINE_LOOP, 3); immVertex2fv(pos, tri[0]); immVertex2fv(pos, tri[1]); immVertex2fv(pos, tri[2]); @@ -853,7 +853,7 @@ BLI_INLINE void draw_tri_point( immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); GPU_line_width(1.0f); - immBegin(GWN_PRIM_LINE_LOOP, 3); + immBegin(GPU_PRIM_LINE_LOOP, 3); immVertex2fv(pos, tri[0]); immVertex2fv(pos, tri[1]); immVertex2fv(pos, tri[2]); @@ -888,7 +888,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); GPU_line_width(3.0f); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2fv(pos, bez->vec[0]); immVertex2fv(pos, bez->vec[1]); immVertex2fv(pos, bez->vec[2]); @@ -902,7 +902,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez else { immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); } - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(pos, bez->vec[0]); immVertex2fv(pos, bez->vec[1]); immEnd(); @@ -913,7 +913,7 @@ BLI_INLINE void draw_bezier_handle_lines(unsigned int pos, float sel_col[4], Bez else { immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f); } - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(pos, bez->vec[1]); immVertex2fv(pos, bez->vec[2]); immEnd(); @@ -930,7 +930,7 @@ static void paint_draw_curve_cursor(Brush *brush) GPU_blend(true); /* draw the bezier handles and the curve segment between the current and next point */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -961,7 +961,7 @@ static void paint_draw_curve_cursor(Brush *brush) immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); GPU_line_width(3.0f); - immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + immBegin(GPU_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { immVertex2fv(pos, v[j]); } @@ -969,7 +969,7 @@ static void paint_draw_curve_cursor(Brush *brush) immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f); GPU_line_width(1.0f); - immBegin(GWN_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); + immBegin(GPU_PRIM_LINE_STRIP, PAINT_CURVE_NUM_SEGMENTS + 1); for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) { immVertex2fv(pos, v[j]); } @@ -1118,7 +1118,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) GPU_blend(true); /* TODO: also set blend mode? */ GPU_line_smooth(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* set brush color */ diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 6276a2838f5..897a74eb497 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -419,15 +419,15 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda GPU_line_smooth(true); GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_width(4.0); immUniformColor4ub(0, 0, 0, 255); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2i(pos, x, y); immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]); immEnd(); @@ -435,7 +435,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda GPU_line_width(2.0); immUniformColor4ub(255, 255, 255, 255); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2i(pos, x, y); immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]); immEnd(); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 0ef25eb63a1..fc008213ae0 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -155,11 +155,11 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata ARegion *ar = stroke->vc.ar; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv(paint->paint_cursor_col); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x, y); immVertex2f(pos, stroke->last_mouse_position[0] + ar->winrct.xmin, @@ -181,7 +181,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) GPU_line_smooth(true); - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -194,7 +194,7 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) immUniformArray4fv("colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2); immUniform1f("dash_width", 6.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); ARegion *ar = stroke->vc.ar; diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index a0ef753e200..8fafc545fa9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -215,7 +215,7 @@ static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(cu alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN); } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3fvAlpha(brush->add_col, alpha); diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 6ebb04fafc4..e679688f887 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -211,8 +211,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) /* first backdrop strips */ y = (float)(-ACHANNEL_HEIGHT(ac)); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -326,7 +326,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) if (saction->flag & SACTION_MOVING) { immUniformColor3f(0.0f, 0.0f, 0.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, saction->timeslide, v2d->cur.ymin - EXTRA_SCROLL_PAD); immVertex2f(pos, saction->timeslide, v2d->cur.ymax); immEnd(); @@ -404,7 +404,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* iterate over pointcaches on the active object, and draw each one's range */ @@ -492,7 +492,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) immUniformColor4fv(col); if (len > 0) { - immBeginAtMost(GWN_PRIM_TRIS, len); + immBeginAtMost(GPU_PRIM_TRIS, len); /* draw a quad for each cached frame */ for (int i = sta; i <= end; i++) { diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 76450cba3cb..2aa0a3e2b9a 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -130,8 +130,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) uint keyframe_len = 0; - Gwn_VertFormat *format = immVertexFormat(); - uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* don't use totrect set, as the width stays the same @@ -215,14 +215,14 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) if (keyframe_len > 0) { /* draw keyframe markers */ format = immVertexFormat(); - pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, keyframe_len); + immBegin(GPU_PRIM_POINTS, keyframe_len); /* all same size with black outline */ immAttrib1f(size_id, 2.0f * STRIP_HEIGHT_HALF); @@ -315,8 +315,8 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) */ float y = (float) CHANNEL_FIRST; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 29bc0543426..ebdf5342172 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -80,7 +80,7 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid int x = (frame - sfra) * framelen; if (width == 1) { - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2i(pos, x, 0); immVertex2i(pos, x, height * UI_DPI_FAC); immEnd(); @@ -167,7 +167,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* track */ @@ -248,7 +248,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC); - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* solver keyframes */ @@ -290,7 +290,7 @@ static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx { int x, y; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* find window pixel coordinates of origin */ @@ -349,7 +349,7 @@ static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int /* draw boundary border for frame if stabilization is enabled */ if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* Exclusive OR allows to get orig value when second operand is 0, * and negative of orig value when second operand is 1. */ @@ -452,7 +452,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin i++; } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -463,7 +463,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((b - a - 1) >= 1) { GPU_point_size(5.0f); - immBegin(GWN_PRIM_POINTS, b - a - 1); + immBegin(GPU_PRIM_POINTS, b - a - 1); for (i = a; i < b; i++) { if (i != curindex) { @@ -478,7 +478,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((b - a) >= 2) { GPU_line_width(3.0f); - immBegin(GWN_PRIM_LINE_STRIP, b - a); + immBegin(GPU_PRIM_LINE_STRIP, b - a); for (i = a; i < b; i++) { immVertex2f(pos, path[i][0], path[i][1]); @@ -494,7 +494,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((curindex - a) >= 1) { immUniformThemeColor(TH_PATH_BEFORE); - immBegin(GWN_PRIM_POINTS, curindex - a); + immBegin(GPU_PRIM_POINTS, curindex - a); for (i = a; i < curindex; i++) { immVertex2f(pos, path[i][0], path[i][1]); @@ -506,7 +506,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((b - curindex - 1) >= 1) { immUniformThemeColor(TH_PATH_AFTER); - immBegin(GWN_PRIM_POINTS, b - curindex - 1); + immBegin(GPU_PRIM_POINTS, b - curindex - 1); for (i = curindex + 1; i < b; i++) { immVertex2f(pos, path[i][0], path[i][1]); @@ -521,7 +521,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((curindex - a + 1) >= 2) { immUniformThemeColor(TH_PATH_BEFORE); - immBegin(GWN_PRIM_LINE_STRIP, curindex - a + 1); + immBegin(GPU_PRIM_LINE_STRIP, curindex - a + 1); for (i = a; i <= curindex; i++) { immVertex2f(pos, path[i][0], path[i][1]); @@ -533,7 +533,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin if ((b - curindex) >= 2) { immUniformThemeColor(TH_PATH_AFTER); - immBegin(GWN_PRIM_LINE_STRIP, b - curindex); + immBegin(GPU_PRIM_LINE_STRIP, b - curindex); for (i = curindex; i < b; i++) { immVertex2f(pos, path[i][0], path[i][1]); @@ -579,12 +579,12 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT { GPU_point_size(tiny ? 3.0f : 4.0f); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(position, pos[0], pos[1]); immEnd(); } else { - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(position, pos[0] + px[0] * 2, pos[1]); immVertex2f(position, pos[0] + px[0] * 8, pos[1]); @@ -607,7 +607,7 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT GPU_matrix_translate_2fv(marker_pos); if (sc->flag & SC_SHOW_MARKER_PATTERN) { - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2fv(position, marker->pattern_corners[0]); immVertex2fv(position, marker->pattern_corners[1]); immVertex2fv(position, marker->pattern_corners[2]); @@ -705,14 +705,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra immUniform1f("dash_factor", 2.0f); /* Solid "line" */ - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(shdr_pos, pos[0], pos[1]); immEnd(); } else { immUniform1f("dash_factor", 2.0f); /* Solid line */ - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(shdr_pos, pos[0] + px[0] * 3, pos[1]); immVertex2f(shdr_pos, pos[0] + px[0] * 7, pos[1]); @@ -735,7 +735,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GL_XOR); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_pos, pos); immVertex2fv(shdr_pos, marker_pos); immEnd(); @@ -783,7 +783,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2fv(shdr_pos, marker->pattern_corners[0]); immVertex2fv(shdr_pos, marker->pattern_corners[1]); immVertex2fv(shdr_pos, marker->pattern_corners[2]); @@ -805,7 +805,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra /* Restore default shader */ immUnbindProgram(); - const uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); BLI_assert(pos == shdr_pos); UNUSED_VARS_NDEBUG(pos); @@ -857,7 +857,7 @@ static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int tdy += px[1]; } - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immVertex2f(pos, x, y); immVertex2f(pos, x - tdx, y); immVertex2f(pos, x, y + tdy); @@ -935,7 +935,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo GPU_line_width(outline ? 3.0f : 1.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, 0.0f, 0.0f); immVertex2fv(pos, tilt_ctrl); immEnd(); @@ -1144,15 +1144,15 @@ static void draw_plane_marker_image(Scene *scene, GPU_matrix_push(); GPU_matrix_mul(gl_matrix); - Gwn_VertFormat *imm_format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *imm_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texCoord = GPU_vertformat_attr_add(imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity); immUniform1i("image", 0); - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texCoord, 0.0f, 0.0f); immVertex2f(pos, 0.0f, 0.0f); @@ -1206,7 +1206,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane } if (draw_plane_quad || is_selected_track) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -1239,7 +1239,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane } /* Draw rectangle itself. */ - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2fv(shdr_pos, plane_marker->corners[0]); immVertex2fv(shdr_pos, plane_marker->corners[1]); immVertex2fv(shdr_pos, plane_marker->corners[2]); @@ -1252,7 +1252,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane immUniformColor3f(1.0f, 0.0f, 0.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point); immVertex2fv(shdr_pos, plane_marker->corners[0]); @@ -1262,7 +1262,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane immUniformColor3f(0.0f, 1.0f, 0.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point); immVertex2fv(shdr_pos, plane_marker->corners[0]); @@ -1414,7 +1414,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie } } - uint position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint position = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1519,7 +1519,7 @@ static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, Movie immUniformColor3f(1.0f, 0.0f, 0.0f); } - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); if (undistort) { immVertex2f(position, pos[0] / width, pos[1] / (height * aspy)); @@ -1598,7 +1598,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, GPU_matrix_mul(sc->stabmat); GPU_matrix_scale_2f(width, height); - uint position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint position = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1675,7 +1675,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, immUniformColor3f(1.0f, 0.0f, 0.0f); for (i = 0; i <= n; i++) { - immBegin(GWN_PRIM_LINE_STRIP, n + 1); + immBegin(GPU_PRIM_LINE_STRIP, n + 1); for (j = 0; j <= n; j++) { immVertex2fv(position, grid[i][j]); @@ -1685,7 +1685,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } for (j = 0; j <= n; j++) { - immBegin(GWN_PRIM_LINE_STRIP, n + 1); + immBegin(GPU_PRIM_LINE_STRIP, n + 1); for (i = 0; i <= n; i++) { immVertex2fv(position, grid[i][j]); @@ -1743,7 +1743,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, sub_v2_v2v2(dpos, npos, pos); mul_v2_fl(dpos, 1.0f / steps); - immBegin(GWN_PRIM_LINE_STRIP, steps + 1); + immBegin(GPU_PRIM_LINE_STRIP, steps + 1); for (j = 0; j <= steps; j++) { BKE_tracking_distort_v2(tracking, pos, tpos); @@ -1756,7 +1756,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } } else if (stroke->totpoints == 1) { - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(position, stroke->points[0].x + offsx, stroke->points[0].y + offsy); immEnd(); } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 0bc9c74cd8c..cc8541d9fd7 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -91,11 +91,11 @@ static void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, immUniformColor4fv(col); if (is_point) { - immBeginAtMost(GWN_PRIM_POINTS, 1); + immBeginAtMost(GPU_PRIM_POINTS, 1); } else { /* Graph can be composed of smaller segments, if any marker is disabled */ - immBeginAtMost(GWN_PRIM_LINE_STRIP, track->markersnr); + immBeginAtMost(GPU_PRIM_LINE_STRIP, track->markersnr); } } @@ -237,11 +237,11 @@ static void tracking_error_segment_start_cb(void *userdata, MovieTrackingTrack * immUniformColor4fv(col); if (is_point) { /* This probably never happens here, but just in case... */ - immBeginAtMost(GWN_PRIM_POINTS, 1); + immBeginAtMost(GPU_PRIM_POINTS, 1); } else { /* Graph can be composed of smaller segments, if any marker is disabled */ - immBeginAtMost(GWN_PRIM_LINE_STRIP, track->markersnr); + immBeginAtMost(GPU_PRIM_LINE_STRIP, track->markersnr); } } } @@ -300,7 +300,7 @@ static void draw_frame_curves(SpaceClip *sc, unsigned int pos) } if (!lines) { - immBeginAtMost(GWN_PRIM_LINE_STRIP, reconstruction->camnr); + immBeginAtMost(GPU_PRIM_LINE_STRIP, reconstruction->camnr); lines = 1; } @@ -328,7 +328,7 @@ void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene) UI_view2d_grid_free(grid); if (clip) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_point_size(3.0f); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index c94853d4233..19d321a53bf 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -273,7 +273,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f); @@ -287,7 +287,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) /* thin lines where the actual frames are */ GPU_line_width(1.0f); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, (float)SFRA, v2d->cur.ymin); immVertex2f(pos, (float)SFRA, v2d->cur.ymax); immVertex2f(pos, (float)EFRA, v2d->cur.ymin); diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 0ffbe451042..789194c21b9 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -158,8 +158,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha int offl = 0, offc = 0; int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN}; int pen[2]; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); xy[1] += tvc->lheight / 6; console_cursor_wrap_offset(sc->prompt, tvc->console_width, &offl, &offc, NULL); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 42ad34b659b..4a71afbcf4a 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -402,8 +402,8 @@ static void file_draw_preview( /* border */ if (use_dropshadow) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f); @@ -466,7 +466,7 @@ static void draw_background(FileLayout *layout, View2D *v2d) int i; int sy; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, -7); @@ -503,12 +503,12 @@ static void draw_dividers(FileLayout *layout, View2D *v2d) v1[1] = v2d->cur.ymax - layout->tile_border_y; v2[1] = v2d->cur.ymin; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, vertex_len); + immBegin(GPU_PRIM_LINES, vertex_len); sx = (int)v2d->tot.xmin; while (sx < v2d->cur.xmax) { diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 2b2d404168f..ad9af8cb948 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -86,7 +86,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d) const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur); int i; - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_line_width(1.0f); @@ -103,7 +103,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d) /* draw two black lines showing the standard reference levels */ - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min); immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min); @@ -122,7 +122,7 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d) /* for now, point color is fixed, and is white */ immUniformColor3f(1.0f, 1.0f, 1.0f); - immBeginAtMost(GWN_PRIM_POINTS, env->totvert * 2); + immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2); for (i = 0, fed = env->data; i < env->totvert; i++, fed++) { /* only draw if visible @@ -178,7 +178,7 @@ static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, boo set_fcurve_vertex_color(fcu, sel); - immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert); + immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert); BezTriple *bezt = fcu->bezt; for (int i = 0; i < fcu->totvert; i++, bezt++) { @@ -230,7 +230,7 @@ static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f); immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */ - immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert * 2); + immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert * 2); BezTriple *bezt = fcu->bezt; BezTriple *prevbezt = NULL; @@ -286,7 +286,7 @@ static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool * - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users) */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_blend(true); GPU_enable_program_point_size(); @@ -330,12 +330,12 @@ static void draw_fcurve_handles(SpaceIpo *sipo, FCurve *fcu) { int sel, b; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBeginAtMost(GWN_PRIM_LINES, 4 * 2 * fcu->totvert); + immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert); /* slightly hacky, but we want to draw unselected points before selected ones * so that selected points are clearly visible @@ -427,7 +427,7 @@ static void draw_fcurve_sample_control(float x, float y, float xscale, float ysc GPU_matrix_scale_2f(1.0f / xscale * hsize, 1.0f / yscale * hsize); /* draw X shape */ - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, -0.7f, -0.7f); immVertex2f(pos, +0.7f, +0.7f); @@ -459,7 +459,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu) if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) GPU_line_smooth(true); GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT); @@ -551,7 +551,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d n = (etime - stime) / samplefreq + 0.5f; if (n > 0) { - immBegin(GWN_PRIM_LINE_STRIP, (n + 1)); + immBegin(GPU_PRIM_LINE_STRIP, (n + 1)); for (i = 0; i <= n; i++) { float ctime = stime + i * samplefreq; @@ -590,7 +590,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie GPU_matrix_scale_2f(1.0f, unit_scale); GPU_matrix_translate_2f(0.0f, offset); - immBegin(GWN_PRIM_LINE_STRIP, count); + immBegin(GPU_PRIM_LINE_STRIP, count); /* extrapolate to left? - left-side of view comes before first keyframe? */ if (prevfpt->vec[0] > v2d->cur.xmin) { @@ -687,7 +687,7 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 /* For now, this assumes the worst case scenario, where all the keyframes have * bezier interpolation, and are drawn at full res. * This is tricky to optimize, but maybe can be improved at some point... */ - immBeginAtMost(GWN_PRIM_LINE_STRIP, (b * 32 + 3)); + immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3)); /* extrapolate to left? */ if (prevbezt->vec[1][0] > v2d->cur.xmin) { @@ -849,7 +849,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) //if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0) // return; - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); float viewport_size[4]; @@ -874,7 +874,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) /* draw 1-1 line, stretching just past the screen limits * NOTE: we need to scale the y-values to be valid for the units */ - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); t = v2d->cur.xmin; immVertex2f(shdr_pos, t, (t + offset) * unitfac); @@ -900,7 +900,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) immUniform1f("dash_width", 10.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2); + immBegin(GPU_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2); /* x-axis lookup */ co[0] = x; @@ -926,7 +926,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) immUnbindProgram(); - /* GWN_PRIM_POINTS do not survive dashed line geometry shader... */ + /* GPU_PRIM_POINTS do not survive dashed line geometry shader... */ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* x marks the spot .................................................... */ @@ -934,7 +934,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) immUniformColor3f(0.9f, 0.9f, 0.9f); GPU_point_size(7.0); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(shdr_pos, x, y); immEnd(); @@ -942,7 +942,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) immUniformColor3f(0.9f, 0.0f, 0.0f); GPU_point_size(3.0); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex2f(shdr_pos, x, y); immEnd(); } @@ -969,7 +969,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar) } GPU_blend(true); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -1055,7 +1055,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } GPU_blend(true); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 699dc29ff47..fa57df0393a 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -279,7 +279,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar) UI_view2d_grid_free(grid); if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -292,7 +292,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar) GPU_blend(true); GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, v2d->cur.xmin, y); immVertex2f(pos, v2d->cur.xmax, y); immEnd(); @@ -310,7 +310,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar) GPU_blend(true); GPU_line_width(2.0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x, v2d->cur.ymin); immVertex2f(pos, x, v2d->cur.ymax); immEnd(); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index ff90e59540e..4cbe25462af 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -127,7 +127,7 @@ static void draw_render_info(const bContext *C, (int)(-rd->border.ymin * rd->ysch * rd->size * 0.01f)); } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_FACE_SELECT); @@ -174,7 +174,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* noisy, high contrast make impossible to read if lower alpha is used. */ @@ -330,7 +330,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d BLI_rcti_init(&color_rect, dx, dx + (1.5f * UI_UNIT_X), 0.15f * UI_UNIT_Y, 0.85f * UI_UNIT_Y); /* BLF uses immediate mode too, so we must reset our vertex format */ - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); if (channels == 4) { @@ -367,7 +367,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, bool color_manage, bool use_d immUnbindProgram(); /* draw outline */ - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ub(128, 128, 128); imm_draw_box_wire_2d(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); @@ -573,8 +573,8 @@ void draw_image_sample_line(SpaceImage *sima) if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) { Histogram *hist = &sima->sample_line_hist; - Gwn_VertFormat *format = immVertexFormat(); - uint shdr_dashed_pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint shdr_dashed_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -586,7 +586,7 @@ void draw_image_sample_line(SpaceImage *sima) immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_dashed_pos, hist->co[0]); immVertex2fv(shdr_dashed_pos, hist->co[1]); immEnd(); @@ -779,7 +779,7 @@ void draw_image_cache(const bContext *C, ARegion *ar) /* Draw current frame. */ x = (cfra - sfra) / (efra - sfra + 1) * ar->winx; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_CFRAME); immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC); diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 5c1b23e140c..c94aaf6e861 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -85,8 +85,8 @@ static void console_draw_sel(const char *str, const int sel[2], const int xy[2], GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv(bg_sel); @@ -191,8 +191,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str cdc->sel[1] = str_len - sel_orig[0]; if (bg) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv(bg); @@ -242,8 +242,8 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str else { /* simple, no wrap */ if (bg) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv(bg); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 5b68c7b6bb7..7dd8c7f2eed 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -120,8 +120,8 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa nla_action_get_color(adt, act, color); color[3] *= 2.5f; - Gwn_VertFormat *format = immVertexFormat(); - uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -142,13 +142,13 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa if (key_len > 0) { format = immVertexFormat(); - pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint size_id = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); - uint color_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - uint outline_color_id = GWN_vertformat_attr_add(format, "outlineColor", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); - immBegin(GWN_PRIM_POINTS, key_len); + immBegin(GPU_PRIM_POINTS, key_len); /* - disregard the selection status of keyframes so they draw a certain way * - size is 6.0f which is smaller than the editable keyframes, so that there is a distinction @@ -177,7 +177,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax if (ELEM(NULL, act, act->markers.first)) return; - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (dashed) { immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -194,7 +194,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax } immUniformThemeColorShade(TH_STRIP_SELECT, shade); - immBeginAtMost(GWN_PRIM_LINES, BLI_listbase_count(&act->markers) * 2); + immBeginAtMost(GPU_PRIM_LINES, BLI_listbase_count(&act->markers) * 2); for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) { if ((marker->frame > strip->actstart) && (marker->frame < strip->actend)) { float frame = nlastrip_get_frame(strip, marker->frame, NLATIME_CONVERT_MAP); @@ -318,7 +318,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns /* plot the curve (over the strip's main region) */ if (fcu) { - immBegin(GWN_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1)); + immBegin(GPU_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1)); /* sample at 1 frame intervals, and draw * - min y-val is yminc, max is y-maxc, so clamp in those regions @@ -335,7 +335,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns else { /* use blend in/out values only if both aren't zero */ if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) { - immBeginAtMost(GWN_PRIM_LINE_STRIP, 4); + immBeginAtMost(GPU_PRIM_LINE_STRIP, 4); /* start of strip - if no blendin, start straight at 1, otherwise from 0 to 1 over blendin frames */ if (IS_EQF(strip->blendin, 0.0f) == 0) { @@ -366,7 +366,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns static uint nla_draw_use_dashed_outlines(float color[4], bool muted) { /* Note that we use dashed shader here, and make it draw solid lines if not muted... */ - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); float viewport_size[4]; @@ -403,7 +403,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri /* get color of strip */ nla_strip_get_color_inside(adt, strip, color); - shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* draw extrapolation info first (as backdrop) @@ -456,7 +456,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri UI_draw_roundbox_shade_x(true, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1, color); /* restore current vertex format & program (roundbox trashes it) */ - shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); } else { @@ -518,7 +518,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri /* only draw lines for whole-numbered repeats, starting from the first full-repeat * up to the last full repeat (but not if it lies on the end of the strip) */ - immBeginAtMost(GWN_PRIM_LINES, 2 * floorf(strip->repeat)); + immBeginAtMost(GPU_PRIM_LINES, 2 * floorf(strip->repeat)); for (int i = 1; i < strip->repeat; i++) { float repeatPos = strip->start + (repeatLen * i); @@ -534,7 +534,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) { const float y = (ymaxc - yminc) * 0.5f + yminc; - immBeginAtMost(GWN_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */ + immBeginAtMost(GPU_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */ /* only draw first-level of child-strips, but don't draw any lines on the endpoints */ for (NlaStrip *cs = strip->strips.first; cs; cs = cs->next) { @@ -706,7 +706,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) { AnimData *adt = ale->adt; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* just draw a semi-shaded rect spanning the width of the viewable area if there's data, @@ -729,7 +729,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) /* white base-lines */ GPU_line_width(2.0f); immUniformColor4f(1.0f, 1.0f, 1.0f, 0.3f); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP); immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP); immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP); @@ -739,7 +739,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) /* black top-lines */ GPU_line_width(1.0f); immUniformColor3f(0.0f, 0.0f, 0.0f); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, v2d->cur.xmin, yminc + NLACHANNEL_SKIP); immVertex2f(pos, v2d->cur.xmax, yminc + NLACHANNEL_SKIP); immVertex2f(pos, v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index dfb85d3c8a4..10532f3ac7d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2184,14 +2184,14 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo const float cy = y + snode->zoom * backdropHeight * node->custom4; const float cross_size = 12 * U.pixelsize; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(1.0f, 1.0f, 1.0f); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, cx - cross_size, cy - cross_size); immVertex2f(pos, cx + cross_size, cy + cross_size); immVertex2f(pos, cx + cross_size, cy - cross_size); @@ -2229,14 +2229,14 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom; y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(1.0f, 1.0f, 1.0f); - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x2, y2); immVertex2f(pos, x3, y3); @@ -2273,14 +2273,14 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop y3 = cy - (-sine * -halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom; y4 = cy - (-sine * halveBoxWidth + cosine * -halveBoxHeight) * snode->zoom; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(1.0f, 1.0f, 1.0f); - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x2, y2); immVertex2f(pos, x3, y3); @@ -3267,7 +3267,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b y + snode->zoom * viewer_border->ymin * ibuf->y, y + snode->zoom * viewer_border->ymax * ibuf->y); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_ACTIVE); @@ -3392,50 +3392,50 @@ static float arrow_verts[3][2] = {{-1.0f, 1.0f}, {0.0f, 0.0f}, {-1.0f, -1.0f}}; static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.7071f, -0.7071f}}; struct { - Gwn_Batch *batch; /* for batching line together */ - Gwn_Batch *batch_single; /* for single line */ - Gwn_VertBuf *inst_vbo; + GPUBatch *batch; /* for batching line together */ + GPUBatch *batch_single; /* for single line */ + GPUVertBuf *inst_vbo; unsigned int p0_id, p1_id, p2_id, p3_id; unsigned int colid_id; - Gwn_VertBufRaw p0_step, p1_step, p2_step, p3_step; - Gwn_VertBufRaw colid_step; + GPUVertBufRaw p0_step, p1_step, p2_step, p3_step; + GPUVertBufRaw colid_step; unsigned int count; bool enabled; } g_batch_link = {0}; static void nodelink_batch_reset(void) { - GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step); - GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step); - GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step); - GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step); - GWN_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step); + GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p0_id, &g_batch_link.p0_step); + GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p1_id, &g_batch_link.p1_step); + GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p2_id, &g_batch_link.p2_step); + GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.p3_id, &g_batch_link.p3_step); + GPU_vertbuf_attr_get_raw_data(g_batch_link.inst_vbo, g_batch_link.colid_id, &g_batch_link.colid_step); g_batch_link.count = 0; } static void set_nodelink_vertex( - Gwn_VertBuf *vbo, + GPUVertBuf *vbo, unsigned int uv_id, unsigned int pos_id, unsigned int exp_id, unsigned int v, const unsigned char uv[2], const float pos[2], const float exp[2]) { - GWN_vertbuf_attr_set(vbo, uv_id, v, uv); - GWN_vertbuf_attr_set(vbo, pos_id, v, pos); - GWN_vertbuf_attr_set(vbo, exp_id, v, exp); + GPU_vertbuf_attr_set(vbo, uv_id, v, uv); + GPU_vertbuf_attr_set(vbo, pos_id, v, pos); + GPU_vertbuf_attr_set(vbo, exp_id, v, exp); } static void nodelink_batch_init(void) { - Gwn_VertFormat format = {0}; - uint uv_id = GWN_vertformat_attr_add(&format, "uv", GWN_COMP_U8, 2, GWN_FETCH_INT_TO_FLOAT_UNIT); - uint pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint expand_id = GWN_vertformat_attr_add(&format, "expand", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STATIC); + GPUVertFormat format = {0}; + uint uv_id = GPU_vertformat_attr_add(&format, "uv", GPU_COMP_U8, 2, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint expand_id = GPU_vertformat_attr_add(&format, "expand", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); int vcount = LINK_RESOL * 2; /* curve */ vcount += 2; /* restart strip */ vcount += 3 * 2; /* arrow */ vcount *= 2; /* shadow */ vcount += 2; /* restart strip */ - GWN_vertbuf_data_alloc(vbo, vcount); + GPU_vertbuf_data_alloc(vbo, vcount); int v = 0; for (int k = 0; k < 2; ++k) { @@ -3479,23 +3479,23 @@ static void nodelink_batch_init(void) set_nodelink_vertex(vbo, uv_id, pos_id, expand_id, v++, uv, pos, exp); } - g_batch_link.batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); + g_batch_link.batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); gpu_batch_presets_register(g_batch_link.batch); - g_batch_link.batch_single = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, 0); + g_batch_link.batch_single = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, 0); gpu_batch_presets_register(g_batch_link.batch_single); /* Instances data */ - Gwn_VertFormat format_inst = {0}; - g_batch_link.p0_id = GWN_vertformat_attr_add(&format_inst, "P0", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - g_batch_link.p1_id = GWN_vertformat_attr_add(&format_inst, "P1", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - g_batch_link.p2_id = GWN_vertformat_attr_add(&format_inst, "P2", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - g_batch_link.p3_id = GWN_vertformat_attr_add(&format_inst, "P3", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - g_batch_link.colid_id = GWN_vertformat_attr_add(&format_inst, "colid_doarrow", GWN_COMP_U8, 4, GWN_FETCH_INT); - g_batch_link.inst_vbo = GWN_vertbuf_create_with_format_ex(&format_inst, GWN_USAGE_STREAM); - GWN_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */ + GPUVertFormat format_inst = {0}; + g_batch_link.p0_id = GPU_vertformat_attr_add(&format_inst, "P0", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + g_batch_link.p1_id = GPU_vertformat_attr_add(&format_inst, "P1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + g_batch_link.p2_id = GPU_vertformat_attr_add(&format_inst, "P2", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + g_batch_link.p3_id = GPU_vertformat_attr_add(&format_inst, "P3", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + g_batch_link.colid_id = GPU_vertformat_attr_add(&format_inst, "colid_doarrow", GPU_COMP_U8, 4, GPU_FETCH_INT); + g_batch_link.inst_vbo = GPU_vertbuf_create_with_format_ex(&format_inst, GPU_USAGE_STREAM); + GPU_vertbuf_data_alloc(g_batch_link.inst_vbo, NODELINK_GROUP_SIZE); /* Alloc max count but only draw the range we need. */ - GWN_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true); + GPU_batch_instbuf_set(g_batch_link.batch, g_batch_link.inst_vbo, true); nodelink_batch_reset(); } @@ -3526,14 +3526,14 @@ static void nodelink_batch_draw(SpaceNode *snode) UI_GetThemeColor4fv(TH_EDGE_SELECT, colors[nodelink_get_color_id(TH_EDGE_SELECT)]); UI_GetThemeColor4fv(TH_REDALERT, colors[nodelink_get_color_id(TH_REDALERT)]); - GWN_vertbuf_vertex_count_set(g_batch_link.inst_vbo, g_batch_link.count); - GWN_vertbuf_use(g_batch_link.inst_vbo); /* force update. */ + GPU_vertbuf_vertex_count_set(g_batch_link.inst_vbo, g_batch_link.count); + GPU_vertbuf_use(g_batch_link.inst_vbo); /* force update. */ - GWN_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST); - GWN_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors); - GWN_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH); - GWN_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE); - GWN_batch_draw(g_batch_link.batch); + GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST); + GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors); + GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH); + GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE); + GPU_batch_draw(g_batch_link.batch); nodelink_batch_reset(); @@ -3562,11 +3562,11 @@ static void nodelink_batch_add_link( BLI_assert(ELEM(th_col3, TH_WIRE, -1)); g_batch_link.count++; - copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p0_step), p0); - copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p1_step), p1); - copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p2_step), p2); - copy_v2_v2(GWN_vertbuf_raw_step(&g_batch_link.p3_step), p3); - char *colid = GWN_vertbuf_raw_step(&g_batch_link.colid_step); + copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p0_step), p0); + copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p1_step), p1); + copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p2_step), p2); + copy_v2_v2(GPU_vertbuf_raw_step(&g_batch_link.p3_step), p3); + char *colid = GPU_vertbuf_raw_step(&g_batch_link.colid_step); colid[0] = nodelink_get_color_id(th_col1); colid[1] = nodelink_get_color_id(th_col2); colid[2] = nodelink_get_color_id(th_col3); @@ -3604,14 +3604,14 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, UI_GetThemeColor4fv(th_col1, colors[1]); UI_GetThemeColor4fv(th_col2, colors[2]); - Gwn_Batch *batch = g_batch_link.batch_single; - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK); - GWN_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec); - GWN_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors); - GWN_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH); - GWN_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE); - GWN_batch_uniform_1i(batch, "doArrow", drawarrow); - GWN_batch_draw(batch); + GPUBatch *batch = g_batch_link.batch_single; + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK); + GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec); + GPU_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors); + GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH); + GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE); + GPU_batch_uniform_1i(batch, "doArrow", drawarrow); + GPU_batch_draw(batch); } } } @@ -3660,7 +3660,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos) { - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); if (border & (NODE_LEFT | NODE_RIGHT)) { immVertex2f(pos, cent[0], v2d->cur.ymin); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 6976edce563..4b3a3abc642 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -648,8 +648,8 @@ static void node_draw_preview_background(float tile, rctf *rect) { float x, y; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -721,7 +721,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) GPU_blend(false); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_BACK, -15, +100); imm_draw_box_wire_2d(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax); @@ -771,9 +771,9 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode * float scale; UI_view2d_scale_get(v2d, &scale, NULL); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPU_blend(true); GPU_enable_program_point_size(); @@ -788,7 +788,7 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode * immUniform1f("outlineWidth", 1.0f); immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 0.6f); - immBeginAtMost(GWN_PRIM_POINTS, total_input_len + total_output_len); + immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len); } /* socket inputs */ @@ -832,7 +832,7 @@ void node_draw_sockets(View2D *v2d, const bContext *C, bNodeTree *ntree, bNode * immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f); immUniform1f("outlineWidth", 1.5f); - immBegin(GWN_PRIM_POINTS, selected_input_len + selected_output_len); + immBegin(GPU_PRIM_POINTS, selected_input_len + selected_output_len); if (selected_input_len) { /* socket inputs */ @@ -1102,13 +1102,13 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b } /* scale widget thing */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShade(color_id, -10); dx = 10.0f; - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, rct->xmax - dx, centy - 4.0f); immVertex2f(pos, rct->xmax - dx, centy + 4.0f); @@ -1119,7 +1119,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b immUniformThemeColorShade(color_id, 30); dx -= snode->aspect; - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, rct->xmax - dx, centy - 4.0f); immVertex2f(pos, rct->xmax - dx, centy + 4.0f); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 8a8f4715ea3..783a03f3993 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -742,11 +742,11 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex) GPU_line_width(1.0f); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_BACK, -15, -200); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, sizex, v2d->cur.ymax); immVertex2f(pos, sizex, miny); @@ -1739,8 +1739,8 @@ static void outliner_draw_tree_element( /* divider */ { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); unsigned char col[4]; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1797,7 +1797,7 @@ static void outliner_draw_tree_element_floating( const TreeElement *te_insert = te_floating->drag_data->insert_handle; const int line_width = 2; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); int coord_y = te_insert->ys; int coord_x = te_insert->xs; float col[4]; @@ -1818,7 +1818,7 @@ static void outliner_draw_tree_element_floating( immUniformColor4fv(col); GPU_line_width(line_width); - immBegin(GWN_PRIM_LINE_STRIP, 2); + immBegin(GPU_PRIM_LINE_STRIP, 2); immVertex2f(pos, coord_x, coord_y); immVertex2f(pos, ar->v2d.cur.xmax, coord_y); immEnd(); @@ -1827,7 +1827,7 @@ static void outliner_draw_tree_element_floating( BLI_assert(te_floating->drag_data->insert_type == TE_INSERT_INTO); immUniformColor3fvAlpha(col, col[3] * 0.5f); - immBegin(GWN_PRIM_TRI_STRIP, 4); + immBegin(GPU_PRIM_TRI_STRIP, 4); immVertex2f(pos, coord_x, coord_y + UI_UNIT_Y); immVertex2f(pos, coord_x, coord_y); immVertex2f(pos, ar->v2d.cur.xmax, coord_y + UI_UNIT_Y); @@ -1901,8 +1901,8 @@ static void outliner_draw_hierarchy_lines_recursive( static void outliner_draw_hierarchy_lines(SpaceOops *soops, ListBase *lb, int startx, int *starty) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); unsigned char col[4]; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1924,8 +1924,8 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase * /* selection status */ if (TSELEM_OPEN(tselem, soops)) { if (tselem->type == TSE_RNA_STRUCT) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immThemeColorShadeAlpha(TH_BACK, -15, -200); immRecti(pos, 0, *starty + 1, (int)ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1); @@ -1937,12 +1937,12 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase * if (TSELEM_OPEN(tselem, soops)) { outliner_draw_struct_marks(ar, soops, &te->subtree, starty); if (tselem->type == TSE_RNA_STRUCT) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immThemeColorShadeAlpha(TH_BACK, -15, -200); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y); immVertex2f(pos, ar->v2d.cur.xmax, (float)*starty + UI_UNIT_Y); immEnd(); @@ -2007,8 +2007,8 @@ static void outliner_draw_highlights(ARegion *ar, SpaceOops *soops, int startx, col_searchmatch[3] = 0.5f; GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); outliner_draw_highlights_recursive( pos, ar, soops, &soops->tree, col_selection, col_highlight, col_searchmatch, @@ -2082,8 +2082,8 @@ static void outliner_back(ARegion *ar) ystart = (int)ar->v2d.tot.ymax; ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShade(TH_BACK, 6); @@ -2093,7 +2093,7 @@ static void outliner_back(ARegion *ar) int tot = (int)floor(ystart - ar->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y); if (tot > 0) { - immBegin(GWN_PRIM_TRIS, 6 * tot); + immBegin(GPU_PRIM_TRIS, 6 * tot); while (tot--) { y1 -= 2 * UI_UNIT_Y; y2 = y1 + UI_UNIT_Y; @@ -2114,10 +2114,10 @@ static void outliner_draw_restrictcols(ARegion *ar) { GPU_line_width(1.0f); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_BACK, -15, -200); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymax); immVertex2i(pos, (int)(ar->v2d.cur.xmax - OL_TOG_HIDEX), (int)ar->v2d.cur.ymin); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 204559ebf4f..47059d65945 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -267,7 +267,7 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s GPU_blend(true); - immBegin(GWN_PRIM_TRI_STRIP, length * 2); + immBegin(GPU_PRIM_TRI_STRIP, length * 2); for (i = 0; i < length; i++) { float sampleoffset = startsample + ((x1_offset - x1) / stepsize + i) * samplestep; @@ -343,7 +343,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, col[3] = 196; /* alpha, used for all meta children */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -457,7 +457,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla immUniformColor4ub(0, 0, 0, 50); } - immBegin(GWN_PRIM_TRIS, 3); + immBegin(GPU_PRIM_TRIS, 3); immVertex2fv(pos, v1); immVertex2fv(pos, v2); immVertex2fv(pos, v3); @@ -719,7 +719,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp; y2 = seq->machine + SEQ_STRIP_OFSTOP; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -781,7 +781,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg if (seq->flag & SEQ_LOCK) { GPU_blend(true); - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES); immUniform4f("color1", 1.0f, 1.0f, 1.0f, 0.125f); @@ -799,7 +799,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg if (!BKE_sequence_is_valid_check(seq)) { GPU_blend(true); - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES); immUniform4f("color1", 1.0f, 0.0f, 0.0f, 1.0f); @@ -834,7 +834,7 @@ static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, AReg drawmeta_contents(scene, seq, x1, y1, x2, y2); } - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* TODO: add back stippled line for muted strips? */ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1040,7 +1040,7 @@ static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, cons GPU_line_width(1.0f); /* border */ - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -1230,9 +1230,9 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* Format needs to be created prior to any immBindProgram call. * Do it here because OCIO binds it's own shader. */ - Gwn_VertFormat *imm_format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *imm_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texCoord = GPU_vertformat_attr_add(imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (scope) { IMB_freeImBuf(ibuf); @@ -1331,7 +1331,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq immUniform1i("image", 0); } - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); if (draw_overlay) { if (sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) { @@ -1514,7 +1514,7 @@ static void draw_seq_backdrop(View2D *v2d) { int i; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* darker gray overlay over the view backdrop */ @@ -1541,7 +1541,7 @@ static void draw_seq_backdrop(View2D *v2d) i = max_ii(1, ((int)v2d->cur.ymin) - 1); int line_len = (int)v2d->cur.ymax - i + 1; immUniformThemeColor(TH_GRID); - immBegin(GWN_PRIM_LINES, line_len * 2); + immBegin(GPU_PRIM_LINES, line_len * 2); while (line_len--) { immVertex2f(pos, v2d->cur.xmax, i); immVertex2f(pos, v2d->cur.xmin, i); @@ -1593,7 +1593,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) const Sequence *seq = special_seq_update; GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ub(255, 255, 255, 48); @@ -1613,7 +1613,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* draw darkened area outside of active timeline @@ -1631,7 +1631,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) immUniformThemeColorShade(TH_BACK, -60); /* thin lines where the actual frames are */ - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, frame_sta, v2d->cur.ymin); immVertex2f(pos, frame_sta, v2d->cur.ymax); @@ -1649,7 +1649,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) immUniformThemeColorShade(TH_BACK, -40); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, ms->disp_range[0], v2d->cur.ymin); immVertex2f(pos, ms->disp_range[0], v2d->cur.ymax); @@ -1735,12 +1735,12 @@ void draw_timeline_seq(const bContext *C, ARegion *ar) if (scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW) { int cfra_over = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ? scene->ed->over_cfra : scene->r.cfra + scene->ed->over_ofs; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(0.2f, 0.2f, 0.2f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, cfra_over, v2d->cur.ymin); immVertex2f(pos, cfra_over, v2d->cur.ymax); immEnd(); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 748a5c05ef1..aa499d52589 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -913,7 +913,7 @@ static void draw_textscroll(const SpaceText *st, rcti *scroll, rcti *back) float rad; /* background so highlights don't go behind the scrollbar */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_BACK); immRecti(pos, back->xmin, back->ymin, back->xmax, back->ymax); @@ -967,24 +967,24 @@ static void draw_documentation(const SpaceText *st, ARegion *ar) boxh = (DOC_HEIGHT + 1) * (st->lheight_dpi + TXT_LINE_SPACING); /* Draw panel */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_BACK); immRecti(pos, x, y, x + boxw, y - boxh); immUniformThemeColor(TH_SHADE1); - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2i(pos, x, y); immVertex2i(pos, x + boxw, y); immVertex2i(pos, x + boxw, y - boxh); immVertex2i(pos, x, y - boxh); immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, 3); + immBegin(GPU_PRIM_LINE_LOOP, 3); immVertex2i(pos, x + boxw - 10, y - 7); immVertex2i(pos, x + boxw - 4, y - 7); immVertex2i(pos, x + boxw - 7, y - 2); immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, 3); + immBegin(GPU_PRIM_LINE_LOOP, 3); immVertex2i(pos, x + boxw - 10, y - boxh + 7); immVertex2i(pos, x + boxw - 4, y - boxh + 7); immVertex2i(pos, x + boxw - 7, y - boxh + 2); @@ -1066,7 +1066,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc /* not needed but stands out nicer */ UI_draw_box_shadow(220, x, y - boxh, x + boxw, y); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_SHADE1); @@ -1089,7 +1089,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc w = st->cwidth * text_get_char_pos(st, str, len); if (item == sel) { - uint posi = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint posi = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_SHADE2); @@ -1130,7 +1130,7 @@ static void draw_text_decoration(SpaceText *st, ARegion *ar) return; } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* Draw the selection */ @@ -1443,7 +1443,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->showlinenrs) { x = TXT_OFFSET + TEXTXLOC; - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_GRID); immRecti(pos, (TXT_OFFSET - 12), 0, (TXT_OFFSET - 5) + TEXTXLOC, ar->winy - 2); @@ -1502,7 +1502,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) margin_column_x = x + st->cwidth * (st->margin_column - st->left); if (margin_column_x >= x) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -1515,7 +1515,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) immUniform1f("dash_width", 2.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2i(shdr_pos, margin_column_x, 0); immVertex2i(shdr_pos, margin_column_x, ar->winy - 2); immEnd(); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index a6714927249..c0abbe636c3 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -244,7 +244,7 @@ void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], un circball_array_fill(verts, cent, rad, tmat); - immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL); + immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL); for (int i = 0; i < CIRCLE_RESOL; ++i) { immVertex3fv(pos, verts[i]); } @@ -285,15 +285,15 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) if (imm_len == 0) return; - 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_U32, 1, GWN_FETCH_INT); + GPUVertFormat *format = immVertexFormat(); + data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32); GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); - immBeginAtMost(GWN_PRIM_POINTS, imm_len); + immBeginAtMost(GPU_PRIM_POINTS, imm_len); dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP); immEnd(); @@ -303,9 +303,9 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *UNUSED(dm), int offset) { Mesh *me = ob->data; - Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } #endif @@ -328,15 +328,15 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) drawBMOffset_userData data; data.bm = em->bm; data.offset = offset; - 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_U32, 1, GWN_FETCH_INT); + GPUVertFormat *format = immVertexFormat(); + data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32); GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); - immBeginAtMost(GWN_PRIM_POINTS, em->bm->totvert); + immBeginAtMost(GPU_PRIM_POINTS, em->bm->totvert); dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, &data, DM_FOREACH_NOP); immEnd(); @@ -348,9 +348,9 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset) GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE)); Mesh *me = em->ob->data; - Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPUBatch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } #endif @@ -375,20 +375,20 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) data.bm = em->bm; data.offset = offset; - Gwn_VertFormat *format = immVertexFormat(); + GPUVertFormat *format = immVertexFormat(); const int imm_len = dm->getNumEdges(dm) * 2; if (imm_len == 0) return; - 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_U32, 1, GWN_FETCH_INT); + data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32); GPU_line_width(1.0f); - immBeginAtMost(GWN_PRIM_LINES, imm_len); + immBeginAtMost(GPU_PRIM_LINES, imm_len); dm->foreachMappedEdge(dm, bbs_mesh_wire__mapFunc, &data); immEnd(); @@ -400,9 +400,9 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset) GPU_line_width(1.0f); Mesh *me = em->ob->data; - Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPUBatch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } #endif @@ -420,13 +420,13 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select if (imm_len == 0) return; - 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_U32, 1, GWN_FETCH_INT); + GPUVertFormat *format = immVertexFormat(); + data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32); - immBeginAtMost(GWN_PRIM_TRIS, imm_len); + immBeginAtMost(GPU_PRIM_TRIS, imm_len); if (use_select == false) { int selcol; @@ -463,20 +463,20 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select) { Mesh *me = em->ob->data; - Gwn_Batch *batch; + GPUBatch *batch; if (use_select) { batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } else { int selcol; GPU_select_index_get(0, &selcol); batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); - GWN_batch_uniform_1ui(batch, "color", selcol); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); + GPU_batch_uniform_1ui(batch, "color", selcol); + GPU_batch_draw(batch); } } #endif @@ -499,15 +499,15 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm) { drawBMOffset_userData data; /* don't use offset */ data.bm = em->bm; - 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_U32, 1, GWN_FETCH_INT); + GPUVertFormat *format = immVertexFormat(); + data.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + data.col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR_U32); GPU_point_size(UI_GetThemeValuef(TH_FACEDOT_SIZE)); - immBeginAtMost(GWN_PRIM_POINTS, em->bm->totface); + immBeginAtMost(GPU_PRIM_POINTS, em->bm->totface); dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, &data, DM_FOREACH_NOP); immEnd(); @@ -517,9 +517,9 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm) static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm)) { Mesh *me = em->ob->data; - Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPUBatch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } #endif @@ -583,12 +583,12 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce { int selcol; - Gwn_Batch *batch; + GPUBatch *batch; GPU_select_index_get(0, &selcol); batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); - GWN_batch_uniform_1ui(batch, "color", selcol); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32); + GPU_batch_uniform_1ui(batch, "color", selcol); + GPU_batch_draw(batch); } G.f |= (G_f_orig & G_BACKBUFSEL); @@ -601,15 +601,15 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob) { Mesh *me = ob->data; - Gwn_Batch *batch; + GPUBatch *batch; if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) { batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); } else { batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1); } - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); - GWN_batch_draw(batch); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32); + GPU_batch_draw(batch); } void draw_object_backbufsel( @@ -747,8 +747,8 @@ void ED_draw_object_facemap( Mesh *me = ob->data; const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP); if (facemap_data) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv(col); @@ -788,7 +788,7 @@ void ED_draw_object_facemap( /* use gawain immediate mode fore now */ const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len); - immBeginAtMost(GWN_PRIM_TRIS, looptris_len * 3); + immBeginAtMost(GPU_PRIM_TRIS, looptris_len * 3); MPoly *mp; int i; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index e03fe149af6..552d84ebb39 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -365,7 +365,7 @@ static void drawviewborder_grid3(uint shdr_pos, float x1, float x2, float y1, fl x4 = x1 + (1.0f - fac) * (x2 - x1); y4 = y1 + (1.0f - fac) * (y2 - y1); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(shdr_pos, x1, y3); immVertex2f(shdr_pos, x2, y3); @@ -390,7 +390,7 @@ static void drawviewborder_triangle( float w = x2 - x1; float h = y2 - y1; - immBegin(GWN_PRIM_LINES, 6); + immBegin(GPU_PRIM_LINES, 6); if (w > h) { if (golden) { @@ -467,7 +467,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View x2i = (int)(x2 + (1.0f - 0.0001f)); y2i = (int)(y2 + (1.0f - 0.0001f)); - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* First, solid lines. */ { @@ -559,7 +559,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View x3 = x1 + 0.5f * (x2 - x1); y3 = y1 + 0.5f * (y2 - y1); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(shdr_pos, x1, y3); immVertex2f(shdr_pos, x2, y3); @@ -571,7 +571,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View } if (ca->dtx & CAM_DTX_CENTER_DIAG) { - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); immVertex2f(shdr_pos, x1, y1); immVertex2f(shdr_pos, x2, y2); @@ -674,7 +674,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *ar, View static void drawrenderborder(ARegion *ar, View3D *v3d) { /* use the same program for everything */ - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPU_line_width(1.0f); @@ -814,12 +814,12 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, 6); + immBegin(GPU_PRIM_LINES, 6); for (int axis_i = 0; axis_i < 3; axis_i++) { int i = axis_order[axis_i]; @@ -859,9 +859,9 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d) GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_FALSE); /* don't overwrite zbuf */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - uint col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); @@ -872,7 +872,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d) mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); color[3] = 0; /* more transparent toward the ends */ immAttrib4ubv(col, color); add_v3_v3v3(end, o, scaled_axis); @@ -911,7 +911,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d) axis_angle_to_quat(q, vis_axis, vis_angle); } - immBegin(GWN_PRIM_LINE_LOOP, ROT_AXIS_DETAIL); + immBegin(GPU_PRIM_LINE_LOOP, ROT_AXIS_DETAIL); color[3] = 63; /* somewhat faint */ immAttrib4ubv(col, color); float angle = 0.0f; @@ -940,7 +940,7 @@ static void UNUSED_FUNCTION(draw_rotation_guide)(RegionView3D *rv3d) /* -- draw rotation center -- */ immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); GPU_point_size(5.0f); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immAttrib4ubv(col, color); immVertex3fv(pos, o); immEnd(); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index d1b9f95ca2a..3cf036e1ce1 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -263,14 +263,14 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), x2 = xoff + 0.55f * fly->width; y2 = yoff + 0.55f * fly->height; - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_VIEW_OVERLAY); - immBegin(GWN_PRIM_LINES, 16); + immBegin(GPU_PRIM_LINES, 16); /* bottom left */ immVertex2f(pos, x1, y1); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 6040e21aacb..238a956cf26 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -84,7 +84,7 @@ static void draw_xyz_wire( switch (axis) { case 0: /* x axis */ - line_type = GWN_PRIM_LINES; + line_type = GPU_PRIM_LINES; /* bottom left to top right */ negate_v3_v3(v1, dx); @@ -105,7 +105,7 @@ static void draw_xyz_wire( break; case 1: /* y axis */ - line_type = GWN_PRIM_LINES; + line_type = GPU_PRIM_LINES; /* bottom left to top right */ mul_v3_fl(dx, 0.75f); @@ -127,7 +127,7 @@ static void draw_xyz_wire( break; case 2: /* z axis */ - line_type = GWN_PRIM_LINE_STRIP; + line_type = GPU_PRIM_LINE_STRIP; /* start at top left */ negate_v3_v3(v1, dx); @@ -172,8 +172,8 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U { GPU_line_width(gz->line_width); - Gwn_VertFormat *format = immVertexFormat(); - const uint pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); struct { @@ -257,7 +257,7 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U float v_start[3]; GPU_line_width(2.0f); immUniformColor4fv(color_current); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); if (axis_align == -1) { zero_v3(v_start); } @@ -280,10 +280,10 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U GPU_matrix_translate_3fv(v_final); GPU_matrix_scale_1f(is_pos ? 0.22f : 0.18f); - Gwn_Batch *sphere = GPU_batch_preset_sphere(0); - GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4fv(sphere, "color", is_pos ? color_current : color_current_fade); - GWN_batch_draw(sphere); + GPUBatch *sphere = GPU_batch_preset_sphere(0); + GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); + GPU_batch_uniform_4fv(sphere, "color", is_pos ? color_current : color_current_fade); + GPU_batch_draw(sphere); GPU_matrix_pop(); } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index e9a8dd5ee08..c716692eb9b 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -548,7 +548,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) GPU_blend(true); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (ruler_item->flag & RULERITEM_USE_ANGLE) { immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -562,7 +562,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2fv(shdr_pos, co_ss[0]); immVertex2fv(shdr_pos, co_ss[1]); @@ -604,7 +604,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1); + immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1); for (j = 0; j <= arc_steps; j++) { madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale); @@ -637,7 +637,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size); immVertex2fv(shdr_pos, cap); @@ -702,7 +702,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_pos, co_ss[0]); immVertex2fv(shdr_pos, co_ss[2]); @@ -726,7 +726,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size); immVertex2fv(shdr_pos, cap); @@ -793,7 +793,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) float co_ss_snap[3]; ED_view3d_project_float_global(ar, ruler_item->co[inter->co_index], co_ss_snap, V3D_PROJ_TEST_NOP); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color_act); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5796014571a..855ee7bb9fc 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -39,7 +39,7 @@ struct ARegion; struct ARegionType; struct Base; struct BoundBox; -struct Gwn_Batch; +struct GPUBatch; struct Depsgraph; struct Object; struct SmokeDomainSettings; diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 133af8e6da7..690fc5e3bdb 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -461,7 +461,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a GPU_blend(true); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (ruler_item->flag & RULERITEM_USE_ANGLE) { immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -475,7 +475,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); - immBegin(GWN_PRIM_LINE_STRIP, 3); + immBegin(GPU_PRIM_LINE_STRIP, 3); immVertex2fv(shdr_pos, co_ss[0]); immVertex2fv(shdr_pos, co_ss[1]); @@ -517,7 +517,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINE_STRIP, arc_steps + 1); + immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1); for (j = 0; j <= arc_steps; j++) { madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale); @@ -550,7 +550,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size); immVertex2fv(shdr_pos, cap); @@ -614,7 +614,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a immUniformArray4fv("colors", (float *)(float[][4]){{0.67f, 0.67f, 0.67f, 1.0f}, {col[0], col[1], col[2], col[3]}}, 2); immUniform1f("dash_width", 6.0f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_pos, co_ss[0]); immVertex2fv(shdr_pos, co_ss[2]); @@ -638,7 +638,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a immUniformColor3ubv(color_wire); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size); immVertex2fv(shdr_pos, cap); @@ -703,7 +703,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a float co_ss[3]; ED_view3d_project_float_global(ar, ruler_item->co[ruler_item->co_index], co_ss, V3D_PROJ_TEST_NOP); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color_act); diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 4c5150fabdd..e4e12cc3686 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -343,14 +343,14 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *a yoff = walk->ar->winy / 2; } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColor(TH_VIEW_OVERLAY); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); /* North */ immVertex2i(pos, xoff, yoff + inner_length); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index e9abdd80d20..dab53c04806 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1689,13 +1689,13 @@ typedef enum { } ArrowDirection; #define POS_INDEX 0 -/* NOTE: this --^ is a bit hackish, but simplifies Gwn_VertFormat usage among functions +/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions * private to this file - merwin */ static void drawArrow(ArrowDirection d, short offset, short length, short size) { - immBegin(GWN_PRIM_LINES, 6); + immBegin(GPU_PRIM_LINES, 6); switch (d) { case LEFT: @@ -1732,7 +1732,7 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size) static void drawArrowHead(ArrowDirection d, short size) { - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); switch (d) { case LEFT: @@ -1765,7 +1765,7 @@ static void drawArc(float size, float angle_start, float angle_end, int segments float angle; int a; - immBegin(GWN_PRIM_LINE_STRIP, segments + 1); + immBegin(GPU_PRIM_LINE_STRIP, segments + 1); for (angle = angle_start, a = 0; a < segments; angle += delta, a++) { immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size); @@ -1817,7 +1817,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) /* Dashed lines first. */ if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */ BLI_assert(shdr_pos == POS_INDEX); @@ -1835,7 +1835,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) immUniform1f("dash_width", 6.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(POS_INDEX, cent); immVertex2f(POS_INDEX, tmval[0], tmval[1]); immEnd(); @@ -1844,7 +1844,7 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) } /* And now, solid lines. */ - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); UNUSED_VARS_NDEBUG(pos); /* silence warning */ BLI_assert(pos == POS_INDEX); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -7052,7 +7052,7 @@ static void drawEdgeSlide(TransInfo *t) GPU_matrix_push(); GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -7069,7 +7069,7 @@ static void drawEdgeSlide(TransInfo *t) GPU_line_width(line_size); immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); - immBeginAtMost(GWN_PRIM_LINES, 4); + immBeginAtMost(GPU_PRIM_LINES, 4); if (curr_sv->v_side[0]) { immVertex3fv(pos, curr_sv->v_side[0]->co); immVertex3fv(pos, curr_sv->v_co_orig); @@ -7082,7 +7082,7 @@ static void drawEdgeSlide(TransInfo *t) immUniformThemeColorShadeAlpha(TH_SELECT, -30, alpha_shade); GPU_point_size(ctrl_size); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); if (slp->flipped) { if (curr_sv->v_side[1]) immVertex3fv(pos, curr_sv->v_side[1]->co); } @@ -7093,7 +7093,7 @@ static void drawEdgeSlide(TransInfo *t) immUniformThemeColorShadeAlpha(TH_SELECT, 255, alpha_shade); GPU_point_size(guide_size); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); interp_line_v3_v3v3v3(co_mark, co_b, curr_sv->v_co_orig, co_a, fac); immVertex3fv(pos, co_mark); immEnd(); @@ -7107,7 +7107,7 @@ static void drawEdgeSlide(TransInfo *t) GPU_line_width(line_size); immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); - immBegin(GWN_PRIM_LINES, sld->totsv * 2); + immBegin(GPU_PRIM_LINES, sld->totsv * 2); /* TODO(campbell): Loop over all verts */ sv = sld->sv; @@ -7687,12 +7687,12 @@ static void drawVertSlide(TransInfo *t) GPU_line_width(line_size); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); - immBegin(GWN_PRIM_LINES, sld->totsv * 2); + immBegin(GPU_PRIM_LINES, sld->totsv * 2); if (is_clamp) { sv = sld->sv; for (i = 0; i < sld->totsv; i++, sv++) { @@ -7718,7 +7718,7 @@ static void drawVertSlide(TransInfo *t) GPU_point_size(ctrl_size); - immBegin(GWN_PRIM_POINTS, 1); + immBegin(GPU_PRIM_POINTS, 1); immVertex3fv(shdr_pos, (slp->flipped && slp->use_even) ? curr_sv->co_link_orig_3d[curr_sv->co_link_curr] : curr_sv->co_orig_3d); @@ -7761,7 +7761,7 @@ static void drawVertSlide(TransInfo *t) immUniform1f("dash_width", 6.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(shdr_pos, curr_sv->co_orig_3d); immVertex3fv(shdr_pos, co_dest_3d); immEnd(); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index a02948a9951..c8f74cbcd4f 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -747,7 +747,7 @@ void drawConstraint(TransInfo *t) if (depth_test_enabled) GPU_depth_test(false); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); @@ -760,7 +760,7 @@ void drawConstraint(TransInfo *t) immUniform1f("dash_width", 2.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(shdr_pos, t->center_global); immVertex3fv(shdr_pos, vec); immEnd(); @@ -823,7 +823,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) if (depth_test_enabled) GPU_depth_test(false); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor(TH_GRID); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index c1aa0263ef8..3618d57b3ed 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1132,12 +1132,12 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis } UI_make_axis_color(col, col2, axis); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor3ubv(col2); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3fv(pos, v1); immVertex3fv(pos, v2); immEnd(); diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index dc922b5c9ba..b67fd22dbff 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -165,7 +165,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) invert_m4_m4(imat, rv3d->viewmat); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -190,7 +190,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) if (usingSnappingNormal(t) && validSnappingNormal(t)) { immUniformColor4ubv(activeCol); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex3f(pos, t->tsnap.snapPoint[0], t->tsnap.snapPoint[1], t->tsnap.snapPoint[2]); immVertex3f(pos, t->tsnap.snapPoint[0] + t->tsnap.snapNormal[0], t->tsnap.snapPoint[1] + t->tsnap.snapNormal[1], @@ -219,7 +219,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) GPU_blend(true); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 65147d53b5d..35a77fcd4c0 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -342,7 +342,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info const float mval_dst[2] = {win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin}; - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -355,7 +355,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info immUniform1f("dash_width", 6.0f); immUniform1f("dash_factor", 0.5f); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2fv(shdr_pos, mval_src); immVertex2fv(shdr_pos, mval_dst); immEnd(); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 5ff008e1de2..616f4eac2ad 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -92,7 +92,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) GPU_matrix_translate_2fv(cursor); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -104,7 +104,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f); immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac); @@ -123,7 +123,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); - immBegin(GWN_PRIM_LINES, 8); + immBegin(GPU_PRIM_LINES, 8); immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f); immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f); @@ -168,7 +168,7 @@ static void draw_uvs_shadow(Object *obedit) const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -229,7 +229,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME } } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -241,7 +241,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - immBegin(GWN_PRIM_TRI_FAN, efa->len); + immBegin(GPU_PRIM_TRI_FAN, efa->len); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -281,7 +281,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME immUniformColor3fv(col); /* TODO: use editmesh tessface */ - immBegin(GWN_PRIM_TRI_FAN, efa->len); + immBegin(GPU_PRIM_TRI_FAN, efa->len); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -308,9 +308,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME col[3] = 0.5f; /* hard coded alpha, not that nice */ - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); @@ -353,7 +353,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME } /* TODO: use editmesh tessface */ - immBegin(GWN_PRIM_TRI_FAN, efa->len); + immBegin(GPU_PRIM_TRI_FAN, efa->len); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); a = fabsf(uvang[i] - ang[i]) / (float)M_PI; @@ -393,7 +393,7 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co MLoopUV *luv; /* For more efficiency first transfer the entire buffer to vram. */ - Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop); + GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop); BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) @@ -407,17 +407,17 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co immEnd(); /* Then draw each face contour separately. */ - GWN_batch_program_use_begin(loop_batch); + GPU_batch_program_use_begin(loop_batch); unsigned int index = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; - GWN_batch_draw_range_ex(loop_batch, index, efa->len, false); + GPU_batch_draw_range_ex(loop_batch, index, efa->len, false); index += efa->len; } - GWN_batch_program_use_end(loop_batch); - GWN_batch_discard(loop_batch); + GPU_batch_program_use_end(loop_batch); + GPU_batch_discard(loop_batch); } static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos) @@ -425,7 +425,7 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos) MLoopUV *mloopuv; int i; - immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop); + immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop); mloopuv = &me->mloopuv[mpoly->loopstart]; for (i = mpoly->totloop; i != 0; i--, mloopuv++) { @@ -495,7 +495,7 @@ static void draw_uvs_other_mesh(Object *ob, const Image *curimage, static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const int other_uv_filter) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -536,7 +536,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la mloopuv = me->mloopuv; } - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -548,7 +548,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1) continue; - immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop); + immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop); mloopuv = mloopuv_base + mpoly->loopstart; for (b = 0; b < mpoly->totloop; b++, mloopuv++) { @@ -658,13 +658,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); GPU_blend(true); - Gwn_VertFormat *format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - Gwn_Batch *face_batch = immBeginBatch(GWN_PRIM_TRIS, tri_count * 3); + GPUBatch *face_batch = immBeginBatch(GPU_PRIM_TRIS, tri_count * 3); for (unsigned int i = 0; i < em->tottri; i++) { efa = em->looptris[i][0]->f; if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { @@ -686,9 +686,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje immEnd(); /* XXX performance: we should not create and throw away result. */ - GWN_batch_draw(face_batch); - GWN_batch_program_use_end(face_batch); - GWN_batch_discard(face_batch); + GPU_batch_draw(face_batch); + GPU_batch_program_use_end(face_batch); + GPU_batch_discard(face_batch); immUnbindProgram(); @@ -712,7 +712,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); } - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); switch (sima->dt_uv) { case SI_UVDT_DASH: @@ -751,8 +751,8 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje } /* For more efficiency first transfer the entire buffer to vram. */ - Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop); - Gwn_VertBuf *loop_vbo = loop_batch->verts[0]; + GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop); + GPUVertBuf *loop_vbo = loop_batch->verts[0]; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; @@ -766,17 +766,17 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje /* Then draw each face contour separately. */ if (loop_vbo->vertex_len != 0) { - GWN_batch_program_use_begin(loop_batch); + GPU_batch_program_use_begin(loop_batch); unsigned int index = 0, loop_vbo_count; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; - GWN_batch_draw_range_ex(loop_batch, index, efa->len, false); + GPU_batch_draw_range_ex(loop_batch, index, efa->len, false); index += efa->len; } loop_vbo_count = index; - GWN_batch_program_use_end(loop_batch); + GPU_batch_program_use_end(loop_batch); immUnbindProgram(); @@ -790,14 +790,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje if (interpedges) { /* Create a color buffer. */ - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static uint shdr_col; if (format.attr_len == 0) { - shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + shdr_col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo_col, loop_vbo_count); + GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo_col, loop_vbo_count); index = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { @@ -806,36 +806,36 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) { sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); - GWN_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2); + GPU_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2); } } /* Reuse the UV buffer and add the color buffer. */ - GWN_batch_vertbuf_add_ex(loop_batch, vbo_col, true); + GPU_batch_vertbuf_add_ex(loop_batch, vbo_col, true); /* Now draw each face contour separately with another builtin program. */ - GWN_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR); + GPU_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR); GPU_matrix_bind(loop_batch->interface); - GWN_batch_program_use_begin(loop_batch); + GPU_batch_program_use_begin(loop_batch); index = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; - GWN_batch_draw_range_ex(loop_batch, index, efa->len, false); + GPU_batch_draw_range_ex(loop_batch, index, efa->len, false); index += efa->len; } - GWN_batch_program_use_end(loop_batch); + GPU_batch_program_use_end(loop_batch); } else { - Gwn_VertFormat *format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); /* Use batch here to avoid problems with `IMM_BUFFER_SIZE`. */ - Gwn_Batch *flat_edges_batch = immBeginBatchAtMost(GWN_PRIM_LINES, loop_vbo_count * 2); + GPUBatch *flat_edges_batch = immBeginBatchAtMost(GPU_PRIM_LINES, loop_vbo_count * 2); BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; @@ -852,27 +852,27 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje } immEnd(); - GWN_batch_draw(flat_edges_batch); - GWN_batch_discard(flat_edges_batch); + GPU_batch_draw(flat_edges_batch); + GPU_batch_discard(flat_edges_batch); immUnbindProgram(); } } else { - GWN_batch_uniform_4fv(loop_batch, "color", col2); + GPU_batch_uniform_4fv(loop_batch, "color", col2); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* no nice edges */ - GWN_batch_program_use_begin(loop_batch); + GPU_batch_program_use_begin(loop_batch); index = 0; BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; - GWN_batch_draw_range_ex(loop_batch, index, efa->len, false); + GPU_batch_draw_range_ex(loop_batch, index, efa->len, false); index += efa->len; } - GWN_batch_program_use_end(loop_batch); + GPU_batch_program_use_end(loop_batch); immUnbindProgram(); } } @@ -881,7 +881,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje immUnbindProgram(); } - GWN_batch_discard(loop_batch); + GPU_batch_discard(loop_batch); if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(false); @@ -894,16 +894,16 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje float cent[2]; bool col_set = false; - Gwn_VertFormat *format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); GPU_point_size(pointsize); - immBeginAtMost(GWN_PRIM_POINTS, bm->totface); + immBeginAtMost(GPU_PRIM_POINTS, bm->totface); /* unselected faces */ @@ -955,7 +955,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje /* 6. draw uv vertices */ if (drawfaces != 2) { /* 2 means Mesh Face Mode */ - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -964,7 +964,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); GPU_point_size(pointsize); - immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + immBeginAtMost(GPU_PRIM_POINTS, bm->totloop); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) @@ -984,7 +984,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje GPU_point_size(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0)); imm_cpack(0xFF); - immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + immBeginAtMost(GPU_PRIM_POINTS, bm->totloop); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) @@ -1004,7 +1004,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje immUniformThemeColor(TH_VERTEX_SELECT); GPU_point_size(pointsize); - immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + immBeginAtMost(GPU_PRIM_POINTS, bm->totloop); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 9265bc05154..18f1bc872c0 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1547,13 +1547,13 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no /** */ -static void stitch_draw_vbo(Gwn_VertBuf *vbo, Gwn_PrimType prim_type, const float col[4]) +static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float col[4]) { - Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); - GWN_batch_uniform_4fv(batch, "color", col); - GWN_batch_draw(batch); - GWN_batch_discard(batch); + GPUBatch *batch = GPU_batch_create_ex(prim_type, vbo, NULL, GPU_BATCH_OWNS_VBO); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); + GPU_batch_uniform_4fv(batch, "color", col); + GPU_batch_draw(batch); + GPU_batch_discard(batch); } /* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */ @@ -1563,25 +1563,25 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0; StitchState *state = (StitchState *)arg; StitchPreviewer *stitch_preview = state->stitch_preview; - Gwn_VertBuf *vbo, *vbo_line; + GPUVertBuf *vbo, *vbo_line; float col[4]; - static Gwn_VertFormat format = { 0 }; + static GPUVertFormat format = { 0 }; static unsigned int pos_id; if (format.attr_len == 0) { - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } GPU_blend(true); /* Static Tris */ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3); for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) { - GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]); } - stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col); + stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); /* Preview Polys */ @@ -1591,39 +1591,39 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar num_tri = num_line - 2 * stitch_preview->num_polys; /* we need to convert the polys into triangles / lines */ - vbo = GWN_vertbuf_create_with_format(&format); - vbo_line = GWN_vertbuf_create_with_format(&format); + vbo = GPU_vertbuf_create_with_format(&format); + vbo_line = GPU_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, num_tri * 3); - GWN_vertbuf_data_alloc(vbo_line, num_line * 2); + GPU_vertbuf_data_alloc(vbo, num_tri * 3); + GPU_vertbuf_data_alloc(vbo_line, num_line * 2); for (int i = 0; i < stitch_preview->num_polys; i++) { BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3); /* Start line */ - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]); for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) { - GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]); - GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); - GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]); + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); } /* Closing line */ - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); /* j = uvs_per_polygon[i] - 1*/ - GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]); index += stitch_preview->uvs_per_polygon[i] * 2; } UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col); - stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col); + stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col); - stitch_draw_vbo(vbo_line, GWN_PRIM_LINES, col); + stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col); GPU_blend(false); @@ -1633,37 +1633,37 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *ar GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f); UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable); for (int i = 0; i < stitch_preview->num_stitchable; i++) { - GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); } - stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col); + stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable); for (int i = 0; i < stitch_preview->num_unstitchable; i++) { - GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); } - stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col); + stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); } else { UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2); for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) { - GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); } - stitch_draw_vbo(vbo, GWN_PRIM_LINES, col); + stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); - vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2); for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) { - GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); } - stitch_draw_vbo(vbo, GWN_PRIM_LINES, col); + stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); } } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 3d207b85760..58295ae9329 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -23,7 +23,7 @@ # # ***** END GPL LICENSE BLOCK ***** -# WITH_OPENGL limits the visibility of the opengl headers to just gawain and bg_gpu, +# WITH_OPENGL limits the visibility of the opengl headers to just GPU and bg_gpu, # to more easily highlight codepadths in other libraries that need to be refactored, # bf_gpu is allowed to have opengl regardless of this option. diff --git a/source/blender/gpu/GPU_attr_binding.h b/source/blender/gpu/GPU_attr_binding.h index 41050a095cd..186acacb71d 100644 --- a/source/blender/gpu/GPU_attr_binding.h +++ b/source/blender/gpu/GPU_attr_binding.h @@ -23,20 +23,20 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_attr_binding.h +/** \file blender/gpu/GPU_attr_binding.h * \ingroup gpu * - * Gawain vertex attribute binding + * GPU vertex attribute binding */ -#ifndef __GWN_ATTR_BINDING_H__ -#define __GWN_ATTR_BINDING_H__ +#ifndef __GPU_ATTR_BINDING_H__ +#define __GPU_ATTR_BINDING_H__ #include "GPU_common.h" -typedef struct Gwn_AttrBinding { +typedef struct GPUAttrBinding { uint64_t loc_bits; /* store 4 bits for each of the 16 attribs */ uint16_t enabled_bits; /* 1 bit for each attrib */ -} Gwn_AttrBinding; +} GPUAttrBinding; -#endif /* __GWN_ATTR_BINDING_H__ */ +#endif /* __GPU_ATTR_BINDING_H__ */ diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index 4c98eb8f537..bd0e3b43e6c 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -23,15 +23,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_batch.h +/** \file blender/gpu/GPU_batch.h * \ingroup gpu * - * Gawain geometry batch + * GPU geometry batch * Contains VAOs + VBOs + Shader representing a drawable entity. */ -#ifndef __GWN_BATCH_H__ -#define __GWN_BATCH_H__ +#ifndef __GPU_BATCH_H__ +#define __GPU_BATCH_H__ #include "GPU_vertex_buffer.h" #include "GPU_element.h" @@ -39,32 +39,32 @@ #include "GPU_shader.h" typedef enum { - GWN_BATCH_READY_TO_FORMAT, - GWN_BATCH_READY_TO_BUILD, - GWN_BATCH_BUILDING, - GWN_BATCH_READY_TO_DRAW -} Gwn_BatchPhase; + GPU_BATCH_READY_TO_FORMAT, + GPU_BATCH_READY_TO_BUILD, + GPU_BATCH_BUILDING, + GPU_BATCH_READY_TO_DRAW +} GPUBatchPhase; -#define GWN_BATCH_VBO_MAX_LEN 3 -#define GWN_BATCH_VAO_STATIC_LEN 3 -#define GWN_BATCH_VAO_DYN_ALLOC_COUNT 16 +#define GPU_BATCH_VBO_MAX_LEN 3 +#define GPU_BATCH_VAO_STATIC_LEN 3 +#define GPU_BATCH_VAO_DYN_ALLOC_COUNT 16 -typedef struct Gwn_Batch { +typedef struct GPUBatch { /* geometry */ - Gwn_VertBuf* verts[GWN_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ - Gwn_VertBuf* inst; /* instance attribs */ - Gwn_IndexBuf* elem; /* NULL if element list not needed */ + GPUVertBuf* verts[GPU_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ + GPUVertBuf* inst; /* instance attribs */ + GPUIndexBuf* elem; /* NULL if element list not needed */ uint32_t gl_prim_type; /* cached values (avoid dereferencing later) */ uint32_t vao_id; uint32_t program; - const struct Gwn_ShaderInterface* interface; + const struct GPUShaderInterface* interface; /* book-keeping */ uint owns_flag; - struct Gwn_Context *context; /* used to free all vaos. this implies all vaos were created under the same context. */ - Gwn_BatchPhase phase; + struct GPUContext *context; /* used to free all vaos. this implies all vaos were created under the same context. */ + GPUBatchPhase phase; bool program_in_use; /* Vao management: remembers all geometry state (vertex attrib bindings & element buffer) @@ -74,113 +74,113 @@ typedef struct Gwn_Batch { union { /* Static handle count */ struct { - const struct Gwn_ShaderInterface* interfaces[GWN_BATCH_VAO_STATIC_LEN]; - uint32_t vao_ids[GWN_BATCH_VAO_STATIC_LEN]; + const struct GPUShaderInterface* interfaces[GPU_BATCH_VAO_STATIC_LEN]; + uint32_t vao_ids[GPU_BATCH_VAO_STATIC_LEN]; } static_vaos; /* Dynamic handle count */ struct { uint count; - const struct Gwn_ShaderInterface** interfaces; + const struct GPUShaderInterface** interfaces; uint32_t* vao_ids; } dynamic_vaos; }; /* XXX This is the only solution if we want to have some data structure using * batches as key to identify nodes. We must destroy these nodes with this callback. */ - void (*free_callback)(struct Gwn_Batch*, void*); + void (*free_callback)(struct GPUBatch*, void*); void* callback_data; -} Gwn_Batch; +} GPUBatch; enum { - GWN_BATCH_OWNS_VBO = (1 << 0), + GPU_BATCH_OWNS_VBO = (1 << 0), /* each vbo index gets bit-shifted */ - GWN_BATCH_OWNS_INSTANCES = (1 << 30), - GWN_BATCH_OWNS_INDEX = (1 << 31), + GPU_BATCH_OWNS_INSTANCES = (1 << 30), + GPU_BATCH_OWNS_INDEX = (1 << 31), }; -Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); -void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, uint owns_flag); -Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src); +GPUBatch* GPU_batch_create_ex(GPUPrimType, GPUVertBuf*, GPUIndexBuf*, uint owns_flag); +void GPU_batch_init_ex(GPUBatch*, GPUPrimType, GPUVertBuf*, GPUIndexBuf*, uint owns_flag); +GPUBatch* GPU_batch_duplicate(GPUBatch* batch_src); -#define GWN_batch_create(prim, verts, elem) \ - GWN_batch_create_ex(prim, verts, elem, 0) -#define GWN_batch_init(batch, prim, verts, elem) \ - GWN_batch_init_ex(batch, prim, verts, elem, 0) +#define GPU_batch_create(prim, verts, elem) \ + GPU_batch_create_ex(prim, verts, elem, 0) +#define GPU_batch_init(batch, prim, verts, elem) \ + GPU_batch_init_ex(batch, prim, verts, elem, 0) -void GWN_batch_discard(Gwn_Batch*); /* verts & elem are not discarded */ +void GPU_batch_discard(GPUBatch*); /* verts & elem are not discarded */ -void gwn_batch_vao_cache_clear(Gwn_Batch*); +void GPU_batch_vao_cache_clear(GPUBatch*); -void GWN_batch_callback_free_set(Gwn_Batch*, void (*callback)(Gwn_Batch*, void*), void*); +void GPU_batch_callback_free_set(GPUBatch*, void (*callback)(GPUBatch*, void*), void*); -void GWN_batch_instbuf_set(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); /* Instancing */ +void GPU_batch_instbuf_set(GPUBatch*, GPUVertBuf*, bool own_vbo); /* Instancing */ -int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); +int GPU_batch_vertbuf_add_ex(GPUBatch*, GPUVertBuf*, bool own_vbo); -#define GWN_batch_vertbuf_add(batch, verts) \ - GWN_batch_vertbuf_add_ex(batch, verts, false) +#define GPU_batch_vertbuf_add(batch, verts) \ + GPU_batch_vertbuf_add_ex(batch, verts, false) -void GWN_batch_program_set_no_use(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); -void GWN_batch_program_set(Gwn_Batch*, uint32_t program, const Gwn_ShaderInterface*); -void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id); +void GPU_batch_program_set_no_use(GPUBatch*, uint32_t program, const GPUShaderInterface*); +void GPU_batch_program_set(GPUBatch*, uint32_t program, const GPUShaderInterface*); +void GPU_batch_program_set_builtin(GPUBatch *batch, GPUBuiltinShader shader_id); /* Entire batch draws with one shader program, but can be redrawn later with another program. */ /* Vertex shader's inputs must be compatible with the batch's vertex format. */ -void GWN_batch_program_use_begin(Gwn_Batch*); /* call before Batch_Uniform (temp hack?) */ -void GWN_batch_program_use_end(Gwn_Batch*); - -void GWN_batch_uniform_1ui(Gwn_Batch*, const char* name, int value); -void GWN_batch_uniform_1i(Gwn_Batch*, const char* name, int value); -void GWN_batch_uniform_1b(Gwn_Batch*, const char* name, bool value); -void GWN_batch_uniform_1f(Gwn_Batch*, const char* name, float value); -void GWN_batch_uniform_2f(Gwn_Batch*, const char* name, float x, float y); -void GWN_batch_uniform_3f(Gwn_Batch*, const char* name, float x, float y, float z); -void GWN_batch_uniform_4f(Gwn_Batch*, const char* name, float x, float y, float z, float w); -void GWN_batch_uniform_2fv(Gwn_Batch*, const char* name, const float data[2]); -void GWN_batch_uniform_3fv(Gwn_Batch*, const char* name, const float data[3]); -void GWN_batch_uniform_4fv(Gwn_Batch*, const char* name, const float data[4]); -void GWN_batch_uniform_2fv_array(Gwn_Batch*, const char* name, int len, const float *data); -void GWN_batch_uniform_4fv_array(Gwn_Batch*, const char* name, int len, const float *data); -void GWN_batch_uniform_mat4(Gwn_Batch*, const char* name, const float data[4][4]); - -void GWN_batch_draw(Gwn_Batch*); +void GPU_batch_program_use_begin(GPUBatch*); /* call before Batch_Uniform (temp hack?) */ +void GPU_batch_program_use_end(GPUBatch*); + +void GPU_batch_uniform_1ui(GPUBatch*, const char* name, int value); +void GPU_batch_uniform_1i(GPUBatch*, const char* name, int value); +void GPU_batch_uniform_1b(GPUBatch*, const char* name, bool value); +void GPU_batch_uniform_1f(GPUBatch*, const char* name, float value); +void GPU_batch_uniform_2f(GPUBatch*, const char* name, float x, float y); +void GPU_batch_uniform_3f(GPUBatch*, const char* name, float x, float y, float z); +void GPU_batch_uniform_4f(GPUBatch*, const char* name, float x, float y, float z, float w); +void GPU_batch_uniform_2fv(GPUBatch*, const char* name, const float data[2]); +void GPU_batch_uniform_3fv(GPUBatch*, const char* name, const float data[3]); +void GPU_batch_uniform_4fv(GPUBatch*, const char* name, const float data[4]); +void GPU_batch_uniform_2fv_array(GPUBatch*, const char* name, int len, const float *data); +void GPU_batch_uniform_4fv_array(GPUBatch*, const char* name, int len, const float *data); +void GPU_batch_uniform_mat4(GPUBatch*, const char* name, const float data[4][4]); + +void GPU_batch_draw(GPUBatch*); /* This does not bind/unbind shader and does not call GPU_matrix_bind() */ -void GWN_batch_draw_range_ex(Gwn_Batch*, int v_first, int v_count, bool force_instance); +void GPU_batch_draw_range_ex(GPUBatch*, int v_first, int v_count, bool force_instance); /* Does not even need batch */ -void GWN_draw_primitive(Gwn_PrimType, int v_count); +void GPU_draw_primitive(GPUPrimType, int v_count); #if 0 /* future plans */ -/* Can multiple batches share a Gwn_VertBuf? Use ref count? */ +/* Can multiple batches share a GPUVertBuf? Use ref count? */ /* We often need a batch with its own data, to be created and discarded together. */ /* WithOwn variants reduce number of system allocations. */ typedef struct BatchWithOwnVertexBuffer { - Gwn_Batch batch; - Gwn_VertBuf verts; /* link batch.verts to this */ + GPUBatch batch; + GPUVertBuf verts; /* link batch.verts to this */ } BatchWithOwnVertexBuffer; typedef struct BatchWithOwnElementList { - Gwn_Batch batch; - Gwn_IndexBuf elem; /* link batch.elem to this */ + GPUBatch batch; + GPUIndexBuf elem; /* link batch.elem to this */ } BatchWithOwnElementList; typedef struct BatchWithOwnVertexBufferAndElementList { - Gwn_Batch batch; - Gwn_IndexBuf elem; /* link batch.elem to this */ - Gwn_VertBuf verts; /* link batch.verts to this */ + GPUBatch batch; + GPUIndexBuf elem; /* link batch.elem to this */ + GPUVertBuf verts; /* link batch.verts to this */ } BatchWithOwnVertexBufferAndElementList; -Gwn_Batch* create_BatchWithOwnVertexBuffer(Gwn_PrimType, Gwn_VertFormat*, uint v_len, Gwn_IndexBuf*); -Gwn_Batch* create_BatchWithOwnElementList(Gwn_PrimType, Gwn_VertBuf*, uint prim_len); -Gwn_Batch* create_BatchWithOwnVertexBufferAndElementList(Gwn_PrimType, Gwn_VertFormat*, uint v_len, uint prim_len); +GPUBatch* create_BatchWithOwnVertexBuffer(GPUPrimType, GPUVertFormat*, uint v_len, GPUIndexBuf*); +GPUBatch* create_BatchWithOwnElementList(GPUPrimType, GPUVertBuf*, uint prim_len); +GPUBatch* create_BatchWithOwnVertexBufferAndElementList(GPUPrimType, GPUVertFormat*, uint v_len, uint prim_len); /* verts: shared, own */ /* elem: none, shared, own */ -Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStuff); +GPUBatch* create_BatchInGeneral(GPUPrimType, VertexBufferStuff, ElementListStuff); #endif /* future plans */ @@ -189,11 +189,11 @@ void gpu_batch_exit(void); /* Macros */ -#define GWN_BATCH_DISCARD_SAFE(batch) do { \ +#define GPU_BATCH_DISCARD_SAFE(batch) do { \ if (batch != NULL) { \ - GWN_batch_discard(batch); \ + GPU_batch_discard(batch); \ batch = NULL; \ } \ } while (0) -#endif /* __GWN_BATCH_H__ */ +#endif /* __GPU_BATCH_H__ */ diff --git a/source/blender/gpu/GPU_batch_presets.h b/source/blender/gpu/GPU_batch_presets.h index 2450a1760c3..a33b864c5b9 100644 --- a/source/blender/gpu/GPU_batch_presets.h +++ b/source/blender/gpu/GPU_batch_presets.h @@ -24,7 +24,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/* Batched geometry rendering is powered by the Gawain library. +/* Batched geometry rendering is powered by the GPU library. * This file contains any additions or modifications specific to Blender. */ @@ -32,20 +32,20 @@ #define __GPU_BATCH_PRESETS_H__ struct rctf; -struct Gwn_VertFormat; +struct GPUVertFormat; #include "BLI_compiler_attrs.h" #include "BLI_sys_types.h" /* gpu_batch_presets.c */ -struct Gwn_VertFormat *GPU_batch_preset_format_3d(void); +struct GPUVertFormat *GPU_batch_preset_format_3d(void); /* Replacement for gluSphere */ -struct Gwn_Batch *GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT; -struct Gwn_Batch *GPU_batch_preset_sphere_wire(int lod) ATTR_WARN_UNUSED_RESULT; +struct GPUBatch *GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT; +struct GPUBatch *GPU_batch_preset_sphere_wire(int lod) ATTR_WARN_UNUSED_RESULT; void gpu_batch_presets_init(void); -void gpu_batch_presets_register(struct Gwn_Batch *preset_batch); +void gpu_batch_presets_register(struct GPUBatch *preset_batch); void gpu_batch_presets_reset(void); void gpu_batch_presets_exit(void); diff --git a/source/blender/gpu/GPU_batch_utils.h b/source/blender/gpu/GPU_batch_utils.h index b23b7723dc0..d558b7a1097 100644 --- a/source/blender/gpu/GPU_batch_utils.h +++ b/source/blender/gpu/GPU_batch_utils.h @@ -27,14 +27,14 @@ struct rctf; #include "BLI_sys_types.h" /* gpu_batch_utils.c */ -struct Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded( +struct GPUBatch *GPU_batch_tris_from_poly_2d_encoded( const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); -struct Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded( +struct GPUBatch *GPU_batch_wire_from_poly_2d_encoded( const uchar *polys_flat, uint polys_flat_len, const struct rctf *rect ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); /* Only use by draw manager. Use the presets function instead for interface. */ -struct Gwn_Batch *gpu_batch_sphere(int lat_res, int lon_res) ATTR_WARN_UNUSED_RESULT; +struct GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) ATTR_WARN_UNUSED_RESULT; #endif /* __GPU_BATCH_UTILS_H__ */ diff --git a/source/blender/gpu/GPU_buffer_id.h b/source/blender/gpu/GPU_buffer_id.h index fd680ff31f5..4615e9e2c66 100644 --- a/source/blender/gpu/GPU_buffer_id.h +++ b/source/blender/gpu/GPU_buffer_id.h @@ -23,14 +23,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_buffer_id.h +/** \file blender/gpu/GPU_buffer_id.h * \ingroup gpu * - * Gawain buffer IDs + * GPU buffer IDs */ -#ifndef __GWN_BUFFER_ID_H__ -#define __GWN_BUFFER_ID_H__ +#ifndef __GPU_BUFFER_ID_H__ +#define __GPU_BUFFER_ID_H__ /* Manage GL buffer IDs in a thread-safe way * Use these instead of glGenBuffers & its friends @@ -43,11 +43,11 @@ extern "C" { #include "GPU_common.h" -GLuint GWN_buf_id_alloc(void); -void GWN_buf_id_free(GLuint buffer_id); +GLuint GPU_buf_id_alloc(void); +void GPU_buf_id_free(GLuint buffer_id); #ifdef __cplusplus } #endif -#endif /* __GWN_BUFFER_ID_H__ */ +#endif /* __GPU_BUFFER_ID_H__ */ diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index f496c92f283..77801256463 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -91,7 +91,7 @@ void GPU_pbvh_grid_buffers_update( const int update_flags); /* draw */ -struct Gwn_Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast); +struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast); /* debug PBVH draw */ void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, unsigned int pos); diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h index 2587e8670a9..cb506c6b0bc 100644 --- a/source/blender/gpu/GPU_common.h +++ b/source/blender/gpu/GPU_common.h @@ -23,12 +23,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_common.h +/** \file blender/gpu/GPU_common.h * \ingroup gpu */ -#ifndef __GWN_COMMON_H__ -#define __GWN_COMMON_H__ +#ifndef __GPU_COMMON_H__ +#define __GPU_COMMON_H__ #define PROGRAM_NO_OPTI 0 @@ -51,11 +51,11 @@ #include #endif -/* GWN_INLINE */ +/* GPU_INLINE */ #if defined(_MSC_VER) -# define GWN_INLINE static __forceinline +# define GPU_INLINE static __forceinline #else -# define GWN_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) +# define GPU_INLINE static inline __attribute__((always_inline)) __attribute__((__unused__)) #endif -#endif /* __GWN_COMMON_H__ */ +#endif /* __GPU_COMMON_H__ */ diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h index 0cedc109645..5f63c408801 100644 --- a/source/blender/gpu/GPU_context.h +++ b/source/blender/gpu/GPU_context.h @@ -23,14 +23,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_context.h +/** \file blender/gpu/GPU_context.h * \ingroup gpu * - * This interface allow Gawain to manage VAOs for mutiple context and threads. + * This interface allow GPU to manage VAOs for mutiple context and threads. */ -#ifndef __GWN_CONTEXT_H__ -#define __GWN_CONTEXT_H__ +#ifndef __GPU_CONTEXT_H__ +#define __GPU_CONTEXT_H__ #ifdef __cplusplus extern "C" { @@ -40,16 +40,16 @@ extern "C" { #include "GPU_batch.h" #include "GPU_shader_interface.h" -typedef struct Gwn_Context Gwn_Context; +typedef struct GPUContext GPUContext; -Gwn_Context* GWN_context_create(void); -void GWN_context_discard(Gwn_Context*); +GPUContext* GPU_context_create(void); +void GPU_context_discard(GPUContext*); -void GWN_context_active_set(Gwn_Context*); -Gwn_Context* GWN_context_active_get(void); +void GPU_context_active_set(GPUContext*); +GPUContext* GPU_context_active_get(void); #ifdef __cplusplus } #endif -#endif /* __GWN_CONTEXT_H__ */ +#endif /* __GPU_CONTEXT_H__ */ diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h index 0c23e90569b..508c079fcd3 100644 --- a/source/blender/gpu/GPU_element.h +++ b/source/blender/gpu/GPU_element.h @@ -23,31 +23,31 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_element.h +/** \file blender/gpu/GPU_element.h * \ingroup gpu * - * Gawain element list (AKA index buffer) + * GPU element list (AKA index buffer) */ -#ifndef __GWN_ELEMENT_H__ -#define __GWN_ELEMENT_H__ +#ifndef __GPU_ELEMENT_H__ +#define __GPU_ELEMENT_H__ #include "GPU_primitive.h" -#define GWN_TRACK_INDEX_RANGE 1 +#define GPU_TRACK_INDEX_RANGE 1 -#define GWN_PRIM_RESTART 0xFFFFFFFF +#define GPU_PRIM_RESTART 0xFFFFFFFF typedef enum { - GWN_INDEX_U8, /* GL has this, Vulkan does not */ - GWN_INDEX_U16, - GWN_INDEX_U32 -} Gwn_IndexBufType; + GPU_INDEX_U8, /* GL has this, Vulkan does not */ + GPU_INDEX_U16, + GPU_INDEX_U32 +} GPUIndexBufType; -typedef struct Gwn_IndexBuf { +typedef struct GPUIndexBuf { uint index_len; -#if GWN_TRACK_INDEX_RANGE - Gwn_IndexBufType index_type; +#if GPU_TRACK_INDEX_RANGE + GPUIndexBufType index_type; uint32_t gl_index_type; uint min_index; uint max_index; @@ -55,48 +55,48 @@ typedef struct Gwn_IndexBuf { #endif uint32_t vbo_id; /* 0 indicates not yet sent to VRAM */ bool use_prim_restart; -} Gwn_IndexBuf; +} GPUIndexBuf; -void GWN_indexbuf_use(Gwn_IndexBuf*); -uint GWN_indexbuf_size_get(const Gwn_IndexBuf*); +void GPU_indexbuf_use(GPUIndexBuf*); +uint GPU_indexbuf_size_get(const GPUIndexBuf*); -typedef struct Gwn_IndexBufBuilder { +typedef struct GPUIndexBufBuilder { uint max_allowed_index; uint max_index_len; uint index_len; - Gwn_PrimType prim_type; + GPUPrimType prim_type; uint* data; bool use_prim_restart; -} Gwn_IndexBufBuilder; +} GPUIndexBufBuilder; /* supports all primitive types. */ -void GWN_indexbuf_init_ex(Gwn_IndexBufBuilder*, Gwn_PrimType, uint index_len, uint vertex_len, bool use_prim_restart); +void GPU_indexbuf_init_ex(GPUIndexBufBuilder*, GPUPrimType, uint index_len, uint vertex_len, bool use_prim_restart); -/* supports only GWN_PRIM_POINTS, GWN_PRIM_LINES and GWN_PRIM_TRIS. */ -void GWN_indexbuf_init(Gwn_IndexBufBuilder*, Gwn_PrimType, uint prim_len, uint vertex_len); +/* supports only GPU_PRIM_POINTS, GPU_PRIM_LINES and GPU_PRIM_TRIS. */ +void GPU_indexbuf_init(GPUIndexBufBuilder*, GPUPrimType, uint prim_len, uint vertex_len); -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder*, uint v); -void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder*); +void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder*, uint v); +void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder*); -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder*, uint v); -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder*, uint v1, uint v2); -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3); -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); +void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder*, uint v); +void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder*, uint v1, uint v2); +void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder*, uint v1, uint v2, uint v3); +void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); -Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder*); -void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder*, Gwn_IndexBuf*); +GPUIndexBuf* GPU_indexbuf_build(GPUIndexBufBuilder*); +void GPU_indexbuf_build_in_place(GPUIndexBufBuilder*, GPUIndexBuf*); -void GWN_indexbuf_discard(Gwn_IndexBuf*); +void GPU_indexbuf_discard(GPUIndexBuf*); /* Macros */ -#define GWN_INDEXBUF_DISCARD_SAFE(elem) do { \ +#define GPU_INDEXBUF_DISCARD_SAFE(elem) do { \ if (elem != NULL) { \ - GWN_indexbuf_discard(elem); \ + GPU_indexbuf_discard(elem); \ elem = NULL; \ } \ } while (0) -#endif /* __GWN_ELEMENT_H__ */ +#endif /* __GPU_ELEMENT_H__ */ diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index c5892886825..a756687b557 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -27,7 +27,7 @@ /** \file blender/gpu/GPU_immediate.h * \ingroup gpu * - * Gawain immediate mode work-alike + * GPU immediate mode work-alike */ #ifndef __GPU_IMMEDIATE_H__ @@ -40,20 +40,20 @@ #include "GPU_immediate_util.h" #include "GPU_shader.h" -Gwn_VertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ +GPUVertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ -void immBindProgram(uint32_t program, const Gwn_ShaderInterface*); /* every immBegin must have a program bound first. */ +void immBindProgram(uint32_t program, const GPUShaderInterface*); /* every immBegin must have a program bound first. */ void immUnbindProgram(void); /* call after your last immEnd, or before binding another program. */ -void immBegin(Gwn_PrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ -void immBeginAtMost(Gwn_PrimType, uint max_vertex_len); /* can supply fewer vertices. */ +void immBegin(GPUPrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ +void immBeginAtMost(GPUPrimType, uint max_vertex_len); /* can supply fewer vertices. */ void immEnd(void); /* finishes and draws. */ /* ImmBegin a batch, then use standard immFunctions as usual. */ /* ImmEnd will finalize the batch instead of drawing. */ /* Then you can draw it as many times as you like! Partially replaces the need for display lists. */ -Gwn_Batch* immBeginBatch(Gwn_PrimType, uint vertex_len); -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType, uint vertex_len); +GPUBatch* immBeginBatch(GPUPrimType, uint vertex_len); +GPUBatch* immBeginBatchAtMost(GPUPrimType, uint vertex_len); /* Provide attribute values that can change per vertex. */ /* First vertex after immBegin must have all its attributes specified. */ diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h index 0a5c9805509..58555e287b0 100644 --- a/source/blender/gpu/GPU_immediate_util.h +++ b/source/blender/gpu/GPU_immediate_util.h @@ -32,7 +32,7 @@ void immRectf(uint pos, float x1, float y1, float x2, float y2); void immRecti(uint pos, int x1, int y1, int x2, int y2); -/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GWN_PRIM_TRIS. */ +/* Same as immRectf/immRecti but does not call immBegin/immEnd. To use with GPU_PRIM_TRIS. */ void immRectf_fast_with_color(uint pos, uint col, float x1, float y1, float x2, float y2, const float color[4]); void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2, const float color[4]); @@ -44,7 +44,7 @@ void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float radius, int void imm_draw_circle_wire_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments); void imm_draw_circle_fill_aspect_2d(uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments); -/* use this version when Gwn_VertFormat has a vec3 position */ +/* use this version when GPUVertFormat has a vec3 position */ void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments); void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments); diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h index f5e34bd4c90..23f19ed19cd 100644 --- a/source/blender/gpu/GPU_matrix.h +++ b/source/blender/gpu/GPU_matrix.h @@ -38,7 +38,7 @@ extern "C" { #endif -struct Gwn_ShaderInterface; +struct GPUShaderInterface; void GPU_matrix_reset(void); /* to Identity transform & empty stack */ @@ -111,7 +111,7 @@ const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3]; /* set uniform values for currently bound shader */ -void GPU_matrix_bind(const struct Gwn_ShaderInterface *); +void GPU_matrix_bind(const struct GPUShaderInterface *); bool GPU_matrix_dirty_get(void); /* since last bind */ diff --git a/source/blender/gpu/GPU_primitive.h b/source/blender/gpu/GPU_primitive.h index 44348b9b593..bcedfa56ab1 100644 --- a/source/blender/gpu/GPU_primitive.h +++ b/source/blender/gpu/GPU_primitive.h @@ -23,43 +23,43 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_primitive.h +/** \file blender/gpu/GPU_primitive.h * \ingroup gpu * - * Gawain geometric primitives + * GPU geometric primitives */ -#ifndef __GWN_PRIMITIVE_H__ -#define __GWN_PRIMITIVE_H__ +#ifndef __GPU_PRIMITIVE_H__ +#define __GPU_PRIMITIVE_H__ #include "GPU_common.h" typedef enum { - GWN_PRIM_POINTS, - GWN_PRIM_LINES, - GWN_PRIM_TRIS, - GWN_PRIM_LINE_STRIP, - GWN_PRIM_LINE_LOOP, /* GL has this, Vulkan does not */ - GWN_PRIM_TRI_STRIP, - GWN_PRIM_TRI_FAN, + GPU_PRIM_POINTS, + GPU_PRIM_LINES, + GPU_PRIM_TRIS, + GPU_PRIM_LINE_STRIP, + GPU_PRIM_LINE_LOOP, /* GL has this, Vulkan does not */ + GPU_PRIM_TRI_STRIP, + GPU_PRIM_TRI_FAN, - GWN_PRIM_LINES_ADJ, - GWN_PRIM_TRIS_ADJ, - GWN_PRIM_LINE_STRIP_ADJ, + GPU_PRIM_LINES_ADJ, + GPU_PRIM_TRIS_ADJ, + GPU_PRIM_LINE_STRIP_ADJ, - GWN_PRIM_NONE -} Gwn_PrimType; + GPU_PRIM_NONE +} GPUPrimType; /* what types of primitives does each shader expect? */ typedef enum { - GWN_PRIM_CLASS_NONE = 0, - GWN_PRIM_CLASS_POINT = (1 << 0), - GWN_PRIM_CLASS_LINE = (1 << 1), - GWN_PRIM_CLASS_SURFACE = (1 << 2), - GWN_PRIM_CLASS_ANY = GWN_PRIM_CLASS_POINT | GWN_PRIM_CLASS_LINE | GWN_PRIM_CLASS_SURFACE -} Gwn_PrimClass; + GPU_PRIM_CLASS_NONE = 0, + GPU_PRIM_CLASS_POINT = (1 << 0), + GPU_PRIM_CLASS_LINE = (1 << 1), + GPU_PRIM_CLASS_SURFACE = (1 << 2), + GPU_PRIM_CLASS_ANY = GPU_PRIM_CLASS_POINT | GPU_PRIM_CLASS_LINE | GPU_PRIM_CLASS_SURFACE +} GPUPrimClass; -Gwn_PrimClass GWN_primtype_class(Gwn_PrimType); -bool GWN_primtype_belongs_to_class(Gwn_PrimType, Gwn_PrimClass); +GPUPrimClass GPU_primtype_class(GPUPrimType); +bool GPU_primtype_belongs_to_class(GPUPrimType, GPUPrimClass); -#endif /* __GWN_PRIMITIVE_H__ */ +#endif /* __GPU_PRIMITIVE_H__ */ diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h index 36842e9847a..c80cc1021ec 100644 --- a/source/blender/gpu/GPU_shader_interface.h +++ b/source/blender/gpu/GPU_shader_interface.h @@ -23,82 +23,82 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_shader_interface.h +/** \file blender/gpu/GPU_shader_interface.h * \ingroup gpu * - * Gawain shader interface (C --> GLSL) + * GPU shader interface (C --> GLSL) */ -#ifndef __GWN_SHADER_INTERFACE_H__ -#define __GWN_SHADER_INTERFACE_H__ +#ifndef __GPU_SHADER_INTERFACE_H__ +#define __GPU_SHADER_INTERFACE_H__ #include "GPU_common.h" typedef enum { - GWN_UNIFORM_NONE = 0, /* uninitialized/unknown */ + GPU_UNIFORM_NONE = 0, /* uninitialized/unknown */ - GWN_UNIFORM_MODEL, /* mat4 ModelMatrix */ - GWN_UNIFORM_VIEW, /* mat4 ViewMatrix */ - GWN_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */ - GWN_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */ - GWN_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */ - GWN_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */ + GPU_UNIFORM_MODEL, /* mat4 ModelMatrix */ + GPU_UNIFORM_VIEW, /* mat4 ViewMatrix */ + GPU_UNIFORM_MODELVIEW, /* mat4 ModelViewMatrix */ + GPU_UNIFORM_PROJECTION, /* mat4 ProjectionMatrix */ + GPU_UNIFORM_VIEWPROJECTION, /* mat4 ViewProjectionMatrix */ + GPU_UNIFORM_MVP, /* mat4 ModelViewProjectionMatrix */ - GWN_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */ - GWN_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */ - GWN_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */ - GWN_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */ - GWN_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */ + GPU_UNIFORM_MODEL_INV, /* mat4 ModelMatrixInverse */ + GPU_UNIFORM_VIEW_INV, /* mat4 ViewMatrixInverse */ + GPU_UNIFORM_MODELVIEW_INV, /* mat4 ModelViewMatrixInverse */ + GPU_UNIFORM_PROJECTION_INV, /* mat4 ProjectionMatrixInverse */ + GPU_UNIFORM_VIEWPROJECTION_INV, /* mat4 ViewProjectionMatrixInverse */ - GWN_UNIFORM_NORMAL, /* mat3 NormalMatrix */ - GWN_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */ - GWN_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */ - GWN_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */ + GPU_UNIFORM_NORMAL, /* mat3 NormalMatrix */ + GPU_UNIFORM_WORLDNORMAL, /* mat3 WorldNormalMatrix */ + GPU_UNIFORM_CAMERATEXCO, /* vec4 CameraTexCoFactors */ + GPU_UNIFORM_ORCO, /* vec3 OrcoTexCoFactors[] */ - GWN_UNIFORM_COLOR, /* vec4 color */ - GWN_UNIFORM_EYE, /* vec3 eye */ - GWN_UNIFORM_CALLID, /* int callId */ + GPU_UNIFORM_COLOR, /* vec4 color */ + GPU_UNIFORM_EYE, /* vec3 eye */ + GPU_UNIFORM_CALLID, /* int callId */ - GWN_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */ + GPU_UNIFORM_CUSTOM, /* custom uniform, not one of the above built-ins */ - GWN_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ -} Gwn_UniformBuiltin; + GPU_NUM_UNIFORMS, /* Special value, denotes number of builtin uniforms. */ +} GPUUniformBuiltin; -typedef struct Gwn_ShaderInput { - struct Gwn_ShaderInput* next; +typedef struct GPUShaderInput { + struct GPUShaderInput* next; uint32_t name_offset; uint name_hash; - Gwn_UniformBuiltin builtin_type; /* only for uniform inputs */ + GPUUniformBuiltin builtin_type; /* only for uniform inputs */ uint32_t gl_type; /* only for attrib inputs */ int32_t size; /* only for attrib inputs */ int32_t location; -} Gwn_ShaderInput; +} GPUShaderInput; -#define GWN_NUM_SHADERINTERFACE_BUCKETS 257 -#define GWN_SHADERINTERFACE_REF_ALLOC_COUNT 16 +#define GPU_NUM_SHADERINTERFACE_BUCKETS 257 +#define GPU_SHADERINTERFACE_REF_ALLOC_COUNT 16 -typedef struct Gwn_ShaderInterface { +typedef struct GPUShaderInterface { int32_t program; uint32_t name_buffer_offset; - Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]; - Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS]; + GPUShaderInput* attrib_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput* uniform_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput* ubo_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput* builtin_uniforms[GPU_NUM_UNIFORMS]; char* name_buffer; - struct Gwn_Batch** batches; /* references to batches using this interface */ + struct GPUBatch** batches; /* references to batches using this interface */ uint batches_len; -} Gwn_ShaderInterface; +} GPUShaderInterface; -Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program_id); -void GWN_shaderinterface_discard(Gwn_ShaderInterface*); +GPUShaderInterface* GPU_shaderinterface_create(int32_t program_id); +void GPU_shaderinterface_discard(GPUShaderInterface*); -const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface*, const char* name); -const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface*, Gwn_UniformBuiltin); -const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name); -const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name); +const GPUShaderInput* GPU_shaderinterface_uniform(const GPUShaderInterface*, const char* name); +const GPUShaderInput* GPU_shaderinterface_uniform_builtin(const GPUShaderInterface*, GPUUniformBuiltin); +const GPUShaderInput* GPU_shaderinterface_ubo(const GPUShaderInterface*, const char* name); +const GPUShaderInput* GPU_shaderinterface_attr(const GPUShaderInterface*, const char* name); /* keep track of batches using this interface */ -void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); -void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface*, struct Gwn_Batch*); +void GPU_shaderinterface_add_batch_ref(GPUShaderInterface*, struct GPUBatch*); +void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface*, struct GPUBatch*); -#endif /* __GWN_SHADER_INTERFACE_H__ */ +#endif /* __GPU_SHADER_INTERFACE_H__ */ diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 3ed9014d431..e3db18f1358 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -41,7 +41,7 @@ extern "C" { struct Image; struct ImageUser; struct PreviewImage; -struct Gwn_VertBuf; +struct GPUVertBuf; struct GPUFrameBuffer; typedef struct GPUTexture GPUTexture; @@ -174,7 +174,7 @@ GPUTexture *GPU_texture_create_3D( GPUTexture *GPU_texture_create_cube( int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_from_vertbuf( - struct Gwn_VertBuf *vert); + struct GPUVertBuf *vert); GPUTexture *GPU_texture_create_buffer( GPUTextureFormat data_type, const uint buffer); diff --git a/source/blender/gpu/GPU_vertex_array_id.h b/source/blender/gpu/GPU_vertex_array_id.h index 925cd74511d..3b3fdc1709d 100644 --- a/source/blender/gpu/GPU_vertex_array_id.h +++ b/source/blender/gpu/GPU_vertex_array_id.h @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_vertex_array_id.h +/** \file blender/gpu/GPU_vertex_array_id.h * \ingroup gpu * * Manage GL vertex array IDs in a thread-safe way @@ -34,8 +34,8 @@ * - free can be called from any thread */ -#ifndef __GWN_VERTEX_ARRAY_ID_H__ -#define __GWN_VERTEX_ARRAY_ID_H__ +#ifndef __GPU_VERTEX_ARRAY_ID_H__ +#define __GPU_VERTEX_ARRAY_ID_H__ #ifdef __cplusplus extern "C" { @@ -44,12 +44,12 @@ extern "C" { #include "GPU_common.h" #include "GPU_context.h" -GLuint GWN_vao_default(void); -GLuint GWN_vao_alloc(void); -void GWN_vao_free(GLuint vao_id, Gwn_Context*); +GLuint GPU_vao_default(void); +GLuint GPU_vao_alloc(void); +void GPU_vao_free(GLuint vao_id, GPUContext*); #ifdef __cplusplus } #endif -#endif /* __GWN_VERTEX_ARRAY_ID_H__ */ +#endif /* __GPU_VERTEX_ARRAY_ID_H__ */ diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index 7e4aa24ff2c..896de387065 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -23,73 +23,73 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_vertex_buffer.h +/** \file blender/gpu/GPU_vertex_buffer.h * \ingroup gpu * - * Gawain vertex buffer + * GPU vertex buffer */ -#ifndef __GWN_VERTEX_BUFFER_H__ -#define __GWN_VERTEX_BUFFER_H__ +#ifndef __GPU_VERTEX_BUFFER_H__ +#define __GPU_VERTEX_BUFFER_H__ #include "GPU_vertex_format.h" #define VRAM_USAGE 1 -/* How to create a Gwn_VertBuf: */ -/* 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts) */ -/* 2) GWN_vertformat_attr_add(verts->format, ...) */ -/* 3) GWN_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format */ -/* 4) GWN_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ +/* How to create a GPUVertBuf: */ +/* 1) verts = GPU_vertbuf_create() or GPU_vertbuf_init(verts) */ +/* 2) GPU_vertformat_attr_add(verts->format, ...) */ +/* 3) GPU_vertbuf_data_alloc(verts, vertex_len) <-- finalizes/packs vertex format */ +/* 4) GPU_vertbuf_attr_fill(verts, pos, application_pos_buffer) */ -/* Is Gwn_VertBuf always used as part of a Gwn_Batch? */ +/* Is GPUVertBuf always used as part of a GPUBatch? */ typedef enum { /* can be extended to support more types */ - GWN_USAGE_STREAM, - GWN_USAGE_STATIC, /* do not keep data in memory */ - GWN_USAGE_DYNAMIC -} Gwn_UsageType; + GPU_USAGE_STREAM, + GPU_USAGE_STATIC, /* do not keep data in memory */ + GPU_USAGE_DYNAMIC +} GPUUsageType; -typedef struct Gwn_VertBuf { - Gwn_VertFormat format; +typedef struct GPUVertBuf { + GPUVertFormat format; uint vertex_len; /* number of verts we want to draw */ uint vertex_alloc; /* number of verts data */ bool dirty; unsigned char* data; /* NULL indicates data in VRAM (unmapped) */ uint32_t vbo_id; /* 0 indicates not yet allocated */ - Gwn_UsageType usage; /* usage hint for GL optimisation */ -} Gwn_VertBuf; + GPUUsageType usage; /* usage hint for GL optimisation */ +} GPUVertBuf; -Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType); -Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat*, Gwn_UsageType); +GPUVertBuf* GPU_vertbuf_create(GPUUsageType); +GPUVertBuf* GPU_vertbuf_create_with_format_ex(const GPUVertFormat*, GPUUsageType); -#define GWN_vertbuf_create_with_format(format) \ - GWN_vertbuf_create_with_format_ex(format, GWN_USAGE_STATIC) +#define GPU_vertbuf_create_with_format(format) \ + GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC) -void GWN_vertbuf_discard(Gwn_VertBuf*); +void GPU_vertbuf_discard(GPUVertBuf*); -void GWN_vertbuf_init(Gwn_VertBuf*, Gwn_UsageType); -void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf*, const Gwn_VertFormat*, Gwn_UsageType); +void GPU_vertbuf_init(GPUVertBuf*, GPUUsageType); +void GPU_vertbuf_init_with_format_ex(GPUVertBuf*, const GPUVertFormat*, GPUUsageType); -#define GWN_vertbuf_init_with_format(verts, format) \ - GWN_vertbuf_init_with_format_ex(verts, format, GWN_USAGE_STATIC) +#define GPU_vertbuf_init_with_format(verts, format) \ + GPU_vertbuf_init_with_format_ex(verts, format, GPU_USAGE_STATIC) -uint GWN_vertbuf_size_get(const Gwn_VertBuf*); -void GWN_vertbuf_data_alloc(Gwn_VertBuf*, uint v_len); -void GWN_vertbuf_data_resize(Gwn_VertBuf*, uint v_len); -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf*, uint v_len); +uint GPU_vertbuf_size_get(const GPUVertBuf*); +void GPU_vertbuf_data_alloc(GPUVertBuf*, uint v_len); +void GPU_vertbuf_data_resize(GPUVertBuf*, uint v_len); +void GPU_vertbuf_vertex_count_set(GPUVertBuf*, uint v_len); /* The most important set_attrib variant is the untyped one. Get it right first. */ /* It takes a void* so the app developer is responsible for matching their app data types */ /* to the vertex attribute's type and component count. They're in control of both, so this */ /* should not be a problem. */ -void GWN_vertbuf_attr_set(Gwn_VertBuf*, uint a_idx, uint v_idx, const void* data); -void GWN_vertbuf_attr_fill(Gwn_VertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, uint a_idx, uint stride, const void* data); +void GPU_vertbuf_attr_set(GPUVertBuf*, uint a_idx, uint v_idx, const void* data); +void GPU_vertbuf_attr_fill(GPUVertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ +void GPU_vertbuf_attr_fill_stride(GPUVertBuf*, uint a_idx, uint stride, const void* data); /* For low level access only */ -typedef struct Gwn_VertBufRaw { +typedef struct GPUVertBufRaw { uint size; uint stride; unsigned char* data; @@ -98,9 +98,9 @@ typedef struct Gwn_VertBufRaw { /* Only for overflow check */ unsigned char* _data_end; #endif -} Gwn_VertBufRaw; +} GPUVertBufRaw; -GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) +GPU_INLINE void *GPU_vertbuf_raw_step(GPUVertBufRaw *a) { unsigned char* data = a->data; a->data += a->stride; @@ -110,12 +110,12 @@ GWN_INLINE void *GWN_vertbuf_raw_step(Gwn_VertBufRaw *a) return (void *)data; } -GWN_INLINE uint GWN_vertbuf_raw_used(Gwn_VertBufRaw *a) +GPU_INLINE uint GPU_vertbuf_raw_used(GPUVertBufRaw *a) { return ((a->data - a->data_init) / a->stride); } -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, uint a_idx, Gwn_VertBufRaw *access); +void GPU_vertbuf_attr_get_raw_data(GPUVertBuf*, uint a_idx, GPUVertBufRaw *access); /* TODO: decide whether to keep the functions below */ /* doesn't immediate mode satisfy these needs? */ @@ -128,17 +128,17 @@ void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf*, uint a_idx, Gwn_VertBufRaw *acc /* void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); */ /* void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); */ -void GWN_vertbuf_use(Gwn_VertBuf*); +void GPU_vertbuf_use(GPUVertBuf*); /* Metrics */ -uint GWN_vertbuf_get_memory_usage(void); +uint GPU_vertbuf_get_memory_usage(void); /* Macros */ -#define GWN_VERTBUF_DISCARD_SAFE(verts) do { \ +#define GPU_VERTBUF_DISCARD_SAFE(verts) do { \ if (verts != NULL) { \ - GWN_vertbuf_discard(verts); \ + GPU_vertbuf_discard(verts); \ verts = NULL; \ } \ } while (0) -#endif /* __GWN_VERTEX_BUFFER_H__ */ +#endif /* __GPU_VERTEX_BUFFER_H__ */ diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index 91e31b5ece4..7ae8118a928 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -23,79 +23,79 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_vertex_format.h +/** \file blender/gpu/GPU_vertex_format.h * \ingroup gpu * - * Gawain vertex format + * GPU vertex format */ -#ifndef __GWN_VERTEX_FORMAT_H__ -#define __GWN_VERTEX_FORMAT_H__ +#ifndef __GPU_VERTEX_FORMAT_H__ +#define __GPU_VERTEX_FORMAT_H__ #include "GPU_common.h" -#define GWN_VERT_ATTR_MAX_LEN 16 -#define GWN_VERT_ATTR_MAX_NAMES 3 -#define GWN_VERT_ATTR_NAME_AVERAGE_LEN 11 -#define GWN_VERT_ATTR_NAMES_BUF_LEN ((GWN_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GWN_VERT_ATTR_MAX_LEN) +#define GPU_VERT_ATTR_MAX_LEN 16 +#define GPU_VERT_ATTR_MAX_NAMES 3 +#define GPU_VERT_ATTR_NAME_AVERAGE_LEN 11 +#define GPU_VERT_ATTR_NAMES_BUF_LEN ((GPU_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GPU_VERT_ATTR_MAX_LEN) typedef enum { - GWN_COMP_I8, - GWN_COMP_U8, - GWN_COMP_I16, - GWN_COMP_U16, - GWN_COMP_I32, - GWN_COMP_U32, + GPU_COMP_I8, + GPU_COMP_U8, + GPU_COMP_I16, + GPU_COMP_U16, + GPU_COMP_I32, + GPU_COMP_U32, - GWN_COMP_F32, + GPU_COMP_F32, - GWN_COMP_I10 -} Gwn_VertCompType; + GPU_COMP_I10 +} GPUVertCompType; typedef enum { - GWN_FETCH_FLOAT, - GWN_FETCH_INT, - GWN_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ - GWN_FETCH_INT_TO_FLOAT /* 127 (any int type) -> 127.0 */ -} Gwn_VertFetchMode; - -typedef struct Gwn_VertAttr { - Gwn_VertFetchMode fetch_mode; - Gwn_VertCompType comp_type; + GPU_FETCH_FLOAT, + GPU_FETCH_INT, + GPU_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */ + GPU_FETCH_INT_TO_FLOAT /* 127 (any int type) -> 127.0 */ +} GPUVertFetchMode; + +typedef struct GPUVertAttr { + GPUVertFetchMode fetch_mode; + GPUVertCompType comp_type; uint gl_comp_type; uint comp_len; /* 1 to 4 or 8 or 12 or 16 */ uint sz; /* size in bytes, 1 to 64 */ uint offset; /* from beginning of vertex, in bytes */ - uint name_len; /* up to GWN_VERT_ATTR_MAX_NAMES */ - const char* name[GWN_VERT_ATTR_MAX_NAMES]; -} Gwn_VertAttr; + uint name_len; /* up to GPU_VERT_ATTR_MAX_NAMES */ + const char* name[GPU_VERT_ATTR_MAX_NAMES]; +} GPUVertAttr; -typedef struct Gwn_VertFormat { - uint attr_len; /* 0 to 16 (GWN_VERT_ATTR_MAX_LEN) */ +typedef struct GPUVertFormat { + uint attr_len; /* 0 to 16 (GPU_VERT_ATTR_MAX_LEN) */ uint name_len; /* total count of active vertex attrib */ uint stride; /* stride in bytes, 1 to 256 */ uint name_offset; bool packed; - char names[GWN_VERT_ATTR_NAMES_BUF_LEN]; - Gwn_VertAttr attribs[GWN_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ -} Gwn_VertFormat; + char names[GPU_VERT_ATTR_NAMES_BUF_LEN]; + GPUVertAttr attribs[GPU_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ +} GPUVertFormat; -void GWN_vertformat_clear(Gwn_VertFormat*); -void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src); +void GPU_vertformat_clear(GPUVertFormat*); +void GPU_vertformat_copy(GPUVertFormat* dest, const GPUVertFormat* src); -uint GWN_vertformat_attr_add(Gwn_VertFormat*, const char* name, Gwn_VertCompType, uint comp_len, Gwn_VertFetchMode); -void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias); +uint GPU_vertformat_attr_add(GPUVertFormat*, const char* name, GPUVertCompType, uint comp_len, GPUVertFetchMode); +void GPU_vertformat_alias_add(GPUVertFormat*, const char* alias); /* format conversion */ -typedef struct Gwn_PackedNormal { +typedef struct GPUPackedNormal { int x : 10; int y : 10; int z : 10; int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ -} Gwn_PackedNormal; +} GPUPackedNormal; -Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]); -Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]); +GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3]); +GPUPackedNormal GPU_normal_convert_i10_s3(const short data[3]); -#endif /* __GWN_VERTEX_FORMAT_H__ */ +#endif /* __GPU_VERTEX_FORMAT_H__ */ diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.c index e7eba369335..9ac38578792 100644 --- a/source/blender/gpu/intern/gpu_attr_binding.c +++ b/source/blender/gpu/intern/gpu_attr_binding.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_attr_binding.c +/** \file blender/gpu/intern/gpu_attr_binding.c * \ingroup gpu * - * Gawain vertex attribute binding + * GPU vertex attribute binding */ #include "GPU_attr_binding.h" @@ -34,30 +34,30 @@ #include #include -#if GWN_VERT_ATTR_MAX_LEN != 16 - #error "attrib binding code assumes GWN_VERT_ATTR_MAX_LEN = 16" +#if GPU_VERT_ATTR_MAX_LEN != 16 + #error "attrib binding code assumes GPU_VERT_ATTR_MAX_LEN = 16" #endif -void AttribBinding_clear(Gwn_AttrBinding* binding) +void AttribBinding_clear(GPUAttrBinding* binding) { binding->loc_bits = 0; binding->enabled_bits = 0; } -uint read_attrib_location(const Gwn_AttrBinding* binding, uint a_idx) +uint read_attrib_location(const GPUAttrBinding* binding, uint a_idx) { #if TRUST_NO_ONE - assert(a_idx < GWN_VERT_ATTR_MAX_LEN); + assert(a_idx < GPU_VERT_ATTR_MAX_LEN); assert(binding->enabled_bits & (1 << a_idx)); #endif return (binding->loc_bits >> (4 * a_idx)) & 0xF; } -static void write_attrib_location(Gwn_AttrBinding* binding, uint a_idx, uint location) +static void write_attrib_location(GPUAttrBinding* binding, uint a_idx, uint location) { #if TRUST_NO_ONE - assert(a_idx < GWN_VERT_ATTR_MAX_LEN); - assert(location < GWN_VERT_ATTR_MAX_LEN); + assert(a_idx < GPU_VERT_ATTR_MAX_LEN); + assert(location < GPU_VERT_ATTR_MAX_LEN); #endif const uint shift = 4 * a_idx; const uint64_t mask = ((uint64_t)0xF) << shift; @@ -67,14 +67,14 @@ static void write_attrib_location(Gwn_AttrBinding* binding, uint a_idx, uint loc binding->enabled_bits |= 1 << a_idx; } -void get_attrib_locations(const Gwn_VertFormat* format, Gwn_AttrBinding* binding, const Gwn_ShaderInterface* shaderface) +void get_attrib_locations(const GPUVertFormat* format, GPUAttrBinding* binding, const GPUShaderInterface* shaderface) { AttribBinding_clear(binding); for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) { - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertAttr* a = format->attribs + a_idx; for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const Gwn_ShaderInput* input = GWN_shaderinterface_attr(shaderface, a->name[n_idx]); + const GPUShaderInput* input = GPU_shaderinterface_attr(shaderface, a->name[n_idx]); #if TRUST_NO_ONE assert(input != NULL); /* TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program */ diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h index 0e0bf89178a..240509de0d4 100644 --- a/source/blender/gpu/intern/gpu_attr_binding_private.h +++ b/source/blender/gpu/intern/gpu_attr_binding_private.h @@ -23,21 +23,21 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_attr_binding_private.h +/** \file blender/gpu/intern/gpu_attr_binding_private.h * \ingroup gpu * - * Gawain vertex attribute binding + * GPU vertex attribute binding */ -#ifndef __GWN_ATTR_BINDING_PRIVATE_H__ -#define __GWN_ATTR_BINDING_PRIVATE_H__ +#ifndef __GPU_ATTR_BINDING_PRIVATE_H__ +#define __GPU_ATTR_BINDING_PRIVATE_H__ #include "GPU_vertex_format.h" #include "GPU_shader_interface.h" -void AttribBinding_clear(Gwn_AttrBinding*); +void AttribBinding_clear(GPUAttrBinding*); -void get_attrib_locations(const Gwn_VertFormat*, Gwn_AttrBinding*, const Gwn_ShaderInterface*); -unsigned read_attrib_location(const Gwn_AttrBinding*, unsigned a_idx); +void get_attrib_locations(const GPUVertFormat*, GPUAttrBinding*, const GPUShaderInterface*); +unsigned read_attrib_location(const GPUAttrBinding*, unsigned a_idx); -#endif /* __GWN_ATTR_BINDING_PRIVATE_H__ */ +#endif /* __GPU_ATTR_BINDING_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 90f30930884..4d455f6f464 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_batch.c +/** \file blender/gpu/intern/gpu_batch.c * \ingroup gpu * - * Gawain geometry batch + * GPU geometry batch * Contains VAOs + VBOs + Shader representing a drawable entity. */ @@ -44,9 +44,9 @@ #include #include -static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first); +static void batch_update_program_bindings(GPUBatch* batch, uint v_first); -void gwn_batch_vao_cache_clear(Gwn_Batch* batch) +void GPU_batch_vao_cache_clear(GPUBatch* batch) { if (batch->context == NULL) { return; @@ -54,45 +54,45 @@ void gwn_batch_vao_cache_clear(Gwn_Batch* batch) if (batch->is_dynamic_vao_count) { for (int i = 0; i < batch->dynamic_vaos.count; ++i) { if (batch->dynamic_vaos.vao_ids[i]) { - GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); + GPU_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); } if (batch->dynamic_vaos.interfaces[i]) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); + GPU_shaderinterface_remove_batch_ref((GPUShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); } } free(batch->dynamic_vaos.interfaces); free(batch->dynamic_vaos.vao_ids); } else { - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + for (int i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) { if (batch->static_vaos.vao_ids[i]) { - GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); + GPU_vao_free(batch->static_vaos.vao_ids[i], batch->context); } if (batch->static_vaos.interfaces[i]) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface *)batch->static_vaos.interfaces[i], batch); + GPU_shaderinterface_remove_batch_ref((GPUShaderInterface *)batch->static_vaos.interfaces[i], batch); } } } batch->is_dynamic_vao_count = false; - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + for (int i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) { batch->static_vaos.vao_ids[i] = 0; batch->static_vaos.interfaces[i] = NULL; } - gwn_context_remove_batch(batch->context, batch); + gpu_context_remove_batch(batch->context, batch); batch->context = NULL; } -Gwn_Batch* GWN_batch_create_ex( - Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, +GPUBatch* GPU_batch_create_ex( + GPUPrimType prim_type, GPUVertBuf* verts, GPUIndexBuf* elem, uint owns_flag) { - Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch)); - GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag); + GPUBatch* batch = calloc(1, sizeof(GPUBatch)); + GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } -void GWN_batch_init_ex( - Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, +void GPU_batch_init_ex( + GPUBatch* batch, GPUPrimType prim_type, GPUVertBuf* verts, GPUIndexBuf* elem, uint owns_flag) { #if TRUST_NO_ONE @@ -100,49 +100,49 @@ void GWN_batch_init_ex( #endif batch->verts[0] = verts; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; ++v) { batch->verts[v] = NULL; } batch->inst = NULL; batch->elem = elem; batch->gl_prim_type = convert_prim_type_to_gl(prim_type); - batch->phase = GWN_BATCH_READY_TO_DRAW; + batch->phase = GPU_BATCH_READY_TO_DRAW; batch->is_dynamic_vao_count = false; batch->owns_flag = owns_flag; batch->free_callback = NULL; } /* This will share the VBOs with the new batch. */ -Gwn_Batch* GWN_batch_duplicate(Gwn_Batch* batch_src) +GPUBatch* GPU_batch_duplicate(GPUBatch* batch_src) { - Gwn_Batch* batch = GWN_batch_create_ex(GWN_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); + GPUBatch* batch = GPU_batch_create_ex(GPU_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); batch->gl_prim_type = batch_src->gl_prim_type; - for (int v = 1; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; ++v) { batch->verts[v] = batch_src->verts[v]; } return batch; } -void GWN_batch_discard(Gwn_Batch* batch) +void GPU_batch_discard(GPUBatch* batch) { - if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) { - GWN_indexbuf_discard(batch->elem); + if (batch->owns_flag & GPU_BATCH_OWNS_INDEX) { + GPU_indexbuf_discard(batch->elem); } - if (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES) { - GWN_vertbuf_discard(batch->inst); + if (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES) { + GPU_vertbuf_discard(batch->inst); } - if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) { - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + if ((batch->owns_flag & ~GPU_BATCH_OWNS_INDEX) != 0) { + for (int v = 0; v < GPU_BATCH_VBO_MAX_LEN; ++v) { if (batch->verts[v] == NULL) { break; } if (batch->owns_flag & (1 << v)) { - GWN_vertbuf_discard(batch->verts[v]); + GPU_vertbuf_discard(batch->verts[v]); } } } - gwn_batch_vao_cache_clear(batch); + GPU_batch_vao_cache_clear(batch); if (batch->free_callback) { batch->free_callback(batch, batch->callback_data); @@ -150,42 +150,42 @@ void GWN_batch_discard(Gwn_Batch* batch) free(batch); } -void GWN_batch_callback_free_set(Gwn_Batch* batch, void (*callback)(Gwn_Batch*, void*), void* user_data) +void GPU_batch_callback_free_set(GPUBatch* batch, void (*callback)(GPUBatch*, void*), void* user_data) { batch->free_callback = callback; batch->callback_data = user_data; } -void GWN_batch_instbuf_set(Gwn_Batch* batch, Gwn_VertBuf* inst, bool own_vbo) +void GPU_batch_instbuf_set(GPUBatch* batch, GPUVertBuf* inst, bool own_vbo) { #if TRUST_NO_ONE assert(inst != NULL); #endif /* redo the bindings */ - gwn_batch_vao_cache_clear(batch); + GPU_batch_vao_cache_clear(batch); - if (batch->inst != NULL && (batch->owns_flag & GWN_BATCH_OWNS_INSTANCES)) { - GWN_vertbuf_discard(batch->inst); + if (batch->inst != NULL && (batch->owns_flag & GPU_BATCH_OWNS_INSTANCES)) { + GPU_vertbuf_discard(batch->inst); } batch->inst = inst; if (own_vbo) { - batch->owns_flag |= GWN_BATCH_OWNS_INSTANCES; + batch->owns_flag |= GPU_BATCH_OWNS_INSTANCES; } else { - batch->owns_flag &= ~GWN_BATCH_OWNS_INSTANCES; + batch->owns_flag &= ~GPU_BATCH_OWNS_INSTANCES; } } /* Returns the index of verts in the batch. */ -int GWN_batch_vertbuf_add_ex( - Gwn_Batch* batch, Gwn_VertBuf* verts, +int GPU_batch_vertbuf_add_ex( + GPUBatch* batch, GPUVertBuf* verts, bool own_vbo) { /* redo the bindings */ - gwn_batch_vao_cache_clear(batch); + GPU_batch_vao_cache_clear(batch); - for (uint v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { + for (uint v = 0; v < GPU_BATCH_VBO_MAX_LEN; ++v) { if (batch->verts[v] == NULL) { #if TRUST_NO_ONE /* for now all VertexBuffers must have same vertex_len */ @@ -199,14 +199,14 @@ int GWN_batch_vertbuf_add_ex( } } - /* we only make it this far if there is no room for another Gwn_VertBuf */ + /* we only make it this far if there is no room for another GPUVertBuf */ #if TRUST_NO_ONE assert(false); #endif return -1; } -static GLuint batch_vao_get(Gwn_Batch *batch) +static GLuint batch_vao_get(GPUBatch *batch) { /* Search through cache */ if (batch->is_dynamic_vao_count) { @@ -215,22 +215,22 @@ static GLuint batch_vao_get(Gwn_Batch *batch) return batch->dynamic_vaos.vao_ids[i]; } else { - for (int i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) + for (int i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) if (batch->static_vaos.interfaces[i] == batch->interface) return batch->static_vaos.vao_ids[i]; } /* Set context of this batch. - * It will be bound to it until gwn_batch_vao_cache_clear is called. + * It will be bound to it until GPU_batch_vao_cache_clear is called. * Until then it can only be drawn with this context. */ if (batch->context == NULL) { - batch->context = GWN_context_active_get(); - gwn_context_add_batch(batch->context, batch); + batch->context = GPU_context_active_get(); + gpu_context_add_batch(batch->context, batch); } #if TRUST_NO_ONE else { /* Make sure you are not trying to draw this batch in another context. */ - assert(batch->context == GWN_context_active_get()); + assert(batch->context == GPU_context_active_get()); } #endif @@ -238,25 +238,25 @@ static GLuint batch_vao_get(Gwn_Batch *batch) GLuint new_vao = 0; if (!batch->is_dynamic_vao_count) { int i; /* find first unused slot */ - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) + for (i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) if (batch->static_vaos.vao_ids[i] == 0) break; - if (i < GWN_BATCH_VAO_STATIC_LEN) { + if (i < GPU_BATCH_VAO_STATIC_LEN) { batch->static_vaos.interfaces[i] = batch->interface; - batch->static_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); + batch->static_vaos.vao_ids[i] = new_vao = GPU_vao_alloc(); } else { /* Not enough place switch to dynamic. */ batch->is_dynamic_vao_count = true; /* Erase previous entries, they will be added back if drawn again. */ - for (int j = 0; j < GWN_BATCH_VAO_STATIC_LEN; ++j) { - GWN_shaderinterface_remove_batch_ref((Gwn_ShaderInterface*)batch->static_vaos.interfaces[j], batch); - GWN_vao_free(batch->static_vaos.vao_ids[j], batch->context); + for (int j = 0; j < GPU_BATCH_VAO_STATIC_LEN; ++j) { + GPU_shaderinterface_remove_batch_ref((GPUShaderInterface*)batch->static_vaos.interfaces[j], batch); + GPU_vao_free(batch->static_vaos.vao_ids[j], batch->context); } /* Init dynamic arrays and let the branch below set the values. */ - batch->dynamic_vaos.count = GWN_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(Gwn_ShaderInterface*)); + batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT; + batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(GPUShaderInterface*)); batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); } } @@ -270,17 +270,17 @@ static GLuint batch_vao_get(Gwn_Batch *batch) if (i == batch->dynamic_vaos.count) { /* Not enough place, realloc the array. */ i = batch->dynamic_vaos.count; - batch->dynamic_vaos.count += GWN_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(Gwn_ShaderInterface*) * batch->dynamic_vaos.count); + batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT; + batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(GPUShaderInterface*) * batch->dynamic_vaos.count); batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); - memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(Gwn_ShaderInterface*) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); - memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GWN_BATCH_VAO_DYN_ALLOC_COUNT); + memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(GPUShaderInterface*) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); + memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); } batch->dynamic_vaos.interfaces[i] = batch->interface; - batch->dynamic_vaos.vao_ids[i] = new_vao = GWN_vao_alloc(); + batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc(); } - GWN_shaderinterface_add_batch_ref((Gwn_ShaderInterface*)batch->interface, batch); + GPU_shaderinterface_add_batch_ref((GPUShaderInterface*)batch->interface, batch); #if TRUST_NO_ONE assert(new_vao != 0); @@ -294,7 +294,7 @@ static GLuint batch_vao_get(Gwn_Batch *batch) return new_vao; } -void GWN_batch_program_set_no_use(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) +void GPU_batch_program_set_no_use(GPUBatch* batch, uint32_t program, const GPUShaderInterface* shaderface) { #if TRUST_NO_ONE assert(glIsProgram(shaderface->program)); @@ -305,18 +305,18 @@ void GWN_batch_program_set_no_use(Gwn_Batch* batch, uint32_t program, const Gwn_ batch->vao_id = batch_vao_get(batch); } -void GWN_batch_program_set(Gwn_Batch* batch, uint32_t program, const Gwn_ShaderInterface* shaderface) +void GPU_batch_program_set(GPUBatch* batch, uint32_t program, const GPUShaderInterface* shaderface) { - GWN_batch_program_set_no_use(batch, program, shaderface); - GWN_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ + GPU_batch_program_set_no_use(batch, program, shaderface); + GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ } -void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* interface) +void gpu_batch_remove_interface_ref(GPUBatch* batch, const GPUShaderInterface* interface) { if (batch->is_dynamic_vao_count) { for (int i = 0; i < batch->dynamic_vaos.count; ++i) { if (batch->dynamic_vaos.interfaces[i] == interface) { - GWN_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); + GPU_vao_free(batch->dynamic_vaos.vao_ids[i], batch->context); batch->dynamic_vaos.vao_ids[i] = 0; batch->dynamic_vaos.interfaces[i] = NULL; break; /* cannot have duplicates */ @@ -325,9 +325,9 @@ void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* } else { int i; - for (i = 0; i < GWN_BATCH_VAO_STATIC_LEN; ++i) { + for (i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) { if (batch->static_vaos.interfaces[i] == interface) { - GWN_vao_free(batch->static_vaos.vao_ids[i], batch->context); + GPU_vao_free(batch->static_vaos.vao_ids[i], batch->context); batch->static_vaos.vao_ids[i] = 0; batch->static_vaos.interfaces[i] = NULL; break; /* cannot have duplicates */ @@ -337,28 +337,28 @@ void gwn_batch_remove_interface_ref(Gwn_Batch* batch, const Gwn_ShaderInterface* } static void create_bindings( - Gwn_VertBuf* verts, const Gwn_ShaderInterface* interface, + GPUVertBuf* verts, const GPUShaderInterface* interface, uint v_first, const bool use_instancing) { - const Gwn_VertFormat* format = &verts->format; + const GPUVertFormat* format = &verts->format; const uint attr_len = format->attr_len; const uint stride = format->stride; - GWN_vertbuf_use(verts); + GPU_vertbuf_use(verts); for (uint a_idx = 0; a_idx < attr_len; ++a_idx) { - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertAttr* a = format->attribs + a_idx; const GLvoid* pointer = (const GLubyte*)0 + a->offset + v_first * stride; for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const Gwn_ShaderInput* input = GWN_shaderinterface_attr(interface, a->name[n_idx]); + const GPUShaderInput* input = GPU_shaderinterface_attr(interface, a->name[n_idx]); if (input == NULL) continue; if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { #if TRUST_NO_ONE - assert(a->fetch_mode == GWN_FETCH_FLOAT); + assert(a->fetch_mode == GPU_FETCH_FLOAT); assert(a->gl_comp_type == GL_FLOAT); #endif for (int i = 0; i < a->comp_len / 4; ++i) { @@ -374,14 +374,14 @@ static void create_bindings( glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0); switch (a->fetch_mode) { - case GWN_FETCH_FLOAT: - case GWN_FETCH_INT_TO_FLOAT: + case GPU_FETCH_FLOAT: + case GPU_FETCH_INT_TO_FLOAT: glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); break; - case GWN_FETCH_INT_TO_FLOAT_UNIT: + case GPU_FETCH_INT_TO_FLOAT_UNIT: glVertexAttribPointer(input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); break; - case GWN_FETCH_INT: + case GPU_FETCH_INT: glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer); break; } @@ -390,20 +390,20 @@ static void create_bindings( } } -static void batch_update_program_bindings(Gwn_Batch* batch, uint v_first) +static void batch_update_program_bindings(GPUBatch* batch, uint v_first) { - for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { + for (int v = 0; v < GPU_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false); } if (batch->inst) { create_bindings(batch->inst, batch->interface, v_first, true); } if (batch->elem) { - GWN_indexbuf_use(batch->elem); + GPU_indexbuf_use(batch->elem); } } -void GWN_batch_program_use_begin(Gwn_Batch* batch) +void GPU_batch_program_use_begin(GPUBatch* batch) { /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with * the GL context's active program. use_program doesn't mark other programs as "not used". */ @@ -415,7 +415,7 @@ void GWN_batch_program_use_begin(Gwn_Batch* batch) } } -void GWN_batch_program_use_end(Gwn_Batch* batch) +void GPU_batch_program_use_end(GPUBatch* batch) { if (batch->program_in_use) { #if PROGRAM_NO_OPTI @@ -426,99 +426,99 @@ void GWN_batch_program_use_end(Gwn_Batch* batch) } #if TRUST_NO_ONE - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); assert(uniform); + #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(batch->interface, name); assert(uniform); #else - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(batch->interface, name); + #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(batch->interface, name); #endif -void GWN_batch_uniform_1ui(Gwn_Batch* batch, const char* name, int value) +void GPU_batch_uniform_1ui(GPUBatch* batch, const char* name, int value) { GET_UNIFORM glUniform1ui(uniform->location, value); } -void GWN_batch_uniform_1i(Gwn_Batch* batch, const char* name, int value) +void GPU_batch_uniform_1i(GPUBatch* batch, const char* name, int value) { GET_UNIFORM glUniform1i(uniform->location, value); } -void GWN_batch_uniform_1b(Gwn_Batch* batch, const char* name, bool value) +void GPU_batch_uniform_1b(GPUBatch* batch, const char* name, bool value) { GET_UNIFORM glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE); } -void GWN_batch_uniform_2f(Gwn_Batch* batch, const char* name, float x, float y) +void GPU_batch_uniform_2f(GPUBatch* batch, const char* name, float x, float y) { GET_UNIFORM glUniform2f(uniform->location, x, y); } -void GWN_batch_uniform_3f(Gwn_Batch* batch, const char* name, float x, float y, float z) +void GPU_batch_uniform_3f(GPUBatch* batch, const char* name, float x, float y, float z) { GET_UNIFORM glUniform3f(uniform->location, x, y, z); } -void GWN_batch_uniform_4f(Gwn_Batch* batch, const char* name, float x, float y, float z, float w) +void GPU_batch_uniform_4f(GPUBatch* batch, const char* name, float x, float y, float z, float w) { GET_UNIFORM glUniform4f(uniform->location, x, y, z, w); } -void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x) +void GPU_batch_uniform_1f(GPUBatch* batch, const char* name, float x) { GET_UNIFORM glUniform1f(uniform->location, x); } -void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2]) +void GPU_batch_uniform_2fv(GPUBatch* batch, const char* name, const float data[2]) { GET_UNIFORM glUniform2fv(uniform->location, 1, data); } -void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3]) +void GPU_batch_uniform_3fv(GPUBatch* batch, const char* name, const float data[3]) { GET_UNIFORM glUniform3fv(uniform->location, 1, data); } -void GWN_batch_uniform_4fv(Gwn_Batch* batch, const char* name, const float data[4]) +void GPU_batch_uniform_4fv(GPUBatch* batch, const char* name, const float data[4]) { GET_UNIFORM glUniform4fv(uniform->location, 1, data); } -void GWN_batch_uniform_2fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) +void GPU_batch_uniform_2fv_array(GPUBatch* batch, const char* name, const int len, const float *data) { GET_UNIFORM glUniform2fv(uniform->location, len, data); } -void GWN_batch_uniform_4fv_array(Gwn_Batch* batch, const char* name, const int len, const float *data) +void GPU_batch_uniform_4fv_array(GPUBatch* batch, const char* name, const int len, const float *data) { GET_UNIFORM glUniform4fv(uniform->location, len, data); } -void GWN_batch_uniform_mat4(Gwn_Batch* batch, const char* name, const float data[4][4]) +void GPU_batch_uniform_mat4(GPUBatch* batch, const char* name, const float data[4][4]) { GET_UNIFORM glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); } -static void primitive_restart_enable(const Gwn_IndexBuf *el) +static void primitive_restart_enable(const GPUIndexBuf *el) { // TODO(fclem) Replace by GL_PRIMITIVE_RESTART_FIXED_INDEX when we have ogl 4.3 glEnable(GL_PRIMITIVE_RESTART); GLuint restart_index = (GLuint)0xFFFFFFFF; -#if GWN_TRACK_INDEX_RANGE - if (el->index_type == GWN_INDEX_U8) +#if GPU_TRACK_INDEX_RANGE + if (el->index_type == GPU_INDEX_U8) restart_index = (GLuint)0xFF; - else if (el->index_type == GWN_INDEX_U16) + else if (el->index_type == GPU_INDEX_U16) restart_index = (GLuint)0xFFFF; #endif @@ -530,21 +530,21 @@ static void primitive_restart_disable(void) glDisable(GL_PRIMITIVE_RESTART); } -void GWN_batch_draw(Gwn_Batch* batch) +void GPU_batch_draw(GPUBatch* batch) { #if TRUST_NO_ONE - assert(batch->phase == GWN_BATCH_READY_TO_DRAW); + assert(batch->phase == GPU_BATCH_READY_TO_DRAW); assert(batch->verts[0]->vbo_id != 0); #endif - GWN_batch_program_use_begin(batch); + GPU_batch_program_use_begin(batch); GPU_matrix_bind(batch->interface); // external call. - GWN_batch_draw_range_ex(batch, 0, 0, false); + GPU_batch_draw_range_ex(batch, 0, 0, false); - GWN_batch_program_use_end(batch); + GPU_batch_program_use_end(batch); } -void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool force_instance) +void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool force_instance) { #if TRUST_NO_ONE assert(!(force_instance && (batch->inst == NULL)) || v_count > 0); // we cannot infer length if force_instance @@ -553,7 +553,7 @@ void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool fo // If using offset drawing, use the default VAO and redo bindings. if (v_first != 0 && (do_instance || batch->elem)) { - glBindVertexArray(GWN_vao_default()); + glBindVertexArray(GPU_vao_default()); batch_update_program_bindings(batch, v_first); } else { @@ -567,12 +567,12 @@ void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool fo } if (batch->elem) { - const Gwn_IndexBuf* el = batch->elem; + const GPUIndexBuf* el = batch->elem; if (el->use_prim_restart) { primitive_restart_enable(el); } -#if GWN_TRACK_INDEX_RANGE +#if GPU_TRACK_INDEX_RANGE glDrawElementsInstancedBaseVertex(batch->gl_prim_type, el->index_len, el->gl_index_type, @@ -597,13 +597,13 @@ void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool fo } if (batch->elem) { - const Gwn_IndexBuf* el = batch->elem; + const GPUIndexBuf* el = batch->elem; if (el->use_prim_restart) { primitive_restart_enable(el); } -#if GWN_TRACK_INDEX_RANGE +#if GPU_TRACK_INDEX_RANGE if (el->base_index) { glDrawRangeElementsBaseVertex(batch->gl_prim_type, el->min_index, @@ -634,10 +634,10 @@ void GWN_batch_draw_range_ex(Gwn_Batch* batch, int v_first, int v_count, bool fo } /* just draw some vertices and let shader place them where we want. */ -void GWN_draw_primitive(Gwn_PrimType prim_type, int v_count) +void GPU_draw_primitive(GPUPrimType prim_type, int v_count) { /* we cannot draw without vao ... annoying ... */ - glBindVertexArray(GWN_vao_default()); + glBindVertexArray(GPU_vao_default()); GLenum type = convert_prim_type_to_gl(prim_type); glDrawArrays(type, 0, v_count); @@ -652,10 +652,10 @@ void GWN_draw_primitive(Gwn_PrimType prim_type, int v_count) /** \name Utilities * \{ */ -void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id) +void GPU_batch_program_set_builtin(GPUBatch *batch, GPUBuiltinShader shader_id) { GPUShader *shader = GPU_shader_get_builtin_shader(shader_id); - GWN_batch_program_set(batch, shader->program, shader->interface); + GPU_batch_program_set(batch, shader->program, shader->interface); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c index fb696fd09a5..83287c57441 100644 --- a/source/blender/gpu/intern/gpu_batch_presets.c +++ b/source/blender/gpu/intern/gpu_batch_presets.c @@ -45,14 +45,14 @@ /* Struct to store 3D Batches and their format */ static struct { struct { - Gwn_Batch *sphere_high; - Gwn_Batch *sphere_med; - Gwn_Batch *sphere_low; - Gwn_Batch *sphere_wire_low; - Gwn_Batch *sphere_wire_med; + GPUBatch *sphere_high; + GPUBatch *sphere_med; + GPUBatch *sphere_low; + GPUBatch *sphere_wire_low; + GPUBatch *sphere_wire_med; } batch; - Gwn_VertFormat format; + GPUVertFormat format; struct { uint pos, nor; @@ -66,28 +66,28 @@ static ListBase presets_list = {NULL, NULL}; /** \name 3D Primitives * \{ */ -static Gwn_VertFormat *preset_3d_format(void) +static GPUVertFormat *preset_3d_format(void) { if (g_presets_3d.format.attr_len == 0) { - Gwn_VertFormat *format = &g_presets_3d.format; - g_presets_3d.attr_id.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - g_presets_3d.attr_id.nor = GWN_vertformat_attr_add(format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + GPUVertFormat *format = &g_presets_3d.format; + g_presets_3d.attr_id.pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + g_presets_3d.attr_id.nor = GPU_vertformat_attr_add(format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); } return &g_presets_3d.format; } static void batch_sphere_lat_lon_vert( - Gwn_VertBufRaw *pos_step, Gwn_VertBufRaw *nor_step, + GPUVertBufRaw *pos_step, GPUVertBufRaw *nor_step, float lat, float lon) { float pos[3]; pos[0] = sinf(lat) * cosf(lon); pos[1] = cosf(lat); pos[2] = sinf(lat) * sinf(lon); - copy_v3_v3(GWN_vertbuf_raw_step(pos_step), pos); - copy_v3_v3(GWN_vertbuf_raw_step(nor_step), pos); + copy_v3_v3(GPU_vertbuf_raw_step(pos_step), pos); + copy_v3_v3(GPU_vertbuf_raw_step(nor_step), pos); } -Gwn_Batch *GPU_batch_preset_sphere(int lod) +GPUBatch *GPU_batch_preset_sphere(int lod) { BLI_assert(lod >= 0 && lod <= 2); BLI_assert(BLI_thread_is_main()); @@ -103,7 +103,7 @@ Gwn_Batch *GPU_batch_preset_sphere(int lod) } } -Gwn_Batch *GPU_batch_preset_sphere_wire(int lod) +GPUBatch *GPU_batch_preset_sphere_wire(int lod) { BLI_assert(lod >= 0 && lod <= 1); BLI_assert(BLI_thread_is_main()); @@ -123,19 +123,19 @@ Gwn_Batch *GPU_batch_preset_sphere_wire(int lod) * \{ */ /* Replacement for gluSphere */ -Gwn_Batch *gpu_batch_sphere(int lat_res, int lon_res) +GPUBatch *gpu_batch_sphere(int lat_res, int lon_res) { const float lon_inc = 2 * M_PI / lon_res; const float lat_inc = M_PI / lat_res; float lon, lat; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(preset_3d_format()); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_3d_format()); const uint vbo_len = (lat_res - 1) * lon_res * 6; - GWN_vertbuf_data_alloc(vbo, vbo_len); + GPU_vertbuf_data_alloc(vbo, vbo_len); - Gwn_VertBufRaw pos_step, nor_step; - GWN_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step); - GWN_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step); + GPUVertBufRaw pos_step, nor_step; + GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step); + GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step); lon = 0.0f; for (int i = 0; i < lon_res; i++, lon += lon_inc) { @@ -155,25 +155,25 @@ Gwn_Batch *gpu_batch_sphere(int lat_res, int lon_res) } } - BLI_assert(vbo_len == GWN_vertbuf_raw_used(&pos_step)); - BLI_assert(vbo_len == GWN_vertbuf_raw_used(&nor_step)); + BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step)); - return GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO); + return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); } -static Gwn_Batch *batch_sphere_wire(int lat_res, int lon_res) +static GPUBatch *batch_sphere_wire(int lat_res, int lon_res) { const float lon_inc = 2 * M_PI / lon_res; const float lat_inc = M_PI / lat_res; float lon, lat; - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(preset_3d_format()); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_3d_format()); const uint vbo_len = (lat_res * lon_res * 2) + ((lat_res - 1) * lon_res * 2); - GWN_vertbuf_data_alloc(vbo, vbo_len); + GPU_vertbuf_data_alloc(vbo, vbo_len); - Gwn_VertBufRaw pos_step, nor_step; - GWN_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step); - GWN_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step); + GPUVertBufRaw pos_step, nor_step; + GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.pos, &pos_step); + GPU_vertbuf_attr_get_raw_data(vbo, g_presets_3d.attr_id.nor, &nor_step); lon = 0.0f; for (int i = 0; i < lon_res; i++, lon += lon_inc) { @@ -189,10 +189,10 @@ static Gwn_Batch *batch_sphere_wire(int lat_res, int lon_res) } } - BLI_assert(vbo_len == GWN_vertbuf_raw_used(&pos_step)); - BLI_assert(vbo_len == GWN_vertbuf_raw_used(&nor_step)); + BLI_assert(vbo_len == GPU_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len == GPU_vertbuf_raw_used(&nor_step)); - return GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO); + return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } /** \} */ @@ -216,7 +216,7 @@ void gpu_batch_presets_init(void) gpu_batch_presets_register(g_presets_3d.batch.sphere_wire_med); } -void gpu_batch_presets_register(Gwn_Batch *preset_batch) +void gpu_batch_presets_register(GPUBatch *preset_batch) { BLI_addtail(&presets_list, BLI_genericNodeN(preset_batch)); } @@ -227,8 +227,8 @@ void gpu_batch_presets_reset(void) * This way they will draw correctly for each window. */ LinkData *link = presets_list.first; for (link = presets_list.first; link; link = link->next) { - Gwn_Batch *preset = link->data; - gwn_batch_vao_cache_clear(preset); + GPUBatch *preset = link->data; + GPU_batch_vao_cache_clear(preset); } } @@ -236,8 +236,8 @@ void gpu_batch_presets_exit(void) { LinkData *link; while ((link = BLI_pophead(&presets_list))) { - Gwn_Batch *preset = link->data; - GWN_batch_discard(preset); + GPUBatch *preset = link->data; + GPU_batch_discard(preset); MEM_freeN(link); } } diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h index 1e72bae503f..0b25c0aef05 100644 --- a/source/blender/gpu/intern/gpu_batch_private.h +++ b/source/blender/gpu/intern/gpu_batch_private.h @@ -23,15 +23,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_batch_private.h +/** \file blender/gpu/intern/gpu_batch_private.h * \ingroup gpu * - * Gawain geometry batch + * GPU geometry batch * Contains VAOs + VBOs + Shader representing a drawable entity. */ -#ifndef __GWN_BATCH_PRIVATE_H__ -#define __GWN_BATCH_PRIVATE_H__ +#ifndef __GPU_BATCH_PRIVATE_H__ +#define __GPU_BATCH_PRIVATE_H__ #ifdef __cplusplus extern "C" { @@ -41,13 +41,13 @@ extern "C" { #include "GPU_context.h" #include "GPU_shader_interface.h" -void gwn_batch_remove_interface_ref(Gwn_Batch*, const Gwn_ShaderInterface*); +void gpu_batch_remove_interface_ref(GPUBatch*, const GPUShaderInterface*); -void gwn_context_add_batch(Gwn_Context*, Gwn_Batch*); -void gwn_context_remove_batch(Gwn_Context*, Gwn_Batch*); +void gpu_context_add_batch(GPUContext*, GPUBatch*); +void gpu_context_remove_batch(GPUContext*, GPUBatch*); #ifdef __cplusplus } #endif -#endif /* __GWN_BATCH_PRIVATE_H__ */ +#endif /* __GPU_BATCH_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch_utils.c b/source/blender/gpu/intern/gpu_batch_utils.c index d6d82ac18b6..0a7f1ca901d 100644 --- a/source/blender/gpu/intern/gpu_batch_utils.c +++ b/source/blender/gpu/intern/gpu_batch_utils.c @@ -47,7 +47,7 @@ * \param polys_flat_len: Length of the array (must be an even number). * \param rect: Optional region to map the byte 0..255 coords to. When not set use -1..1. */ -Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded( +GPUBatch *GPU_batch_tris_from_poly_2d_encoded( const uchar *polys_flat, uint polys_flat_len, const rctf *rect) { const uchar (*polys)[2] = (const void *)polys_flat; @@ -103,41 +103,41 @@ Gwn_Batch *GPU_batch_tris_from_poly_2d_encoded( } /* We have vertices and tris, make a batch from this. */ - static Gwn_VertFormat format = {0}; + static GPUVertFormat format = {0}; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } const uint verts_len = (verts_step - verts); const uint tris_len = (tris_step - tris); - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, verts_len); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, verts_len); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); for (uint i = 0; i < verts_len; i++) { - copy_v2_v2(GWN_vertbuf_raw_step(&pos_step), verts[i]); + copy_v2_v2(GPU_vertbuf_raw_step(&pos_step), verts[i]); } - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tris_len, verts_len); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tris_len, verts_len); for (uint i = 0; i < tris_len; i++) { - GWN_indexbuf_add_tri_verts(&elb, UNPACK3(tris[i])); + GPU_indexbuf_add_tri_verts(&elb, UNPACK3(tris[i])); } - Gwn_IndexBuf *indexbuf = GWN_indexbuf_build(&elb); + GPUIndexBuf *indexbuf = GPU_indexbuf_build(&elb); MEM_freeN(tris); MEM_freeN(verts); - return GWN_batch_create_ex( - GWN_PRIM_TRIS, vbo, + return GPU_batch_create_ex( + GPU_PRIM_TRIS, vbo, indexbuf, - GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); + GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } -Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded( +GPUBatch *GPU_batch_wire_from_poly_2d_encoded( const uchar *polys_flat, uint polys_flat_len, const rctf *rect) { const uchar (*polys)[2] = (const void *)polys_flat; @@ -206,18 +206,18 @@ Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded( } /* We have vertices and tris, make a batch from this. */ - static Gwn_VertFormat format = {0}; + static GPUVertFormat format = {0}; static struct { uint pos; } attr_id; if (format.attr_len == 0) { - attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); const uint vbo_len_capacity = lines_len * 2; - GWN_vertbuf_data_alloc(vbo, vbo_len_capacity); + GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); - Gwn_VertBufRaw pos_step; - GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); + GPUVertBufRaw pos_step; + GPU_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step); for (uint i = 0; i < lines_len; i++) { union { @@ -226,18 +226,18 @@ Gwn_Batch *GPU_batch_wire_from_poly_2d_encoded( } data; data.as_u32 = lines[i]; for (uint k = 0; k < 2; k++) { - float *pos_v2 = GWN_vertbuf_raw_step(&pos_step); + float *pos_v2 = GPU_vertbuf_raw_step(&pos_step); for (uint j = 0; j < 2; j++) { pos_v2[j] = min_uchar[j] + ((float)data.as_u8_pair[k][j] * range_uchar[j]); } } } - BLI_assert(vbo_len_capacity == GWN_vertbuf_raw_used(&pos_step)); + BLI_assert(vbo_len_capacity == GPU_vertbuf_raw_used(&pos_step)); MEM_freeN(lines); - return GWN_batch_create_ex( - GWN_PRIM_LINES, vbo, + return GPU_batch_create_ex( + GPU_PRIM_LINES, vbo, NULL, - GWN_BATCH_OWNS_VBO); + GPU_BATCH_OWNS_VBO); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_buffer_id.cpp b/source/blender/gpu/intern/gpu_buffer_id.cpp index 0c442f687a0..c1aaf1945aa 100644 --- a/source/blender/gpu/intern/gpu_buffer_id.cpp +++ b/source/blender/gpu/intern/gpu_buffer_id.cpp @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_buffer_id.cpp +/** \file blender/gpu/intern/gpu_buffer_id.cpp * \ingroup gpu * - * Gawain buffer IDs + * GPU buffer IDs */ #include "GPU_buffer_id.h" @@ -54,7 +54,7 @@ static bool thread_is_main() return BLI_thread_is_main(); } -GLuint GWN_buf_id_alloc() +GLuint GPU_buf_id_alloc() { /* delete orphaned IDs */ orphan_mutex.lock(); @@ -73,7 +73,7 @@ GLuint GWN_buf_id_alloc() return new_buffer_id; } -void GWN_buf_id_free(GLuint buffer_id) +void GPU_buf_id_free(GLuint buffer_id) { if (thread_is_main()) { glDeleteBuffers(1, &buffer_id); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 1a4750652cc..d466fa87388 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -62,7 +62,7 @@ static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER; /* multires global buffer, can be used for many grids having the same grid size */ typedef struct GridCommonGPUBuffer { - Gwn_IndexBuf *mres_buffer; + GPUIndexBuf *mres_buffer; int mres_prev_gridsize; unsigned mres_prev_totquad; } GridCommonGPUBuffer; @@ -71,11 +71,11 @@ typedef struct GridCommonGPUBuffer { * drawing and doesn't interact at all with the buffer code above */ struct GPU_PBVH_Buffers { - Gwn_IndexBuf *index_buf, *index_buf_fast; - Gwn_VertBuf *vert_buf; + GPUIndexBuf *index_buf, *index_buf_fast; + GPUVertBuf *vert_buf; - Gwn_Batch *triangles; - Gwn_Batch *triangles_fast; + GPUBatch *triangles; + GPUBatch *triangles_fast; /* mesh pointers in case buffer allocation fails */ const MPoly *mpoly; @@ -132,23 +132,23 @@ static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, unsigned int v /* Initialize vertex buffer */ /* match 'VertexBufferFormat' */ - static Gwn_VertFormat format = {0}; + static GPUVertFormat format = {0}; if (format.attr_len == 0) { - g_vbo_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - g_vbo_id.nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_I16, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - g_vbo_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); + g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + g_vbo_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + g_vbo_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); } #if 0 - buffers->vert_buf = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_DYNAMIC); - GWN_vertbuf_data_alloc(buffers->vert_buf, vert_len); + buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DYNAMIC); + GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); } else if (vert_len != buffers->vert_buf->vertex_len) { - GWN_vertbuf_data_resize(buffers->vert_buf, vert_len); + GPU_vertbuf_data_resize(buffers->vert_buf, vert_len); } #else - buffers->vert_buf = GWN_vertbuf_create_with_format_ex(&format, GWN_USAGE_STATIC); + buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); } - GWN_vertbuf_data_alloc(buffers->vert_buf, vert_len); + GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); #endif return buffers->vert_buf->data != NULL; } @@ -157,19 +157,19 @@ static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers) { /* force flushing to the GPU */ if (buffers->vert_buf->data) { - GWN_vertbuf_use(buffers->vert_buf); + GPU_vertbuf_use(buffers->vert_buf); } if (buffers->triangles == NULL) { - buffers->triangles = GWN_batch_create( - GWN_PRIM_TRIS, buffers->vert_buf, + buffers->triangles = GPU_batch_create( + GPU_PRIM_TRIS, buffers->vert_buf, /* can be NULL */ buffers->index_buf); } if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) { - buffers->triangles_fast = GWN_batch_create( - GWN_PRIM_TRIS, buffers->vert_buf, + buffers->triangles_fast = GPU_batch_create( + GPU_PRIM_TRIS, buffers->vert_buf, /* can be NULL */ buffers->index_buf_fast); } @@ -245,8 +245,8 @@ void GPU_pbvh_mesh_buffers_update( if (buffers->smooth) { for (uint i = 0; i < totvert; ++i) { const MVert *v = &mvert[vert_indices[i]]; - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no); } for (uint i = 0; i < buffers->face_indices_len; i++) { @@ -257,10 +257,10 @@ void GPU_pbvh_mesh_buffers_update( int v_index = buffers->mloop[lt->tri[j]].v; uchar color_ub[3]; gpu_color_from_mask_copy(vmask[v_index], diffuse_color, color_ub); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, color_ub); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, color_ub); } else { - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, diffuse_color_ub); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, diffuse_color_ub); } } } @@ -303,9 +303,9 @@ void GPU_pbvh_mesh_buffers_update( for (uint j = 0; j < 3; j++) { const MVert *v = &mvert[vtri[j]]; - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); vbo_index++; } @@ -367,8 +367,8 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build( if (buffers->smooth) { /* Fill the triangle buffer */ buffers->index_buf = NULL; - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tottri, INT_MAX); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, INT_MAX); for (i = 0; i < face_indices_len; ++i) { const MLoopTri *lt = &looptri[face_indices[i]]; @@ -377,13 +377,13 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build( if (paint_is_face_hidden(lt, mvert, mloop)) continue; - GWN_indexbuf_add_tri_verts(&elb, UNPACK3(face_vert_indices[i])); + GPU_indexbuf_add_tri_verts(&elb, UNPACK3(face_vert_indices[i])); } - buffers->index_buf = GWN_indexbuf_build(&elb); + buffers->index_buf = GPU_indexbuf_build(&elb); } else { if (!buffers->is_index_buf_global) { - GWN_INDEXBUF_DISCARD_SAFE(buffers->index_buf); + GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf); } buffers->index_buf = NULL; buffers->is_index_buf_global = false; @@ -438,12 +438,12 @@ void GPU_pbvh_grid_buffers_update( for (y = 0; y < key->grid_size; y++) { for (x = 0; x < key->grid_size; x++) { CCGElem *elem = CCG_grid_elem(key, grid, x, y); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem)); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem)); if (buffers->smooth) { short no_short[3]; normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); if (has_mask) { uchar color_ub[3]; @@ -454,7 +454,7 @@ void GPU_pbvh_grid_buffers_update( else { unit_float_to_uchar_clamp_v3(color_ub, diffuse_color); } - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); } } vbo_index += 1; @@ -481,7 +481,7 @@ void GPU_pbvh_grid_buffers_update( vbo_index = vbo_index_offset + ((j + 1) * key->grid_size + k); short no_short[3]; normal_float_to_short_v3(no_short, fno); - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); if (has_mask) { uchar color_ub[3]; @@ -497,7 +497,7 @@ void GPU_pbvh_grid_buffers_update( else { unit_float_to_uchar_clamp_v3(color_ub, diffuse_color); } - GWN_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, color_ub); } } } @@ -526,9 +526,9 @@ void GPU_pbvh_grid_buffers_update( int offset = 0; \ int i, j, k; \ \ - Gwn_IndexBufBuilder elb; \ - GWN_indexbuf_init( \ - &elb, GWN_PRIM_TRIS, tot_quad_ * 2, max_vert_); \ + GPUIndexBufBuilder elb; \ + GPU_indexbuf_init( \ + &elb, GPU_PRIM_TRIS, tot_quad_ * 2, max_vert_); \ \ /* Fill the buffer */ \ for (i = 0; i < totgrid; ++i) { \ @@ -544,25 +544,25 @@ void GPU_pbvh_grid_buffers_update( { \ continue; \ } \ - GWN_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ - GWN_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k); \ - GWN_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k); \ + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ \ - GWN_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k + 1); \ - GWN_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ - GWN_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ } \ } \ \ offset += gridsize * gridsize; \ } \ - buffer_ = GWN_indexbuf_build(&elb); \ + buffer_ = GPU_indexbuf_build(&elb); \ } (void)0 /* end FILL_QUAD_BUFFER */ -static Gwn_IndexBuf *gpu_get_grid_buffer( +static GPUIndexBuf *gpu_get_grid_buffer( int gridsize, unsigned *totquad, GridCommonGPUBuffer **grid_common_gpu_buffer, - /* remove this arg when gawain gets base-vertex support! */ + /* remove this arg when GPU gets base-vertex support! */ int totgrid) { /* used in the FILL_QUAD_BUFFER macro */ @@ -586,7 +586,7 @@ static Gwn_IndexBuf *gpu_get_grid_buffer( } /* we can't reuse old, delete the existing buffer */ else if (gridbuff->mres_buffer) { - GWN_indexbuf_discard(gridbuff->mres_buffer); + GPU_indexbuf_discard(gridbuff->mres_buffer); gridbuff->mres_buffer = NULL; } @@ -603,17 +603,17 @@ static Gwn_IndexBuf *gpu_get_grid_buffer( #define FILL_FAST_BUFFER() \ { \ - Gwn_IndexBufBuilder elb; \ - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, 6 * totgrid, INT_MAX); \ + GPUIndexBufBuilder elb; \ + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 6 * totgrid, INT_MAX); \ for (int i = 0; i < totgrid; i++) { \ - GWN_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1); \ - GWN_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize); \ - GWN_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize); \ - GWN_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - 1); \ - GWN_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1); \ - GWN_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize); \ + GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1); \ + GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize); \ + GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize); \ + GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - 1); \ + GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1); \ + GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize); \ } \ - buffers->index_buf_fast = GWN_indexbuf_build(&elb); \ + buffers->index_buf_fast = GPU_indexbuf_build(&elb); \ } (void)0 GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build( @@ -684,7 +684,7 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build( */ static void gpu_bmesh_vert_to_buffer_copy__gwn( BMVert *v, - Gwn_VertBuf *vert_buf, + GPUVertBuf *vert_buf, int *v_index, const float fno[3], const float *fmask, @@ -695,12 +695,12 @@ static void gpu_bmesh_vert_to_buffer_copy__gwn( if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { /* Set coord, normal, and mask */ - GWN_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); { short no_short[3]; normal_float_to_short_v3(no_short, fno ? fno : v->no); - GWN_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); } { @@ -718,7 +718,7 @@ static void gpu_bmesh_vert_to_buffer_copy__gwn( effective_mask, diffuse_color, color_ub); - GWN_vertbuf_attr_set(vert_buf, g_vbo_id.col, *v_index, color_ub); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, *v_index, color_ub); } /* Assign index for use in the triangle index buffer */ @@ -792,7 +792,7 @@ void GPU_pbvh_bmesh_buffers_update( if (buffers->smooth) { /* Smooth needs to recreate index buffer, so we have to invalidate the batch. */ - GWN_BATCH_DISCARD_SAFE(buffers->triangles); + GPU_BATCH_DISCARD_SAFE(buffers->triangles); /* Count visible vertices */ totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts); } @@ -893,8 +893,8 @@ void GPU_pbvh_bmesh_buffers_update( if (buffers->smooth) { /* Fill the triangle buffer */ buffers->index_buf = NULL; - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tottri, maxvert); + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert); /* Initialize triangle index buffer */ buffers->is_index_buf_global = false; @@ -911,7 +911,7 @@ void GPU_pbvh_bmesh_buffers_update( BMVert *v[3]; BM_face_as_array_vert_tri(f, v); - GWN_indexbuf_add_tri_verts( + GPU_indexbuf_add_tri_verts( &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2])); } } @@ -919,16 +919,16 @@ void GPU_pbvh_bmesh_buffers_update( buffers->tot_tri = tottri; if (buffers->index_buf == NULL) { - buffers->index_buf = GWN_indexbuf_build(&elb); + buffers->index_buf = GPU_indexbuf_build(&elb); } else { - GWN_indexbuf_build_in_place(&elb, buffers->index_buf); + GPU_indexbuf_build_in_place(&elb, buffers->index_buf); } } } else if (buffers->index_buf) { if (!buffers->is_index_buf_global) { - GWN_INDEXBUF_DISCARD_SAFE(buffers->index_buf); + GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf); } buffers->index_buf = NULL; buffers->is_index_buf_global = false; @@ -950,7 +950,7 @@ GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading) return buffers; } -Gwn_Batch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast) +GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast) { return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles; @@ -1003,13 +1003,13 @@ bool GPU_pbvh_buffers_mask_changed(GPU_PBVH_Buffers *buffers, bool show_mask) void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers) { if (buffers) { - GWN_BATCH_DISCARD_SAFE(buffers->triangles); - GWN_BATCH_DISCARD_SAFE(buffers->triangles_fast); + GPU_BATCH_DISCARD_SAFE(buffers->triangles); + GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast); if (!buffers->is_index_buf_global) { - GWN_INDEXBUF_DISCARD_SAFE(buffers->index_buf); + GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf); } - GWN_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast); - GWN_VERTBUF_DISCARD_SAFE(buffers->vert_buf); + GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast); + GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf); #ifdef USE_BASE_ELEM if (buffers->baseelemarray) @@ -1029,7 +1029,7 @@ void GPU_pbvh_multires_buffers_free(GridCommonGPUBuffer **grid_common_gpu_buffer if (gridbuff) { if (gridbuff->mres_buffer) { BLI_mutex_lock(&buffer_mutex); - GWN_INDEXBUF_DISCARD_SAFE(gridbuff->mres_buffer); + GPU_INDEXBUF_DISCARD_SAFE(gridbuff->mres_buffer); BLI_mutex_unlock(&buffer_mutex); } MEM_freeN(gridbuff); @@ -1049,7 +1049,7 @@ void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, unsigned int pos) * could keep a static batch & index buffer, change the VBO contents per draw */ - immBegin(GWN_PRIM_LINES, 24); + immBegin(GPU_PRIM_LINES, 24); /* top */ immVertex3f(pos, min[0], min[1], max[2]); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index a450b551d4a..51f21d01a9f 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -917,7 +917,7 @@ static const char *attrib_prefix_get(CustomDataType type) case CD_TANGENT: return "t"; case CD_MCOL: return "c"; case CD_AUTO_FROM_NAME: return "a"; - default: BLI_assert(false && "Gwn_VertAttr Prefix type not found : This should not happen!"); return ""; + default: BLI_assert(false && "GPUVertAttr Prefix type not found : This should not happen!"); return ""; } } diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 596530a6ff4..1b5a08ac35c 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_element.c +/** \file blender/gpu/intern/gpu_element.c * \ingroup gpu * - * Gawain element list (AKA index buffer) + * GPU element list (AKA index buffer) */ #include "GPU_element.h" @@ -36,23 +36,23 @@ #define KEEP_SINGLE_COPY 1 -static GLenum convert_index_type_to_gl(Gwn_IndexBufType type) +static GLenum convert_index_type_to_gl(GPUIndexBufType type) { static const GLenum table[] = { - [GWN_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ - [GWN_INDEX_U16] = GL_UNSIGNED_SHORT, - [GWN_INDEX_U32] = GL_UNSIGNED_INT + [GPU_INDEX_U8] = GL_UNSIGNED_BYTE, /* GL has this, Vulkan does not */ + [GPU_INDEX_U16] = GL_UNSIGNED_SHORT, + [GPU_INDEX_U32] = GL_UNSIGNED_INT }; return table[type]; } -uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) +uint GPU_indexbuf_size_get(const GPUIndexBuf* elem) { -#if GWN_TRACK_INDEX_RANGE +#if GPU_TRACK_INDEX_RANGE static const uint table[] = { - [GWN_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ - [GWN_INDEX_U16] = sizeof(GLushort), - [GWN_INDEX_U32] = sizeof(GLuint) + [GPU_INDEX_U8] = sizeof(GLubyte), /* GL has this, Vulkan does not */ + [GPU_INDEX_U16] = sizeof(GLushort), + [GPU_INDEX_U32] = sizeof(GLuint) }; return elem->index_len * table[elem->index_type]; #else @@ -60,8 +60,8 @@ uint GWN_indexbuf_size_get(const Gwn_IndexBuf* elem) #endif } -void GWN_indexbuf_init_ex( - Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, +void GPU_indexbuf_init_ex( + GPUIndexBufBuilder* builder, GPUPrimType prim_type, uint index_len, uint vertex_len, bool use_prim_restart) { builder->use_prim_restart = use_prim_restart; @@ -72,20 +72,20 @@ void GWN_indexbuf_init_ex( builder->data = calloc(builder->max_index_len, sizeof(uint)); } -void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uint prim_len, uint vertex_len) +void GPU_indexbuf_init(GPUIndexBufBuilder* builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) { uint verts_per_prim = 0; switch (prim_type) { - case GWN_PRIM_POINTS: + case GPU_PRIM_POINTS: verts_per_prim = 1; break; - case GWN_PRIM_LINES: + case GPU_PRIM_LINES: verts_per_prim = 2; break; - case GWN_PRIM_TRIS: + case GPU_PRIM_TRIS: verts_per_prim = 3; break; - case GWN_PRIM_LINES_ADJ: + case GPU_PRIM_LINES_ADJ: verts_per_prim = 4; break; default: @@ -95,10 +95,10 @@ void GWN_indexbuf_init(Gwn_IndexBufBuilder* builder, Gwn_PrimType prim_type, uin return; } - GWN_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); + GPU_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); } -void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v) +void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder* builder, uint v) { #if TRUST_NO_ONE assert(builder->data != NULL); @@ -108,58 +108,58 @@ void GWN_indexbuf_add_generic_vert(Gwn_IndexBufBuilder* builder, uint v) builder->data[builder->index_len++] = v; } -void GWN_indexbuf_add_primitive_restart(Gwn_IndexBufBuilder* builder) +void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder* builder) { #if TRUST_NO_ONE assert(builder->data != NULL); assert(builder->index_len < builder->max_index_len); assert(builder->use_prim_restart); #endif - builder->data[builder->index_len++] = GWN_PRIM_RESTART; + builder->data[builder->index_len++] = GPU_PRIM_RESTART; } -void GWN_indexbuf_add_point_vert(Gwn_IndexBufBuilder* builder, uint v) +void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder* builder, uint v) { #if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_POINTS); + assert(builder->prim_type == GPU_PRIM_POINTS); #endif - GWN_indexbuf_add_generic_vert(builder, v); + GPU_indexbuf_add_generic_vert(builder, v); } -void GWN_indexbuf_add_line_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2) +void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder* builder, uint v1, uint v2) { #if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_LINES); + assert(builder->prim_type == GPU_PRIM_LINES); assert(v1 != v2); #endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); } -void GWN_indexbuf_add_tri_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3) +void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder* builder, uint v1, uint v2, uint v3) { #if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_TRIS); + assert(builder->prim_type == GPU_PRIM_TRIS); assert(v1 != v2 && v2 != v3 && v3 != v1); #endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); - GWN_indexbuf_add_generic_vert(builder, v3); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v3); } -void GWN_indexbuf_add_line_adj_verts(Gwn_IndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) +void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) { #if TRUST_NO_ONE - assert(builder->prim_type == GWN_PRIM_LINES_ADJ); + assert(builder->prim_type == GPU_PRIM_LINES_ADJ); assert(v2 != v3); /* only the line need diff indices */ #endif - GWN_indexbuf_add_generic_vert(builder, v1); - GWN_indexbuf_add_generic_vert(builder, v2); - GWN_indexbuf_add_generic_vert(builder, v3); - GWN_indexbuf_add_generic_vert(builder, v4); + GPU_indexbuf_add_generic_vert(builder, v1); + GPU_indexbuf_add_generic_vert(builder, v2); + GPU_indexbuf_add_generic_vert(builder, v3); + GPU_indexbuf_add_generic_vert(builder, v4); } -#if GWN_TRACK_INDEX_RANGE +#if GPU_TRACK_INDEX_RANGE /* Everything remains 32 bit while building to keep things simple. * Find min/max after, then convert to smallest index type possible. */ @@ -174,7 +174,7 @@ static uint index_range(const uint values[], uint value_len, uint* min_out, uint uint max_value = values[0]; for (uint i = 1; i < value_len; ++i) { const uint value = values[i]; - if (value == GWN_PRIM_RESTART) + if (value == GPU_PRIM_RESTART) continue; else if (value < min_value) min_value = value; @@ -186,7 +186,7 @@ static uint index_range(const uint values[], uint value_len, uint* min_out, uint return max_value - min_value; } -static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) +static void squeeze_indices_byte(GPUIndexBufBuilder *builder, GPUIndexBuf* elem) { const uint *values = builder->data; const uint index_len = elem->index_len; @@ -201,7 +201,7 @@ static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* ele elem->min_index = 0; elem->max_index -= base; for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); + data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFF : (GLubyte)(values[i] - base); } } else { @@ -212,7 +212,7 @@ static void squeeze_indices_byte(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* ele } } -static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* elem) +static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf* elem) { const uint *values = builder->data; const uint index_len = elem->index_len; @@ -227,7 +227,7 @@ static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* el elem->min_index = 0; elem->max_index -= base; for (uint i = 0; i < index_len; ++i) { - data[i] = (values[i] == GWN_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); + data[i] = (values[i] == GPU_PRIM_RESTART) ? 0xFFFF : (GLushort)(values[i] - base); } } else { @@ -238,16 +238,16 @@ static void squeeze_indices_short(Gwn_IndexBufBuilder *builder, Gwn_IndexBuf* el } } -#endif /* GWN_TRACK_INDEX_RANGE */ +#endif /* GPU_TRACK_INDEX_RANGE */ -Gwn_IndexBuf* GWN_indexbuf_build(Gwn_IndexBufBuilder* builder) +GPUIndexBuf* GPU_indexbuf_build(GPUIndexBufBuilder* builder) { - Gwn_IndexBuf* elem = calloc(1, sizeof(Gwn_IndexBuf)); - GWN_indexbuf_build_in_place(builder, elem); + GPUIndexBuf* elem = calloc(1, sizeof(GPUIndexBuf)); + GPU_indexbuf_build_in_place(builder, elem); return elem; } -void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* elem) +void GPU_indexbuf_build_in_place(GPUIndexBufBuilder* builder, GPUIndexBuf* elem) { #if TRUST_NO_ONE assert(builder->data != NULL); @@ -255,7 +255,7 @@ void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* ele elem->index_len = builder->index_len; elem->use_prim_restart = builder->use_prim_restart; -#if GWN_TRACK_INDEX_RANGE +#if GPU_TRACK_INDEX_RANGE uint range = index_range(builder->data, builder->index_len, &elem->min_index, &elem->max_index); /* count the primitive restart index. */ @@ -264,29 +264,29 @@ void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* ele } if (range <= 0xFF) { - elem->index_type = GWN_INDEX_U8; + elem->index_type = GPU_INDEX_U8; squeeze_indices_byte(builder, elem); } else if (range <= 0xFFFF) { - elem->index_type = GWN_INDEX_U16; + elem->index_type = GPU_INDEX_U16; squeeze_indices_short(builder, elem); } else { - elem->index_type = GWN_INDEX_U32; + elem->index_type = GPU_INDEX_U32; elem->base_index = 0; } elem->gl_index_type = convert_index_type_to_gl(elem->index_type); #endif if (elem->vbo_id == 0) { - elem->vbo_id = GWN_buf_id_alloc(); + elem->vbo_id = GPU_buf_id_alloc(); } /* send data to GPU */ /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, * so we use the GL_ARRAY_BUFFER here to create a buffer without * interfering in the VAO state. */ glBindBuffer(GL_ARRAY_BUFFER, elem->vbo_id); - glBufferData(GL_ARRAY_BUFFER, GWN_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); /* discard builder (one-time use) */ free(builder->data); @@ -294,15 +294,15 @@ void GWN_indexbuf_build_in_place(Gwn_IndexBufBuilder* builder, Gwn_IndexBuf* ele /* other fields are safe to leave */ } -void GWN_indexbuf_use(Gwn_IndexBuf* elem) +void GPU_indexbuf_use(GPUIndexBuf* elem) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id); } -void GWN_indexbuf_discard(Gwn_IndexBuf* elem) +void GPU_indexbuf_discard(GPUIndexBuf* elem) { if (elem->vbo_id) { - GWN_buf_id_free(elem->vbo_id); + GPU_buf_id_free(elem->vbo_id); } free(elem); } diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 661594faf39..a320935919a 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_immediate.c +/** \file blender/gpu/intern/gpu_immediate.c * \ingroup gpu * - * Gawain immediate mode work-alike + * GPU immediate mode work-alike */ #include "UI_resources.h" @@ -45,14 +45,14 @@ #include /* necessary functions from matrix API */ -extern void GPU_matrix_bind(const Gwn_ShaderInterface*); +extern void GPU_matrix_bind(const GPUShaderInterface*); extern bool GPU_matrix_dirty_get(void); typedef struct { /* TODO: organize this struct by frequency of change (run-time) */ - Gwn_Batch* batch; - Gwn_Context* context; + GPUBatch* batch; + GPUContext* context; /* current draw call */ GLubyte* buffer_data; @@ -60,9 +60,9 @@ typedef struct { uint buffer_bytes_mapped; uint vertex_len; bool strict_vertex_len; - Gwn_PrimType prim_type; + GPUPrimType prim_type; - Gwn_VertFormat vertex_format; + GPUVertFormat vertex_format; /* current vertex */ uint vertex_idx; @@ -73,8 +73,8 @@ typedef struct { GLuint vao_id; GLuint bound_program; - const Gwn_ShaderInterface* shader_interface; - Gwn_AttrBinding attrib_binding; + const GPUShaderInterface* shader_interface; + GPUAttrBinding attrib_binding; uint16_t prev_enabled_attrib_bits; /* <-- only affects this VAO, so we're ok */ } Immediate; @@ -91,11 +91,11 @@ void immInit(void) #endif memset(&imm, 0, sizeof(Immediate)); - imm.vbo_id = GWN_buf_id_alloc(); + imm.vbo_id = GPU_buf_id_alloc(); glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); - imm.prim_type = GWN_PRIM_NONE; + imm.prim_type = GPU_PRIM_NONE; imm.strict_vertex_len = true; glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -106,38 +106,38 @@ void immActivate(void) { #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ + assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ assert(imm.vao_id == 0); #endif - imm.vao_id = GWN_vao_alloc(); - imm.context = GWN_context_active_get(); + imm.vao_id = GPU_vao_alloc(); + imm.context = GPU_context_active_get(); } void immDeactivate(void) { #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we're not between a Begin/End pair */ + assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ assert(imm.vao_id != 0); #endif - GWN_vao_free(imm.vao_id, imm.context); + GPU_vao_free(imm.vao_id, imm.context); imm.vao_id = 0; imm.prev_enabled_attrib_bits = 0; } void immDestroy(void) { - GWN_buf_id_free(imm.vbo_id); + GPU_buf_id_free(imm.vbo_id); initialized = false; } -Gwn_VertFormat* immVertexFormat(void) +GPUVertFormat* immVertexFormat(void) { - GWN_vertformat_clear(&imm.vertex_format); + GPU_vertformat_clear(&imm.vertex_format); return &imm.vertex_format; } -void immBindProgram(GLuint program, const Gwn_ShaderInterface* shaderface) +void immBindProgram(GLuint program, const GPUShaderInterface* shaderface) { #if TRUST_NO_ONE assert(imm.bound_program == 0); @@ -173,7 +173,7 @@ void immUnbindProgram(void) } #if TRUST_NO_ONE -static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType prim_type) +static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType prim_type) { /* does vertex_len make sense for this primitive type? */ if (vertex_len == 0) { @@ -181,19 +181,19 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType } switch (prim_type) { - case GWN_PRIM_POINTS: + case GPU_PRIM_POINTS: return true; - case GWN_PRIM_LINES: + case GPU_PRIM_LINES: return vertex_len % 2 == 0; - case GWN_PRIM_LINE_STRIP: - case GWN_PRIM_LINE_LOOP: + case GPU_PRIM_LINE_STRIP: + case GPU_PRIM_LINE_LOOP: return vertex_len >= 2; - case GWN_PRIM_LINE_STRIP_ADJ: + case GPU_PRIM_LINE_STRIP_ADJ: return vertex_len >= 4; - case GWN_PRIM_TRIS: + case GPU_PRIM_TRIS: return vertex_len % 3 == 0; - case GWN_PRIM_TRI_STRIP: - case GWN_PRIM_TRI_FAN: + case GPU_PRIM_TRI_STRIP: + case GPU_PRIM_TRI_FAN: return vertex_len >= 3; default: return false; @@ -201,11 +201,11 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, Gwn_PrimType } #endif -void immBegin(Gwn_PrimType prim_type, uint vertex_len) +void immBegin(GPUPrimType prim_type, uint vertex_len) { #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ + assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); #endif imm.prim_type = prim_type; @@ -250,7 +250,7 @@ void immBegin(Gwn_PrimType prim_type, uint vertex_len) imm.vertex_data = imm.buffer_data; } -void immBeginAtMost(Gwn_PrimType prim_type, uint vertex_len) +void immBeginAtMost(GPUPrimType prim_type, uint vertex_len) { #if TRUST_NO_ONE assert(vertex_len > 0); @@ -261,11 +261,11 @@ void immBeginAtMost(Gwn_PrimType prim_type, uint vertex_len) } -Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, uint vertex_len) +GPUBatch* immBeginBatch(GPUPrimType prim_type, uint vertex_len) { #if TRUST_NO_ONE assert(initialized); - assert(imm.prim_type == GWN_PRIM_NONE); /* make sure we haven't already begun */ + assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); #endif imm.prim_type = prim_type; @@ -273,19 +273,19 @@ Gwn_Batch* immBeginBatch(Gwn_PrimType prim_type, uint vertex_len) imm.vertex_idx = 0; imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - Gwn_VertBuf* verts = GWN_vertbuf_create_with_format(&imm.vertex_format); - GWN_vertbuf_data_alloc(verts, vertex_len); + GPUVertBuf* verts = GPU_vertbuf_create_with_format(&imm.vertex_format); + GPU_vertbuf_data_alloc(verts, vertex_len); - imm.buffer_bytes_mapped = GWN_vertbuf_size_get(verts); + imm.buffer_bytes_mapped = GPU_vertbuf_size_get(verts); imm.vertex_data = verts->data; - imm.batch = GWN_batch_create_ex(prim_type, verts, NULL, GWN_BATCH_OWNS_VBO); - imm.batch->phase = GWN_BATCH_BUILDING; + imm.batch = GPU_batch_create_ex(prim_type, verts, NULL, GPU_BATCH_OWNS_VBO); + imm.batch->phase = GPU_BATCH_BUILDING; return imm.batch; } -Gwn_Batch* immBeginBatchAtMost(Gwn_PrimType prim_type, uint vertex_len) +GPUBatch* immBeginBatchAtMost(GPUPrimType prim_type, uint vertex_len) { imm.strict_vertex_len = false; return immBeginBatch(prim_type, vertex_len); @@ -298,7 +298,7 @@ static void immDrawSetup(void) /* enable/disable vertex attribs as needed */ if (imm.attrib_binding.enabled_bits != imm.prev_enabled_attrib_bits) { - for (uint loc = 0; loc < GWN_VERT_ATTR_MAX_LEN; ++loc) { + for (uint loc = 0; loc < GPU_VERT_ATTR_MAX_LEN; ++loc) { bool is_enabled = imm.attrib_binding.enabled_bits & (1 << loc); bool was_enabled = imm.prev_enabled_attrib_bits & (1 << loc); @@ -316,7 +316,7 @@ static void immDrawSetup(void) const uint stride = imm.vertex_format.stride; for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { - const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; + const GPUVertAttr* a = imm.vertex_format.attribs + a_idx; const uint offset = imm.buffer_offset + a->offset; const GLvoid* pointer = (const GLubyte*)0 + offset; @@ -324,14 +324,14 @@ static void immDrawSetup(void) const uint loc = read_attrib_location(&imm.attrib_binding, a_idx); switch (a->fetch_mode) { - case GWN_FETCH_FLOAT: - case GWN_FETCH_INT_TO_FLOAT: + case GPU_FETCH_FLOAT: + case GPU_FETCH_INT_TO_FLOAT: glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer); break; - case GWN_FETCH_INT_TO_FLOAT_UNIT: + case GPU_FETCH_INT_TO_FLOAT_UNIT: glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer); break; - case GWN_FETCH_INT: + case GPU_FETCH_INT: glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer); } } @@ -344,7 +344,7 @@ static void immDrawSetup(void) void immEnd(void) { #if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif uint buffer_bytes_used; @@ -375,11 +375,11 @@ void immEnd(void) if (imm.batch) { if (buffer_bytes_used != imm.buffer_bytes_mapped) { - GWN_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); + GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len); /* TODO: resize only if vertex count is much smaller */ } - GWN_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); - imm.batch->phase = GWN_BATCH_READY_TO_DRAW; + GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface); + imm.batch->phase = GPU_BATCH_READY_TO_DRAW; imm.batch = NULL; /* don't free, batch belongs to caller */ } else { @@ -395,7 +395,7 @@ void immEnd(void) } /* prep for next immBegin */ - imm.prim_type = GWN_PRIM_NONE; + imm.prim_type = GPU_PRIM_NONE; imm.strict_vertex_len = true; } @@ -413,13 +413,13 @@ static void setAttribValueBit(uint attrib_id) void immAttrib1f(uint attrib_id, float x) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_type == GPU_COMP_F32); assert(attrib->comp_len == 1); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -431,13 +431,13 @@ void immAttrib1f(uint attrib_id, float x) void immAttrib2f(uint attrib_id, float x, float y) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_type == GPU_COMP_F32); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -450,13 +450,13 @@ void immAttrib2f(uint attrib_id, float x, float y) void immAttrib3f(uint attrib_id, float x, float y, float z) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_type == GPU_COMP_F32); assert(attrib->comp_len == 3); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -470,13 +470,13 @@ void immAttrib3f(uint attrib_id, float x, float y, float z) void immAttrib4f(uint attrib_id, float x, float y, float z, float w) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_F32); + assert(attrib->comp_type == GPU_COMP_F32); assert(attrib->comp_len == 4); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -491,13 +491,13 @@ void immAttrib4f(uint attrib_id, float x, float y, float z, float w) void immAttrib1u(uint attrib_id, uint x) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U32); + assert(attrib->comp_type == GPU_COMP_U32); assert(attrib->comp_len == 1); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -508,13 +508,13 @@ void immAttrib1u(uint attrib_id, uint x) void immAttrib2i(uint attrib_id, int x, int y) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_I32); + assert(attrib->comp_type == GPU_COMP_I32); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -526,13 +526,13 @@ void immAttrib2i(uint attrib_id, int x, int y) void immAttrib2s(uint attrib_id, short x, short y) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_I16); + assert(attrib->comp_type == GPU_COMP_I16); assert(attrib->comp_len == 2); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -559,13 +559,13 @@ void immAttrib4fv(uint attrib_id, const float data[4]) void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U8); + assert(attrib->comp_type == GPU_COMP_U8); assert(attrib->comp_len == 3); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -579,13 +579,13 @@ void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned cha void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - Gwn_VertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); - assert(attrib->comp_type == GWN_COMP_U8); + assert(attrib->comp_type == GPU_COMP_U8); assert(attrib->comp_len == 4); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); @@ -613,7 +613,7 @@ void immSkipAttrib(uint attrib_id) #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(imm.vertex_idx < imm.vertex_len); - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ #endif setAttribValueBit(attrib_id); } @@ -621,7 +621,7 @@ void immSkipAttrib(uint attrib_id) static void immEndVertex(void) /* and move on to the next vertex */ { #if TRUST_NO_ONE - assert(imm.prim_type != GWN_PRIM_NONE); /* make sure we're between a Begin/End pair */ + assert(imm.prim_type != GPU_PRIM_NONE); /* make sure we're between a Begin/End pair */ assert(imm.vertex_idx < imm.vertex_len); #endif @@ -633,7 +633,7 @@ static void immEndVertex(void) /* and move on to the next vertex */ #endif for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { if ((imm.unassigned_attrib_bits >> a_idx) & 1) { - const Gwn_VertAttr* a = imm.vertex_format.attribs + a_idx; + const GPUVertAttr* a = imm.vertex_format.attribs + a_idx; /* printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); */ @@ -702,16 +702,16 @@ void immVertex2iv(uint attrib_id, const int data[2]) #if 0 #if TRUST_NO_ONE - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); + #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); #else - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); + #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); #endif #else /* NOTE: It is possible to have uniform fully optimized out from the shader. * In this case we can't assert failure or allow NULL-pointer dereference. * TODO(sergey): How can we detect existing-but-optimized-out uniform but still * catch typos in uniform names passed to immUniform*() functions? */ - #define GET_UNIFORM const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; + #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; #endif void immUniform1f(const char* name, float x) @@ -817,7 +817,7 @@ void immUniform4iv(const char* name, const int data[4]) void immUniformColor4f(float r, float g, float b, float a) { - const Gwn_ShaderInput* uniform = GWN_shaderinterface_uniform_builtin(imm.shader_interface, GWN_UNIFORM_COLOR); + const GPUShaderInput* uniform = GPU_shaderinterface_uniform_builtin(imm.shader_interface, GPU_UNIFORM_COLOR); #if TRUST_NO_ONE assert(uniform != NULL); #endif diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index 4b2fb1b8e8a..b794048087a 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -18,10 +18,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_imm_util.c +/** \file blender/gpu/intern/gpu_imm_util.c * \ingroup gpu * - * Gawain immediate mode drawing utilities + * GPU immediate mode drawing utilities */ #include @@ -70,7 +70,7 @@ static const int cube_line_index[12][2] = { void immRectf(uint pos, float x1, float y1, float x2, float y2) { - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x2, y1); immVertex2f(pos, x2, y2); @@ -80,7 +80,7 @@ void immRectf(uint pos, float x1, float y1, float x2, float y2) void immRecti(uint pos, int x1, int y1, int x2, int y2) { - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immVertex2i(pos, x1, y1); immVertex2i(pos, x2, y1); immVertex2i(pos, x2, y2); @@ -125,8 +125,8 @@ void immRecti_fast_with_color(uint pos, uint col, int x1, int y1, int x2, int y2 #if 0 /* more complete version in case we want that */ void immRecti_complete(int x1, int y1, int x2, int y2, const float color[4]) { - Gwn_VertFormat *format = immVertexFormat(); - uint pos = add_attrib(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = add_attrib(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); immRecti(pos, x1, y1, x2, y2); @@ -153,7 +153,7 @@ void imm_cpack(unsigned int x) } static void imm_draw_circle( - Gwn_PrimType prim_type, const uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments) + GPUPrimType prim_type, const uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments) { immBegin(prim_type, nsegments); for (int i = 0; i < nsegments; ++i) { @@ -175,7 +175,7 @@ static void imm_draw_circle( */ void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float rad, int nsegments) { - imm_draw_circle(GWN_PRIM_LINE_LOOP, shdr_pos, x, y, rad, rad, nsegments); + imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, rad, rad, nsegments); } /** @@ -190,23 +190,23 @@ void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float rad, int nse */ void imm_draw_circle_fill_2d(uint shdr_pos, float x, float y, float rad, int nsegments) { - imm_draw_circle(GWN_PRIM_TRI_FAN, shdr_pos, x, y, rad, rad, nsegments); + imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, rad, rad, nsegments); } void imm_draw_circle_wire_aspect_2d(uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments) { - imm_draw_circle(GWN_PRIM_LINE_LOOP, shdr_pos, x, y, rad_x, rad_y, nsegments); + imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, rad_x, rad_y, nsegments); } void imm_draw_circle_fill_aspect_2d(uint shdr_pos, float x, float y, float rad_x, float rad_y, int nsegments) { - imm_draw_circle(GWN_PRIM_TRI_FAN, shdr_pos, x, y, rad_x, rad_y, nsegments); + imm_draw_circle(GPU_PRIM_TRI_FAN, shdr_pos, x, y, rad_x, rad_y, nsegments); } /** * \note We could have `imm_draw_lined_disk_partial` but currently there is no need. */ static void imm_draw_disk_partial( - Gwn_PrimType prim_type, unsigned pos, float x, float y, + GPUPrimType prim_type, unsigned pos, float x, float y, float rad_inner, float rad_outer, int nsegments, float start, float sweep) { /* shift & reverse angle, increase 'nsegments' to match gluPartialDisk */ @@ -243,11 +243,11 @@ void imm_draw_disk_partial_fill_2d( unsigned pos, float x, float y, float rad_inner, float rad_outer, int nsegments, float start, float sweep) { - imm_draw_disk_partial(GWN_PRIM_TRI_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep); + imm_draw_disk_partial(GPU_PRIM_TRI_STRIP, pos, x, y, rad_inner, rad_outer, nsegments, start, sweep); } static void imm_draw_circle_3D( - Gwn_PrimType prim_type, unsigned pos, float x, float y, + GPUPrimType prim_type, unsigned pos, float x, float y, float rad, int nsegments) { immBegin(prim_type, nsegments); @@ -260,12 +260,12 @@ static void imm_draw_circle_3D( void imm_draw_circle_wire_3d(unsigned pos, float x, float y, float rad, int nsegments) { - imm_draw_circle_3D(GWN_PRIM_LINE_LOOP, pos, x, y, rad, nsegments); + imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, rad, nsegments); } void imm_draw_circle_fill_3d(unsigned pos, float x, float y, float rad, int nsegments) { - imm_draw_circle_3D(GWN_PRIM_TRI_FAN, pos, x, y, rad, nsegments); + imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, rad, nsegments); } /** @@ -279,7 +279,7 @@ void imm_draw_circle_fill_3d(unsigned pos, float x, float y, float rad, int nseg */ void imm_draw_box_wire_2d(unsigned pos, float x1, float y1, float x2, float y2) { - immBegin(GWN_PRIM_LINE_LOOP, 4); + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex2f(pos, x1, y1); immVertex2f(pos, x1, y2); immVertex2f(pos, x2, y2); @@ -289,8 +289,8 @@ void imm_draw_box_wire_2d(unsigned pos, float x1, float y1, float x2, float y2) void imm_draw_box_wire_3d(unsigned pos, float x1, float y1, float x2, float y2) { - /* use this version when Gwn_VertFormat has a vec3 position */ - immBegin(GWN_PRIM_LINE_LOOP, 4); + /* use this version when GPUVertFormat has a vec3 position */ + immBegin(GPU_PRIM_LINE_LOOP, 4); immVertex3f(pos, x1, y1, 0.0f); immVertex3f(pos, x1, y2, 0.0f); immVertex3f(pos, x2, y2, 0.0f); @@ -303,7 +303,7 @@ void imm_draw_box_wire_3d(unsigned pos, float x1, float y1, float x2, float y2) */ void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2) { - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); immUniform4f("color1", 0.15f, 0.15f, 0.15f, 1.0f); @@ -323,7 +323,7 @@ void imm_draw_cube_fill_3d(uint pos, const float co[3], const float aspect[3]) madd_v3_v3v3v3(coords[i], co, cube_coords[i], aspect); } - immBegin(GWN_PRIM_TRIS, ARRAY_SIZE(cube_quad_index) * 3 * 2); + immBegin(GPU_PRIM_TRIS, ARRAY_SIZE(cube_quad_index) * 3 * 2); for (int i = 0; i < ARRAY_SIZE(cube_quad_index); i++) { immVertex3fv(pos, coords[cube_quad_index[i][0]]); immVertex3fv(pos, coords[cube_quad_index[i][1]]); @@ -344,7 +344,7 @@ void imm_draw_cube_wire_3d(uint pos, const float co[3], const float aspect[3]) madd_v3_v3v3v3(coords[i], co, cube_coords[i], aspect); } - immBegin(GWN_PRIM_LINES, ARRAY_SIZE(cube_line_index) * 2); + immBegin(GPU_PRIM_LINES, ARRAY_SIZE(cube_line_index) * 2); for (int i = 0; i < ARRAY_SIZE(cube_line_index); i++) { immVertex3fv(pos, coords[cube_line_index[i][0]]); immVertex3fv(pos, coords[cube_line_index[i][1]]); @@ -367,7 +367,7 @@ void imm_draw_cube_wire_3d(uint pos, const float co[3], const float aspect[3]) void imm_draw_cylinder_fill_normal_3d( unsigned int pos, unsigned int nor, float base, float top, float height, int slices, int stacks) { - immBegin(GWN_PRIM_TRIS, 6 * slices * stacks); + immBegin(GPU_PRIM_TRIS, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); @@ -418,7 +418,7 @@ void imm_draw_cylinder_fill_normal_3d( void imm_draw_cylinder_wire_3d(unsigned int pos, float base, float top, float height, int slices, int stacks) { - immBegin(GWN_PRIM_LINES, 6 * slices * stacks); + immBegin(GPU_PRIM_LINES, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); @@ -455,7 +455,7 @@ void imm_draw_cylinder_wire_3d(unsigned int pos, float base, float top, float he void imm_draw_cylinder_fill_3d(unsigned int pos, float base, float top, float height, int slices, int stacks) { - immBegin(GWN_PRIM_TRIS, 6 * slices * stacks); + immBegin(GPU_PRIM_TRIS, 6 * slices * stacks); for (int i = 0; i < slices; ++i) { const float angle1 = (float)(2 * M_PI) * ((float)i / (float)slices); const float angle2 = (float)(2 * M_PI) * ((float)(i + 1) / (float)slices); diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c index 13c6fbea1c6..87fcc5f25a3 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.c @@ -558,20 +558,20 @@ const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3] return m; } -void GPU_matrix_bind(const Gwn_ShaderInterface *shaderface) +void GPU_matrix_bind(const GPUShaderInterface *shaderface) { /* set uniform values to matrix stack values * call this before a draw call if desired matrices are dirty * call glUseProgram before this, as glUniform expects program to be bound */ - const Gwn_ShaderInput *MV = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_MODELVIEW); - const Gwn_ShaderInput *P = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_PROJECTION); - const Gwn_ShaderInput *MVP = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_MVP); + const GPUShaderInput *MV = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW); + const GPUShaderInput *P = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION); + const GPUShaderInput *MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP); - const Gwn_ShaderInput *N = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_NORMAL); - const Gwn_ShaderInput *MV_inv = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_MODELVIEW_INV); - const Gwn_ShaderInput *P_inv = GWN_shaderinterface_uniform_builtin(shaderface, GWN_UNIFORM_PROJECTION_INV); + const GPUShaderInput *N = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_NORMAL); + const GPUShaderInput *MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV); + const GPUShaderInput *P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV); if (MV) { #if DEBUG_MATRIX_BIND diff --git a/source/blender/gpu/intern/gpu_primitive.c b/source/blender/gpu/intern/gpu_primitive.c index 0f0c28c05dc..189d17f2dd2 100644 --- a/source/blender/gpu/intern/gpu_primitive.c +++ b/source/blender/gpu/intern/gpu_primitive.c @@ -23,61 +23,61 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_primitive.c +/** \file blender/gpu/intern/gpu_primitive.c * \ingroup gpu * - * Gawain geometric primitives + * GPU geometric primitives */ #include "GPU_primitive.h" #include "gpu_primitive_private.h" -Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type) +GPUPrimClass GPU_primtype_class(GPUPrimType prim_type) { - static const Gwn_PrimClass classes[] = { - [GWN_PRIM_POINTS] = GWN_PRIM_CLASS_POINT, - [GWN_PRIM_LINES] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_STRIP] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_LOOP] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_TRIS] = GWN_PRIM_CLASS_SURFACE, - [GWN_PRIM_TRI_STRIP] = GWN_PRIM_CLASS_SURFACE, - [GWN_PRIM_TRI_FAN] = GWN_PRIM_CLASS_SURFACE, + static const GPUPrimClass classes[] = { + [GPU_PRIM_POINTS] = GPU_PRIM_CLASS_POINT, + [GPU_PRIM_LINES] = GPU_PRIM_CLASS_LINE, + [GPU_PRIM_LINE_STRIP] = GPU_PRIM_CLASS_LINE, + [GPU_PRIM_LINE_LOOP] = GPU_PRIM_CLASS_LINE, + [GPU_PRIM_TRIS] = GPU_PRIM_CLASS_SURFACE, + [GPU_PRIM_TRI_STRIP] = GPU_PRIM_CLASS_SURFACE, + [GPU_PRIM_TRI_FAN] = GPU_PRIM_CLASS_SURFACE, - [GWN_PRIM_LINES_ADJ] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_LINE_STRIP_ADJ] = GWN_PRIM_CLASS_LINE, - [GWN_PRIM_TRIS_ADJ] = GWN_PRIM_CLASS_SURFACE, + [GPU_PRIM_LINES_ADJ] = GPU_PRIM_CLASS_LINE, + [GPU_PRIM_LINE_STRIP_ADJ] = GPU_PRIM_CLASS_LINE, + [GPU_PRIM_TRIS_ADJ] = GPU_PRIM_CLASS_SURFACE, - [GWN_PRIM_NONE] = GWN_PRIM_CLASS_NONE + [GPU_PRIM_NONE] = GPU_PRIM_CLASS_NONE }; return classes[prim_type]; } -bool GWN_primtype_belongs_to_class(Gwn_PrimType prim_type, Gwn_PrimClass prim_class) +bool GPU_primtype_belongs_to_class(GPUPrimType prim_type, GPUPrimClass prim_class) { - if (prim_class == GWN_PRIM_CLASS_NONE && prim_type == GWN_PRIM_NONE) { + if (prim_class == GPU_PRIM_CLASS_NONE && prim_type == GPU_PRIM_NONE) { return true; } - return prim_class & GWN_primtype_class(prim_type); + return prim_class & GPU_primtype_class(prim_type); } -GLenum convert_prim_type_to_gl(Gwn_PrimType prim_type) +GLenum convert_prim_type_to_gl(GPUPrimType prim_type) { #if TRUST_NO_ONE - assert(prim_type != GWN_PRIM_NONE); + assert(prim_type != GPU_PRIM_NONE); #endif static const GLenum table[] = { - [GWN_PRIM_POINTS] = GL_POINTS, - [GWN_PRIM_LINES] = GL_LINES, - [GWN_PRIM_LINE_STRIP] = GL_LINE_STRIP, - [GWN_PRIM_LINE_LOOP] = GL_LINE_LOOP, - [GWN_PRIM_TRIS] = GL_TRIANGLES, - [GWN_PRIM_TRI_STRIP] = GL_TRIANGLE_STRIP, - [GWN_PRIM_TRI_FAN] = GL_TRIANGLE_FAN, + [GPU_PRIM_POINTS] = GL_POINTS, + [GPU_PRIM_LINES] = GL_LINES, + [GPU_PRIM_LINE_STRIP] = GL_LINE_STRIP, + [GPU_PRIM_LINE_LOOP] = GL_LINE_LOOP, + [GPU_PRIM_TRIS] = GL_TRIANGLES, + [GPU_PRIM_TRI_STRIP] = GL_TRIANGLE_STRIP, + [GPU_PRIM_TRI_FAN] = GL_TRIANGLE_FAN, - [GWN_PRIM_LINES_ADJ] = GL_LINES_ADJACENCY, - [GWN_PRIM_LINE_STRIP_ADJ] = GL_LINE_STRIP_ADJACENCY, - [GWN_PRIM_TRIS_ADJ] = GL_TRIANGLES_ADJACENCY, + [GPU_PRIM_LINES_ADJ] = GL_LINES_ADJACENCY, + [GPU_PRIM_LINE_STRIP_ADJ] = GL_LINE_STRIP_ADJACENCY, + [GPU_PRIM_TRIS_ADJ] = GL_TRIANGLES_ADJACENCY, }; return table[prim_type]; diff --git a/source/blender/gpu/intern/gpu_primitive_private.h b/source/blender/gpu/intern/gpu_primitive_private.h index 6d3f1e20da7..d057f29fdc5 100644 --- a/source/blender/gpu/intern/gpu_primitive_private.h +++ b/source/blender/gpu/intern/gpu_primitive_private.h @@ -23,15 +23,15 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_primitive_private.h +/** \file blender/gpu/intern/gpu_primitive_private.h * \ingroup gpu * - * Gawain geometric primitives + * GPU geometric primitives */ -#ifndef __GWN_PRIMITIVE_PRIVATE_H__ -#define __GWN_PRIMITIVE_PRIVATE_H__ +#ifndef __GPU_PRIMITIVE_PRIVATE_H__ +#define __GPU_PRIMITIVE_PRIVATE_H__ -GLenum convert_prim_type_to_gl(Gwn_PrimType); +GLenum convert_prim_type_to_gl(GPUPrimType); -#endif /* __GWN_PRIMITIVE_PRIVATE_H__ */ +#endif /* __GPU_PRIMITIVE_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 99baaa1164f..c5325b6ff21 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -496,24 +496,24 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, return NULL; } - shader->interface = GWN_shaderinterface_create(shader->program); + shader->interface = GPU_shaderinterface_create(shader->program); #ifdef WITH_OPENSUBDIV /* TODO(sergey): Find a better place for this. */ if (use_opensubdiv) { if (GLEW_VERSION_4_1) { glProgramUniform1i(shader->program, - GWN_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, + GPU_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, 30); /* GL_TEXTURE30 */ glProgramUniform1i(shader->program, - GWN_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, + GPU_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, 31); /* GL_TEXTURE31 */ } else { glUseProgram(shader->program); - glUniform1i(GWN_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, 30); - glUniform1i(GWN_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, 31); + glUniform1i(GPU_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, 30); + glUniform1i(GPU_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, 31); glUseProgram(0); } } @@ -575,7 +575,7 @@ void GPU_shader_free(GPUShader *shader) glDeleteProgram(shader->program); if (shader->interface) - GWN_shaderinterface_discard(shader->interface); + GPU_shaderinterface_discard(shader->interface); MEM_freeN(shader); } @@ -583,14 +583,14 @@ void GPU_shader_free(GPUShader *shader) int GPU_shader_get_uniform(GPUShader *shader, const char *name) { BLI_assert(shader && shader->program); - const Gwn_ShaderInput *uniform = GWN_shaderinterface_uniform(shader->interface, name); + const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name); return uniform ? uniform->location : -1; } int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin) { BLI_assert(shader && shader->program); - const Gwn_ShaderInput *uniform = GWN_shaderinterface_uniform_builtin(shader->interface, builtin); + const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(shader->interface, builtin); return uniform ? uniform->location : -1; } @@ -598,7 +598,7 @@ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name) { BLI_assert(shader && shader->program); - const Gwn_ShaderInput *ubo = GWN_shaderinterface_ubo(shader->interface, name); + const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name); return ubo ? ubo->location : -1; } @@ -675,7 +675,7 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText int GPU_shader_get_attribute(GPUShader *shader, const char *name) { BLI_assert(shader && shader->program); - const Gwn_ShaderInput *attrib = GWN_shaderinterface_attr(shader->interface, name); + const GPUShaderInput *attrib = GPU_shaderinterface_attr(shader->interface, name); return attrib ? attrib->location : -1; } diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index 56b25726a84..ec2f52a2a2d 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_shader_interface.c +/** \file blender/gpu/intern/gpu_shader_interface.c * \ingroup gpu * - * Gawain shader interface (C --> GLSL) + * GPU shader interface (C --> GLSL) */ #include "gpu_batch_private.h" @@ -42,46 +42,46 @@ #include #endif -static const char* BuiltinUniform_name(Gwn_UniformBuiltin u) +static const char* BuiltinUniform_name(GPUUniformBuiltin u) { static const char* names[] = { - [GWN_UNIFORM_NONE] = NULL, - - [GWN_UNIFORM_MODEL] = "ModelMatrix", - [GWN_UNIFORM_VIEW] = "ViewMatrix", - [GWN_UNIFORM_MODELVIEW] = "ModelViewMatrix", - [GWN_UNIFORM_PROJECTION] = "ProjectionMatrix", - [GWN_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix", - [GWN_UNIFORM_MVP] = "ModelViewProjectionMatrix", - - [GWN_UNIFORM_MODEL_INV] = "ModelMatrixInverse", - [GWN_UNIFORM_VIEW_INV] = "ViewMatrixInverse", - [GWN_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse", - [GWN_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse", - [GWN_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse", - - [GWN_UNIFORM_NORMAL] = "NormalMatrix", - [GWN_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix", - [GWN_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors", - [GWN_UNIFORM_ORCO] = "OrcoTexCoFactors", - - [GWN_UNIFORM_COLOR] = "color", - [GWN_UNIFORM_EYE] = "eye", - [GWN_UNIFORM_CALLID] = "callId", - - [GWN_UNIFORM_CUSTOM] = NULL, - [GWN_NUM_UNIFORMS] = NULL, + [GPU_UNIFORM_NONE] = NULL, + + [GPU_UNIFORM_MODEL] = "ModelMatrix", + [GPU_UNIFORM_VIEW] = "ViewMatrix", + [GPU_UNIFORM_MODELVIEW] = "ModelViewMatrix", + [GPU_UNIFORM_PROJECTION] = "ProjectionMatrix", + [GPU_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix", + [GPU_UNIFORM_MVP] = "ModelViewProjectionMatrix", + + [GPU_UNIFORM_MODEL_INV] = "ModelMatrixInverse", + [GPU_UNIFORM_VIEW_INV] = "ViewMatrixInverse", + [GPU_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse", + [GPU_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse", + [GPU_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse", + + [GPU_UNIFORM_NORMAL] = "NormalMatrix", + [GPU_UNIFORM_WORLDNORMAL] = "WorldNormalMatrix", + [GPU_UNIFORM_CAMERATEXCO] = "CameraTexCoFactors", + [GPU_UNIFORM_ORCO] = "OrcoTexCoFactors", + + [GPU_UNIFORM_COLOR] = "color", + [GPU_UNIFORM_EYE] = "eye", + [GPU_UNIFORM_CALLID] = "callId", + + [GPU_UNIFORM_CUSTOM] = NULL, + [GPU_NUM_UNIFORMS] = NULL, }; return names[u]; } -GWN_INLINE bool match(const char* a, const char* b) +GPU_INLINE bool match(const char* a, const char* b) { return strcmp(a, b) == 0; } -GWN_INLINE uint hash_string(const char *str) +GPU_INLINE uint hash_string(const char *str) { uint i = 0, c; while ((c = *str++)) { @@ -90,7 +90,7 @@ GWN_INLINE uint hash_string(const char *str) return i; } -GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* input, +GPU_INLINE void set_input_name(GPUShaderInterface* shaderface, GPUShaderInput* input, const char* name, uint32_t name_len) { input->name_offset = shaderface->name_buffer_offset; @@ -98,20 +98,20 @@ GWN_INLINE void set_input_name(Gwn_ShaderInterface* shaderface, Gwn_ShaderInput* shaderface->name_buffer_offset += name_len + 1; /* include NULL terminator */ } -GWN_INLINE void shader_input_to_bucket(Gwn_ShaderInput* input, - Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) +GPU_INLINE void shader_input_to_bucket(GPUShaderInput* input, + GPUShaderInput* buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) { - const uint bucket_index = input->name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; + const uint bucket_index = input->name_hash % GPU_NUM_SHADERINTERFACE_BUCKETS; input->next = buckets[bucket_index]; buckets[bucket_index] = input; } -GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[GWN_NUM_SHADERINTERFACE_BUCKETS], +GPU_INLINE const GPUShaderInput* buckets_lookup(GPUShaderInput* const buckets[GPU_NUM_SHADERINTERFACE_BUCKETS], const char *name_buffer, const char *name) { const uint name_hash = hash_string(name); - const uint bucket_index = name_hash % GWN_NUM_SHADERINTERFACE_BUCKETS; - const Gwn_ShaderInput* input = buckets[bucket_index]; + const uint bucket_index = name_hash % GPU_NUM_SHADERINTERFACE_BUCKETS; + const GPUShaderInput* input = buckets[bucket_index]; if (input == NULL) { /* Requested uniform is not found at all. */ return NULL; @@ -129,7 +129,7 @@ GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[ return NULL; } /* Work through possible collisions. */ - const Gwn_ShaderInput* next = input; + const GPUShaderInput* next = input; while (next != NULL) { input = next; next = input->next; @@ -143,37 +143,37 @@ GWN_INLINE const Gwn_ShaderInput* buckets_lookup(Gwn_ShaderInput* const buckets[ return NULL; /* not found */ } -GWN_INLINE void buckets_free(Gwn_ShaderInput* buckets[GWN_NUM_SHADERINTERFACE_BUCKETS]) +GPU_INLINE void buckets_free(GPUShaderInput* buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) { - for (uint bucket_index = 0; bucket_index < GWN_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { - Gwn_ShaderInput *input = buckets[bucket_index]; + for (uint bucket_index = 0; bucket_index < GPU_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { + GPUShaderInput *input = buckets[bucket_index]; while (input != NULL) { - Gwn_ShaderInput *input_next = input->next; + GPUShaderInput *input_next = input->next; free(input); input = input_next; } } } -static bool setup_builtin_uniform(Gwn_ShaderInput* input, const char* name) +static bool setup_builtin_uniform(GPUShaderInput* input, const char* name) { /* TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types */ /* detect built-in uniforms (name must match) */ - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { + for (GPUUniformBuiltin u = GPU_UNIFORM_NONE + 1; u < GPU_UNIFORM_CUSTOM; ++u) { const char* builtin_name = BuiltinUniform_name(u); if (match(name, builtin_name)) { input->builtin_type = u; return true; } } - input->builtin_type = GWN_UNIFORM_CUSTOM; + input->builtin_type = GPU_UNIFORM_CUSTOM; return false; } -static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const char* name) +static const GPUShaderInput* add_uniform(GPUShaderInterface* shaderface, const char* name) { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); input->location = glGetUniformLocation(shaderface->program, name); @@ -186,13 +186,13 @@ static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const setup_builtin_uniform(input, name); shader_input_to_bucket(input, shaderface->uniform_buckets); - if (input->builtin_type != GWN_UNIFORM_NONE && - input->builtin_type != GWN_UNIFORM_CUSTOM) + if (input->builtin_type != GPU_UNIFORM_NONE && + input->builtin_type != GPU_UNIFORM_CUSTOM) { shaderface->builtin_uniforms[input->builtin_type] = input; } #if DEBUG_SHADER_INTERFACE - printf("Gwn_ShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, + printf("GPUShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, shaderface->program, name, input->location); @@ -200,14 +200,14 @@ static const Gwn_ShaderInput* add_uniform(Gwn_ShaderInterface* shaderface, const return input; } -Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) +GPUShaderInterface* GPU_shaderinterface_create(int32_t program) { - Gwn_ShaderInterface* shaderface = calloc(1, sizeof(Gwn_ShaderInterface)); + GPUShaderInterface* shaderface = calloc(1, sizeof(GPUShaderInterface)); shaderface->program = program; #if DEBUG_SHADER_INTERFACE printf("%s {\n", __func__); /* enter function */ - printf("Gwn_ShaderInterface %p, program %d\n", shaderface, program); + printf("GPUShaderInterface %p, program %d\n", shaderface, program); #endif GLint max_attrib_name_len, attr_len; @@ -223,7 +223,7 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) /* Attributes */ for (uint32_t i = 0; i < attr_len; ++i) { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char* name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; @@ -250,7 +250,7 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) } /* Uniform Blocks */ for (uint32_t i = 0; i < ubo_len; ++i) { - Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput)); + GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char* name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; @@ -268,20 +268,20 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(int32_t program) #endif } /* Builtin Uniforms */ - for (Gwn_UniformBuiltin u = GWN_UNIFORM_NONE + 1; u < GWN_UNIFORM_CUSTOM; ++u) { + for (GPUUniformBuiltin u = GPU_UNIFORM_NONE + 1; u < GPU_UNIFORM_CUSTOM; ++u) { const char* builtin_name = BuiltinUniform_name(u); if (glGetUniformLocation(program, builtin_name) != -1) { - add_uniform((Gwn_ShaderInterface*)shaderface, builtin_name); + add_uniform((GPUShaderInterface*)shaderface, builtin_name); } } /* Batches ref buffer */ - shaderface->batches_len = GWN_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = calloc(shaderface->batches_len, sizeof(Gwn_Batch*)); + shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT; + shaderface->batches = calloc(shaderface->batches_len, sizeof(GPUBatch*)); return shaderface; } -void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) +void GPU_shaderinterface_discard(GPUShaderInterface* shaderface) { /* Free memory used by buckets and has entries. */ buckets_free(shaderface->uniform_buckets); @@ -292,7 +292,7 @@ void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) /* Remove this interface from all linked Batches vao cache. */ for (int i = 0; i < shaderface->batches_len; ++i) { if (shaderface->batches[i] != NULL) { - gwn_batch_remove_interface_ref(shaderface->batches[i], shaderface); + gpu_batch_remove_interface_ref(shaderface->batches[i], shaderface); } } free(shaderface->batches); @@ -300,39 +300,39 @@ void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface) free(shaderface); } -const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface* shaderface, const char* name) +const GPUShaderInput* GPU_shaderinterface_uniform(const GPUShaderInterface* shaderface, const char* name) { /* TODO: Warn if we find a matching builtin, since these can be looked up much quicker. */ - const Gwn_ShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); + const GPUShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); /* If input is not found add it so it's found next time. */ if (input == NULL) { - input = add_uniform((Gwn_ShaderInterface*)shaderface, name); + input = add_uniform((GPUShaderInterface*)shaderface, name); } return (input->location != -1) ? input : NULL; } -const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin( - const Gwn_ShaderInterface* shaderface, Gwn_UniformBuiltin builtin) +const GPUShaderInput* GPU_shaderinterface_uniform_builtin( + const GPUShaderInterface* shaderface, GPUUniformBuiltin builtin) { #if TRUST_NO_ONE - assert(builtin != GWN_UNIFORM_NONE); - assert(builtin != GWN_UNIFORM_CUSTOM); - assert(builtin != GWN_NUM_UNIFORMS); + assert(builtin != GPU_UNIFORM_NONE); + assert(builtin != GPU_UNIFORM_CUSTOM); + assert(builtin != GPU_NUM_UNIFORMS); #endif return shaderface->builtin_uniforms[builtin]; } -const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name) +const GPUShaderInput* GPU_shaderinterface_ubo(const GPUShaderInterface* shaderface, const char* name) { return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name); } -const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name) +const GPUShaderInput* GPU_shaderinterface_attr(const GPUShaderInterface* shaderface, const char* name) { return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name); } -void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) +void GPU_shaderinterface_add_batch_ref(GPUShaderInterface* shaderface, GPUBatch* batch) { int i; /* find first unused slot */ for (i = 0; i < shaderface->batches_len; ++i) { @@ -343,14 +343,14 @@ void GWN_shaderinterface_add_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batc if (i == shaderface->batches_len) { /* Not enough place, realloc the array. */ i = shaderface->batches_len; - shaderface->batches_len += GWN_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = realloc(shaderface->batches, sizeof(Gwn_Batch*) * shaderface->batches_len); - memset(shaderface->batches + i, 0, sizeof(Gwn_Batch*) * GWN_SHADERINTERFACE_REF_ALLOC_COUNT); + shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT; + shaderface->batches = realloc(shaderface->batches, sizeof(GPUBatch*) * shaderface->batches_len); + memset(shaderface->batches + i, 0, sizeof(GPUBatch*) * GPU_SHADERINTERFACE_REF_ALLOC_COUNT); } shaderface->batches[i] = batch; } -void GWN_shaderinterface_remove_batch_ref(Gwn_ShaderInterface* shaderface, Gwn_Batch* batch) +void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface* shaderface, GPUBatch* batch) { for (int i = 0; i < shaderface->batches_len; ++i) { if (shaderface->batches[i] == batch) { diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index bf54d269fb5..d16aae79aae 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -35,7 +35,7 @@ struct GPUShader { GLuint geometry; /* handle for geometry shader */ GLuint fragment; /* handle for fragment shader */ - Gwn_ShaderInterface *interface; /* cached uniform & attrib interface for shader */ + GPUShaderInterface *interface; /* cached uniform & attrib interface for shader */ int feedback_transform_type; }; diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index d9248e06dfb..52afe17d885 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -911,28 +911,28 @@ GPUTexture *GPU_texture_create_cube( tex_format, GPU_DATA_FLOAT, err_out); } -GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert) +GPUTexture *GPU_texture_create_from_vertbuf(GPUVertBuf *vert) { - Gwn_VertFormat *format = &vert->format; - Gwn_VertAttr *attr = &format->attribs[0]; + GPUVertFormat *format = &vert->format; + GPUVertAttr *attr = &format->attribs[0]; /* Detect incompatible cases (not supported by texture buffers) */ BLI_assert(format->attr_len == 1 && vert->vbo_id != 0); BLI_assert(attr->comp_len != 3); /* Not until OGL 4.0 */ - BLI_assert(attr->comp_type != GWN_COMP_I10); - BLI_assert(attr->fetch_mode != GWN_FETCH_INT_TO_FLOAT); + BLI_assert(attr->comp_type != GPU_COMP_I10); + BLI_assert(attr->fetch_mode != GPU_FETCH_INT_TO_FLOAT); unsigned int byte_per_comp = attr->sz / attr->comp_len; - bool is_uint = ELEM(attr->comp_type, GWN_COMP_U8, GWN_COMP_U16, GWN_COMP_U32); + bool is_uint = ELEM(attr->comp_type, GPU_COMP_U8, GPU_COMP_U16, GPU_COMP_U32); /* Cannot fetch signed int or 32bit ints as normalized float. */ - if (attr->fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT) { + if (attr->fetch_mode == GPU_FETCH_INT_TO_FLOAT_UNIT) { BLI_assert(is_uint || byte_per_comp <= 2); } GPUTextureFormat data_type; switch (attr->fetch_mode) { - case GWN_FETCH_FLOAT: + case GPU_FETCH_FLOAT: switch (attr->comp_len) { case 1: data_type = GPU_R32F; break; case 2: data_type = GPU_RG32F; break; @@ -940,7 +940,7 @@ GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert) default: data_type = GPU_RGBA32F; break; } break; - case GWN_FETCH_INT: + case GPU_FETCH_INT: switch (attr->comp_len) { case 1: switch (byte_per_comp) { @@ -965,7 +965,7 @@ GPUTexture *GPU_texture_create_from_vertbuf(Gwn_VertBuf *vert) break; } break; - case GWN_FETCH_INT_TO_FLOAT_UNIT: + case GPU_FETCH_INT_TO_FLOAT_UNIT: switch (attr->comp_len) { case 1: data_type = (byte_per_comp == 1) ? GPU_R8 : GPU_R16; break; case 2: data_type = (byte_per_comp == 1) ? GPU_RG8 : GPU_RG16; break; diff --git a/source/blender/gpu/intern/gpu_vertex_array_id.cpp b/source/blender/gpu/intern/gpu_vertex_array_id.cpp index de5be15ec19..2f29bbfbc33 100644 --- a/source/blender/gpu/intern/gpu_vertex_array_id.cpp +++ b/source/blender/gpu/intern/gpu_vertex_array_id.cpp @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_vertex_array_id.cpp +/** \file blender/gpu/gpu_vertex_array_id.cpp * \ingroup gpu * * Manage GL vertex array IDs in a thread-safe way @@ -56,16 +56,16 @@ static bool thread_is_main() { #endif #endif -struct Gwn_Context { +struct GPUContext { GLuint default_vao; - std::unordered_set batches; /* Batches that have VAOs from this context */ + std::unordered_set batches; /* Batches that have VAOs from this context */ std::vector orphaned_vertarray_ids; std::mutex orphans_mutex; /* todo: try spinlock instead */ #if TRUST_NO_ONE pthread_t thread; /* Thread on which this context is active. */ bool thread_is_used; - Gwn_Context() { + GPUContext() { thread_is_used = false; } #endif @@ -73,12 +73,12 @@ struct Gwn_Context { #if defined(_MSC_VER) && (_MSC_VER == 1800) #define thread_local __declspec(thread) -thread_local Gwn_Context* active_ctx = NULL; +thread_local GPUContext* active_ctx = NULL; #else -static thread_local Gwn_Context* active_ctx = NULL; +static thread_local GPUContext* active_ctx = NULL; #endif -static void clear_orphans(Gwn_Context* ctx) +static void clear_orphans(GPUContext* ctx) { ctx->orphans_mutex.lock(); if (!ctx->orphaned_vertarray_ids.empty()) { @@ -89,19 +89,19 @@ static void clear_orphans(Gwn_Context* ctx) ctx->orphans_mutex.unlock(); } -Gwn_Context* GWN_context_create(void) +GPUContext* GPU_context_create(void) { #if TRUST_NO_ONE /* assert(thread_is_main()); */ #endif - Gwn_Context* ctx = new Gwn_Context; + GPUContext* ctx = new GPUContext; glGenVertexArrays(1, &ctx->default_vao); - GWN_context_active_set(ctx); + GPU_context_active_set(ctx); return ctx; } -/* to be called after GWN_context_active_set(ctx_to_destroy) */ -void GWN_context_discard(Gwn_Context* ctx) +/* to be called after GPU_context_active_set(ctx_to_destroy) */ +void GPU_context_discard(GPUContext* ctx) { #if TRUST_NO_ONE /* Make sure no other thread has locked it. */ @@ -112,7 +112,7 @@ void GWN_context_discard(Gwn_Context* ctx) /* delete remaining vaos */ while (!ctx->batches.empty()) { /* this removes the array entry */ - gwn_batch_vao_cache_clear(*ctx->batches.begin()); + GPU_batch_vao_cache_clear(*ctx->batches.begin()); } glDeleteVertexArrays(1, &ctx->default_vao); delete ctx; @@ -120,7 +120,7 @@ void GWN_context_discard(Gwn_Context* ctx) } /* ctx can be NULL */ -void GWN_context_active_set(Gwn_Context* ctx) +void GPU_context_active_set(GPUContext* ctx) { #if TRUST_NO_ONE if (active_ctx) { @@ -140,12 +140,12 @@ void GWN_context_active_set(Gwn_Context* ctx) active_ctx = ctx; } -Gwn_Context* GWN_context_active_get(void) +GPUContext* GPU_context_active_get(void) { return active_ctx; } -GLuint GWN_vao_default(void) +GLuint GPU_vao_default(void) { #if TRUST_NO_ONE assert(active_ctx); /* need at least an active context */ @@ -154,7 +154,7 @@ GLuint GWN_vao_default(void) return active_ctx->default_vao; } -GLuint GWN_vao_alloc(void) +GLuint GPU_vao_alloc(void) { #if TRUST_NO_ONE assert(active_ctx); /* need at least an active context */ @@ -168,7 +168,7 @@ GLuint GWN_vao_alloc(void) } /* this can be called from multiple thread */ -void GWN_vao_free(GLuint vao_id, Gwn_Context* ctx) +void GPU_vao_free(GLuint vao_id, GPUContext* ctx) { #if TRUST_NO_ONE assert(ctx); @@ -183,12 +183,12 @@ void GWN_vao_free(GLuint vao_id, Gwn_Context* ctx) } } -void gwn_context_add_batch(Gwn_Context* ctx, Gwn_Batch* batch) +void gpu_context_add_batch(GPUContext* ctx, GPUBatch* batch) { ctx->batches.emplace(batch); } -void gwn_context_remove_batch(Gwn_Context* ctx, Gwn_Batch* batch) +void gpu_context_remove_batch(GPUContext* ctx, GPUBatch* batch) { ctx->orphans_mutex.lock(); ctx->batches.erase(batch); diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index 32f3d494015..5b29913800d 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_vertex_buffer.c +/** \file blender/gpu/intern/gpu_vertex_buffer.c * \ingroup gpu * - * Gawain vertex buffer + * GPU vertex buffer */ #include "GPU_vertex_buffer.h" @@ -39,27 +39,27 @@ static uint vbo_memory_usage; -static GLenum convert_usage_type_to_gl(Gwn_UsageType type) +static GLenum convert_usage_type_to_gl(GPUUsageType type) { static const GLenum table[] = { - [GWN_USAGE_STREAM] = GL_STREAM_DRAW, - [GWN_USAGE_STATIC] = GL_STATIC_DRAW, - [GWN_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW + [GPU_USAGE_STREAM] = GL_STREAM_DRAW, + [GPU_USAGE_STATIC] = GL_STATIC_DRAW, + [GPU_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW }; return table[type]; } -Gwn_VertBuf* GWN_vertbuf_create(Gwn_UsageType usage) +GPUVertBuf* GPU_vertbuf_create(GPUUsageType usage) { - Gwn_VertBuf* verts = malloc(sizeof(Gwn_VertBuf)); - GWN_vertbuf_init(verts, usage); + GPUVertBuf* verts = malloc(sizeof(GPUVertBuf)); + GPU_vertbuf_init(verts, usage); return verts; } -Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat* format, Gwn_UsageType usage) +GPUVertBuf* GPU_vertbuf_create_with_format_ex(const GPUVertFormat* format, GPUUsageType usage) { - Gwn_VertBuf* verts = GWN_vertbuf_create(usage); - GWN_vertformat_copy(&verts->format, format); + GPUVertBuf* verts = GPU_vertbuf_create(usage); + GPU_vertformat_copy(&verts->format, format); if (!format->packed) { VertexFormat_pack(&verts->format); } @@ -69,28 +69,28 @@ Gwn_VertBuf* GWN_vertbuf_create_with_format_ex(const Gwn_VertFormat* format, Gwn /* TODO: implement those memory savings */ } -void GWN_vertbuf_init(Gwn_VertBuf* verts, Gwn_UsageType usage) +void GPU_vertbuf_init(GPUVertBuf* verts, GPUUsageType usage) { - memset(verts, 0, sizeof(Gwn_VertBuf)); + memset(verts, 0, sizeof(GPUVertBuf)); verts->usage = usage; verts->dirty = true; } -void GWN_vertbuf_init_with_format_ex(Gwn_VertBuf* verts, const Gwn_VertFormat* format, Gwn_UsageType usage) +void GPU_vertbuf_init_with_format_ex(GPUVertBuf* verts, const GPUVertFormat* format, GPUUsageType usage) { - GWN_vertbuf_init(verts, usage); - GWN_vertformat_copy(&verts->format, format); + GPU_vertbuf_init(verts, usage); + GPU_vertformat_copy(&verts->format, format); if (!format->packed) { VertexFormat_pack(&verts->format); } } -void GWN_vertbuf_discard(Gwn_VertBuf* verts) +void GPU_vertbuf_discard(GPUVertBuf* verts) { if (verts->vbo_id) { - GWN_buf_id_free(verts->vbo_id); + GPU_buf_id_free(verts->vbo_id); #if VRAM_USAGE - vbo_memory_usage -= GWN_vertbuf_size_get(verts); + vbo_memory_usage -= GPU_vertbuf_size_get(verts); #endif } if (verts->data) { @@ -99,15 +99,15 @@ void GWN_vertbuf_discard(Gwn_VertBuf* verts) free(verts); } -uint GWN_vertbuf_size_get(const Gwn_VertBuf* verts) +uint GPU_vertbuf_size_get(const GPUVertBuf* verts) { return vertex_buffer_size(&verts->format, verts->vertex_len); } /* create a new allocation, discarding any existing data */ -void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) +void GPU_vertbuf_data_alloc(GPUVertBuf* verts, uint v_len) { - Gwn_VertFormat* format = &verts->format; + GPUVertFormat* format = &verts->format; if (!format->packed) { VertexFormat_pack(format); } @@ -117,7 +117,7 @@ void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) #endif /* only create the buffer the 1st time */ if (verts->vbo_id == 0) { - verts->vbo_id = GWN_buf_id_alloc(); + verts->vbo_id = GPU_buf_id_alloc(); } /* discard previous data if any */ if (verts->data) { @@ -125,15 +125,15 @@ void GWN_vertbuf_data_alloc(Gwn_VertBuf* verts, uint v_len) } #if VRAM_USAGE uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); + vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = malloc(sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); + verts->data = malloc(sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); } /* resize buffer keeping existing data */ -void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, uint v_len) +void GPU_vertbuf_data_resize(GPUVertBuf* verts, uint v_len) { #if TRUST_NO_ONE assert(verts->data != NULL); @@ -142,17 +142,17 @@ void GWN_vertbuf_data_resize(Gwn_VertBuf* verts, uint v_len) #if VRAM_USAGE uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); + vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = realloc(verts->data, sizeof(GLubyte) * GWN_vertbuf_size_get(verts)); + verts->data = realloc(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); } /* Set vertex count but does not change allocation. * Only this many verts will be uploaded to the GPU and rendered. * This is usefull for streaming data. */ -void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, uint v_len) +void GPU_vertbuf_vertex_count_set(GPUVertBuf* verts, uint v_len) { #if TRUST_NO_ONE assert(verts->data != NULL); /* only for dynamic data */ @@ -161,15 +161,15 @@ void GWN_vertbuf_vertex_count_set(Gwn_VertBuf* verts, uint v_len) #if VRAM_USAGE uint new_size = vertex_buffer_size(&verts->format, v_len); - vbo_memory_usage += new_size - GWN_vertbuf_size_get(verts); + vbo_memory_usage += new_size - GPU_vertbuf_size_get(verts); #endif verts->vertex_len = v_len; } -void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, uint a_idx, uint v_idx, const void* data) +void GPU_vertbuf_attr_set(GPUVertBuf* verts, uint a_idx, uint v_idx, const void* data) { - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertFormat* format = &verts->format; + const GPUVertAttr* a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -180,23 +180,23 @@ void GWN_vertbuf_attr_set(Gwn_VertBuf* verts, uint a_idx, uint v_idx, const void memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz); } -void GWN_vertbuf_attr_fill(Gwn_VertBuf* verts, uint a_idx, const void* data) +void GPU_vertbuf_attr_fill(GPUVertBuf* verts, uint a_idx, const void* data) { - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertFormat* format = &verts->format; + const GPUVertAttr* a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); #endif const uint stride = a->sz; /* tightly packed input data */ - GWN_vertbuf_attr_fill_stride(verts, a_idx, stride, data); + GPU_vertbuf_attr_fill_stride(verts, a_idx, stride, data); } -void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, uint a_idx, uint stride, const void* data) +void GPU_vertbuf_attr_fill_stride(GPUVertBuf* verts, uint a_idx, uint stride, const void* data) { - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertFormat* format = &verts->format; + const GPUVertAttr* a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -217,10 +217,10 @@ void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf* verts, uint a_idx, uint stride, c } } -void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, uint a_idx, Gwn_VertBufRaw *access) +void GPU_vertbuf_attr_get_raw_data(GPUVertBuf* verts, uint a_idx, GPUVertBufRaw *access) { - const Gwn_VertFormat* format = &verts->format; - const Gwn_VertAttr* a = format->attribs + a_idx; + const GPUVertFormat* format = &verts->format; + const GPUVertAttr* a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -238,23 +238,23 @@ void GWN_vertbuf_attr_get_raw_data(Gwn_VertBuf* verts, uint a_idx, Gwn_VertBufRa #endif } -static void VertBuffer_upload_data(Gwn_VertBuf* verts) +static void VertBuffer_upload_data(GPUVertBuf* verts) { - uint buffer_sz = GWN_vertbuf_size_get(verts); + uint buffer_sz = GPU_vertbuf_size_get(verts); /* orphan the vbo to avoid sync */ glBufferData(GL_ARRAY_BUFFER, buffer_sz, NULL, convert_usage_type_to_gl(verts->usage)); /* upload data */ glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); - if (verts->usage == GWN_USAGE_STATIC) { + if (verts->usage == GPU_USAGE_STATIC) { free(verts->data); verts->data = NULL; } verts->dirty = false; } -void GWN_vertbuf_use(Gwn_VertBuf* verts) +void GPU_vertbuf_use(GPUVertBuf* verts) { glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); if (verts->dirty) { @@ -262,7 +262,7 @@ void GWN_vertbuf_use(Gwn_VertBuf* verts) } } -uint GWN_vertbuf_get_memory_usage(void) +uint GPU_vertbuf_get_memory_usage(void) { return vbo_memory_usage; } diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index bd9f9250564..d0a907bcd0d 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -23,10 +23,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gwn_vertex_format.c +/** \file blender/gpu/intern/gpu_vertex_format.c * \ingroup gpu * - * Gawain vertex format + * GPU vertex format */ #include "GPU_vertex_format.h" @@ -40,26 +40,26 @@ #include #endif -void GWN_vertformat_clear(Gwn_VertFormat* format) +void GPU_vertformat_clear(GPUVertFormat* format) { #if TRUST_NO_ONE - memset(format, 0, sizeof(Gwn_VertFormat)); + memset(format, 0, sizeof(GPUVertFormat)); #else format->attr_len = 0; format->packed = false; format->name_offset = 0; format->name_len = 0; - for (unsigned i = 0; i < GWN_VERT_ATTR_MAX_LEN; i++) { + for (unsigned i = 0; i < GPU_VERT_ATTR_MAX_LEN; i++) { format->attribs[i].name_len = 0; } #endif } -void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src) +void GPU_vertformat_copy(GPUVertFormat* dest, const GPUVertFormat* src) { /* copy regular struct fields */ - memcpy(dest, src, sizeof(Gwn_VertFormat)); + memcpy(dest, src, sizeof(GPUVertFormat)); for (unsigned i = 0; i < dest->attr_len; i++) { for (unsigned j = 0; j < dest->attribs[i].name_len; j++) { @@ -68,43 +68,43 @@ void GWN_vertformat_copy(Gwn_VertFormat* dest, const Gwn_VertFormat* src) } } -static GLenum convert_comp_type_to_gl(Gwn_VertCompType type) +static GLenum convert_comp_type_to_gl(GPUVertCompType type) { static const GLenum table[] = { - [GWN_COMP_I8] = GL_BYTE, - [GWN_COMP_U8] = GL_UNSIGNED_BYTE, - [GWN_COMP_I16] = GL_SHORT, - [GWN_COMP_U16] = GL_UNSIGNED_SHORT, - [GWN_COMP_I32] = GL_INT, - [GWN_COMP_U32] = GL_UNSIGNED_INT, + [GPU_COMP_I8] = GL_BYTE, + [GPU_COMP_U8] = GL_UNSIGNED_BYTE, + [GPU_COMP_I16] = GL_SHORT, + [GPU_COMP_U16] = GL_UNSIGNED_SHORT, + [GPU_COMP_I32] = GL_INT, + [GPU_COMP_U32] = GL_UNSIGNED_INT, - [GWN_COMP_F32] = GL_FLOAT, + [GPU_COMP_F32] = GL_FLOAT, - [GWN_COMP_I10] = GL_INT_2_10_10_10_REV + [GPU_COMP_I10] = GL_INT_2_10_10_10_REV }; return table[type]; } -static unsigned comp_sz(Gwn_VertCompType type) +static unsigned comp_sz(GPUVertCompType type) { #if TRUST_NO_ONE - assert(type <= GWN_COMP_F32); /* other types have irregular sizes (not bytes) */ + assert(type <= GPU_COMP_F32); /* other types have irregular sizes (not bytes) */ #endif const GLubyte sizes[] = {1,1,2,2,4,4,4}; return sizes[type]; } -static unsigned attrib_sz(const Gwn_VertAttr *a) +static unsigned attrib_sz(const GPUVertAttr *a) { - if (a->comp_type == GWN_COMP_I10) { + if (a->comp_type == GPU_COMP_I10) { return 4; /* always packed as 10_10_10_2 */ } return a->comp_len * comp_sz(a->comp_type); } -static unsigned attrib_align(const Gwn_VertAttr *a) +static unsigned attrib_align(const GPUVertAttr *a) { - if (a->comp_type == GWN_COMP_I10) { + if (a->comp_type == GPU_COMP_I10) { return 4; /* always packed as 10_10_10_2 */ } unsigned c = comp_sz(a->comp_type); @@ -116,7 +116,7 @@ static unsigned attrib_align(const Gwn_VertAttr *a) } } -unsigned vertex_buffer_size(const Gwn_VertFormat* format, unsigned vertex_len) +unsigned vertex_buffer_size(const GPUVertFormat* format, unsigned vertex_len) { #if TRUST_NO_ONE assert(format->packed && format->stride > 0); @@ -124,11 +124,11 @@ unsigned vertex_buffer_size(const Gwn_VertFormat* format, unsigned vertex_len) return format->stride * vertex_len; } -static const char* copy_attrib_name(Gwn_VertFormat* format, const char* name) +static const char* copy_attrib_name(GPUVertFormat* format, const char* name) { /* strncpy does 110% of what we need; let's do exactly 100% */ char* name_copy = format->names + format->name_offset; - unsigned available = GWN_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; + unsigned available = GPU_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; bool terminated = false; for (unsigned i = 0; i < available; ++i) { @@ -142,35 +142,35 @@ static const char* copy_attrib_name(Gwn_VertFormat* format, const char* name) } #if TRUST_NO_ONE assert(terminated); - assert(format->name_offset <= GWN_VERT_ATTR_NAMES_BUF_LEN); + assert(format->name_offset <= GPU_VERT_ATTR_NAMES_BUF_LEN); #else (void)terminated; #endif return name_copy; } -unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_VertCompType comp_type, unsigned comp_len, Gwn_VertFetchMode fetch_mode) +unsigned GPU_vertformat_attr_add(GPUVertFormat* format, const char* name, GPUVertCompType comp_type, unsigned comp_len, GPUVertFetchMode fetch_mode) { #if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(format->attr_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(format->attr_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ assert(!format->packed); /* packed means frozen/locked */ assert((comp_len >= 1 && comp_len <= 4) || comp_len == 8 || comp_len == 12 || comp_len == 16); switch (comp_type) { - case GWN_COMP_F32: + case GPU_COMP_F32: /* float type can only kept as float */ - assert(fetch_mode == GWN_FETCH_FLOAT); + assert(fetch_mode == GPU_FETCH_FLOAT); break; - case GWN_COMP_I10: + case GPU_COMP_I10: /* 10_10_10 format intended for normals (xyz) or colors (rgb) * extra component packed.w can be manually set to { -2, -1, 0, 1 } */ assert(comp_len == 3 || comp_len == 4); - assert(fetch_mode == GWN_FETCH_INT_TO_FLOAT_UNIT); /* not strictly required, may relax later */ + assert(fetch_mode == GPU_FETCH_INT_TO_FLOAT_UNIT); /* not strictly required, may relax later */ break; default: /* integer types can be kept as int or converted/normalized to float */ - assert(fetch_mode != GWN_FETCH_FLOAT); + assert(fetch_mode != GPU_FETCH_FLOAT); /* only support float matrices (see Batch_update_program_bindings) */ assert(comp_len != 8 && comp_len != 12 && comp_len != 16); } @@ -178,12 +178,12 @@ unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_V format->name_len++; /* multiname support */ const unsigned attrib_id = format->attr_len++; - Gwn_VertAttr* attrib = format->attribs + attrib_id; + GPUVertAttr* attrib = format->attribs + attrib_id; attrib->name[attrib->name_len++] = copy_attrib_name(format, name); attrib->comp_type = comp_type; attrib->gl_comp_type = convert_comp_type_to_gl(comp_type); - attrib->comp_len = (comp_type == GWN_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ + attrib->comp_len = (comp_type == GPU_COMP_I10) ? 4 : comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */ attrib->sz = attrib_sz(attrib); attrib->offset = 0; /* offsets & stride are calculated later (during pack) */ attrib->fetch_mode = fetch_mode; @@ -191,12 +191,12 @@ unsigned GWN_vertformat_attr_add(Gwn_VertFormat* format, const char* name, Gwn_V return attrib_id; } -void GWN_vertformat_alias_add(Gwn_VertFormat* format, const char* alias) +void GPU_vertformat_alias_add(GPUVertFormat* format, const char* alias) { - Gwn_VertAttr* attrib = format->attribs + (format->attr_len - 1); + GPUVertAttr* attrib = format->attribs + (format->attr_len - 1); #if TRUST_NO_ONE - assert(format->name_len < GWN_VERT_ATTR_MAX_LEN); /* there's room for more */ - assert(attrib->name_len < GWN_VERT_ATTR_MAX_NAMES); + assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ + assert(attrib->name_len < GPU_VERT_ATTR_MAX_NAMES); #endif format->name_len++; /* multiname support */ attrib->name[attrib->name_len++] = copy_attrib_name(format, alias); @@ -221,7 +221,7 @@ static void show_pack(unsigned a_idx, unsigned sz, unsigned pad) } #endif -void VertexFormat_pack(Gwn_VertFormat* format) +void VertexFormat_pack(GPUVertFormat* format) { /* For now, attributes are packed in the order they were added, * making sure each attrib is naturally aligned (add padding where necessary) @@ -231,7 +231,7 @@ void VertexFormat_pack(Gwn_VertFormat* format) /* TODO: realloc just enough to hold the final combo string. And just enough to * hold used attribs, not all 16. */ - Gwn_VertAttr* a0 = format->attribs + 0; + GPUVertAttr* a0 = format->attribs + 0; a0->offset = 0; unsigned offset = a0->sz; @@ -240,7 +240,7 @@ void VertexFormat_pack(Gwn_VertFormat* format) #endif for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) { - Gwn_VertAttr* a = format->attribs + a_idx; + GPUVertAttr* a = format->attribs + a_idx; unsigned mid_padding = padding(offset, attrib_align(a)); offset += mid_padding; a->offset = offset; @@ -263,7 +263,7 @@ void VertexFormat_pack(Gwn_VertFormat* format) /* OpenGL ES packs in a different order as desktop GL but component conversion is the same. - * Of the code here, only struct Gwn_PackedNormal needs to change. */ + * Of the code here, only struct GPUPackedNormal needs to change. */ #define SIGNED_INT_10_MAX 511 #define SIGNED_INT_10_MIN -512 @@ -297,14 +297,14 @@ static int convert_i16(short x) return x >> 6; } -Gwn_PackedNormal GWN_normal_convert_i10_v3(const float data[3]) +GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3]) { - Gwn_PackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) }; + GPUPackedNormal n = { .x = quantize(data[0]), .y = quantize(data[1]), .z = quantize(data[2]) }; return n; } -Gwn_PackedNormal GWN_normal_convert_i10_s3(const short data[3]) +GPUPackedNormal GPU_normal_convert_i10_s3(const short data[3]) { - Gwn_PackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) }; + GPUPackedNormal n = { .x = convert_i16(data[0]), .y = convert_i16(data[1]), .z = convert_i16(data[2]) }; return n; } diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h index 3cae9969fd8..4ce3ebba714 100644 --- a/source/blender/gpu/intern/gpu_vertex_format_private.h +++ b/source/blender/gpu/intern/gpu_vertex_format_private.h @@ -23,17 +23,17 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gwn_vertex_format_private.h +/** \file blender/gpu/intern/gpu_vertex_format_private.h * \ingroup gpu * - * Gawain vertex format + * GPU vertex format */ -#ifndef __GWN_VERTEX_FORMAT_PRIVATE_H__ -#define __GWN_VERTEX_FORMAT_PRIVATE_H__ +#ifndef __GPU_VERTEX_FORMAT_PRIVATE_H__ +#define __GPU_VERTEX_FORMAT_PRIVATE_H__ -void VertexFormat_pack(Gwn_VertFormat*); +void VertexFormat_pack(GPUVertFormat*); uint padding(uint offset, uint alignment); -uint vertex_buffer_size(const Gwn_VertFormat*, uint vertex_len); +uint vertex_buffer_size(const GPUVertFormat*, uint vertex_len); -#endif /* __GWN_VERTEX_FORMAT_PRIVATE_H__ */ +#endif /* __GPU_VERTEX_FORMAT_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 0bf215f31a8..5d495779ba1 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -539,9 +539,9 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) glUniform1i(GPU_shader_get_uniform(shader, "image"), 0); glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), halfx, halfy, 1.0f + halfx, 1.0f + halfy); glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), x1, y1, x2, y2); - glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f); - GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4); + GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); GPU_texture_unbind(color); } diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 0546dcb1a6c..55e1a43925d 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -82,9 +82,9 @@ typedef struct bMotionPath { int flag; /* baking settings - eMotionPath_Flag */ /* Used for drawing. */ - struct Gwn_VertBuf *points_vbo; - struct Gwn_Batch *batch_line; - struct Gwn_Batch *batch_points; + struct GPUVertBuf *points_vbo; + struct GPUBatch *batch_line; + struct GPUBatch *batch_points; void *pad; } bMotionPath; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 80ad3840a8f..25d9e50ff7a 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -184,7 +184,7 @@ typedef struct wmWindow { struct wmWindow *next, *prev; void *ghostwin; /* don't want to include ghost.h stuff */ - void *gwnctx; /* don't want to include gawin stuff */ + void *gpuctx; /* don't want to include gpu stuff */ struct wmWindow *parent; /* Parent window */ diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt index 8d26fee0abd..030576fefd1 100644 --- a/source/blender/python/CMakeLists.txt +++ b/source/blender/python/CMakeLists.txt @@ -17,7 +17,7 @@ # ***** END GPL LICENSE BLOCK ***** add_subdirectory(intern) -add_subdirectory(gawain) add_subdirectory(generic) +add_subdirectory(gpu) add_subdirectory(mathutils) add_subdirectory(bmesh) diff --git a/source/blender/python/gawain/CMakeLists.txt b/source/blender/python/gawain/CMakeLists.txt deleted file mode 100644 index 9eab323a0fe..00000000000 --- a/source/blender/python/gawain/CMakeLists.txt +++ /dev/null @@ -1,47 +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. -# -# Contributor(s): Campbell Barton -# -# ***** END GPL LICENSE BLOCK ***** - -set(INC - . - ../../blenkernel - ../../blenlib - ../../gpu - ../../makesdna - ../../../../intern/gawain - ../../../../intern/guardedalloc - ../../../../intern/glew-mx -) - -set(INC_SYS - ${GLEW_INCLUDE_PATH} - ${PYTHON_INCLUDE_DIRS} -) - -set(SRC - gwn_py_api.c - gwn_py_types.c - - gwn_py_api.h - gwn_py_types.h -) - -add_definitions(${GL_DEFINITIONS}) - -blender_add_lib(bf_python_gawain "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/python/gawain/gwn_py_api.c b/source/blender/python/gawain/gwn_py_api.c deleted file mode 100644 index 1f7a1297448..00000000000 --- a/source/blender/python/gawain/gwn_py_api.c +++ /dev/null @@ -1,63 +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. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/gawain/gwn_py_api.c - * \ingroup pygawain - * - * Experimental Python API, not considered public yet (called '_gawain'), - * we may re-expose as public later. - */ - -#include - -#include "GPU_batch.h" -#include "GPU_vertex_format.h" - -#include "gwn_py_api.h" -#include "gwn_py_types.h" - -#include "BLI_utildefines.h" - -#include "../generic/python_utildefines.h" - -PyDoc_STRVAR(GWN_doc, -"This module provides access to gawain drawing functions." -); -static struct PyModuleDef GWN_module_def = { - PyModuleDef_HEAD_INIT, - .m_name = "_gawain", /* m_name */ - .m_doc = GWN_doc, /* m_doc */ -}; - -PyObject *BPyInit_gawain(void) -{ - PyObject *sys_modules = PyThreadState_GET()->interp->modules; - PyObject *submodule; - PyObject *mod; - - mod = PyModule_Create(&GWN_module_def); - - /* _gawain.types */ - PyModule_AddObject(mod, "types", (submodule = BPyInit_gawain_types())); - PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule); - Py_INCREF(submodule); - - return mod; -} diff --git a/source/blender/python/gawain/gwn_py_api.h b/source/blender/python/gawain/gwn_py_api.h deleted file mode 100644 index 3ef85e8ae0f..00000000000 --- a/source/blender/python/gawain/gwn_py_api.h +++ /dev/null @@ -1,30 +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. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __GWN_PY_API_H__ -#define __GWN_PY_API_H__ - -/** \file blender/python/gawain/gwn_py_api.h - * \ingroup pygawain - */ - -PyObject *BPyInit_gawain(void); - -#endif /* __GWN_PY_API_H__ */ diff --git a/source/blender/python/gawain/gwn_py_types.c b/source/blender/python/gawain/gwn_py_types.c deleted file mode 100644 index 04c50ac0784..00000000000 --- a/source/blender/python/gawain/gwn_py_types.c +++ /dev/null @@ -1,847 +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. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/gawain/gwn_py_types.c - * \ingroup pygawain - * - * - Use ``bpygwn_`` for local API. - * - Use ``BPyGwn_`` for public API. - */ - -#include - -#include "GPU_batch.h" -#include "GPU_vertex_format.h" - -#include "BLI_math.h" - -#include "GPU_batch.h" - -#include "MEM_guardedalloc.h" - -#include "../generic/py_capi_utils.h" -#include "../generic/python_utildefines.h" - -#include "gwn_py_types.h" /* own include */ - -#ifdef __BIG_ENDIAN__ - /* big endian */ -# define MAKE_ID2(c, d) ((c) << 8 | (d)) -# define MAKE_ID3(a, b, c) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 ) -# define MAKE_ID4(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) ) -#else - /* little endian */ -# define MAKE_ID2(c, d) ((d) << 8 | (c)) -# define MAKE_ID3(a, b, c) ( (int)(c) << 16 | (b) << 8 | (a) ) -# define MAKE_ID4(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) ) -#endif - -/* -------------------------------------------------------------------- */ - -/** \name Enum Conversion - * - * Use with PyArg_ParseTuple's "O&" formatting. - * \{ */ - -static int bpygwn_ParseVertCompType(PyObject *o, void *p) -{ - Py_ssize_t comp_type_id_len; - const char *comp_type_id = _PyUnicode_AsStringAndSize(o, &comp_type_id_len); - if (comp_type_id == NULL) { - PyErr_Format(PyExc_ValueError, - "expected a string, got %s", - Py_TYPE(o)->tp_name); - return 0; - } - - Gwn_VertCompType comp_type; - if (comp_type_id_len == 2) { - switch (*((ushort *)comp_type_id)) { - case MAKE_ID2('I', '8'): { comp_type = GWN_COMP_I8; goto success; } - case MAKE_ID2('U', '8'): { comp_type = GWN_COMP_U8; goto success; } - } - } - else if (comp_type_id_len == 3) { - switch (*((uint *)comp_type_id)) { - case MAKE_ID3('I', '1', '6'): { comp_type = GWN_COMP_I16; goto success; } - case MAKE_ID3('U', '1', '6'): { comp_type = GWN_COMP_U16; goto success; } - case MAKE_ID3('I', '3', '2'): { comp_type = GWN_COMP_I32; goto success; } - case MAKE_ID3('U', '3', '2'): { comp_type = GWN_COMP_U32; goto success; } - case MAKE_ID3('F', '3', '2'): { comp_type = GWN_COMP_F32; goto success; } - case MAKE_ID3('I', '1', '0'): { comp_type = GWN_COMP_I10; goto success; } - } - } - - PyErr_Format(PyExc_ValueError, - "unknown type literal: '%s'", - comp_type_id); - return 0; - -success: - *((Gwn_VertCompType *)p) = comp_type; - return 1; -} - -static int bpygwn_ParseVertFetchMode(PyObject *o, void *p) -{ - Py_ssize_t mode_id_len; - const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len); - if (mode_id == NULL) { - PyErr_Format(PyExc_ValueError, - "expected a string, got %s", - Py_TYPE(o)->tp_name); - return 0; - } -#define MATCH_ID(id) \ - if (mode_id_len == strlen(STRINGIFY(id))) { \ - if (STREQ(mode_id, STRINGIFY(id))) { \ - mode = GWN_FETCH_##id; \ - goto success; \ - } \ - } ((void)0) - - Gwn_VertFetchMode mode; - MATCH_ID(FLOAT); - MATCH_ID(INT); - MATCH_ID(INT_TO_FLOAT_UNIT); - MATCH_ID(INT_TO_FLOAT); -#undef MATCH_ID - PyErr_Format(PyExc_ValueError, - "unknown type literal: '%s'", - mode_id); - return 0; - -success: - (*(Gwn_VertFetchMode *)p) = mode; - return 1; -} - -static int bpygwn_ParsePrimType(PyObject *o, void *p) -{ - Py_ssize_t mode_id_len; - const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len); - if (mode_id == NULL) { - PyErr_Format(PyExc_ValueError, - "expected a string, got %s", - Py_TYPE(o)->tp_name); - return 0; - } -#define MATCH_ID(id) \ - if (mode_id_len == strlen(STRINGIFY(id))) { \ - if (STREQ(mode_id, STRINGIFY(id))) { \ - mode = GWN_PRIM_##id; \ - goto success; \ - } \ - } ((void)0) - - Gwn_PrimType mode; - MATCH_ID(POINTS); - MATCH_ID(LINES); - MATCH_ID(TRIS); - MATCH_ID(LINE_STRIP); - MATCH_ID(LINE_LOOP); - MATCH_ID(TRI_STRIP); - MATCH_ID(TRI_FAN); - MATCH_ID(LINE_STRIP_ADJ); - -#undef MATCH_ID - PyErr_Format(PyExc_ValueError, - "unknown type literal: '%s'", - mode_id); - return 0; - -success: - (*(Gwn_PrimType *)p) = mode; - return 1; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Utility Functions - * \{ */ - -#define PY_AS_NATIVE_SWITCH(attr) \ - switch (attr->comp_type) { \ - case GWN_COMP_I8: { PY_AS_NATIVE(int8_t, PyC_Long_AsI8); break; } \ - case GWN_COMP_U8: { PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); break; } \ - case GWN_COMP_I16: { PY_AS_NATIVE(int16_t, PyC_Long_AsI16); break; } \ - case GWN_COMP_U16: { PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); break; } \ - case GWN_COMP_I32: { PY_AS_NATIVE(int32_t, PyC_Long_AsI32); break; } \ - case GWN_COMP_U32: { PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); break; } \ - case GWN_COMP_F32: { PY_AS_NATIVE(float, PyFloat_AsDouble); break; } \ - default: \ - BLI_assert(0); \ - } ((void)0) - -/* No error checking, callers must run PyErr_Occurred */ -static void fill_format_elem(void *data_dst_void, PyObject *py_src, const Gwn_VertAttr *attr) -{ -#define PY_AS_NATIVE(ty_dst, py_as_native) \ -{ \ - ty_dst *data_dst = data_dst_void; \ - *data_dst = py_as_native(py_src); \ -} ((void)0) - - PY_AS_NATIVE_SWITCH(attr); - -#undef PY_AS_NATIVE -} - -/* No error checking, callers must run PyErr_Occurred */ -static void fill_format_tuple(void *data_dst_void, PyObject *py_src, const Gwn_VertAttr *attr) -{ - const uint len = attr->comp_len; - -/** - * Args are constants, so range checks will be optimized out if they're nop's. - */ -#define PY_AS_NATIVE(ty_dst, py_as_native) \ - ty_dst *data_dst = data_dst_void; \ - for (uint i = 0; i < len; i++) { \ - data_dst[i] = py_as_native(PyTuple_GET_ITEM(py_src, i)); \ - } ((void)0) - - PY_AS_NATIVE_SWITCH(attr); - -#undef PY_AS_NATIVE -} - -#undef PY_AS_NATIVE_SWITCH -#undef WARN_TYPE_LIMIT_PUSH -#undef WARN_TYPE_LIMIT_POP - -static bool bpygwn_vertbuf_fill_impl( - Gwn_VertBuf *vbo, - uint data_id, PyObject *seq) -{ - bool ok = true; - const Gwn_VertAttr *attr = &vbo->format.attribs[data_id]; - - Gwn_VertBufRaw data_step; - GWN_vertbuf_attr_get_raw_data(vbo, data_id, &data_step); - - PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill"); - if (seq_fast == NULL) { - goto finally; - } - - const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast); - - if (seq_len != vbo->vertex_len) { - PyErr_Format(PyExc_ValueError, - "Expected a sequence of size %d, got %d", - vbo->vertex_len, seq_len); - } - - PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast); - - if (attr->comp_len == 1) { - for (uint i = 0; i < seq_len; i++) { - uchar *data = (uchar *)GWN_vertbuf_raw_step(&data_step); - PyObject *item = seq_items[i]; - fill_format_elem(data, item, attr); - } - } - else { - for (uint i = 0; i < seq_len; i++) { - uchar *data = (uchar *)GWN_vertbuf_raw_step(&data_step); - PyObject *item = seq_items[i]; - if (!PyTuple_CheckExact(item)) { - PyErr_Format(PyExc_ValueError, - "expected a tuple, got %s", - Py_TYPE(item)->tp_name); - ok = false; - goto finally; - } - if (PyTuple_GET_SIZE(item) != attr->comp_len) { - PyErr_Format(PyExc_ValueError, - "expected a tuple of size %d, got %d", - attr->comp_len, PyTuple_GET_SIZE(item)); - ok = false; - goto finally; - } - - /* May trigger error, check below */ - fill_format_tuple(data, item, attr); - } - } - - if (PyErr_Occurred()) { - ok = false; - } - -finally: - - Py_DECREF(seq_fast); - return ok; -} - -/* handy, but not used just now */ -#if 0 -static int bpygwn_find_id(const Gwn_VertFormat *fmt, const char *id) -{ - for (int i = 0; i < fmt->attr_len; i++) { - for (uint j = 0; j < fmt->name_len; j++) { - if (STREQ(fmt->attribs[i].name[j], id)) { - return i; - } - } - } - return -1; -} -#endif - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name VertFormat Type - * \{ */ - -static PyObject *bpygwn_VertFormat_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) -{ - if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) { - PyErr_SetString(PyExc_TypeError, - "VertFormat(): takes no arguments"); - return NULL; - } - - BPyGwn_VertFormat *ret = (BPyGwn_VertFormat *)BPyGwn_VertFormat_CreatePyObject(NULL); - - return (PyObject *)ret; -} - -PyDoc_STRVAR(bpygwn_VertFormat_attr_add_doc, -"TODO" -); -static PyObject *bpygwn_VertFormat_attr_add(BPyGwn_VertFormat *self, PyObject *args, PyObject *kwds) -{ - static const char *kwlist[] = {"id", "comp_type", "len", "fetch_mode", NULL}; - - struct { - const char *id; - Gwn_VertCompType comp_type; - uint len; - Gwn_VertFetchMode fetch_mode; - } params; - - if (self->fmt.attr_len == GWN_VERT_ATTR_MAX_LEN) { - PyErr_SetString(PyExc_ValueError, "Maxumum attr reached " STRINGIFY(GWN_VERT_ATTR_MAX_LEN)); - return NULL; - } - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "$sO&IO&:attr_add", (char **)kwlist, - ¶ms.id, - bpygwn_ParseVertCompType, ¶ms.comp_type, - ¶ms.len, - bpygwn_ParseVertFetchMode, ¶ms.fetch_mode)) - { - return NULL; - } - - uint attr_id = GWN_vertformat_attr_add(&self->fmt, params.id, params.comp_type, params.len, params.fetch_mode); - return PyLong_FromLong(attr_id); -} - -static struct PyMethodDef bpygwn_VertFormat_methods[] = { - {"attr_add", (PyCFunction)bpygwn_VertFormat_attr_add, - METH_VARARGS | METH_KEYWORDS, bpygwn_VertFormat_attr_add_doc}, - {NULL, NULL, 0, NULL} -}; - - -static void bpygwn_VertFormat_dealloc(BPyGwn_VertFormat *self) -{ - Py_TYPE(self)->tp_free(self); -} - -PyTypeObject BPyGwn_VertFormat_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "Gwn_VertFormat", - .tp_basicsize = sizeof(BPyGwn_VertFormat), - .tp_dealloc = (destructor)bpygwn_VertFormat_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_methods = bpygwn_VertFormat_methods, - .tp_new = bpygwn_VertFormat_new, -}; - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name VertBuf Type - * \{ */ - -static PyObject *bpygwn_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) -{ - const char * const keywords[] = {"len", "format", NULL}; - - struct { - BPyGwn_VertFormat *py_fmt; - uint len; - } params; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, - "$IO!:Gwn_VertBuf.__new__", (char **)keywords, - ¶ms.len, - &BPyGwn_VertFormat_Type, ¶ms.py_fmt)) - { - return NULL; - } - - struct Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(¶ms.py_fmt->fmt); - - GWN_vertbuf_data_alloc(vbo, params.len); - - return BPyGwn_VertBuf_CreatePyObject(vbo); -} - -PyDoc_STRVAR(bpygwn_VertBuf_fill_doc, -"TODO" -); -static PyObject *bpygwn_VertBuf_fill(BPyGwn_VertBuf *self, PyObject *args, PyObject *kwds) -{ - static const char *kwlist[] = {"id", "data", NULL}; - - struct { - uint id; - PyObject *py_seq_data; - } params; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "$IO:fill", (char **)kwlist, - ¶ms.id, - ¶ms.py_seq_data)) - { - return NULL; - } - - if (params.id >= self->buf->format.attr_len) { - PyErr_Format(PyExc_ValueError, - "Format id %d out of range", - params.id); - return NULL; - } - - if (self->buf->data == NULL) { - PyErr_SetString(PyExc_ValueError, - "Can't fill, static buffer already in use"); - return NULL; - } - - if (!bpygwn_vertbuf_fill_impl(self->buf, params.id, params.py_seq_data)) { - return NULL; - } - Py_RETURN_NONE; -} - -static struct PyMethodDef bpygwn_VertBuf_methods[] = { - {"fill", (PyCFunction) bpygwn_VertBuf_fill, - METH_VARARGS | METH_KEYWORDS, bpygwn_VertBuf_fill_doc}, - {NULL, NULL, 0, NULL} -}; - -static void bpygwn_VertBuf_dealloc(BPyGwn_VertBuf *self) -{ - GWN_vertbuf_discard(self->buf); - Py_TYPE(self)->tp_free(self); -} - -PyTypeObject BPyGwn_VertBuf_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "Gwn_VertBuf", - .tp_basicsize = sizeof(BPyGwn_VertBuf), - .tp_dealloc = (destructor)bpygwn_VertBuf_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_methods = bpygwn_VertBuf_methods, - .tp_new = bpygwn_VertBuf_new, -}; - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name VertBatch Type - * \{ */ - -static PyObject *bpygwn_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) -{ - const char * const keywords[] = {"type", "buf", NULL}; - - struct { - Gwn_PrimType type_id; - BPyGwn_VertBuf *py_buf; - } params; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, - "$O&O!:Gwn_Batch.__new__", (char **)keywords, - bpygwn_ParsePrimType, ¶ms.type_id, - &BPyGwn_VertBuf_Type, ¶ms.py_buf)) - { - return NULL; - } - - Gwn_Batch *batch = GWN_batch_create(params.type_id, params.py_buf->buf, NULL); - BPyGwn_Batch *ret = (BPyGwn_Batch *)BPyGwn_Batch_CreatePyObject(batch); - -#ifdef USE_GWN_PY_REFERENCES - ret->references = PyList_New(1); - PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_buf); - Py_INCREF(params.py_buf); - PyObject_GC_Track(ret); -#endif - - return (PyObject *)ret; -} - -PyDoc_STRVAR(bpygwn_VertBatch_vertbuf_add_doc, -"TODO" -); -static PyObject *bpygwn_VertBatch_vertbuf_add(BPyGwn_Batch *self, BPyGwn_VertBuf *py_buf) -{ - if (!BPyGwn_VertBuf_Check(py_buf)) { - PyErr_Format(PyExc_TypeError, - "Expected a Gwn_VertBuf, got %s", - Py_TYPE(py_buf)->tp_name); - return NULL; - } - - if (self->batch->verts[0]->vertex_len != py_buf->buf->vertex_len) { - PyErr_Format(PyExc_TypeError, - "Expected %d length, got %d", - self->batch->verts[0]->vertex_len, py_buf->buf->vertex_len); - return NULL; - } - -#ifdef USE_GWN_PY_REFERENCES - /* Hold user */ - PyList_Append(self->references, (PyObject *)py_buf); -#endif - - GWN_batch_vertbuf_add(self->batch, py_buf->buf); - Py_RETURN_NONE; -} - -/* Currently magic number from Py perspective. */ -PyDoc_STRVAR(bpygwn_VertBatch_program_set_builtin_doc, -"TODO" -); -static PyObject *bpygwn_VertBatch_program_set_builtin(BPyGwn_Batch *self, PyObject *args, PyObject *kwds) -{ - static const char *kwlist[] = {"id", NULL}; - - struct { - const char *shader; - } params; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "s:program_set_builtin", (char **)kwlist, - ¶ms.shader)) - { - return NULL; - } - - GPUBuiltinShader shader; - -#define MATCH_ID(id) \ - if (STREQ(params.shader, STRINGIFY(id))) { \ - shader = GPU_SHADER_##id; \ - goto success; \ - } ((void)0) - - MATCH_ID(2D_FLAT_COLOR); - MATCH_ID(2D_SMOOTH_COLOR); - MATCH_ID(2D_UNIFORM_COLOR); - - MATCH_ID(3D_FLAT_COLOR); - MATCH_ID(3D_SMOOTH_COLOR); - MATCH_ID(3D_UNIFORM_COLOR); - -#undef MATCH_ID - - PyErr_SetString(PyExc_ValueError, - "shader name not known"); - return NULL; - -success: - GWN_batch_program_set_builtin(self->batch, shader); - Py_RETURN_NONE; -} - -static PyObject *bpygwn_VertBatch_uniform_bool(BPyGwn_Batch *self, PyObject *args) -{ - struct { - const char *id; - bool values[1]; - } params; - - if (!PyArg_ParseTuple( - args, "sO&:uniform_bool", - ¶ms.id, - PyC_ParseBool, ¶ms.values[0])) - { - return NULL; - } - - GWN_batch_uniform_1b(self->batch, params.id, params.values[0]); - Py_RETURN_NONE; -} - -static PyObject *bpygwn_VertBatch_uniform_i32(BPyGwn_Batch *self, PyObject *args) -{ - struct { - const char *id; - int values[1]; - } params; - - if (!PyArg_ParseTuple( - args, "si:uniform_i32", - ¶ms.id, - ¶ms.values[0])) - { - return NULL; - } - - GWN_batch_uniform_1i(self->batch, params.id, params.values[0]); - Py_RETURN_NONE; -} - -static PyObject *bpygwn_VertBatch_uniform_f32(BPyGwn_Batch *self, PyObject *args) -{ - struct { - const char *id; - float values[4]; - } params; - - if (!PyArg_ParseTuple( - args, "sf|fff:uniform_f32", - ¶ms.id, - ¶ms.values[0], ¶ms.values[1], ¶ms.values[2], ¶ms.values[3])) - { - return NULL; - } - - switch (PyTuple_GET_SIZE(args)) { - case 2: GWN_batch_uniform_1f(self->batch, params.id, params.values[0]); break; - case 3: GWN_batch_uniform_2f(self->batch, params.id, UNPACK2(params.values)); break; - case 4: GWN_batch_uniform_3f(self->batch, params.id, UNPACK3(params.values)); break; - case 5: GWN_batch_uniform_4f(self->batch, params.id, UNPACK4(params.values)); break; - default: - BLI_assert(0); - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(bpygwn_VertBatch_draw_doc, -"TODO" -); -static PyObject *bpygwn_VertBatch_draw(BPyGwn_Batch *self) -{ - if (!glIsProgram(self->batch->program)) { - PyErr_SetString(PyExc_ValueError, - "batch program has not not set"); - } - GWN_batch_draw(self->batch); - Py_RETURN_NONE; -} - -static PyObject *bpygwn_VertBatch_program_use_begin(BPyGwn_Batch *self) -{ - if (!glIsProgram(self->batch->program)) { - PyErr_SetString(PyExc_ValueError, - "batch program has not not set"); - } - GWN_batch_program_use_begin(self->batch); - Py_RETURN_NONE; -} - -static PyObject *bpygwn_VertBatch_program_use_end(BPyGwn_Batch *self) -{ - if (!glIsProgram(self->batch->program)) { - PyErr_SetString(PyExc_ValueError, - "batch program has not not set"); - } - GWN_batch_program_use_end(self->batch); - Py_RETURN_NONE; -} - -static struct PyMethodDef bpygwn_VertBatch_methods[] = { - {"vertbuf_add", (PyCFunction)bpygwn_VertBatch_vertbuf_add, - METH_O, bpygwn_VertBatch_vertbuf_add_doc}, - {"program_set_builtin", (PyCFunction)bpygwn_VertBatch_program_set_builtin, - METH_VARARGS | METH_KEYWORDS, bpygwn_VertBatch_program_set_builtin_doc}, - {"uniform_bool", (PyCFunction)bpygwn_VertBatch_uniform_bool, - METH_VARARGS, NULL}, - {"uniform_i32", (PyCFunction)bpygwn_VertBatch_uniform_i32, - METH_VARARGS, NULL}, - {"uniform_f32", (PyCFunction)bpygwn_VertBatch_uniform_f32, - METH_VARARGS, NULL}, - {"draw", (PyCFunction) bpygwn_VertBatch_draw, - METH_NOARGS, bpygwn_VertBatch_draw_doc}, - {"program_use_begin", (PyCFunction)bpygwn_VertBatch_program_use_begin, - METH_NOARGS, ""}, - {"program_use_end", (PyCFunction)bpygwn_VertBatch_program_use_end, - METH_NOARGS, ""}, - {NULL, NULL, 0, NULL} -}; - -#ifdef USE_GWN_PY_REFERENCES - -static int bpygwn_Batch_traverse(BPyGwn_Batch *self, visitproc visit, void *arg) -{ - Py_VISIT(self->references); - return 0; -} - -static int bpygwn_Batch_clear(BPyGwn_Batch *self) -{ - Py_CLEAR(self->references); - return 0; -} - -#endif - -static void bpygwn_Batch_dealloc(BPyGwn_Batch *self) -{ - GWN_batch_discard(self->batch); - -#ifdef USE_GWN_PY_REFERENCES - if (self->references) { - PyObject_GC_UnTrack(self); - bpygwn_Batch_clear(self); - Py_XDECREF(self->references); - } -#endif - - Py_TYPE(self)->tp_free(self); -} - -PyTypeObject BPyGwn_Batch_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "Gwn_Batch", - .tp_basicsize = sizeof(BPyGwn_Batch), - .tp_dealloc = (destructor)bpygwn_Batch_dealloc, -#ifdef USE_GWN_PY_REFERENCES - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)bpygwn_Batch_traverse, - .tp_clear = (inquiry)bpygwn_Batch_clear, -#else - .tp_flags = Py_TPFLAGS_DEFAULT, -#endif - .tp_methods = bpygwn_VertBatch_methods, - .tp_new = bpygwn_Batch_new, -}; - -/* -------------------------------------------------------------------- */ - - -/** \name Gawain Types Module - * \{ */ - -static struct PyModuleDef BPy_BM_types_module_def = { - PyModuleDef_HEAD_INIT, - .m_name = "_gawain.types", -}; - -PyObject *BPyInit_gawain_types(void) -{ - PyObject *submodule; - - submodule = PyModule_Create(&BPy_BM_types_module_def); - - if (PyType_Ready(&BPyGwn_VertFormat_Type) < 0) - return NULL; - if (PyType_Ready(&BPyGwn_VertBuf_Type) < 0) - return NULL; - if (PyType_Ready(&BPyGwn_Batch_Type) < 0) - return NULL; - -#define MODULE_TYPE_ADD(s, t) \ - PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t) - - MODULE_TYPE_ADD(submodule, BPyGwn_VertFormat_Type); - MODULE_TYPE_ADD(submodule, BPyGwn_VertBuf_Type); - MODULE_TYPE_ADD(submodule, BPyGwn_Batch_Type); - -#undef MODULE_TYPE_ADD - - return submodule; -} - -/** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Public API - * \{ */ - -PyObject *BPyGwn_VertFormat_CreatePyObject(Gwn_VertFormat *fmt) -{ - BPyGwn_VertFormat *self; - - self = PyObject_New(BPyGwn_VertFormat, &BPyGwn_VertFormat_Type); - if (fmt) { - self->fmt = *fmt; - } - else { - memset(&self->fmt, 0, sizeof(self->fmt)); - } - - return (PyObject *)self; -} - -PyObject *BPyGwn_VertBuf_CreatePyObject(Gwn_VertBuf *buf) -{ - BPyGwn_VertBuf *self; - - self = PyObject_New(BPyGwn_VertBuf, &BPyGwn_VertBuf_Type); - self->buf = buf; - - return (PyObject *)self; -} - - -PyObject *BPyGwn_Batch_CreatePyObject(Gwn_Batch *batch) -{ - BPyGwn_Batch *self; - -#ifdef USE_GWN_PY_REFERENCES - self = (BPyGwn_Batch *)_PyObject_GC_New(&BPyGwn_Batch_Type); - self->references = NULL; -#else - self = PyObject_New(BPyGwn_Batch, &BPyGwn_Batch_Type); -#endif - - self->batch = batch; - - return (PyObject *)self; -} - -/** \} */ diff --git a/source/blender/python/gawain/gwn_py_types.h b/source/blender/python/gawain/gwn_py_types.h deleted file mode 100644 index dde6cf98827..00000000000 --- a/source/blender/python/gawain/gwn_py_types.h +++ /dev/null @@ -1,67 +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. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/python/gawain/gwn_py_types.h - * \ingroup pygawain - */ - -#ifndef __GWN_PY_TYPES_H__ -#define __GWN_PY_TYPES_H__ - -#include "BLI_compiler_attrs.h" - -#define USE_GWN_PY_REFERENCES - -extern PyTypeObject BPyGwn_VertFormat_Type; -extern PyTypeObject BPyGwn_VertBuf_Type; -extern PyTypeObject BPyGwn_Batch_Type; - -#define BPyGwn_VertFormat_Check(v) (Py_TYPE(v) == &BPyGwn_VertFormat_Type) -#define BPyGwn_VertBuf_Check(v) (Py_TYPE(v) == &BPyGwn_VertBuf_Type) -#define BPyGwn_Batch_Check(v) (Py_TYPE(v) == &BPyGwn_Batch_Type) - -typedef struct BPyGwn_VertFormat { - PyObject_VAR_HEAD - struct Gwn_VertFormat fmt; -} BPyGwn_VertFormat; - -typedef struct BPyGwn_VertBuf { - PyObject_VAR_HEAD - /* The buf is owned, we may support thin wrapped batches later. */ - struct Gwn_VertBuf *buf; -} BPyGwn_VertBuf; - -typedef struct BPyGwn_Batch { - PyObject_VAR_HEAD - /* The batch is owned, we may support thin wrapped batches later. */ - struct Gwn_Batch *batch; -#ifdef USE_GWN_PY_REFERENCES - /* Just to keep a user to prevent freeing buf's we're using */ - PyObject *references; -#endif -} BPyGwn_Batch; - -PyObject *BPyInit_gawain_types(void); - -PyObject *BPyGwn_VertFormat_CreatePyObject(struct Gwn_VertFormat *fmt); -PyObject *BPyGwn_VertBuf_CreatePyObject(struct Gwn_VertBuf *vbo) ATTR_NONNULL(1); -PyObject *BPyGwn_Batch_CreatePyObject(struct Gwn_Batch *batch) ATTR_NONNULL(1); - -#endif /* __GWN_PY_TYPES_H__ */ diff --git a/source/blender/python/gpu/CMakeLists.txt b/source/blender/python/gpu/CMakeLists.txt new file mode 100644 index 00000000000..141a36bbcc2 --- /dev/null +++ b/source/blender/python/gpu/CMakeLists.txt @@ -0,0 +1,46 @@ +# ***** 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. +# +# Contributor(s): Campbell Barton +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + ../../blenkernel + ../../blenlib + ../../gpu + ../../makesdna + ../../../../intern/guardedalloc + ../../../../intern/glew-mx +) + +set(INC_SYS + ${GLEW_INCLUDE_PATH} + ${PYTHON_INCLUDE_DIRS} +) + +set(SRC + gpu_py_api.c + gpu_py_types.c + + gpu_py_api.h + gpu_py_types.h +) + +add_definitions(${GL_DEFINITIONS}) + +blender_add_lib(bf_python_gpu "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c new file mode 100644 index 00000000000..53285b372d8 --- /dev/null +++ b/source/blender/python/gpu/gpu_py_api.c @@ -0,0 +1,63 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/gpu/gpu_py_api.c + * \ingroup pygpu + * + * Experimental Python API, not considered public yet (called '_gpu'), + * we may re-expose as public later. + */ + +#include + +#include "GPU_batch.h" +#include "GPU_vertex_format.h" + +#include "gpu_py_api.h" +#include "gpu_py_types.h" + +#include "BLI_utildefines.h" + +#include "../generic/python_utildefines.h" + +PyDoc_STRVAR(GPU_doc, +"This module provides access to gpu drawing functions." +); +static struct PyModuleDef GPU_module_def = { + PyModuleDef_HEAD_INIT, + .m_name = "_gpu", /* m_name */ + .m_doc = GPU_doc, /* m_doc */ +}; + +PyObject *BPyInit_gpu(void) +{ + PyObject *sys_modules = PyThreadState_GET()->interp->modules; + PyObject *submodule; + PyObject *mod; + + mod = PyModule_Create(&GPU_module_def); + + /* _gpu.types */ + PyModule_AddObject(mod, "types", (submodule = BPyInit_gpu_types())); + PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule); + Py_INCREF(submodule); + + return mod; +} diff --git a/source/blender/python/gpu/gpu_py_api.h b/source/blender/python/gpu/gpu_py_api.h new file mode 100644 index 00000000000..387bfcab950 --- /dev/null +++ b/source/blender/python/gpu/gpu_py_api.h @@ -0,0 +1,30 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __GPU_PY_API_H__ +#define __GPU_PY_API_H__ + +/** \file blender/python/gpu/gpu_py_api.h + * \ingroup pygpu + */ + +PyObject *BPyInit_gpu(void); + +#endif /* __GPU_PY_API_H__ */ diff --git a/source/blender/python/gpu/gpu_py_types.c b/source/blender/python/gpu/gpu_py_types.c new file mode 100644 index 00000000000..0a21da5682b --- /dev/null +++ b/source/blender/python/gpu/gpu_py_types.c @@ -0,0 +1,847 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/gpu/gpu_py_types.c + * \ingroup pygpu + * + * - Use ``bpygpu_`` for local API. + * - Use ``BPyGPU`` for public API. + */ + +#include + +#include "GPU_batch.h" +#include "GPU_vertex_format.h" + +#include "BLI_math.h" + +#include "GPU_batch.h" + +#include "MEM_guardedalloc.h" + +#include "../generic/py_capi_utils.h" +#include "../generic/python_utildefines.h" + +#include "gpu_py_types.h" /* own include */ + +#ifdef __BIG_ENDIAN__ + /* big endian */ +# define MAKE_ID2(c, d) ((c) << 8 | (d)) +# define MAKE_ID3(a, b, c) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 ) +# define MAKE_ID4(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) ) +#else + /* little endian */ +# define MAKE_ID2(c, d) ((d) << 8 | (c)) +# define MAKE_ID3(a, b, c) ( (int)(c) << 16 | (b) << 8 | (a) ) +# define MAKE_ID4(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) ) +#endif + +/* -------------------------------------------------------------------- */ + +/** \name Enum Conversion + * + * Use with PyArg_ParseTuple's "O&" formatting. + * \{ */ + +static int bpygpu_ParseVertCompType(PyObject *o, void *p) +{ + Py_ssize_t comp_type_id_len; + const char *comp_type_id = _PyUnicode_AsStringAndSize(o, &comp_type_id_len); + if (comp_type_id == NULL) { + PyErr_Format(PyExc_ValueError, + "expected a string, got %s", + Py_TYPE(o)->tp_name); + return 0; + } + + GPUVertCompType comp_type; + if (comp_type_id_len == 2) { + switch (*((ushort *)comp_type_id)) { + case MAKE_ID2('I', '8'): { comp_type = GPU_COMP_I8; goto success; } + case MAKE_ID2('U', '8'): { comp_type = GPU_COMP_U8; goto success; } + } + } + else if (comp_type_id_len == 3) { + switch (*((uint *)comp_type_id)) { + case MAKE_ID3('I', '1', '6'): { comp_type = GPU_COMP_I16; goto success; } + case MAKE_ID3('U', '1', '6'): { comp_type = GPU_COMP_U16; goto success; } + case MAKE_ID3('I', '3', '2'): { comp_type = GPU_COMP_I32; goto success; } + case MAKE_ID3('U', '3', '2'): { comp_type = GPU_COMP_U32; goto success; } + case MAKE_ID3('F', '3', '2'): { comp_type = GPU_COMP_F32; goto success; } + case MAKE_ID3('I', '1', '0'): { comp_type = GPU_COMP_I10; goto success; } + } + } + + PyErr_Format(PyExc_ValueError, + "unknown type literal: '%s'", + comp_type_id); + return 0; + +success: + *((GPUVertCompType *)p) = comp_type; + return 1; +} + +static int bpygpu_ParseVertFetchMode(PyObject *o, void *p) +{ + Py_ssize_t mode_id_len; + const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len); + if (mode_id == NULL) { + PyErr_Format(PyExc_ValueError, + "expected a string, got %s", + Py_TYPE(o)->tp_name); + return 0; + } +#define MATCH_ID(id) \ + if (mode_id_len == strlen(STRINGIFY(id))) { \ + if (STREQ(mode_id, STRINGIFY(id))) { \ + mode = GPU_FETCH_##id; \ + goto success; \ + } \ + } ((void)0) + + GPUVertFetchMode mode; + MATCH_ID(FLOAT); + MATCH_ID(INT); + MATCH_ID(INT_TO_FLOAT_UNIT); + MATCH_ID(INT_TO_FLOAT); +#undef MATCH_ID + PyErr_Format(PyExc_ValueError, + "unknown type literal: '%s'", + mode_id); + return 0; + +success: + (*(GPUVertFetchMode *)p) = mode; + return 1; +} + +static int bpygpu_ParsePrimType(PyObject *o, void *p) +{ + Py_ssize_t mode_id_len; + const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len); + if (mode_id == NULL) { + PyErr_Format(PyExc_ValueError, + "expected a string, got %s", + Py_TYPE(o)->tp_name); + return 0; + } +#define MATCH_ID(id) \ + if (mode_id_len == strlen(STRINGIFY(id))) { \ + if (STREQ(mode_id, STRINGIFY(id))) { \ + mode = GPU_PRIM_##id; \ + goto success; \ + } \ + } ((void)0) + + GPUPrimType mode; + MATCH_ID(POINTS); + MATCH_ID(LINES); + MATCH_ID(TRIS); + MATCH_ID(LINE_STRIP); + MATCH_ID(LINE_LOOP); + MATCH_ID(TRI_STRIP); + MATCH_ID(TRI_FAN); + MATCH_ID(LINE_STRIP_ADJ); + +#undef MATCH_ID + PyErr_Format(PyExc_ValueError, + "unknown type literal: '%s'", + mode_id); + return 0; + +success: + (*(GPUPrimType *)p) = mode; + return 1; +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Utility Functions + * \{ */ + +#define PY_AS_NATIVE_SWITCH(attr) \ + switch (attr->comp_type) { \ + case GPU_COMP_I8: { PY_AS_NATIVE(int8_t, PyC_Long_AsI8); break; } \ + case GPU_COMP_U8: { PY_AS_NATIVE(uint8_t, PyC_Long_AsU8); break; } \ + case GPU_COMP_I16: { PY_AS_NATIVE(int16_t, PyC_Long_AsI16); break; } \ + case GPU_COMP_U16: { PY_AS_NATIVE(uint16_t, PyC_Long_AsU16); break; } \ + case GPU_COMP_I32: { PY_AS_NATIVE(int32_t, PyC_Long_AsI32); break; } \ + case GPU_COMP_U32: { PY_AS_NATIVE(uint32_t, PyC_Long_AsU32); break; } \ + case GPU_COMP_F32: { PY_AS_NATIVE(float, PyFloat_AsDouble); break; } \ + default: \ + BLI_assert(0); \ + } ((void)0) + +/* No error checking, callers must run PyErr_Occurred */ +static void fill_format_elem(void *data_dst_void, PyObject *py_src, const GPUVertAttr *attr) +{ +#define PY_AS_NATIVE(ty_dst, py_as_native) \ +{ \ + ty_dst *data_dst = data_dst_void; \ + *data_dst = py_as_native(py_src); \ +} ((void)0) + + PY_AS_NATIVE_SWITCH(attr); + +#undef PY_AS_NATIVE +} + +/* No error checking, callers must run PyErr_Occurred */ +static void fill_format_tuple(void *data_dst_void, PyObject *py_src, const GPUVertAttr *attr) +{ + const uint len = attr->comp_len; + +/** + * Args are constants, so range checks will be optimized out if they're nop's. + */ +#define PY_AS_NATIVE(ty_dst, py_as_native) \ + ty_dst *data_dst = data_dst_void; \ + for (uint i = 0; i < len; i++) { \ + data_dst[i] = py_as_native(PyTuple_GET_ITEM(py_src, i)); \ + } ((void)0) + + PY_AS_NATIVE_SWITCH(attr); + +#undef PY_AS_NATIVE +} + +#undef PY_AS_NATIVE_SWITCH +#undef WARN_TYPE_LIMIT_PUSH +#undef WARN_TYPE_LIMIT_POP + +static bool bpygpu_vertbuf_fill_impl( + GPUVertBuf *vbo, + uint data_id, PyObject *seq) +{ + bool ok = true; + const GPUVertAttr *attr = &vbo->format.attribs[data_id]; + + GPUVertBufRaw data_step; + GPU_vertbuf_attr_get_raw_data(vbo, data_id, &data_step); + + PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill"); + if (seq_fast == NULL) { + goto finally; + } + + const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast); + + if (seq_len != vbo->vertex_len) { + PyErr_Format(PyExc_ValueError, + "Expected a sequence of size %d, got %d", + vbo->vertex_len, seq_len); + } + + PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast); + + if (attr->comp_len == 1) { + for (uint i = 0; i < seq_len; i++) { + uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); + PyObject *item = seq_items[i]; + fill_format_elem(data, item, attr); + } + } + else { + for (uint i = 0; i < seq_len; i++) { + uchar *data = (uchar *)GPU_vertbuf_raw_step(&data_step); + PyObject *item = seq_items[i]; + if (!PyTuple_CheckExact(item)) { + PyErr_Format(PyExc_ValueError, + "expected a tuple, got %s", + Py_TYPE(item)->tp_name); + ok = false; + goto finally; + } + if (PyTuple_GET_SIZE(item) != attr->comp_len) { + PyErr_Format(PyExc_ValueError, + "expected a tuple of size %d, got %d", + attr->comp_len, PyTuple_GET_SIZE(item)); + ok = false; + goto finally; + } + + /* May trigger error, check below */ + fill_format_tuple(data, item, attr); + } + } + + if (PyErr_Occurred()) { + ok = false; + } + +finally: + + Py_DECREF(seq_fast); + return ok; +} + +/* handy, but not used just now */ +#if 0 +static int bpygpu_find_id(const GPUVertFormat *fmt, const char *id) +{ + for (int i = 0; i < fmt->attr_len; i++) { + for (uint j = 0; j < fmt->name_len; j++) { + if (STREQ(fmt->attribs[i].name[j], id)) { + return i; + } + } + } + return -1; +} +#endif + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name VertFormat Type + * \{ */ + +static PyObject *bpygpu_VertFormat_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) +{ + if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) { + PyErr_SetString(PyExc_TypeError, + "VertFormat(): takes no arguments"); + return NULL; + } + + BPyGPUVertFormat *ret = (BPyGPUVertFormat *)BPyGPUVertFormat_CreatePyObject(NULL); + + return (PyObject *)ret; +} + +PyDoc_STRVAR(bpygpu_VertFormat_attr_add_doc, +"TODO" +); +static PyObject *bpygpu_VertFormat_attr_add(BPyGPUVertFormat *self, PyObject *args, PyObject *kwds) +{ + static const char *kwlist[] = {"id", "comp_type", "len", "fetch_mode", NULL}; + + struct { + const char *id; + GPUVertCompType comp_type; + uint len; + GPUVertFetchMode fetch_mode; + } params; + + if (self->fmt.attr_len == GPU_VERT_ATTR_MAX_LEN) { + PyErr_SetString(PyExc_ValueError, "Maxumum attr reached " STRINGIFY(GPU_VERT_ATTR_MAX_LEN)); + return NULL; + } + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "$sO&IO&:attr_add", (char **)kwlist, + ¶ms.id, + bpygpu_ParseVertCompType, ¶ms.comp_type, + ¶ms.len, + bpygpu_ParseVertFetchMode, ¶ms.fetch_mode)) + { + return NULL; + } + + uint attr_id = GPU_vertformat_attr_add(&self->fmt, params.id, params.comp_type, params.len, params.fetch_mode); + return PyLong_FromLong(attr_id); +} + +static struct PyMethodDef bpygpu_VertFormat_methods[] = { + {"attr_add", (PyCFunction)bpygpu_VertFormat_attr_add, + METH_VARARGS | METH_KEYWORDS, bpygpu_VertFormat_attr_add_doc}, + {NULL, NULL, 0, NULL} +}; + + +static void bpygpu_VertFormat_dealloc(BPyGPUVertFormat *self) +{ + Py_TYPE(self)->tp_free(self); +} + +PyTypeObject BPyGPUVertFormat_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "GPUVertFormat", + .tp_basicsize = sizeof(BPyGPUVertFormat), + .tp_dealloc = (destructor)bpygpu_VertFormat_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = bpygpu_VertFormat_methods, + .tp_new = bpygpu_VertFormat_new, +}; + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name VertBuf Type + * \{ */ + +static PyObject *bpygpu_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) +{ + const char * const keywords[] = {"len", "format", NULL}; + + struct { + BPyGPUVertFormat *py_fmt; + uint len; + } params; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, + "$IO!:GPUVertBuf.__new__", (char **)keywords, + ¶ms.len, + &BPyGPUVertFormat_Type, ¶ms.py_fmt)) + { + return NULL; + } + + struct GPUVertBuf *vbo = GPU_vertbuf_create_with_format(¶ms.py_fmt->fmt); + + GPU_vertbuf_data_alloc(vbo, params.len); + + return BPyGPUVertBuf_CreatePyObject(vbo); +} + +PyDoc_STRVAR(bpygpu_VertBuf_fill_doc, +"TODO" +); +static PyObject *bpygpu_VertBuf_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds) +{ + static const char *kwlist[] = {"id", "data", NULL}; + + struct { + uint id; + PyObject *py_seq_data; + } params; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "$IO:fill", (char **)kwlist, + ¶ms.id, + ¶ms.py_seq_data)) + { + return NULL; + } + + if (params.id >= self->buf->format.attr_len) { + PyErr_Format(PyExc_ValueError, + "Format id %d out of range", + params.id); + return NULL; + } + + if (self->buf->data == NULL) { + PyErr_SetString(PyExc_ValueError, + "Can't fill, static buffer already in use"); + return NULL; + } + + if (!bpygpu_vertbuf_fill_impl(self->buf, params.id, params.py_seq_data)) { + return NULL; + } + Py_RETURN_NONE; +} + +static struct PyMethodDef bpygpu_VertBuf_methods[] = { + {"fill", (PyCFunction) bpygpu_VertBuf_fill, + METH_VARARGS | METH_KEYWORDS, bpygpu_VertBuf_fill_doc}, + {NULL, NULL, 0, NULL} +}; + +static void bpygpu_VertBuf_dealloc(BPyGPUVertBuf *self) +{ + GPU_vertbuf_discard(self->buf); + Py_TYPE(self)->tp_free(self); +} + +PyTypeObject BPyGPUVertBuf_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "GPUVertBuf", + .tp_basicsize = sizeof(BPyGPUVertBuf), + .tp_dealloc = (destructor)bpygpu_VertBuf_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = bpygpu_VertBuf_methods, + .tp_new = bpygpu_VertBuf_new, +}; + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name VertBatch Type + * \{ */ + +static PyObject *bpygpu_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) +{ + const char * const keywords[] = {"type", "buf", NULL}; + + struct { + GPUPrimType type_id; + BPyGPUVertBuf *py_buf; + } params; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, + "$O&O!:GPUBatch.__new__", (char **)keywords, + bpygpu_ParsePrimType, ¶ms.type_id, + &BPyGPUVertBuf_Type, ¶ms.py_buf)) + { + return NULL; + } + + GPUBatch *batch = GPU_batch_create(params.type_id, params.py_buf->buf, NULL); + BPyGPUBatch *ret = (BPyGPUBatch *)BPyGPUBatch_CreatePyObject(batch); + +#ifdef USE_GPU_PY_REFERENCES + ret->references = PyList_New(1); + PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_buf); + Py_INCREF(params.py_buf); + PyObject_GC_Track(ret); +#endif + + return (PyObject *)ret; +} + +PyDoc_STRVAR(bpygpu_VertBatch_vertbuf_add_doc, +"TODO" +); +static PyObject *bpygpu_VertBatch_vertbuf_add(BPyGPUBatch *self, BPyGPUVertBuf *py_buf) +{ + if (!BPyGPUVertBuf_Check(py_buf)) { + PyErr_Format(PyExc_TypeError, + "Expected a GPUVertBuf, got %s", + Py_TYPE(py_buf)->tp_name); + return NULL; + } + + if (self->batch->verts[0]->vertex_len != py_buf->buf->vertex_len) { + PyErr_Format(PyExc_TypeError, + "Expected %d length, got %d", + self->batch->verts[0]->vertex_len, py_buf->buf->vertex_len); + return NULL; + } + +#ifdef USE_GPU_PY_REFERENCES + /* Hold user */ + PyList_Append(self->references, (PyObject *)py_buf); +#endif + + GPU_batch_vertbuf_add(self->batch, py_buf->buf); + Py_RETURN_NONE; +} + +/* Currently magic number from Py perspective. */ +PyDoc_STRVAR(bpygpu_VertBatch_program_set_builtin_doc, +"TODO" +); +static PyObject *bpygpu_VertBatch_program_set_builtin(BPyGPUBatch *self, PyObject *args, PyObject *kwds) +{ + static const char *kwlist[] = {"id", NULL}; + + struct { + const char *shader; + } params; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "s:program_set_builtin", (char **)kwlist, + ¶ms.shader)) + { + return NULL; + } + + GPUBuiltinShader shader; + +#define MATCH_ID(id) \ + if (STREQ(params.shader, STRINGIFY(id))) { \ + shader = GPU_SHADER_##id; \ + goto success; \ + } ((void)0) + + MATCH_ID(2D_FLAT_COLOR); + MATCH_ID(2D_SMOOTH_COLOR); + MATCH_ID(2D_UNIFORM_COLOR); + + MATCH_ID(3D_FLAT_COLOR); + MATCH_ID(3D_SMOOTH_COLOR); + MATCH_ID(3D_UNIFORM_COLOR); + +#undef MATCH_ID + + PyErr_SetString(PyExc_ValueError, + "shader name not known"); + return NULL; + +success: + GPU_batch_program_set_builtin(self->batch, shader); + Py_RETURN_NONE; +} + +static PyObject *bpygpu_VertBatch_uniform_bool(BPyGPUBatch *self, PyObject *args) +{ + struct { + const char *id; + bool values[1]; + } params; + + if (!PyArg_ParseTuple( + args, "sO&:uniform_bool", + ¶ms.id, + PyC_ParseBool, ¶ms.values[0])) + { + return NULL; + } + + GPU_batch_uniform_1b(self->batch, params.id, params.values[0]); + Py_RETURN_NONE; +} + +static PyObject *bpygpu_VertBatch_uniform_i32(BPyGPUBatch *self, PyObject *args) +{ + struct { + const char *id; + int values[1]; + } params; + + if (!PyArg_ParseTuple( + args, "si:uniform_i32", + ¶ms.id, + ¶ms.values[0])) + { + return NULL; + } + + GPU_batch_uniform_1i(self->batch, params.id, params.values[0]); + Py_RETURN_NONE; +} + +static PyObject *bpygpu_VertBatch_uniform_f32(BPyGPUBatch *self, PyObject *args) +{ + struct { + const char *id; + float values[4]; + } params; + + if (!PyArg_ParseTuple( + args, "sf|fff:uniform_f32", + ¶ms.id, + ¶ms.values[0], ¶ms.values[1], ¶ms.values[2], ¶ms.values[3])) + { + return NULL; + } + + switch (PyTuple_GET_SIZE(args)) { + case 2: GPU_batch_uniform_1f(self->batch, params.id, params.values[0]); break; + case 3: GPU_batch_uniform_2f(self->batch, params.id, UNPACK2(params.values)); break; + case 4: GPU_batch_uniform_3f(self->batch, params.id, UNPACK3(params.values)); break; + case 5: GPU_batch_uniform_4f(self->batch, params.id, UNPACK4(params.values)); break; + default: + BLI_assert(0); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(bpygpu_VertBatch_draw_doc, +"TODO" +); +static PyObject *bpygpu_VertBatch_draw(BPyGPUBatch *self) +{ + if (!glIsProgram(self->batch->program)) { + PyErr_SetString(PyExc_ValueError, + "batch program has not not set"); + } + GPU_batch_draw(self->batch); + Py_RETURN_NONE; +} + +static PyObject *bpygpu_VertBatch_program_use_begin(BPyGPUBatch *self) +{ + if (!glIsProgram(self->batch->program)) { + PyErr_SetString(PyExc_ValueError, + "batch program has not not set"); + } + GPU_batch_program_use_begin(self->batch); + Py_RETURN_NONE; +} + +static PyObject *bpygpu_VertBatch_program_use_end(BPyGPUBatch *self) +{ + if (!glIsProgram(self->batch->program)) { + PyErr_SetString(PyExc_ValueError, + "batch program has not not set"); + } + GPU_batch_program_use_end(self->batch); + Py_RETURN_NONE; +} + +static struct PyMethodDef bpygpu_VertBatch_methods[] = { + {"vertbuf_add", (PyCFunction)bpygpu_VertBatch_vertbuf_add, + METH_O, bpygpu_VertBatch_vertbuf_add_doc}, + {"program_set_builtin", (PyCFunction)bpygpu_VertBatch_program_set_builtin, + METH_VARARGS | METH_KEYWORDS, bpygpu_VertBatch_program_set_builtin_doc}, + {"uniform_bool", (PyCFunction)bpygpu_VertBatch_uniform_bool, + METH_VARARGS, NULL}, + {"uniform_i32", (PyCFunction)bpygpu_VertBatch_uniform_i32, + METH_VARARGS, NULL}, + {"uniform_f32", (PyCFunction)bpygpu_VertBatch_uniform_f32, + METH_VARARGS, NULL}, + {"draw", (PyCFunction) bpygpu_VertBatch_draw, + METH_NOARGS, bpygpu_VertBatch_draw_doc}, + {"program_use_begin", (PyCFunction)bpygpu_VertBatch_program_use_begin, + METH_NOARGS, ""}, + {"program_use_end", (PyCFunction)bpygpu_VertBatch_program_use_end, + METH_NOARGS, ""}, + {NULL, NULL, 0, NULL} +}; + +#ifdef USE_GPU_PY_REFERENCES + +static int bpygpu_Batch_traverse(BPyGPUBatch *self, visitproc visit, void *arg) +{ + Py_VISIT(self->references); + return 0; +} + +static int bpygpu_Batch_clear(BPyGPUBatch *self) +{ + Py_CLEAR(self->references); + return 0; +} + +#endif + +static void bpygpu_Batch_dealloc(BPyGPUBatch *self) +{ + GPU_batch_discard(self->batch); + +#ifdef USE_GPU_PY_REFERENCES + if (self->references) { + PyObject_GC_UnTrack(self); + bpygpu_Batch_clear(self); + Py_XDECREF(self->references); + } +#endif + + Py_TYPE(self)->tp_free(self); +} + +PyTypeObject BPyGPUBatch_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "GPUBatch", + .tp_basicsize = sizeof(BPyGPUBatch), + .tp_dealloc = (destructor)bpygpu_Batch_dealloc, +#ifdef USE_GPU_PY_REFERENCES + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)bpygpu_Batch_traverse, + .tp_clear = (inquiry)bpygpu_Batch_clear, +#else + .tp_flags = Py_TPFLAGS_DEFAULT, +#endif + .tp_methods = bpygpu_VertBatch_methods, + .tp_new = bpygpu_Batch_new, +}; + +/* -------------------------------------------------------------------- */ + + +/** \name GPU Types Module + * \{ */ + +static struct PyModuleDef BPy_BM_types_module_def = { + PyModuleDef_HEAD_INIT, + .m_name = "_gpu.types", +}; + +PyObject *BPyInit_gpu_types(void) +{ + PyObject *submodule; + + submodule = PyModule_Create(&BPy_BM_types_module_def); + + if (PyType_Ready(&BPyGPUVertFormat_Type) < 0) + return NULL; + if (PyType_Ready(&BPyGPUVertBuf_Type) < 0) + return NULL; + if (PyType_Ready(&BPyGPUBatch_Type) < 0) + return NULL; + +#define MODULE_TYPE_ADD(s, t) \ + PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t) + + MODULE_TYPE_ADD(submodule, BPyGPUVertFormat_Type); + MODULE_TYPE_ADD(submodule, BPyGPUVertBuf_Type); + MODULE_TYPE_ADD(submodule, BPyGPUBatch_Type); + +#undef MODULE_TYPE_ADD + + return submodule; +} + +/** \} */ + + +/* -------------------------------------------------------------------- */ + +/** \name Public API + * \{ */ + +PyObject *BPyGPUVertFormat_CreatePyObject(GPUVertFormat *fmt) +{ + BPyGPUVertFormat *self; + + self = PyObject_New(BPyGPUVertFormat, &BPyGPUVertFormat_Type); + if (fmt) { + self->fmt = *fmt; + } + else { + memset(&self->fmt, 0, sizeof(self->fmt)); + } + + return (PyObject *)self; +} + +PyObject *BPyGPUVertBuf_CreatePyObject(GPUVertBuf *buf) +{ + BPyGPUVertBuf *self; + + self = PyObject_New(BPyGPUVertBuf, &BPyGPUVertBuf_Type); + self->buf = buf; + + return (PyObject *)self; +} + + +PyObject *BPyGPUBatch_CreatePyObject(GPUBatch *batch) +{ + BPyGPUBatch *self; + +#ifdef USE_GPU_PY_REFERENCES + self = (BPyGPUBatch *)_PyObject_GC_New(&BPyGPUBatch_Type); + self->references = NULL; +#else + self = PyObject_New(BPyGPUBatch, &BPyGPUBatch_Type); +#endif + + self->batch = batch; + + return (PyObject *)self; +} + +/** \} */ diff --git a/source/blender/python/gpu/gpu_py_types.h b/source/blender/python/gpu/gpu_py_types.h new file mode 100644 index 00000000000..f736a8f749a --- /dev/null +++ b/source/blender/python/gpu/gpu_py_types.h @@ -0,0 +1,67 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/gpu/gpu_py_types.h + * \ingroup pygpu + */ + +#ifndef __GPU_PY_TYPES_H__ +#define __GPU_PY_TYPES_H__ + +#include "BLI_compiler_attrs.h" + +#define USE_GPU_PY_REFERENCES + +extern PyTypeObject BPyGPUVertFormat_Type; +extern PyTypeObject BPyGPUVertBuf_Type; +extern PyTypeObject BPyGPUBatch_Type; + +#define BPyGPUVertFormat_Check(v) (Py_TYPE(v) == &BPyGPUVertFormat_Type) +#define BPyGPUVertBuf_Check(v) (Py_TYPE(v) == &BPyGPUVertBuf_Type) +#define BPyGPUBatch_Check(v) (Py_TYPE(v) == &BPyGPUBatch_Type) + +typedef struct BPyGPUVertFormat { + PyObject_VAR_HEAD + struct GPUVertFormat fmt; +} BPyGPUVertFormat; + +typedef struct BPyGPUVertBuf { + PyObject_VAR_HEAD + /* The buf is owned, we may support thin wrapped batches later. */ + struct GPUVertBuf *buf; +} BPyGPUVertBuf; + +typedef struct BPyGPUBatch { + PyObject_VAR_HEAD + /* The batch is owned, we may support thin wrapped batches later. */ + struct GPUBatch *batch; +#ifdef USE_GPU_PY_REFERENCES + /* Just to keep a user to prevent freeing buf's we're using */ + PyObject *references; +#endif +} BPyGPUBatch; + +PyObject *BPyInit_gpu_types(void); + +PyObject *BPyGPUVertFormat_CreatePyObject(struct GPUVertFormat *fmt); +PyObject *BPyGPUVertBuf_CreatePyObject(struct GPUVertBuf *vbo) ATTR_NONNULL(1); +PyObject *BPyGPUBatch_CreatePyObject(struct GPUBatch *batch) ATTR_NONNULL(1); + +#endif /* __GPU_PY_TYPES_H__ */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 0d7b0c92a90..64bc54c6221 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -75,7 +75,7 @@ #include "../generic/blf_py_api.h" #include "../generic/idprop_py_api.h" #include "../generic/imbuf_py_api.h" -#include "../gawain/gwn_py_api.h" +#include "../gpu/gpu_py_api.h" #include "../bmesh/bmesh_py_api.h" #include "../mathutils/mathutils.h" @@ -219,7 +219,7 @@ static struct _inittab bpy_internal_modules[] = { {"mathutils.kdtree", PyInit_mathutils_kdtree}, #endif {"_bpy_path", BPyInit__bpy_path}, - {"_gawain", BPyInit_gawain}, + {"_gpu", BPyInit_gpu}, {"bgl", BPyInit_bgl}, {"blf", BPyInit_blf}, {"imbuf", BPyInit_imbuf}, diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index cb32efb0b0f..df8953857ee 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -315,7 +315,7 @@ void RE_current_scene_update_cb(struct Render *re, void *handle, void (*f)(void void RE_gl_context_create(Render *re); void RE_gl_context_destroy(Render *re); void *RE_gl_context_get(Render *re); -void *RE_gwn_context_get(Render *re); +void *RE_gpu_context_get(Render *re); /* should move to kernel once... still unsure on how/where */ float RE_filter_value(int type, float x); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 117b82570e7..5d5d12f028a 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -160,7 +160,7 @@ struct Render { /* TODO replace by a whole draw manager. */ void *gl_context; - void *gwn_context; + void *gpu_context; }; /* **************** defines ********************* */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index af8746a4734..510a4aa4685 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1043,10 +1043,10 @@ void RE_gl_context_create(Render *re) void RE_gl_context_destroy(Render *re) { /* Needs to be called from the thread which used the ogl context for rendering. */ - if (re->gwn_context) { - GWN_context_active_set(re->gwn_context); - GWN_context_discard(re->gwn_context); - re->gwn_context = NULL; + if (re->gpu_context) { + GPU_context_active_set(re->gpu_context); + GPU_context_discard(re->gpu_context); + re->gpu_context = NULL; } if (re->gl_context) { WM_opengl_context_dispose(re->gl_context); @@ -1059,12 +1059,12 @@ void *RE_gl_context_get(Render *re) return re->gl_context; } -void *RE_gwn_context_get(Render *re) +void *RE_gpu_context_get(Render *re) { - if (re->gwn_context == NULL) { - re->gwn_context = GWN_context_create(); + if (re->gpu_context == NULL) { + re->gpu_context = GPU_context_create(); } - return re->gwn_context; + return re->gpu_context; } /* ********* add object data (later) ******** */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 5314c434c4c..160aeb6671b 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -456,9 +456,9 @@ void wm_draw_region_blend(ARegion *ar, int view, bool blend) glUniform1i(GPU_shader_get_uniform(shader, "image"), 0); glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), halfx, halfy, 1.0f + halfx, 1.0f + halfy); glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), ar->winrct.xmin, ar->winrct.ymin, ar->winrct.xmax + 1, ar->winrct.ymax + 1); - glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha); + glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha); - GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4); + GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); glBindTexture(GL_TEXTURE_2D, 0); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 84dcf30e63c..c191255cd21 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -188,7 +188,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) static void wm_window_substitute_old(wmWindowManager *oldwm, wmWindowManager *wm, wmWindow *oldwin, wmWindow *win) { win->ghostwin = oldwin->ghostwin; - win->gwnctx = oldwin->gwnctx; + win->gpuctx = oldwin->gpuctx; win->active = oldwin->active; if (win->active) { wm->winactive = win; @@ -202,7 +202,7 @@ static void wm_window_substitute_old(wmWindowManager *oldwm, wmWindowManager *wm GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ oldwin->ghostwin = NULL; - oldwin->gwnctx = NULL; + oldwin->gpuctx = NULL; win->eventstate = oldwin->eventstate; oldwin->eventstate = NULL; diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 4366013084c..06a7f3528c5 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -166,7 +166,7 @@ static void wm_gesture_draw_line(wmGesture *gt) { rcti *rect = (rcti *)gt->customdata; - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -181,7 +181,7 @@ static void wm_gesture_draw_line(wmGesture *gt) float xmin = (float)rect->xmin; float ymin = (float)rect->ymin; - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(shdr_pos, xmin, ymin); immVertex2f(shdr_pos, (float)rect->xmax, (float)rect->ymax); immEnd(); @@ -193,7 +193,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) { rcti *rect = (rcti *)gt->customdata; - uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); glEnable(GL_BLEND); @@ -206,7 +206,7 @@ static void wm_gesture_draw_rect(wmGesture *gt) glDisable(GL_BLEND); - shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -231,7 +231,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) glEnable(GL_BLEND); - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -346,7 +346,7 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled) return; } - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -358,7 +358,7 @@ static void wm_gesture_draw_lasso(wmGesture *gt, bool filled) immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 2.0f); - immBegin((gt->type == WM_GESTURE_LASSO) ? GWN_PRIM_LINE_LOOP : GWN_PRIM_LINE_STRIP, numverts); + immBegin((gt->type == WM_GESTURE_LASSO) ? GPU_PRIM_LINE_LOOP : GPU_PRIM_LINE_STRIP, numverts); for (i = 0; i < gt->points; i++, lasso += 2) { immVertex2f(shdr_pos, (float)lasso[0], (float)lasso[1]); @@ -377,7 +377,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) float x1, x2, y1, y2; - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); @@ -389,7 +389,7 @@ static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt) immUniformArray4fv("colors", (float *)(float[][4]){{0.4f, 0.4f, 0.4f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); immUniform1f("dash_width", 8.0f); - immBegin(GWN_PRIM_LINES, 4); + immBegin(GPU_PRIM_LINES, 4); x1 = (float)(rect->xmin - winsize_x); y1 = (float)rect->ymin; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 64aa64e1478..e757c7bee52 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2094,12 +2094,12 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph RNA_property_float_get_array(fill_ptr, fill_prop, col); } - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (rc->gltex) { - uint texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, rc->gltex); @@ -2123,7 +2123,7 @@ static void radial_control_paint_tex(RadialControl *rc, float radius, float alph } /* draw textured quad */ - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texCoord, 0, 0); immVertex2f(pos, -radius, -radius); @@ -2226,8 +2226,8 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void if (rc->col_prop) RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col); - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3fvAlpha(col, 0.5f); @@ -2237,14 +2237,14 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void /* draw original angle line */ GPU_matrix_rotate_2d(RAD2DEGF(rc->initial_value)); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); immEnd(); /* draw new angle line */ GPU_matrix_rotate_2d(RAD2DEGF(rc->current_value - rc->initial_value)); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE, 0.0f); immVertex2f(pos, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f); immEnd(); diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 00e7f77569b..6317cca8094 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -187,7 +187,7 @@ typedef enum eWS_Qual { static struct WindowStateGlobal { GHOST_SystemHandle ghost_system; void *ghost_window; - Gwn_Context *gwn_context; + GPUContext *gpu_context; /* events */ eWS_Qual qual; @@ -374,12 +374,12 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf GPU_matrix_push(); GPU_matrix_identity_set(); - uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ub(0, 255, 0); - immBegin(GWN_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, fac, -1.0f); immVertex2f(pos, fac, 1.0f); immEnd(); @@ -1284,7 +1284,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) //GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); /* initialize OpenGL immediate mode */ - g_WS.gwn_context = GWN_context_create(); + g_WS.gpu_context = GPU_context_create(); GPU_init(); immActivate(); @@ -1555,10 +1555,10 @@ static char *wm_main_playanim_intern(int argc, const char **argv) GPU_shader_free_builtin_shaders(); - if (g_WS.gwn_context) { - GWN_context_active_set(g_WS.gwn_context); - GWN_context_discard(g_WS.gwn_context); - g_WS.gwn_context = NULL; + if (g_WS.gpu_context) { + GPU_context_active_set(g_WS.gpu_context); + GPU_context_discard(g_WS.gpu_context); + g_WS.gpu_context = NULL; } BLF_exit(); diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index 1e9f6d6231b..577145aff95 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -87,9 +87,9 @@ void wm_stereo3d_draw_interlace(wmWindow *win, ARegion *ar) float halfx = GLA_PIXEL_OFS / ar->winx; float halfy = GLA_PIXEL_OFS / ar->winy; - Gwn_VertFormat *format = immVertexFormat(); - uint texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* leave GL_TEXTURE0 as the latest active texture */ for (int view = 1; view >= 0; view--) { @@ -104,7 +104,7 @@ void wm_stereo3d_draw_interlace(wmWindow *win, ARegion *ar) immUniform1i("interlace_id", interlace_gpu_id_from_type(interlace_type)); - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texcoord, halfx, halfy); immVertex2f(pos, ar->winrct.xmin, ar->winrct.ymin); @@ -163,9 +163,9 @@ void wm_stereo3d_draw_sidebyside(wmWindow *win, int view) { bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0; - Gwn_VertFormat *format = immVertexFormat(); - uint texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE); @@ -188,7 +188,7 @@ void wm_stereo3d_draw_sidebyside(wmWindow *win, int view) immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */ - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texcoord, halfx, halfy); immVertex2f(pos, soffx, 0.0f); @@ -209,9 +209,9 @@ void wm_stereo3d_draw_sidebyside(wmWindow *win, int view) void wm_stereo3d_draw_topbottom(wmWindow *win, int view) { - Gwn_VertFormat *format = immVertexFormat(); - uint texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE); @@ -232,7 +232,7 @@ void wm_stereo3d_draw_topbottom(wmWindow *win, int view) immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */ - immBegin(GWN_PRIM_TRI_FAN, 4); + immBegin(GPU_PRIM_TRI_FAN, 4); immAttrib2f(texcoord, halfx, halfy); immVertex2f(pos, 0.0f, soffy); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 669480bf098..b87ae7e076c 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -194,14 +194,14 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win) /* We need this window's opengl context active to discard it. */ GHOST_ActivateWindowDrawingContext(win->ghostwin); - GWN_context_active_set(win->gwnctx); + GPU_context_active_set(win->gpuctx); - /* Delete local gawain objects. */ - GWN_context_discard(win->gwnctx); + /* Delete local gpu context. */ + GPU_context_discard(win->gpuctx); GHOST_DisposeWindow(g_system, win->ghostwin); win->ghostwin = NULL; - win->gwnctx = NULL; + win->gpuctx = NULL; } } @@ -645,7 +645,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm /* Clear drawable so we can set the new window. */ wm_window_clear_drawable(wm); - win->gwnctx = GWN_context_create(); + win->gpuctx = GPU_context_create(); /* needed so we can detect the graphics card below */ GPU_init(); @@ -1099,7 +1099,7 @@ static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool acti if (activate) { GHOST_ActivateWindowDrawingContext(win->ghostwin); } - GWN_context_active_set(win->gwnctx); + GPU_context_active_set(win->gpuctx); immActivate(); } -- cgit v1.2.3 From bdda0964e0a5180bd0bc4fb8e38dbe2198bd9a9a Mon Sep 17 00:00:00 2001 From: Stefan Werner Date: Wed, 18 Jul 2018 13:03:09 +0200 Subject: Compositor: Cryptomatte compositing node. This patch adds a new matte node that implements the Cryptomatte specification. It also incluces a custom eye dropper that works outside of a color picker. Cryptomatte export for the Cycles render engine will be in a separate patch. Reviewers: brecht Reviewed By: brecht Subscribers: brecht Tags: #compositing Differential Revision: https://developer.blender.org/D3531 --- release/scripts/startup/nodeitems_builtins.py | 1 + source/blender/blenkernel/BKE_node.h | 6 + source/blender/blenkernel/intern/node.c | 1 + source/blender/blenlib/BLI_hash_mm3.h | 40 +++ source/blender/blenlib/CMakeLists.txt | 2 + source/blender/blenlib/intern/hash_mm3.c | 147 ++++++++++ source/blender/blenloader/intern/readfile.c | 4 + source/blender/blenloader/intern/writefile.c | 7 + source/blender/compositor/CMakeLists.txt | 5 + source/blender/compositor/intern/COM_Converter.cpp | 4 + .../compositor/nodes/COM_CryptomatteNode.cpp | 120 ++++++++ .../blender/compositor/nodes/COM_CryptomatteNode.h | 38 +++ .../operations/COM_CryptomatteOperation.cpp | 75 +++++ .../operations/COM_CryptomatteOperation.h | 40 +++ source/blender/editors/include/UI_interface.h | 1 + .../editors/interface/interface_eyedropper.c | 1 + .../editors/interface/interface_eyedropper_color.c | 89 +++--- .../blender/editors/interface/interface_intern.h | 1 + source/blender/editors/interface/interface_ops.c | 1 + .../editors/interface/interface_templates.c | 18 ++ source/blender/editors/space_node/drawnode.c | 23 ++ source/blender/editors/space_node/node_edit.c | 90 ++++++ source/blender/editors/space_node/node_intern.h | 3 + source/blender/editors/space_node/node_ops.c | 3 + source/blender/makesdna/DNA_node_types.h | 8 + source/blender/makesrna/intern/rna_nodetree.c | 68 +++++ source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_composite.h | 1 + source/blender/nodes/NOD_static_types.h | 1 + .../composite/nodes/node_composite_cryptomatte.c | 309 +++++++++++++++++++++ 30 files changed, 1066 insertions(+), 42 deletions(-) create mode 100644 source/blender/blenlib/BLI_hash_mm3.h create mode 100644 source/blender/blenlib/intern/hash_mm3.c create mode 100644 source/blender/compositor/nodes/COM_CryptomatteNode.cpp create mode 100644 source/blender/compositor/nodes/COM_CryptomatteNode.h create mode 100644 source/blender/compositor/operations/COM_CryptomatteOperation.cpp create mode 100644 source/blender/compositor/operations/COM_CryptomatteOperation.h create mode 100644 source/blender/nodes/composite/nodes/node_composite_cryptomatte.c diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 92411aeb0ef..c9a15f12f7c 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -394,6 +394,7 @@ compositor_node_categories = [ NodeItem("CompositorNodeChromaMatte"), NodeItem("CompositorNodeColorMatte"), NodeItem("CompositorNodeDoubleEdgeMask"), + NodeItem("CompositorNodeCryptomatte"), ]), CompositorNodeCategory("CMP_DISTORT", "Distort", items=[ NodeItem("CompositorNodeScale"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index eca7f82541f..8e54c6a87c4 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -945,6 +945,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria #define CMP_NODE_PLANETRACKDEFORM 320 #define CMP_NODE_CORNERPIN 321 #define CMP_NODE_SWITCH_VIEW 322 +#define CMP_NODE_CRYPTOMATTE 323 /* channel toggles */ #define CMP_CHAN_RGB 1 @@ -997,6 +998,11 @@ void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocke void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node); void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node); +void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *ntree, bNode *node); +void ntreeCompositCryptomatteSyncFromRemove(bNodeTree *ntree, bNode *node); +struct bNodeSocket *ntreeCompositCryptomatteAddSocket(struct bNodeTree *ntree, struct bNode *node); +int ntreeCompositCryptomatteRemoveSocket(struct bNodeTree *ntree, struct bNode *node); + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 499f92b3878..f15d90100d2 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3528,6 +3528,7 @@ static void registerCompositNodes(void) register_node_type_cmp_doubleedgemask(); register_node_type_cmp_keyingscreen(); register_node_type_cmp_keying(); + register_node_type_cmp_cryptomatte(); register_node_type_cmp_translate(); register_node_type_cmp_rotate(); diff --git a/source/blender/blenlib/BLI_hash_mm3.h b/source/blender/blenlib/BLI_hash_mm3.h new file mode 100644 index 00000000000..93bf963c9a4 --- /dev/null +++ b/source/blender/blenlib/BLI_hash_mm3.h @@ -0,0 +1,40 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_HASH_MM3_H__ +#define __BLI_HASH_MM3_H__ + +/** \file BLI_hash_mm3.h + * \ingroup bli + */ + +#include "BLI_sys_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t BLI_hash_mm3(const unsigned char *data, size_t len, uint32_t seed); + +#ifdef __cplusplus +} +#endif + +#endif /* __BLI_HASH_MM2A_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 16497c12022..e3f5773b1e4 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -74,6 +74,7 @@ set(SRC intern/gsqueue.c intern/hash_md5.c intern/hash_mm2a.c + intern/hash_mm3.c intern/jitter_2d.c intern/lasso_2d.c intern/list_sort_impl.h @@ -159,6 +160,7 @@ set(SRC BLI_hash.h BLI_hash_md5.h BLI_hash_mm2a.h + BLI_hash_mm3.h BLI_heap.h BLI_jitter_2d.h BLI_kdopbvh.h diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c new file mode 100644 index 00000000000..ac483795e45 --- /dev/null +++ b/source/blender/blenlib/intern/hash_mm3.c @@ -0,0 +1,147 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Copyright (C) 2018 Blender Foundation. + * + */ + +/** \file blender/blenlib/intern/hash_mm3.c + * \ingroup bli + * + * Functions to compute Murmur3 hash key. + * + * This Code is based on alShaders/Cryptomatte/MurmurHash3.h: + * + * MurmurHash3 was written by Austin Appleby, and is placed in the public + * domain. The author hereby disclaims copyright to this source code. + * + */ + +#include "BLI_compiler_compat.h" +#include "BLI_compiler_attrs.h" +#include "BLI_hash_mm3.h" /* own include */ + +#if defined(_MSC_VER) +# include +# define ROTL32(x,y) _rotl(x,y) +# define BIG_CONSTANT(x) (x) + +/* Other compilers */ +#else /* defined(_MSC_VER) */ +static inline uint32_t rotl32(uint32_t x, int8_t r) +{ + return (x << r) | (x >> (32 - r)); +} +# define ROTL32(x,y) rotl32(x,y) +# define BIG_CONSTANT(x) (x##LLU) +#endif /* !defined(_MSC_VER) */ + +/* Block read - if your platform needs to do endian-swapping or can only + * handle aligned reads, do the conversion here + */ + +BLI_INLINE uint32_t getblock32(const uint32_t * p, int i) +{ + return p[i]; +} + +BLI_INLINE uint64_t getblock64(const uint64_t * p, int i) +{ + return p[i]; +} + +/* Finalization mix - force all bits of a hash block to avalanche */ + +BLI_INLINE uint32_t fmix32(uint32_t h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +BLI_INLINE uint64_t fmix64(uint64_t k) +{ + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) +{ + const uint8_t *data = (const uint8_t*)in; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + /* body */ + + const uint32_t *blocks = (const uint32_t *)(data + nblocks*4); + + for (int i = -nblocks; i; i++) { + uint32_t k1 = getblock32(blocks,i); + + k1 *= c1; + k1 = ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1,13); + h1 = h1*5+0xe6546b64; + } + + /* tail */ + + const uint8_t *tail = (const uint8_t*)(data + nblocks*4); + + uint32_t k1 = 0; + + switch (len & 3) { + case 3: + k1 ^= tail[2] << 16; + ATTR_FALLTHROUGH; + case 2: + k1 ^= tail[1] << 8; + ATTR_FALLTHROUGH; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1,15); + k1 *= c2; + h1 ^= k1; + }; + + /* finalization */ + + h1 ^= len; + + h1 = fmix32(h1); + + return h1; +} diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4e845b9a60d..1def462b1ca 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3161,6 +3161,10 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) direct_link_curvemapping(fd, node->storage); else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) ((ImageUser *)node->storage)->ok = 1; + else if (node->type==CMP_NODE_CRYPTOMATTE) { + NodeCryptomatte *nc = (NodeCryptomatte *) node->storage; + nc->matte_id = newdataadr(fd, nc->matte_id); + } } else if ( ntree->type==NTREE_TEXTURE) { if (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e3a901f4211..4b64d0a3d3f 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1077,6 +1077,13 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree) } writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage); } + else if ((ntree->type == NTREE_COMPOSIT) && (node->type == CMP_NODE_CRYPTOMATTE)) { + NodeCryptomatte *nc = (NodeCryptomatte *)node->storage; + if (nc->matte_id) { + writedata(wd, DATA, strlen(nc->matte_id) + 1, nc->matte_id); + } + writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage); + } else { writestruct_id(wd, DATA, node->typeinfo->storagename, 1, node->storage); } diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index 3e1dd83112a..0ad53d3ab80 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -182,6 +182,11 @@ set(SRC operations/COM_SunBeamsOperation.cpp operations/COM_SunBeamsOperation.h + nodes/COM_CryptomatteNode.cpp + nodes/COM_CryptomatteNode.h + operations/COM_CryptomatteOperation.cpp + operations/COM_CryptomatteOperation.h + nodes/COM_CornerPinNode.cpp nodes/COM_CornerPinNode.h nodes/COM_PlaneTrackDeformNode.cpp diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 58e0da04e5e..c9181905908 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -55,6 +55,7 @@ extern "C" { #include "COM_Converter.h" #include "COM_CornerPinNode.h" #include "COM_CropNode.h" +#include "COM_CryptomatteNode.h" #include "COM_DefocusNode.h" #include "COM_DespeckleNode.h" #include "COM_DifferenceMatteNode.h" @@ -406,6 +407,9 @@ Node *Converter::convert(bNode *b_node) case CMP_NODE_SUNBEAMS: node = new SunBeamsNode(b_node); break; + case CMP_NODE_CRYPTOMATTE: + node = new CryptomatteNode(b_node); + break; } return node; } diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp new file mode 100644 index 00000000000..c8134068543 --- /dev/null +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp @@ -0,0 +1,120 @@ +/* + * Copyright 2018, Blender Foundation. + * + * 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. + * + * Contributor: + * Lukas Stockner + * Stefan Werner + */ + +#include "COM_CryptomatteNode.h" +#include "COM_CryptomatteOperation.h" +#include "COM_SetAlphaOperation.h" +#include "COM_ConvertOperation.h" +#include "BLI_string.h" +#include "BLI_hash_mm3.h" +#include "BLI_assert.h" +#include + +CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode) +{ + /* pass */ +} + +/* This is taken from the Cryptomatte specification 1.0. */ +static inline float hash_to_float(uint32_t hash) { + uint32_t mantissa = hash & (( 1 << 23) - 1); + uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); + exponent = max(exponent, (uint32_t) 1); + exponent = min(exponent, (uint32_t) 254); + exponent = exponent << 23; + uint32_t sign = (hash >> 31); + sign = sign << 31; + uint32_t float_bits = sign | exponent | mantissa; + float f; + /* Bit casting relies on equal size for both types. */ + BLI_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "float and uint32_t are not the same size") + ::memcpy(&f, &float_bits, sizeof(float)); + return f; +} + +void CryptomatteNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const +{ + NodeInput *inputSocketImage = this->getInputSocket(0); + NodeOutput *outputSocketImage = this->getOutputSocket(0); + NodeOutput *outputSocketMatte = this->getOutputSocket(1); + NodeOutput *outputSocketPick = this->getOutputSocket(2); + + bNode *node = this->getbNode(); + NodeCryptomatte *cryptoMatteSettings = (NodeCryptomatte *)node->storage; + + CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets()-1); + if (cryptoMatteSettings) { + if (cryptoMatteSettings->matte_id) { + /* Split the string by commas, ignoring white space. */ + std::string input = cryptoMatteSettings->matte_id; + std::istringstream ss(input); + while (ss.good()) { + std::string token; + getline(ss, token, ','); + /* Ignore empty tokens. */ + if (token.length() > 0) { + size_t first = token.find_first_not_of(' '); + size_t last = token.find_last_not_of(' '); + if (first == std::string::npos || last == std::string::npos) { + break; + } + token = token.substr(first, (last - first + 1)); + if (*token.begin() == '<' && *(--token.end()) == '>') { + operation->addObjectIndex(atof(token.substr(1, token.length() - 2).c_str())); + } + else { + uint32_t hash = BLI_hash_mm3((const unsigned char*)token.c_str(), token.length(), 0); + operation->addObjectIndex(hash_to_float(hash)); + } + } + } + } + } + + converter.addOperation(operation); + + for (int i = 0; i < getNumberOfInputSockets()-1; ++i) { + converter.mapInputSocket(this->getInputSocket(i + 1), operation->getInputSocket(i)); + } + + SeparateChannelOperation *separateOperation = new SeparateChannelOperation; + separateOperation->setChannel(3); + converter.addOperation(separateOperation); + + SetAlphaOperation *operationAlpha = new SetAlphaOperation(); + converter.addOperation(operationAlpha); + + converter.addLink(operation->getOutputSocket(0), separateOperation->getInputSocket(0)); + converter.addLink(separateOperation->getOutputSocket(0), operationAlpha->getInputSocket(1)); + + SetAlphaOperation *clearAlphaOperation = new SetAlphaOperation(); + converter.addOperation(clearAlphaOperation); + converter.addInputValue(clearAlphaOperation->getInputSocket(1), 1.0f); + + converter.addLink(operation->getOutputSocket(0), clearAlphaOperation->getInputSocket(0)); + + converter.mapInputSocket(inputSocketImage, operationAlpha->getInputSocket(0)); + converter.mapOutputSocket(outputSocketMatte, separateOperation->getOutputSocket(0)); + converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket(0)); + converter.mapOutputSocket(outputSocketPick, clearAlphaOperation->getOutputSocket(0)); + +} diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h new file mode 100644 index 00000000000..5251b57d8af --- /dev/null +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.h @@ -0,0 +1,38 @@ +/* + * Copyright 2018, Blender Foundation. + * + * 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. + * + * Contributor: + * Lukas Stockner + */ + +#ifndef _COM_CryptomatteNode_h_ +#define _COM_CryptomatteNode_h_ + +#include "COM_Node.h" + +/** + * @brief CryptomatteNode + * @ingroup Node + */ +class CryptomatteNode : public Node { +public: + CryptomatteNode(bNode *editorNode); + void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; +}; + +#endif + diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp new file mode 100644 index 00000000000..9dd36863d37 --- /dev/null +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2018, Blender Foundation. + * + * 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. + * + * Contributor: Lukas Stockner, Stefan Werner + */ + +#include "COM_CryptomatteOperation.h" + +CryptomatteOperation::CryptomatteOperation(size_t num_inputs) : NodeOperation() +{ + for(size_t i = 0; i < num_inputs; i++) { + this->addInputSocket(COM_DT_COLOR); + } + inputs.resize(num_inputs); + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); +} + +void CryptomatteOperation::initExecution() +{ + for (size_t i = 0; i < inputs.size(); i++) { + inputs[i] = this->getInputSocketReader(i); + } +} + +void CryptomatteOperation::addObjectIndex(float objectIndex) +{ + if (objectIndex != 0.0f) { + m_objectIndex.push_back(objectIndex); + } +} + +void CryptomatteOperation::executePixel(float output[4], + int x, + int y, + void *data) +{ + float input[4]; + output[0] = output[1] = output[2] = output[3] = 0.0f; + for (size_t i = 0; i < inputs.size(); i++) { + inputs[i]->read(input, x, y, data); + if (i == 0) { + /* Write the frontmost object as false color for picking. */ + output[0] = input[0]; + uint32_t m3hash; + ::memcpy(&m3hash, &input[0], sizeof(uint32_t)); + /* Since the red channel is likely to be out of display range, + * setting green and blue gives more meaningful images. */ + output[1] = ((float) ((m3hash << 8)) / (float) UINT32_MAX); + output[2] = ((float) ((m3hash << 16)) / (float) UINT32_MAX); + } + for(size_t i = 0; i < m_objectIndex.size(); i++) { + if (m_objectIndex[i] == input[0]) { + output[3] += input[1]; + } + if (m_objectIndex[i] == input[2]) { + output[3] += input[3]; + } + } + } +} diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.h b/source/blender/compositor/operations/COM_CryptomatteOperation.h new file mode 100644 index 00000000000..9ce02c048b3 --- /dev/null +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.h @@ -0,0 +1,40 @@ +/* + * Copyright 2018, Blender Foundation. + * + * 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. + * + * Contributor: Lukas Stockner, Stefan Werner + */ + +#ifndef _COM_CryptomatteOperation_h +#define _COM_CryptomatteOperation_h +#include "COM_NodeOperation.h" + + +class CryptomatteOperation : public NodeOperation { +private: + std::vector m_objectIndex; +public: + std::vector inputs; + + CryptomatteOperation(size_t num_inputs = 6); + + void initExecution(); + void executePixel(float output[4], int x, int y, void *data); + + void addObjectIndex(float objectIndex); + +}; +#endif diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 51f79e05bf9..eefbeee6336 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -969,6 +969,7 @@ void uiTemplateCurveMapping( bool levels, bool brush, bool neg_slope); void uiTemplateColorPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool value_slider, bool lock, bool lock_luminosity, bool cubic); void uiTemplatePalette(uiLayout *layout, struct PointerRNA *ptr, const char *propname, bool color); +void uiTemplateCryptoPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname); void uiTemplateLayers( uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *used_ptr, const char *used_propname, int active_layer); diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index fafe5f48f75..67486f38760 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -82,6 +82,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf) /* assign to operators */ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorband"); WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color"); + WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color_crypto"); WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id"); WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth"); WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver"); diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c index 7dd7de0817e..bcb60013eda 100644 --- a/source/blender/editors/interface/interface_eyedropper_color.c +++ b/source/blender/editors/interface/interface_eyedropper_color.c @@ -36,6 +36,7 @@ #include "DNA_screen_types.h" #include "BLI_math_vector.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_main.h" @@ -72,6 +73,8 @@ typedef struct Eyedropper { bool accum_start; /* has mouse been pressed */ float accum_col[3]; int accum_tot; + + bool accumulate; /* Color picking for cryptomatte, without accumulation. */ } Eyedropper; static bool eyedropper_init(bContext *C, wmOperator *op) @@ -80,6 +83,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op) Eyedropper *eye; op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper"); + eye->accumulate = !STREQ(op->type->idname, "UI_OT_eyedropper_color_crypto"); UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index); @@ -207,29 +211,30 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3 RNA_property_update(C, &eye->ptr, eye->prop); } -/* set sample from accumulated values */ -static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) -{ - float col[3]; - mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); - eyedropper_color_set(C, eye, col); -} - -/* single point sample & set */ static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) { + /* Accumulate color. */ float col[3]; eyedropper_color_sample_fl(C, mx, my, col); - eyedropper_color_set(C, eye, col); -} -static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx, int my) -{ - float col[3]; - eyedropper_color_sample_fl(C, mx, my, col); - /* delay linear conversion */ - add_v3_v3(eye->accum_col, col); - eye->accum_tot++; + if (eye->accumulate) { + add_v3_v3(eye->accum_col, col); + eye->accum_tot++; + } + else { + copy_v3_v3(eye->accum_col, col); + eye->accum_tot = 1; + } + + /* Apply to property. */ + float accum_col[3]; + if (eye->accum_tot > 1) { + mul_v3_v3fl(accum_col, eye->accum_col, 1.0f / (float)eye->accum_tot); + } + else { + copy_v3_v3(accum_col, eye->accum_col); + } + eyedropper_color_set(C, eye, accum_col); } static void eyedropper_cancel(bContext *C, wmOperator *op) @@ -254,29 +259,24 @@ static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) if (eye->accum_tot == 0) { eyedropper_color_sample(C, eye, event->x, event->y); } - else { - eyedropper_color_set_accum(C, eye); - } eyedropper_exit(C, op); return OPERATOR_FINISHED; case EYE_MODAL_SAMPLE_BEGIN: /* enable accum and make first sample */ eye->accum_start = true; - eyedropper_color_sample_accum(C, eye, event->x, event->y); + eyedropper_color_sample(C, eye, event->x, event->y); break; case EYE_MODAL_SAMPLE_RESET: eye->accum_tot = 0; zero_v3(eye->accum_col); - eyedropper_color_sample_accum(C, eye, event->x, event->y); - eyedropper_color_set_accum(C, eye); + eyedropper_color_sample(C, eye, event->x, event->y); break; } } - else if (event->type == MOUSEMOVE) { + else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { if (eye->accum_start) { /* button is pressed so keep sampling */ - eyedropper_color_sample_accum(C, eye, event->x, event->y); - eyedropper_color_set_accum(C, eye); + eyedropper_color_sample(C, eye, event->x, event->y); } } @@ -321,20 +321,9 @@ static int eyedropper_exec(bContext *C, wmOperator *op) static bool eyedropper_poll(bContext *C) { - PointerRNA ptr; - PropertyRNA *prop; - int index_dummy; - uiBut *but; - - /* Only color buttons */ - if ((CTX_wm_window(C) != NULL) && - (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) && - (but->type == UI_BTYPE_COLOR)) - { - return 1; - } - - return 0; + /* Actual test for active button happens later, since we don't + * know which one is active until mouse over. */ + return (CTX_wm_window(C) != NULL); } void UI_OT_eyedropper_color(wmOperatorType *ot) @@ -353,6 +342,22 @@ void UI_OT_eyedropper_color(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; +} + +void UI_OT_eyedropper_color_crypto(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Cryptomatte Eyedropper"; + ot->idname = "UI_OT_eyedropper_color_crypto"; + ot->description = "Pick a color from Cryptomatte node Pick output image"; - /* properties */ + /* api callbacks */ + ot->invoke = eyedropper_invoke; + ot->modal = eyedropper_modal; + ot->cancel = eyedropper_cancel; + ot->exec = eyedropper_exec; + ot->poll = eyedropper_poll; + + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index cc86530871d..dc5e100b5f2 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -763,6 +763,7 @@ struct wmKeyMap *eyedropper_colorband_modal_keymap(struct wmKeyConfig *keyconf); /* interface_eyedropper_color.c */ void UI_OT_eyedropper_color(struct wmOperatorType *ot); +void UI_OT_eyedropper_color_crypto(struct wmOperatorType *ot); /* interface_eyedropper_colorband.c */ void UI_OT_eyedropper_colorband(struct wmOperatorType *ot); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 9a4ea41141a..1e67ecdfc90 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1138,6 +1138,7 @@ void ED_operatortypes_ui(void) /* external */ WM_operatortype_append(UI_OT_eyedropper_color); + WM_operatortype_append(UI_OT_eyedropper_color_crypto); WM_operatortype_append(UI_OT_eyedropper_colorband); WM_operatortype_append(UI_OT_eyedropper_colorband_point); WM_operatortype_append(UI_OT_eyedropper_id); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index bd4bb032717..daee0d3af3f 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2572,6 +2572,24 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, } } +void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname) +{ + PropertyRNA *prop = RNA_struct_find_property(ptr, propname); + uiBlock *block; + uiBut *but; + + if (!prop) { + RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); + return; + } + + block = uiLayoutGetBlock(layout); + + but = uiDefIconTextButO(block, UI_BTYPE_BUT, "UI_OT_eyedropper_color_crypto", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, RNA_property_ui_name(prop), 0, 0, UI_UNIT_X, UI_UNIT_Y, RNA_property_ui_description(prop)); + but->rnapoin = *ptr; + but->rnaprop = prop; + but->rnaindex = -1; +} /********************* Layer Buttons Template ************************/ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index b0440b39823..23df1b72c37 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2544,6 +2544,25 @@ static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), P uiItemR(layout, ptr, "ray_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE); } +static void node_composit_buts_cryptomatte(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *col = uiLayoutColumn(layout, true); + + uiItemL(col, IFACE_("Matte Objects:"), ICON_NONE); + + uiLayout *row = uiLayoutRow(col, true); + uiTemplateCryptoPicker(row, ptr, "add"); + uiTemplateCryptoPicker(row, ptr, "remove"); + + uiItemR(col, ptr, "matte_id", 0, "", ICON_NONE); +} + +static void node_composit_buts_cryptomatte_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr)) +{ + uiItemO(layout, IFACE_("Add Crypto Layer"), ICON_ZOOMIN, "NODE_OT_cryptomatte_layer_add"); + uiItemO(layout, IFACE_("Remove Crypto Layer"), ICON_ZOOMOUT, "NODE_OT_cryptomatte_layer_remove"); +} + static void node_composit_buts_brightcontrast(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE); @@ -2776,6 +2795,10 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_SUNBEAMS: ntype->draw_buttons = node_composit_buts_sunbeams; break; + case CMP_NODE_CRYPTOMATTE: + ntype->draw_buttons = node_composit_buts_cryptomatte; + ntype->draw_buttons_ex = node_composit_buts_cryptomatte_ex; + break; case CMP_NODE_BRIGHTCONTRAST: ntype->draw_buttons = node_composit_buts_brightcontrast; } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c49c8c201c4..97c5157486d 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2611,3 +2611,93 @@ void NODE_OT_clear_viewer_border(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/* ****************** Cryptomatte Add Socket ******************* */ + +static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + PointerRNA ptr = CTX_data_pointer_get(C, "node"); + bNodeTree *ntree = NULL; + bNode *node = NULL; + + if (ptr.data) { + node = ptr.data; + ntree = ptr.id.data; + } + else if (snode && snode->edittree) { + ntree = snode->edittree; + node = nodeGetActive(snode->edittree); + } + + if (!node || node->type != CMP_NODE_CRYPTOMATTE) { + return OPERATOR_CANCELLED; + } + + ntreeCompositCryptomatteAddSocket(ntree, node); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_cryptomatte_layer_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Cryptomatte Socket"; + ot->description = "Add a new input layer to a Cryptomatte node"; + ot->idname = "NODE_OT_cryptomatte_layer_add"; + + /* callbacks */ + ot->exec = node_cryptomatte_add_socket_exec; + ot->poll = composite_node_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* ****************** Cryptomatte Remove Socket ******************* */ + +static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + PointerRNA ptr = CTX_data_pointer_get(C, "node"); + bNodeTree *ntree = NULL; + bNode *node = NULL; + + if (ptr.data) { + node = ptr.data; + ntree = ptr.id.data; + } + else if (snode && snode->edittree) { + ntree = snode->edittree; + node = nodeGetActive(snode->edittree); + } + + if (!node || node->type != CMP_NODE_CRYPTOMATTE) { + return OPERATOR_CANCELLED; + } + + if (!ntreeCompositCryptomatteRemoveSocket(ntree, node)) { + return OPERATOR_CANCELLED; + } + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_cryptomatte_layer_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Cryptomatte Socket"; + ot->description = "Remove layer from a Crytpomatte node"; + ot->idname = "NODE_OT_cryptomatte_layer_remove"; + + /* callbacks */ + ot->exec = node_cryptomatte_remove_socket_exec; + ot->poll = composite_node_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index fd62c52bd5a..9b396aa9642 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -222,6 +222,9 @@ void NODE_OT_shader_script_update(struct wmOperatorType *ot); void NODE_OT_viewer_border(struct wmOperatorType *ot); void NODE_OT_clear_viewer_border(struct wmOperatorType *ot); +void NODE_OT_cryptomatte_layer_add(struct wmOperatorType *ot); +void NODE_OT_cryptomatte_layer_remove(struct wmOperatorType *ot); + extern const char *node_context_dir[]; // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index d7ded62a988..ea07341beb9 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -130,6 +130,9 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_tree_socket_add); WM_operatortype_append(NODE_OT_tree_socket_remove); WM_operatortype_append(NODE_OT_tree_socket_move); + + WM_operatortype_append(NODE_OT_cryptomatte_layer_add); + WM_operatortype_append(NODE_OT_cryptomatte_layer_remove); } void ED_operatormacros_node(void) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 129172315dd..00758bd1379 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -907,6 +907,14 @@ typedef struct NodeSunBeams { float ray_length; } NodeSunBeams; +typedef struct NodeCryptomatte { + float add[3]; + float remove[3]; + char *matte_id; + int num_inputs; + int pad; +} NodeCryptomatte; + /* script node mode */ #define NODE_SCRIPT_INTERNAL 0 #define NODE_SCRIPT_EXTERNAL 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e66c1e937e6..52fbadd0f54 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2880,6 +2880,48 @@ static void rna_NodeColorBalance_update_cdl(Main *bmain, Scene *scene, PointerRN rna_Node_update(bmain, scene, ptr); } +static void rna_NodeCryptomatte_matte_get(PointerRNA *ptr, char *value) +{ + bNode *node = (bNode *)ptr->data; + NodeCryptomatte *nc = node->storage; + + strcpy(value, (nc->matte_id) ? nc->matte_id : ""); +} + +static int rna_NodeCryptomatte_matte_length(PointerRNA *ptr) +{ + bNode *node = (bNode *)ptr->data; + NodeCryptomatte *nc = node->storage; + + return (nc->matte_id) ? strlen(nc->matte_id) : 0; +} + +static void rna_NodeCryptomatte_matte_set(PointerRNA *ptr, const char *value) +{ + bNode *node = (bNode *)ptr->data; + NodeCryptomatte *nc = node->storage; + + if (nc->matte_id) + MEM_freeN(nc->matte_id); + + if (value && value[0]) + nc->matte_id = BLI_strdup(value); + else + nc->matte_id = NULL; +} + +static void rna_NodeCryptomatte_update_add(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ntreeCompositCryptomatteSyncFromAdd(ptr->id.data, ptr->data); + rna_Node_update(bmain, scene, ptr); +} + +static void rna_NodeCryptomatte_update_remove(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + ntreeCompositCryptomatteSyncFromRemove(ptr->id.data, ptr->data); + rna_Node_update(bmain, scene, ptr); +} + /* ******** Node Socket Types ******** */ static PointerRNA rna_NodeOutputFile_slot_layer_get(CollectionPropertyIterator *iter) @@ -6977,6 +7019,32 @@ static void def_cmp_sunbeams(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_cmp_cryptomatte(StructRNA *srna) +{ + PropertyRNA *prop; + static float default_1[3] = {1.f, 1.f, 1.f}; + + RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage"); + prop = RNA_def_property(srna, "matte_id", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_NodeCryptomatte_matte_get", "rna_NodeCryptomatte_matte_length", + "rna_NodeCryptomatte_matte_set"); + RNA_def_property_ui_text(prop, "Matte Objects", "List of object and material crypto IDs to include in matte"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + + prop = RNA_def_property(srna, "add", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_array_default(prop, default_1); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_text(prop, "Add", "Add object or material to matte, by picking a color from the Pick output"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_add"); + + prop = RNA_def_property(srna, "remove", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_array_default(prop, default_1); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_text(prop, "Remove", "Remove object or material from matte, by picking a color from the Pick output"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeCryptomatte_update_remove"); +} + /* -- Texture Nodes --------------------------------------------------------- */ static void def_tex_output(StructRNA *srna) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index cc0bef30047..5a5d5997878 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -59,6 +59,7 @@ set(SRC composite/nodes/node_composite_composite.c composite/nodes/node_composite_cornerpin.c composite/nodes/node_composite_crop.c + composite/nodes/node_composite_cryptomatte.c composite/nodes/node_composite_curves.c composite/nodes/node_composite_despeckle.c composite/nodes/node_composite_doubleEdgeMask.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index a5c2e604f46..2a82b706de5 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -109,6 +109,7 @@ void register_node_type_cmp_luma_matte(void); void register_node_type_cmp_doubleedgemask(void); void register_node_type_cmp_keyingscreen(void); void register_node_type_cmp_keying(void); +void register_node_type_cmp_cryptomatte(void); void register_node_type_cmp_translate(void); void register_node_type_cmp_rotate(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 5217c7dc6e7..a4f8a798576 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -219,6 +219,7 @@ DefNode( CompositorNode, CMP_NODE_PIXELATE, 0, "PIXEL DefNode( CompositorNode, CMP_NODE_PLANETRACKDEFORM,def_cmp_planetrackdeform,"PLANETRACKDEFORM",PlaneTrackDeform,"Plane Track Deform","" ) DefNode( CompositorNode, CMP_NODE_CORNERPIN, 0, "CORNERPIN", CornerPin, "Corner Pin", "" ) DefNode( CompositorNode, CMP_NODE_SUNBEAMS, def_cmp_sunbeams, "SUNBEAMS", SunBeams, "Sun Beams", "" ) +DefNode( CompositorNode, CMP_NODE_CRYPTOMATTE, def_cmp_cryptomatte, "CRYPTOMATTE", Cryptomatte, "Cryptomatte", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c new file mode 100644 index 00000000000..488dfa6756e --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -0,0 +1,309 @@ +/* + * ***** 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) 2018 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Stockner, Stefan Werner + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_cryptomatte.c + * \ingroup cmpnodes + */ + +#include "node_composite_util.h" +#include "BLI_dynstr.h" +#include "BLI_hash_mm3.h" +#include "BLI_assert.h" + +#ifndef max + #define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min + #define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +/* this is taken from the cryptomatte specification 1.0 */ + +static inline float hash_to_float(uint32_t hash) +{ + uint32_t mantissa = hash & (( 1 << 23) - 1); + uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); + exponent = max(exponent, (uint32_t) 1); + exponent = min(exponent, (uint32_t) 254); + exponent = exponent << 23; + uint32_t sign = (hash >> 31); + sign = sign << 31; + uint32_t float_bits = sign | exponent | mantissa; + float f; + /* Bit casting relies on equal size for both types. */ + BLI_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "float and uint32_t are not the same size") + memcpy(&f, &float_bits, sizeof(float)); + return f; +} + +static void cryptomatte_add(NodeCryptomatte* n, float f) +{ + /* Turn the number into a string. */ + char number[32]; + BLI_snprintf(number, sizeof(number), "<%.9g>", f); + + /* Search if we already have the number. */ + if (n->matte_id && strlen(n->matte_id) != 0) { + size_t start = 0; + const size_t end = strlen(n->matte_id); + size_t token_len = 0; + while (start < end) { + /* Ignore leading whitespace. */ + while (start < end && n->matte_id[start] == ' ') { + ++start; + } + + /* Find the next seprator. */ + char* token_end = strchr(n->matte_id+start, ','); + if (token_end == NULL || token_end == n->matte_id+start) { + token_end = n->matte_id+end; + } + /* Be aware that token_len still contains any trailing white space. */ + token_len = token_end - (n->matte_id + start); + + /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ + if (n->matte_id[start] == '<') { + if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + /* This number is already there, so continue. */ + return; + } + } + else { + /* Remove trailing white space */ + size_t name_len = token_len; + while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + name_len--; + } + /* Calculate the hash of the token and compare. */ + uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + if (f == hash_to_float(hash)) { + return; + } + } + start += token_len+1; + } + } + + DynStr *new_matte = BLI_dynstr_new(); + if (!new_matte) { + return; + } + + if(n->matte_id) { + BLI_dynstr_append(new_matte, n->matte_id); + MEM_freeN(n->matte_id); + } + + if(BLI_dynstr_get_len(new_matte) > 0) { + BLI_dynstr_append(new_matte, ","); + } + BLI_dynstr_append(new_matte, number); + n->matte_id = BLI_dynstr_get_cstring(new_matte); + BLI_dynstr_free(new_matte); +} + +static void cryptomatte_remove(NodeCryptomatte*n, float f) +{ + if (n->matte_id == NULL || strlen(n->matte_id) == 0) { + /* Empty string, nothing to remove. */ + return; + } + + /* This will be the new string without the removed key. */ + DynStr *new_matte = BLI_dynstr_new(); + if (!new_matte) { + return; + } + + /* Turn the number into a string. */ + static char number[32]; + BLI_snprintf(number, sizeof(number), "<%.9g>", f); + + /* Search if we already have the number. */ + size_t start = 0; + const size_t end = strlen(n->matte_id); + size_t token_len = 0; + bool is_first = true; + while (start < end) { + bool skip = false; + /* Ignore leading whitespace or commas. */ + while (start < end && ((n->matte_id[start] == ' ') || (n->matte_id[start] == ','))) { + ++start; + } + + /* Find the next seprator. */ + char* token_end = strchr(n->matte_id+start+1, ','); + if (token_end == NULL || token_end == n->matte_id+start) { + token_end = n->matte_id+end; + } + /* Be aware that token_len still contains any trailing white space. */ + token_len = token_end - (n->matte_id + start); + + if (token_len == 1) { + skip = true; + } + /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ + else if (n->matte_id[start] == '<') { + if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + /* This number is already there, so skip it. */ + skip = true; + } + } + else { + /* Remove trailing white space */ + size_t name_len = token_len; + while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + name_len--; + } + /* Calculate the hash of the token and compare. */ + uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + if (f == hash_to_float(hash)) { + skip = true; + } + } + if (!skip) { + if (is_first) { + is_first = false; + } + else { + BLI_dynstr_append(new_matte, ", "); + } + BLI_dynstr_nappend(new_matte, n->matte_id+start, token_len); + } + start += token_len+1; + } + + if(n->matte_id) { + MEM_freeN(n->matte_id); + n->matte_id = NULL; + } + if(BLI_dynstr_get_len(new_matte) > 0) { + n->matte_id = BLI_dynstr_get_cstring(new_matte); + } + BLI_dynstr_free(new_matte); +} + +static bNodeSocketTemplate outputs[] = { + { SOCK_RGBA, 0, N_("Image")}, + { SOCK_FLOAT, 0, N_("Matte")}, + { SOCK_RGBA, 0, N_("Pick")}, + { -1, 0, "" } +}; + +void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeCryptomatte *n = node->storage; + if (n->add[0] != 0.0f) { + cryptomatte_add(n, n->add[0]); + n->add[0] = 0.0f; + n->add[1] = 0.0f; + n->add[2] = 0.0f; + } +} + +void ntreeCompositCryptomatteSyncFromRemove(bNodeTree *UNUSED(ntree), bNode *node) +{ + NodeCryptomatte *n = node->storage; + if (n->remove[0] != 0.0f) { + cryptomatte_remove(n, n->remove[0]); + n->remove[0] = 0.0f; + n->remove[1] = 0.0f; + n->remove[2] = 0.0f; + } +} + +bNodeSocket *ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node) +{ + NodeCryptomatte *n = node->storage; + char sockname[32]; + n->num_inputs++; + BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs-1); + bNodeSocket *sock = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, NULL, sockname); + return sock; +} + +int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node) +{ + NodeCryptomatte *n = node->storage; + if (n->num_inputs < 2) { + return 0; + } + bNodeSocket *sock = node->inputs.last; + nodeRemoveSocket(ntree, node, sock); + n->num_inputs--; + return 1; +} + +static void init(bNodeTree *ntree, bNode *node) +{ + NodeCryptomatte *user = MEM_callocN(sizeof(NodeCryptomatte), "cryptomatte user"); + node->storage = user; + + + nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, "image", "Image"); + + /* Add three inputs by default, as recommended by the Cryptomatte specification. */ + ntreeCompositCryptomatteAddSocket(ntree, node); + ntreeCompositCryptomatteAddSocket(ntree, node); + ntreeCompositCryptomatteAddSocket(ntree, node); +} + +static void node_free_cryptomatte(bNode *node) +{ + NodeCryptomatte *nc = node->storage; + + if (nc) { + if (nc->matte_id) { + MEM_freeN(nc->matte_id); + } + + MEM_freeN(nc); + } +} + +static void node_copy_cryptomatte(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node) +{ + NodeCryptomatte *src_nc = src_node->storage; + NodeCryptomatte *dest_nc = MEM_dupallocN(src_nc); + + if (src_nc->matte_id) + dest_nc->matte_id = MEM_dupallocN(src_nc->matte_id); + + dest_node->storage = dest_nc; +} + +void register_node_type_cmp_cryptomatte(void) +{ + static bNodeType ntype; + + cmp_node_type_base(&ntype, CMP_NODE_CRYPTOMATTE, "Cryptomatte", NODE_CLASS_CONVERTOR, 0); + node_type_socket_templates(&ntype, NULL, outputs); + node_type_init(&ntype, init); + node_type_storage(&ntype, "NodeCryptomatte", node_free_cryptomatte, node_copy_cryptomatte); + nodeRegisterType(&ntype); +} -- cgit v1.2.3 From 566b319335563888e252b2186c93606ad41ff216 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jul 2018 13:34:22 +0200 Subject: Cleanup: Cryptomatte node style tweaks. --- source/blender/blenlib/intern/hash_mm3.c | 2 +- source/blender/compositor/nodes/COM_CryptomatteNode.cpp | 5 +++-- .../nodes/composite/nodes/node_composite_cryptomatte.c | 17 +++++------------ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c index ac483795e45..5ead9ceca63 100644 --- a/source/blender/blenlib/intern/hash_mm3.c +++ b/source/blender/blenlib/intern/hash_mm3.c @@ -49,7 +49,7 @@ static inline uint32_t rotl32(uint32_t x, int8_t r) return (x << r) | (x >> (32 - r)); } # define ROTL32(x,y) rotl32(x,y) -# define BIG_CONSTANT(x) (x##LLU) +# define BIG_CONSTANT(x) (x##LLU) #endif /* !defined(_MSC_VER) */ /* Block read - if your platform needs to do endian-swapping or can only diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp index c8134068543..bc115e66c20 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp @@ -35,7 +35,8 @@ CryptomatteNode::CryptomatteNode(bNode *editorNode) : Node(editorNode) } /* This is taken from the Cryptomatte specification 1.0. */ -static inline float hash_to_float(uint32_t hash) { +static inline float hash_to_float(uint32_t hash) +{ uint32_t mantissa = hash & (( 1 << 23) - 1); uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); exponent = max(exponent, (uint32_t) 1); @@ -95,7 +96,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos for (int i = 0; i < getNumberOfInputSockets()-1; ++i) { converter.mapInputSocket(this->getInputSocket(i + 1), operation->getInputSocket(i)); } - + SeparateChannelOperation *separateOperation = new SeparateChannelOperation; separateOperation->setChannel(3); converter.addOperation(separateOperation); diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c index 488dfa6756e..0231e4717b2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -30,17 +30,10 @@ */ #include "node_composite_util.h" +#include "BLI_assert.h" #include "BLI_dynstr.h" #include "BLI_hash_mm3.h" -#include "BLI_assert.h" - -#ifndef max - #define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef min - #define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif +#include "BLI_utildefines.h" /* this is taken from the cryptomatte specification 1.0 */ @@ -48,8 +41,8 @@ static inline float hash_to_float(uint32_t hash) { uint32_t mantissa = hash & (( 1 << 23) - 1); uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); - exponent = max(exponent, (uint32_t) 1); - exponent = min(exponent, (uint32_t) 254); + exponent = MAX2(exponent, (uint32_t) 1); + exponent = MIN2(exponent, (uint32_t) 254); exponent = exponent << 23; uint32_t sign = (hash >> 31); sign = sign << 31; -- cgit v1.2.3 From 5078b9d2d08a34ae3786100c2301ea960165e7f2 Mon Sep 17 00:00:00 2001 From: "L. E. Segovia" Date: Wed, 18 Jul 2018 11:14:43 +0200 Subject: Cycles: add Principled Hair BSDF. This is a physically-based, easy-to-use shader for rendering hair and fur, with controls for melanin, roughness and randomization. Based on the paper "A Practical and Controllable Hair and Fur Model for Production Path Tracing". Implemented by Leonardo E. Segovia and Lukas Stockner, part of Google Summer of Code 2018. --- intern/cycles/blender/blender_shader.cpp | 6 + intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/closure/bsdf.h | 14 + .../cycles/kernel/closure/bsdf_hair_principled.h | 502 +++++++++++++++++++++ intern/cycles/kernel/geom/geom_curve.h | 27 ++ intern/cycles/kernel/geom/geom_curve_intersect.h | 25 - intern/cycles/kernel/kernel_compat_opencl.h | 1 + intern/cycles/kernel/kernel_volume.h | 6 +- intern/cycles/kernel/osl/osl_closures.cpp | 61 ++- intern/cycles/kernel/osl/osl_closures.h | 1 + intern/cycles/kernel/shaders/CMakeLists.txt | 1 + .../kernel/shaders/node_principled_hair_bsdf.osl | 105 +++++ intern/cycles/kernel/shaders/stdosl.h | 1 + intern/cycles/kernel/svm/svm_closure.h | 120 ++++- intern/cycles/kernel/svm/svm_types.h | 10 +- intern/cycles/render/graph.cpp | 3 + intern/cycles/render/nodes.cpp | 133 ++++++ intern/cycles/render/nodes.h | 39 ++ intern/cycles/util/util_math.h | 19 + intern/cycles/util/util_math_float3.h | 10 + release/scripts/startup/nodeitems_builtins.py | 1 + source/blender/blenkernel/BKE_node.h | 2 + source/blender/blenkernel/intern/node.c | 1 + source/blender/editors/space_node/drawnode.c | 8 + source/blender/makesdna/DNA_node_types.h | 5 + source/blender/makesrna/intern/rna_nodetree.c | 22 + source/blender/nodes/CMakeLists.txt | 1 + source/blender/nodes/NOD_shader.h | 1 + source/blender/nodes/NOD_static_types.h | 1 + .../nodes/node_shader_bsdf_hair_principled.c | 133 ++++++ 30 files changed, 1228 insertions(+), 32 deletions(-) create mode 100644 intern/cycles/kernel/closure/bsdf_hair_principled.h create mode 100644 intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl create mode 100644 source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 956f8f767a6..25e6db18588 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -524,6 +524,12 @@ static ShaderNode *add_node(Scene *scene, } node = hair; } + else if(b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) { + BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node); + PrincipledHairBsdfNode *principled_hair = new PrincipledHairBsdfNode(); + principled_hair->parametrization = (NodePrincipledHairParametrization) get_enum(b_principled_hair_node.ptr, "parametrization", NODE_PRINCIPLED_HAIR_NUM, NODE_PRINCIPLED_HAIR_REFLECTANCE); + node = principled_hair; + } else if(b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) { BL::ShaderNodeBsdfPrincipled b_principled_node(b_node); PrincipledBsdfNode *principled = new PrincipledBsdfNode(); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 092bec08a51..c4cad17429d 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -156,6 +156,7 @@ set(SRC_CLOSURE_HEADERS closure/volume.h closure/bsdf_principled_diffuse.h closure/bsdf_principled_sheen.h + closure/bsdf_hair_principled.h ) set(SRC_SVM_HEADERS diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index f191b812f11..3a9629ea9d7 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -27,6 +27,7 @@ #include "kernel/closure/bsdf_ashikhmin_shirley.h" #include "kernel/closure/bsdf_toon.h" #include "kernel/closure/bsdf_hair.h" +#include "kernel/closure/bsdf_hair_principled.h" #include "kernel/closure/bsdf_principled_diffuse.h" #include "kernel/closure/bsdf_principled_sheen.h" #include "kernel/closure/bssrdf.h" @@ -171,6 +172,10 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg, label = bsdf_hair_transmission_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv, + eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + break; #ifdef __PRINCIPLED__ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: case CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID: @@ -284,6 +289,9 @@ float3 bsdf_eval(KernelGlobals *kg, case CLOSURE_BSDF_GLOSSY_TOON_ID: eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf); break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf); + break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf); break; @@ -366,6 +374,9 @@ float3 bsdf_eval(KernelGlobals *kg, case CLOSURE_BSDF_GLOSSY_TOON_ID: eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf); break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf); + break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf); break; @@ -424,6 +435,9 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness) case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: bsdf_ashikhmin_shirley_blur(sc, roughness); break; + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: + bsdf_principled_hair_blur(sc, roughness); + break; default: break; } diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h new file mode 100644 index 00000000000..4ee58089384 --- /dev/null +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -0,0 +1,502 @@ +/* + * Copyright 2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef __KERNEL_CPU__ +#include +#endif + +#include "kernel/kernel_color.h" + +#ifndef __BSDF_HAIR_PRINCIPLED_H__ +#define __BSDF_HAIR_PRINCIPLED_H__ + +CCL_NAMESPACE_BEGIN + +typedef ccl_addr_space struct PrincipledHairExtra { + /* Geometry data. */ + float4 geom; +} PrincipledHairExtra; + +typedef ccl_addr_space struct PrincipledHairBSDF { + SHADER_CLOSURE_BASE; + + /* Absorption coefficient. */ + float3 sigma; + /* Variance of the underlying logistic distribution. */ + float v; + /* Scale factor of the underlying logistic distribution. */ + float s; + /* Cuticle tilt angle. */ + float alpha; + /* IOR. */ + float eta; + /* Effective variance for the diffuse bounce only. */ + float m0_roughness; + + /* Extra closure. */ + PrincipledHairExtra *extra; +} PrincipledHairBSDF; + +static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF), "PrincipledHairBSDF is too large!"); +static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra), "PrincipledHairExtra is too large!"); + +ccl_device_inline float cos_from_sin(const float s) +{ + return safe_sqrtf(1.0f - s*s); +} + +/* Gives the change in direction in the normal plane for the given angles and p-th-order scattering. */ +ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t) +{ + return 2.0f * p * gamma_t - 2.0f * gamma_o + p * M_PI_F; +} + +/* Remaps the given angle to [-pi, pi]. */ +ccl_device_inline float wrap_angle(float a) +{ + while(a > M_PI_F) { + a -= M_2PI_F; + } + while(a < -M_PI_F) { + a += M_2PI_F; + } + return a; +} + +/* Logistic distribution function. */ +ccl_device_inline float logistic(float x, float s) +{ + float v = expf(-fabsf(x)/s); + return v / (s * sqr(1.0f + v)); +} + +/* Logistic cumulative density function. */ +ccl_device_inline float logistic_cdf(float x, float s) +{ + float arg = -x/s; + /* expf() overflows if arg >= 89.0. */ + if(arg > 88.0f) { + return 0.0f; + } + else { + return 1.0f / (1.0f + expf(arg)); + } +} + +/* Numerical approximation to the Bessel function of the first kind. */ +ccl_device_inline float bessel_I0(float x) +{ + x = sqr(x); + float val = 1.0f + 0.25f*x; + float pow_x_2i = sqr(x); + uint64_t i_fac_2 = 1; + int pow_4_i = 16; + for(int i = 2; i < 10; i++) { + i_fac_2 *= i*i; + float newval = val + pow_x_2i / (pow_4_i * i_fac_2); + if(val == newval) { + return val; + } + val = newval; + pow_x_2i *= x; + pow_4_i *= 4; + } + return val; +} + +/* Logarithm of the Bessel function of the first kind. */ +ccl_device_inline float log_bessel_I0(float x) +{ + if (x > 12.0f) { + /* log(1/x) == -log(x) iff x > 0. + * This is only used with positive cosines */ + return x + 0.5f * (1.f / (8.0f * x) - M_LN_2PI_F - logf(x)); + } + else { + return logf(bessel_I0(x)); + } +} + +/* Logistic distribution limited to the interval [-pi, pi]. */ +ccl_device_inline float trimmed_logistic(float x, float s) +{ + /* The logistic distribution is symmetric and centered around zero, + * so logistic_cdf(x, s) = 1 - logistic_cdf(-x, s). + * Therefore, logistic_cdf(x, s)-logistic_cdf(-x, s) = 1 - 2*logistic_cdf(-x, s) */ + float scaling_fac = 1.0f - 2.0f*logistic_cdf(-M_PI_F, s); + float val = logistic(x, s); + return safe_divide(val, scaling_fac); +} + +/* Sampling function for the trimmed logistic function. */ +ccl_device_inline float sample_trimmed_logistic(float u, float s) +{ + float cdf_minuspi = logistic_cdf(-M_PI_F, s); + float x = -s*logf(1.0f / (u*(1.0f - 2.0f*cdf_minuspi) + cdf_minuspi) - 1.0f); + return clamp(x, -M_PI_F, M_PI_F); +} + +/* Azimuthal scattering function Np. */ +ccl_device_inline float azimuthal_scattering(float phi, + int p, + float s, + float gamma_o, + float gamma_t) +{ + float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t)); + float val = trimmed_logistic(phi_o, s); + return val; +} + +/* Longitudinal scattering function Mp. */ +ccl_device_inline float longitudinal_scattering(float sin_theta_i, + float cos_theta_i, + float sin_theta_o, + float cos_theta_o, + float v) +{ + float inv_v = 1.0f/v; + float cos_arg = cos_theta_i * cos_theta_o * inv_v; + float sin_arg = sin_theta_i * sin_theta_o * inv_v; + if(v <= 0.1f) { + float i0 = log_bessel_I0(cos_arg); + float val = expf(i0 - sin_arg - inv_v + 0.6931f + logf(0.5f*inv_v)); + return val; + } + else { + float i0 = bessel_I0(cos_arg); + float val = (expf(-sin_arg) * i0) / (sinhf(inv_v) * 2.0f * v); + return val; + } +} + +/* Combine the three values using their luminances. */ +ccl_device_inline float4 combine_with_energy(KernelGlobals *kg, float3 c) +{ + return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c)); +} + +#ifdef __HAIR__ +/* Set up the hair closure. */ +ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bsdf) +{ + bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID; + bsdf->v = clamp(bsdf->v, 0.001f, 1.0f); + bsdf->s = clamp(bsdf->s, 0.001f, 1.0f); + /* Apply Primary Reflection Roughness modifier. */ + bsdf->m0_roughness = clamp(bsdf->m0_roughness*bsdf->v, 0.001f, 1.0f); + + /* Map from roughness_u and roughness_v to variance and scale factor. */ + bsdf->v = sqr(0.726f*bsdf->v + 0.812f*sqr(bsdf->v) + 3.700f*pow20(bsdf->v)); + bsdf->s = (0.265f*bsdf->s + 1.194f*sqr(bsdf->s) + 5.372f*pow22(bsdf->s))*M_SQRT_PI_8_F; + bsdf->m0_roughness = sqr(0.726f*bsdf->m0_roughness + 0.812f*sqr(bsdf->m0_roughness) + 3.700f*pow20(bsdf->m0_roughness)); + + /* Compute local frame, aligned to curve tangent and ray direction. */ + float3 X = safe_normalize(sd->dPdu); + float3 Y = safe_normalize(cross(X, sd->I)); + float3 Z = safe_normalize(cross(X, Y)); + /* TODO: the solution below works where sd->Ng is the normal + * pointing from the center of the curve to the shading point. + * It doesn't work for triangles, see https://developer.blender.org/T43625 */ + + /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at + * the center, to grazing the other edge. This is the sine of the angle + * between sd->Ng and Z, as seen from the tangent X. */ + + /* TODO: we convert this value to a cosine later and discard the sign, so + * we could probably save some operations. */ + float h = dot(cross(sd->Ng, X), Z); + + kernel_assert(fabsf(h) < 1.0f + 1e-4f); + kernel_assert(isfinite3_safe(Y)); + kernel_assert(isfinite_safe(h)); + + bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h); + + return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_NEEDS_LCG; +} + +#endif /* __HAIR__ */ + +/* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */ +ccl_device_inline void hair_attenuation(KernelGlobals *kg, + float f, + float3 T, + float4 *Ap) +{ + /* Primary specular (R). */ + Ap[0] = make_float4(f, f, f, f); + + /* Transmission (TT). */ + float3 col = sqr(1.0f - f) * T; + Ap[1] = combine_with_energy(kg, col); + + /* Secondary specular (TRT). */ + col *= T*f; + Ap[2] = combine_with_energy(kg, col); + + /* Residual component (TRRT+). */ + col *= safe_divide_color(T*f, make_float3(1.0f, 1.0f, 1.0f) - T*f); + Ap[3] = combine_with_energy(kg, col); + + /* Normalize sampling weights. */ + float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w; + float fac = safe_divide(1.0f, totweight); + + Ap[0].w *= fac; + Ap[1].w *= fac; + Ap[2].w *= fac; + Ap[3].w *= fac; +} + +/* Given the tilt angle, generate the rotated theta_i for the different bounces. */ +ccl_device_inline void hair_alpha_angles(float sin_theta_i, + float cos_theta_i, + float alpha, + float *angles) +{ + float sin_1alpha = sinf(alpha); + float cos_1alpha = cos_from_sin(sin_1alpha); + float sin_2alpha = 2.0f*sin_1alpha*cos_1alpha; + float cos_2alpha = sqr(cos_1alpha) - sqr(sin_1alpha); + float sin_4alpha = 2.0f*sin_2alpha*cos_2alpha; + float cos_4alpha = sqr(cos_2alpha) - sqr(sin_2alpha); + + angles[0] = sin_theta_i*cos_2alpha + cos_theta_i*sin_2alpha; + angles[1] = fabsf(cos_theta_i*cos_2alpha - sin_theta_i*sin_2alpha); + angles[2] = sin_theta_i*cos_1alpha - cos_theta_i*sin_1alpha; + angles[3] = fabsf(cos_theta_i*cos_1alpha + sin_theta_i*sin_1alpha); + angles[4] = sin_theta_i*cos_4alpha - cos_theta_i*sin_4alpha; + angles[5] = fabsf(cos_theta_i*cos_4alpha + sin_theta_i*sin_4alpha); +} + +/* Evaluation function for our shader. */ +ccl_device float3 bsdf_principled_hair_eval(KernelGlobals *kg, + const ShaderData *sd, + const ShaderClosure *sc, + const float3 omega_in, + float *pdf) +{ + kernel_assert(isfinite3_safe(sd->P) && isfinite_safe(sd->ray_length)); + + const PrincipledHairBSDF *bsdf = (const PrincipledHairBSDF*) sc; + float3 Y = float4_to_float3(bsdf->extra->geom); + + float3 X = safe_normalize(sd->dPdu); + kernel_assert(fabsf(dot(X, Y)) < 1e-4f); + float3 Z = safe_normalize(cross(X, Y)); + + float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); + float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + + float sin_theta_o = wo.x; + float cos_theta_o = cos_from_sin(sin_theta_o); + float phi_o = atan2f(wo.z, wo.y); + + float sin_theta_t = sin_theta_o / bsdf->eta; + float cos_theta_t = cos_from_sin(sin_theta_t); + + float sin_gamma_o = bsdf->extra->geom.w; + float cos_gamma_o = cos_from_sin(sin_gamma_o); + float gamma_o = safe_asinf(sin_gamma_o); + + float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o)); + float cos_gamma_t = cos_from_sin(sin_gamma_t); + float gamma_t = safe_asinf(sin_gamma_t); + + float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); + float4 Ap[4]; + hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap); + + float sin_theta_i = wi.x; + float cos_theta_i = cos_from_sin(sin_theta_i); + float phi_i = atan2f(wi.z, wi.y); + + float phi = phi_i - phi_o; + + float angles[6]; + hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); + + float4 F; + float Mp, Np; + + /* Primary specular (R). */ + Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness); + Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t); + F = Ap[0] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Transmission (TT). */ + Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f*bsdf->v); + Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t); + F += Ap[1] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Secondary specular (TRT). */ + Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f*bsdf->v); + Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t); + F += Ap[2] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Residual component (TRRT+). */ + Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f*bsdf->v); + Np = M_1_2PI_F; + F += Ap[3] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + *pdf = F.w; + return float4_to_float3(F); +} + +/* Sampling function for the hair shader. */ +ccl_device int bsdf_principled_hair_sample(KernelGlobals *kg, + const ShaderClosure *sc, + ShaderData *sd, + float randu, + float randv, + float3 *eval, + float3 *omega_in, + float3 *domega_in_dx, + float3 *domega_in_dy, + float *pdf) +{ + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*) sc; + + float3 Y = float4_to_float3(bsdf->extra->geom); + + float3 X = safe_normalize(sd->dPdu); + kernel_assert(fabsf(dot(X, Y)) < 1e-4f); + float3 Z = safe_normalize(cross(X, Y)); + + float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); + + float2 u[2]; + u[0] = make_float2(randu, randv); + u[1].x = lcg_step_float_addrspace(&sd->lcg_state); + u[1].y = lcg_step_float_addrspace(&sd->lcg_state); + + float sin_theta_o = wo.x; + float cos_theta_o = cos_from_sin(sin_theta_o); + float phi_o = atan2f(wo.z, wo.y); + + float sin_theta_t = sin_theta_o / bsdf->eta; + float cos_theta_t = cos_from_sin(sin_theta_t); + + float sin_gamma_o = bsdf->extra->geom.w; + float cos_gamma_o = cos_from_sin(sin_gamma_o); + float gamma_o = safe_asinf(sin_gamma_o); + + float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o)); + float cos_gamma_t = cos_from_sin(sin_gamma_t); + float gamma_t = safe_asinf(sin_gamma_t); + + float3 T = exp3(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); + float4 Ap[4]; + hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap); + + int p = 0; + for(; p < 3; p++) { + if(u[0].x < Ap[p].w) { + break; + } + u[0].x -= Ap[p].w; + } + + float v = bsdf->v; + if(p == 1) { + v *= 0.25f; + } + if(p >= 2) { + v *= 4.0f; + } + + u[1].x = max(u[1].x, 1e-5f); + float fac = 1.0f + v*logf(u[1].x + (1.0f - u[1].x)*expf(-2.0f/v)); + float sin_theta_i = -fac * sin_theta_o + cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o; + float cos_theta_i = cos_from_sin(sin_theta_i); + + float angles[6]; + if(p < 3) { + hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles); + sin_theta_i = angles[2*p]; + cos_theta_i = angles[2*p+1]; + } + + float phi; + if(p < 3) { + phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s); + } + else { + phi = M_2PI_F*u[0].y; + } + float phi_i = phi_o + phi; + + hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); + + float4 F; + float Mp, Np; + + /* Primary specular (R). */ + Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness); + Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t); + F = Ap[0] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Transmission (TT). */ + Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f*bsdf->v); + Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t); + F += Ap[1] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Secondary specular (TRT). */ + Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f*bsdf->v); + Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t); + F += Ap[2] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + /* Residual component (TRRT+). */ + Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f*bsdf->v); + Np = M_1_2PI_F; + F += Ap[3] * Mp * Np; + kernel_assert(isfinite3_safe(float4_to_float3(F))); + + *eval = float4_to_float3(F); + *pdf = F.w; + + *omega_in = X*sin_theta_i + Y*cos_theta_i*cosf(phi_i) + Z*cos_theta_i*sinf(phi_i); + +#ifdef __RAY_DIFFERENTIALS__ + float3 N = safe_normalize(sd->I + *omega_in); + *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx; + *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy; +#endif + + return LABEL_GLOSSY|((p == 0)? LABEL_REFLECT : LABEL_TRANSMIT); +} + +/* Implements Filter Glossy by capping the effective roughness. */ +ccl_device void bsdf_principled_hair_blur(ShaderClosure *sc, float roughness) +{ + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)sc; + + bsdf->v = fmaxf(roughness, bsdf->v); + bsdf->s = fmaxf(roughness, bsdf->s); + bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness); +} + +CCL_NAMESPACE_END + +#endif /* __BSDF_HAIR_PRINCIPLED_H__ */ diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index e35267f02bf..dea0c742ed7 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -23,6 +23,33 @@ CCL_NAMESPACE_BEGIN #ifdef __HAIR__ +/* Interpolation of curve geometry */ + +ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3) +{ + float fc = 0.71f; + float data[4]; + float t2 = t * t; + data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc; + data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t; + data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc; + data[3] = 3.0f * fc * t2 - 2.0f * fc * t; + return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3; +} + +ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3) +{ + float data[4]; + float fc = 0.71f; + float t2 = t * t; + float t3 = t2 * t; + data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t; + data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f; + data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t; + data[3] = fc * t3 - fc * t2; + return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3; +} + /* Reading attributes on various curve elements */ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h index 46c3f408f0b..4cfbe21685c 100644 --- a/intern/cycles/kernel/geom/geom_curve_intersect.h +++ b/intern/cycles/kernel/geom/geom_curve_intersect.h @@ -752,31 +752,6 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals *kg, #endif } -ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3) -{ - float fc = 0.71f; - float data[4]; - float t2 = t * t; - data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc; - data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t; - data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc; - data[3] = 3.0f * fc * t2 - 2.0f * fc * t; - return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3; -} - -ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3) -{ - float data[4]; - float fc = 0.71f; - float t2 = t * t; - float t3 = t2 * t; - data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t; - data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f; - data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t; - data[3] = fc * t3 - fc * t2; - return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3; -} - ccl_device_inline float3 curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h index d1ae10a0384..3f7e264fbee 100644 --- a/intern/cycles/kernel/kernel_compat_opencl.h +++ b/intern/cycles/kernel/kernel_compat_opencl.h @@ -123,6 +123,7 @@ #define fmaxf(x, y) fmax(((float)(x)), ((float)(y))) #define fminf(x, y) fmin(((float)(x)), ((float)(y))) #define fmodf(x, y) fmod((float)(x), (float)(y)) +#define sinhf(x) sinh(((float)(x))) #ifndef __CL_USE_NATIVE__ # define sinf(x) native_sin(((float)(x))) diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index a7072c3ad03..d71761a97bc 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -91,7 +91,7 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg, ccl_device float3 volume_color_transmittance(float3 sigma, float t) { - return make_float3(expf(-sigma.x * t), expf(-sigma.y * t), expf(-sigma.z * t)); + return exp3(-sigma * t); } ccl_device float kernel_volume_channel_get(float3 value, int channel) @@ -234,7 +234,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, sum += (-sigma_t * (new_t - t)); if((i & 0x07) == 0) { /* ToDo: Other interval? */ - tp = *throughput * make_float3(expf(sum.x), expf(sum.y), expf(sum.z)); + tp = *throughput * exp3(sum); /* stop if nearly all light is blocked */ if(tp.x < tp_eps && tp.y < tp_eps && tp.z < tp_eps) @@ -246,7 +246,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, t = new_t; if(t == ray->t) { /* Update throughput in case we haven't done it above */ - tp = *throughput * make_float3(expf(sum.x), expf(sum.y), expf(sum.z)); + tp = *throughput * exp3(sum); break; } } diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp index 581b38e65c0..8c7ae30725c 100644 --- a/intern/cycles/kernel/osl/osl_closures.cpp +++ b/intern/cycles/kernel/osl/osl_closures.cpp @@ -4,7 +4,7 @@ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. * All Rights Reserved. * - * Modifications Copyright 2011, Blender Foundation. + * Modifications Copyright 2011-2018, Blender Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -59,6 +59,7 @@ #include "kernel/closure/bsdf_ashikhmin_shirley.h" #include "kernel/closure/bsdf_toon.h" #include "kernel/closure/bsdf_hair.h" +#include "kernel/closure/bsdf_hair_principled.h" #include "kernel/closure/bsdf_principled_diffuse.h" #include "kernel/closure/bsdf_principled_sheen.h" #include "kernel/closure/volume.h" @@ -176,6 +177,61 @@ BSDF_CLOSURE_CLASS_BEGIN(PrincipledSheen, principled_sheen, PrincipledSheenBsdf, CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N), BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen) +/* PRINCIPLED HAIR BSDF */ +class PrincipledHairClosure : public CBSDFClosure { +public: + PrincipledHairBSDF params; + + PrincipledHairBSDF *alloc(ShaderData *sd, int path_flag, float3 weight) + { + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)bsdf_alloc_osl(sd, sizeof(PrincipledHairBSDF), weight, ¶ms); + if(!bsdf) { + return NULL; + } + + PrincipledHairExtra *extra = (PrincipledHairExtra*)closure_alloc_extra(sd, sizeof(PrincipledHairExtra)); + if(!extra) { + return NULL; + } + + bsdf->extra = extra; + return bsdf; + } + + void setup(ShaderData *sd, int path_flag, float3 weight) + { + if(!skip(sd, path_flag, LABEL_GLOSSY)) + { + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)alloc(sd, path_flag, weight); + if (!bsdf) + { + return; + } + + sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0; + } + } +}; + +static ClosureParam *closure_bsdf_principled_hair_params() +{ + static ClosureParam params[] = { + CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N), + CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma), + CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v), + CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s), + CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness), + CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha), + CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta), + CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"), + CLOSURE_FINISH_PARAM(PrincipledHairClosure) + }; + + return params; +} + +CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure) + /* DISNEY PRINCIPLED CLEARCOAT */ class PrincipledClearcoatClosure : public CBSDFClosure { public: @@ -322,6 +378,9 @@ void OSLShader::register_closures(OSLShadingSystem *ss_) register_closure(ss, "hair_transmission", id++, bsdf_hair_transmission_params(), bsdf_hair_transmission_prepare); + register_closure(ss, "principled_hair", id++, + closure_bsdf_principled_hair_params(), closure_bsdf_principled_hair_prepare); + register_closure(ss, "henyey_greenstein", id++, closure_henyey_greenstein_params(), closure_henyey_greenstein_prepare); register_closure(ss, "absorption", id++, diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 857cc84afd2..d9aeb9ab9fb 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -79,6 +79,7 @@ void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data); void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data); +void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data); #define CCLOSURE_PREPARE(name, classname) \ void name(RendererServices *, int id, void *data) \ diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index 9ee78d160a4..4740db27d4e 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -85,6 +85,7 @@ set(SRC_OSL node_wave_texture.osl node_wireframe.osl node_hair_bsdf.osl + node_principled_hair_bsdf.osl node_uv_map.osl node_principled_bsdf.osl node_rgb_to_bw.osl diff --git a/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl new file mode 100644 index 00000000000..757a88f8ece --- /dev/null +++ b/intern/cycles/kernel/shaders/node_principled_hair_bsdf.osl @@ -0,0 +1,105 @@ +/* + * Copyright 2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdosl.h" + +color log3(color a) +{ + return color(log(a[0]), log(a[1]), log(a[2])); +} + +color sigma_from_concentration(float eumelanin, float pheomelanin) +{ + return eumelanin*color(0.506, 0.841, 1.653) + pheomelanin*color(0.343, 0.733, 1.924); +} + +color sigma_from_reflectance(color c, float azimuthal_roughness) +{ + float x = azimuthal_roughness; + float roughness_fac = (((((0.245*x) + 5.574)*x - 10.73)*x + 2.532)*x - 0.215)*x + 5.969; + color sigma = log3(c) / roughness_fac; + return sigma * sigma; +} + +shader node_principled_hair_bsdf( + color Color = color(0.017513, 0.005763, 0.002059), + float Melanin = 0.8, + float MelaninRedness = 1.0, + float RandomColor = 0.0, + color Tint = 1.0, + color AbsorptionCoefficient = color(0.245531, 0.52, 1.365), + normal Normal = Ng, + string parametrization = "Absorption coefficient", + float Offset = radians(2), + float Roughness = 0.3, + float RadialRoughness = 0.3, + float RandomRoughness = 0.0, + float Coat = 0.0, + float IOR = 1.55, + string AttrRandom = "geom:curve_random", + float Random = 0.0, + + output closure color BSDF = 0) +{ + /* Get random value from curve in none is specified. */ + float random_value = 0.0; + + if (isconnected(Random)) { + random_value = Random; + } + else { + getattribute(AttrRandom, random_value); + } + + /* Compute roughness. */ + float factor_random_roughness = 1.0 + 2.0*(random_value - 0.5)*RandomRoughness; + float m0_roughness = 1.0 - clamp(Coat, 0.0, 1.0); + float roughness = Roughness*factor_random_roughness; + float radial_roughness = RadialRoughness*factor_random_roughness; + + /* Compute absorption. */ + color sigma; + + if (parametrization == "Absorption coefficient") { + sigma = AbsorptionCoefficient; + } + else if (parametrization == "Melanin concentration") { + /* Randomize melanin. */ + float factor_random_color = 1.0 + 2.0*(random_value - 0.5) * RandomColor; + float melanin = Melanin * factor_random_color; + + /* Map melanin 0..inf from more perceptually linear 0..1. */ + melanin = -log(max(1.0 - melanin, 0.0001)); + + /* Benedikt Bitterli's melanin ratio remapping. */ + float eumelanin = melanin * (1.0 - MelaninRedness); + float pheomelanin = melanin * MelaninRedness; + color melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin); + + /* Optional tint. */ + color tint_sigma = sigma_from_reflectance(Tint, radial_roughness); + sigma = melanin_sigma + tint_sigma; + } + else if (parametrization == "Direct coloring"){ + sigma = sigma_from_reflectance(Color, radial_roughness); + } + else { + /* Fallback to brownish hair, same as defaults for melanin. */ + sigma = sigma_from_concentration(0.0, 0.8054375); + } + + BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, m0_roughness, Offset, IOR); +} diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index 82223ca0219..df9c2010872 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -554,6 +554,7 @@ closure color bssrdf(string method, normal N, vector radius, color albedo) BUILT // Hair closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN; closure color hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN; +closure color principled_hair(normal N, color sigma, float roughnessu, float roughnessv, float coat, float alpha, float eta) BUILTIN; // Volume closure color henyey_greenstein(float g) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 4de9cfb88db..aa253223c93 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -16,6 +16,21 @@ CCL_NAMESPACE_BEGIN +/* Hair Melanin */ + +ccl_device_inline float3 sigma_from_concentration(float eumelanin, float pheomelanin) +{ + return eumelanin*make_float3(0.506f, 0.841f, 1.653f) + pheomelanin*make_float3(0.343f, 0.733f, 1.924f); +} + +ccl_device_inline float3 sigma_from_reflectance(float3 color, float azimuthal_roughness) +{ + float x = azimuthal_roughness; + float roughness_fac = (((((0.245f*x) + 5.574f)*x - 10.73f)*x + 2.532f)*x - 0.215f)*x + 5.969f; + float3 sigma = log3(color) / roughness_fac; + return sigma * sigma; +} + /* Closure Nodes */ ccl_device void svm_node_glass_setup(ShaderData *sd, MicrofacetBsdf *bsdf, int type, float eta, float roughness, bool refract) @@ -243,7 +258,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float3 spec_weight = weight * specular_weight; MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc(sd, sizeof(MicrofacetBsdf), spec_weight); - if(!bsdf){ + if(!bsdf) { break; } @@ -722,6 +737,107 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * break; } #ifdef __HAIR__ + case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: { + uint4 data_node2 = read_node(kg, offset); + uint4 data_node3 = read_node(kg, offset); + uint4 data_node4 = read_node(kg, offset); + + float3 weight = sd->svm_closure_weight * mix_weight; + + uint offset_ofs, ior_ofs, color_ofs, parametrization; + decode_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); + float alpha = stack_load_float_default(stack, offset_ofs, data_node.z); + float ior = stack_load_float_default(stack, ior_ofs, data_node.w); + + uint coat_ofs, melanin_ofs, melanin_redness_ofs, absorption_coefficient_ofs; + decode_node_uchar4(data_node2.x, &coat_ofs, &melanin_ofs, &melanin_redness_ofs, &absorption_coefficient_ofs); + + uint tint_ofs, random_ofs, random_color_ofs, random_roughness_ofs; + decode_node_uchar4(data_node3.x, &tint_ofs, &random_ofs, &random_color_ofs, &random_roughness_ofs); + + const AttributeDescriptor attr_descr_random = find_attribute(kg, sd, data_node4.y); + float random = 0.0f; + if (attr_descr_random.offset != ATTR_STD_NOT_FOUND) { + random = primitive_attribute_float(kg, sd, attr_descr_random, NULL, NULL); + } + else { + random = stack_load_float_default(stack, random_ofs, data_node3.y); + } + + + PrincipledHairBSDF *bsdf = (PrincipledHairBSDF*)bsdf_alloc(sd, sizeof(PrincipledHairBSDF), weight); + if(bsdf) { + PrincipledHairExtra *extra = (PrincipledHairExtra*)closure_alloc_extra(sd, sizeof(PrincipledHairExtra)); + + if (!extra) + break; + + /* Random factors range: [-randomization/2, +randomization/2]. */ + float random_roughness = stack_load_float_default(stack, random_roughness_ofs, data_node3.w); + float factor_random_roughness = 1.0f + 2.0f*(random - 0.5f)*random_roughness; + float roughness = param1 * factor_random_roughness; + float radial_roughness = param2 * factor_random_roughness; + + /* Remap Coat value to [0, 100]% of Roughness. */ + float coat = stack_load_float_default(stack, coat_ofs, data_node2.y); + float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f); + + bsdf->N = N; + bsdf->v = roughness; + bsdf->s = radial_roughness; + bsdf->m0_roughness = m0_roughness; + bsdf->alpha = alpha; + bsdf->eta = ior; + bsdf->extra = extra; + + switch(parametrization) { + case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: { + float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs); + bsdf->sigma = absorption_coefficient; + break; + } + case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: { + float melanin = stack_load_float_default(stack, melanin_ofs, data_node2.z); + float melanin_redness = stack_load_float_default(stack, melanin_redness_ofs, data_node2.w); + + /* Randomize melanin. */ + float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z); + random_color = clamp(random_color, 0.0f, 1.0f); + float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color; + melanin *= factor_random_color; + + /* Map melanin 0..inf from more perceptually linear 0..1. */ + melanin = -logf(fmaxf(1.0f - melanin, 0.0001f)); + + /* Benedikt Bitterli's melanin ratio remapping. */ + float eumelanin = melanin * (1.0f - melanin_redness); + float pheomelanin = melanin * melanin_redness; + float3 melanin_sigma = sigma_from_concentration(eumelanin, pheomelanin); + + /* Optional tint. */ + float3 tint = stack_load_float3(stack, tint_ofs); + float3 tint_sigma = sigma_from_reflectance(tint, radial_roughness); + + bsdf->sigma = melanin_sigma + tint_sigma; + break; + } + case NODE_PRINCIPLED_HAIR_REFLECTANCE: { + float3 color = stack_load_float3(stack, color_ofs); + bsdf->sigma = sigma_from_reflectance(color, radial_roughness); + break; + } + default: { + /* Fallback to brownish hair, same as defaults for melanin. */ + kernel_assert(!"Invalid Principled Hair parametrization!"); + bsdf->sigma = sigma_from_concentration(0.0f, 0.8054375f); + break; + } + } + + sd->flag |= bsdf_principled_hair_setup(sd, bsdf); + } + break; + } case CLOSURE_BSDF_HAIR_REFLECTION_ID: case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { float3 weight = sd->svm_closure_weight * mix_weight; @@ -764,7 +880,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * break; } -#endif +#endif /* __HAIR__ */ #ifdef __SUBSURFACE__ case CLOSURE_BSSRDF_CUBIC_ID: diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index e03ad3a0cfe..910537a2539 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -418,6 +418,13 @@ typedef enum ShaderType { SHADER_TYPE_BUMP, } ShaderType; +typedef enum NodePrincipledHairParametrization { + NODE_PRINCIPLED_HAIR_REFLECTANCE = 0, + NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION = 1, + NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION = 2, + NODE_PRINCIPLED_HAIR_NUM, +} NodePrincipledHairParametrization; + /* Closure */ typedef enum ClosureType { @@ -464,6 +471,7 @@ typedef enum ClosureType { CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID, CLOSURE_BSDF_SHARP_GLASS_ID, + CLOSURE_BSDF_HAIR_PRINCIPLED_ID, CLOSURE_BSDF_HAIR_TRANSMISSION_ID, /* Special cases */ @@ -495,7 +503,7 @@ typedef enum ClosureType { /* watch this, being lazy with memory usage */ #define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID) #define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID) -#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) +#define CLOSURE_IS_BSDF_GLOSSY(type) ((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID )|| (type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID)) #define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID) #define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID) #define CLOSURE_IS_BSDF_SINGULAR(type) (type == CLOSURE_BSDF_REFLECTION_ID || \ diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 78a2039c423..3a9e2981418 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -1091,6 +1091,9 @@ int ShaderGraph::get_num_closures() else if(CLOSURE_IS_VOLUME(closure_type)) { num_closures += VOLUME_STACK_SIZE; } + else if(closure_type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) { + num_closures += 4; + } else { ++num_closures; } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 986004433e4..96e7459a48c 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3092,6 +3092,139 @@ void PrincipledVolumeNode::compile(OSLCompiler& compiler) compiler.add(this, "node_principled_volume"); } +/* Principled Hair BSDF Closure */ + +NODE_DEFINE(PrincipledHairBsdfNode) +{ + NodeType* type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER); + + /* Color parametrization specified as enum. */ + static NodeEnum parametrization_enum; + parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE); + parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION); + parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION); + SOCKET_ENUM(parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE); + + /* Initialize sockets to their default values. */ + SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f)); + SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f); + SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f); + SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f)); + SOCKET_IN_VECTOR(absorption_coefficient, "Absorption Coefficient", make_float3(0.245531f, 0.52f, 1.365f), SocketType::VECTOR); + + SOCKET_IN_FLOAT(offset, "Offset", 2.f*M_PI_F/180.f); + SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); + SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f); + SOCKET_IN_FLOAT(coat, "Coat", 0.0f); + SOCKET_IN_FLOAT(ior, "IOR", 1.55f); + + SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f); + SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f); + SOCKET_IN_FLOAT(random, "Random", 0.0f); + + SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL); + SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL); + + SOCKET_OUT_CLOSURE(BSDF, "BSDF"); + + return type; +} + +PrincipledHairBsdfNode::PrincipledHairBsdfNode() +: BsdfBaseNode(node_type) +{ + closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID; +} + +/* Enable retrieving Hair Info -> Random if Random isn't linked. */ +void PrincipledHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) +{ + if(!input("Random")->link) { + attributes->add(ATTR_STD_CURVE_RANDOM); + } + ShaderNode::attributes(shader, attributes); +} + +/* Prepares the input data for the SVM shader. */ +void PrincipledHairBsdfNode::compile(SVMCompiler& compiler) +{ + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, make_float3(1.0f, 1.0f, 1.0f)); + + ShaderInput *roughness_in = input("Roughness"); + ShaderInput *radial_roughness_in = input("Radial Roughness"); + ShaderInput *random_roughness_in = input("Random Roughness"); + ShaderInput *offset_in = input("Offset"); + ShaderInput *coat_in = input("Coat"); + ShaderInput *ior_in = input("IOR"); + ShaderInput *melanin_in = input("Melanin"); + ShaderInput *melanin_redness_in = input("Melanin Redness"); + ShaderInput *random_color_in = input("Random Color"); + + int color_ofs = compiler.stack_assign(input("Color")); + int tint_ofs = compiler.stack_assign(input("Tint")); + int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient")); + + ShaderInput *random_in = input("Random"); + int attr_random = random_in->link ? SVM_STACK_INVALID : compiler.attribute(ATTR_STD_CURVE_RANDOM); + + /* Encode all parameters into data nodes. */ + compiler.add_node(NODE_CLOSURE_BSDF, + /* Socket IDs can be packed 4 at a time into a single data packet */ + compiler.encode_uchar4(closure, + compiler.stack_assign_if_linked(roughness_in), + compiler.stack_assign_if_linked(radial_roughness_in), + compiler.closure_mix_weight_offset()), + /* The rest are stored as unsigned integers */ + __float_as_uint(roughness), + __float_as_uint(radial_roughness)); + + compiler.add_node(compiler.stack_assign_if_linked(input("Normal")), + compiler.encode_uchar4( + compiler.stack_assign_if_linked(offset_in), + compiler.stack_assign_if_linked(ior_in), + color_ofs, + parametrization), + __float_as_uint(offset), + __float_as_uint(ior)); + + compiler.add_node( + compiler.encode_uchar4( + compiler.stack_assign_if_linked(coat_in), + compiler.stack_assign_if_linked(melanin_in), + compiler.stack_assign_if_linked(melanin_redness_in), + absorption_coefficient_ofs), + __float_as_uint(coat), + __float_as_uint(melanin), + __float_as_uint(melanin_redness)); + + compiler.add_node( + compiler.encode_uchar4( + tint_ofs, + compiler.stack_assign_if_linked(random_in), + compiler.stack_assign_if_linked(random_color_in), + compiler.stack_assign_if_linked(random_roughness_in)), + __float_as_uint(random), + __float_as_uint(random_color), + __float_as_uint(random_roughness)); + + compiler.add_node( + compiler.encode_uchar4( + SVM_STACK_INVALID, + SVM_STACK_INVALID, + SVM_STACK_INVALID, + SVM_STACK_INVALID), + attr_random, + SVM_STACK_INVALID, + SVM_STACK_INVALID); +} + +/* Prepares the input data for the OSL shader. */ +void PrincipledHairBsdfNode::compile(OSLCompiler& compiler) +{ + compiler.parameter(this, "parametrization"); + compiler.add(this, "node_principled_hair_bsdf"); +} + /* Hair BSDF Closure */ NODE_DEFINE(HairBsdfNode) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index ebe6db6e362..28bbe2de05a 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -608,6 +608,45 @@ public: float temperature; }; +/* Interface between the I/O sockets and the SVM/OSL backend. */ +class PrincipledHairBsdfNode : public BsdfBaseNode { +public: + SHADER_NODE_CLASS(PrincipledHairBsdfNode) + void attributes(Shader *shader, AttributeRequestSet *attributes); + + /* Longitudinal roughness. */ + float roughness; + /* Azimuthal roughness. */ + float radial_roughness; + /* Randomization factor for roughnesses. */ + float random_roughness; + /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */ + float coat; + /* Index of reflection. */ + float ior; + /* Cuticle tilt angle. */ + float offset; + /* Direct coloring's color. */ + float3 color; + /* Melanin concentration. */ + float melanin; + /* Melanin redness ratio. */ + float melanin_redness; + /* Dye color. */ + float3 tint; + /* Randomization factor for melanin quantities. */ + float random_color; + /* Absorption coefficient (unfiltered). */ + float3 absorption_coefficient; + + float3 normal; + float surface_mix_weight; + /* If linked, here will be the given random number. */ + float random; + /* Selected coloring parametrization. */ + NodePrincipledHairParametrization parametrization; +}; + class HairBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(HairBsdfNode) diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 85cbd18b7ba..52aeb8d8599 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -55,6 +55,15 @@ CCL_NAMESPACE_BEGIN #ifndef M_2_PI_F # define M_2_PI_F (0.6366197723675813f) /* 2/pi */ #endif +#ifndef M_1_2PI_F +# define M_1_2PI_F (0.1591549430918953f) /* 1/(2*pi) */ +#endif +#ifndef M_SQRT_PI_8_F +# define M_SQRT_PI_8_F (0.6266570686577501f) /* sqrt(pi/8) */ +#endif +#ifndef M_LN_2PI_F +# define M_LN_2PI_F (1.8378770664093454f) /* ln(2*pi) */ +#endif /* Multiplication */ #ifndef M_2PI_F @@ -541,6 +550,16 @@ ccl_device_inline float sqr(float a) return a * a; } +ccl_device_inline float pow20(float a) +{ + return sqr(sqr(sqr(sqr(a))*a)); +} + +ccl_device_inline float pow22(float a) +{ + return sqr(a*sqr(sqr(sqr(a))*a)); +} + ccl_device_inline float beta(float x, float y) { #ifndef __KERNEL_OPENCL__ diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index 3a5a2ab2244..ba1c117cdea 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -382,6 +382,16 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b) #endif } +ccl_device_inline float3 exp3(float3 v) +{ + return make_float3(expf(v.x), expf(v.y), expf(v.z)); +} + +ccl_device_inline float3 log3(float3 v) +{ + return make_float3(logf(v.x), logf(v.y), logf(v.z)); +} + ccl_device_inline int3 quick_floor_to_int3(const float3 a) { #ifdef __KERNEL_SSE__ diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index c9a15f12f7c..4f4190da30b 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -246,6 +246,7 @@ shader_node_categories = [ NodeItem("ShaderNodeVolumeAbsorption"), NodeItem("ShaderNodeVolumeScatter"), NodeItem("ShaderNodeVolumePrincipled"), + NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_shader_nodes_poll) ]), ShaderNewNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 8e54c6a87c4..23ef45416f7 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -794,6 +794,8 @@ struct ShadeResult; #define SH_NODE_DISPLACEMENT 198 #define SH_NODE_VECTOR_DISPLACEMENT 199 #define SH_NODE_VOLUME_PRINCIPLED 200 +/* 201..700 occupied by other node types, continue from 701 */ +#define SH_NODE_BSDF_HAIR_PRINCIPLED 701 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f15d90100d2..c830917a547 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3622,6 +3622,7 @@ static void registerShaderNodes(void) register_node_type_sh_bsdf_velvet(); register_node_type_sh_bsdf_toon(); register_node_type_sh_bsdf_hair(); + register_node_type_sh_bsdf_hair_principled(); register_node_type_sh_emission(); register_node_type_sh_holdout(); register_node_type_sh_volume_absorption(); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 23df1b72c37..6e52af2898e 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1111,6 +1111,11 @@ static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), Pointer uiItemR(layout, ptr, "component", 0, "", ICON_NONE); } +static void node_shader_buts_principled_hair(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "parametrization", 0, "", ICON_NONE); +} + static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *row; @@ -1301,6 +1306,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_BSDF_HAIR: ntype->draw_buttons = node_shader_buts_hair; break; + case SH_NODE_BSDF_HAIR_PRINCIPLED: + ntype->draw_buttons = node_shader_buts_principled_hair; + break; case SH_NODE_SCRIPT: ntype->draw_buttons = node_shader_buts_script; ntype->draw_buttons_ex = node_shader_buts_script_ex; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 00758bd1379..5c692cf85da 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -963,6 +963,11 @@ typedef struct NodeCryptomatte { #define SHD_HAIR_REFLECTION 0 #define SHD_HAIR_TRANSMISSION 1 +/* principled hair parametrization */ +#define SHD_PRINCIPLED_HAIR_REFLECTANCE 0 +#define SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION 1 +#define SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION 2 + /* blend texture */ #define SHD_BLEND_LINEAR 0 #define SHD_BLEND_QUADRATIC 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 52fbadd0f54..b41e9b1c4e5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3350,6 +3350,13 @@ static const EnumPropertyItem node_hair_items[] = { {0, NULL, 0, NULL, NULL} }; +static const EnumPropertyItem node_principled_hair_items[] = { + {SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION, "ABSORPTION", 0, "Absorption coefficient", "Directly set the absorption coefficient sigma_a. This is not the most intuitive way to color hair."}, + {SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION, "MELANIN", 0, "Melanin concentration", "Define the melanin concentrations below to get the most realistic-looking hair. You can get the concentrations for different types of hair online."}, + {SHD_PRINCIPLED_HAIR_REFLECTANCE, "COLOR", 0, "Direct coloring", "Choose the color of your preference, and the shader will approximate the absorption coefficient to render lookalike hair."}, + {0, NULL, 0, NULL, NULL} +}; + static const EnumPropertyItem node_script_mode_items[] = { {NODE_SCRIPT_INTERNAL, "INTERNAL", 0, "Internal", "Use internal text data-block"}, {NODE_SCRIPT_EXTERNAL, "EXTERNAL", 0, "External", "Use external .osl or .oso file"}, @@ -4409,6 +4416,21 @@ static void def_hair(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +/* RNA initialization for the custom property. */ +static void def_hair_principled(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "parametrization", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_ui_text(prop, "Color parametrization", "Select the shader's color parametrization"); + RNA_def_property_enum_items(prop, node_principled_hair_items); + RNA_def_property_enum_default(prop, SHD_PRINCIPLED_HAIR_REFLECTANCE); + /* Upon editing, update both the node data AND the UI representation */ + /* (This effectively shows/hides the relevant sockets) */ + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); +} + static void def_sh_uvmap(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 5a5d5997878..7ef41b25de8 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -173,6 +173,7 @@ set(SRC shader/nodes/node_shader_bsdf_transparent.c shader/nodes/node_shader_bsdf_velvet.c shader/nodes/node_shader_bsdf_hair.c + shader/nodes/node_shader_bsdf_hair_principled.c shader/nodes/node_shader_bump.c shader/nodes/node_shader_emission.c shader/nodes/node_shader_fresnel.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index ca604363e35..d4134f09597 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -116,6 +116,7 @@ void register_node_type_sh_volume_absorption(void); void register_node_type_sh_volume_scatter(void); void register_node_type_sh_volume_principled(void); void register_node_type_sh_bsdf_hair(void); +void register_node_type_sh_bsdf_hair_principled(void); void register_node_type_sh_subsurface_scattering(void); void register_node_type_sh_mix_shader(void); void register_node_type_sh_add_shader(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index a4f8a798576..2fa8cda56a5 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -89,6 +89,7 @@ DefNode( ShaderNode, SH_NODE_BSDF_TRANSPARENT, 0, "BS DefNode( ShaderNode, SH_NODE_BSDF_VELVET, 0, "BSDF_VELVET", BsdfVelvet, "Velvet BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_TOON, def_toon, "BSDF_TOON", BsdfToon, "Toon BSDF", "" ) DefNode( ShaderNode, SH_NODE_BSDF_HAIR, def_hair, "BSDF_HAIR", BsdfHair, "Hair BSDF", "" ) +DefNode( ShaderNode, SH_NODE_BSDF_HAIR_PRINCIPLED, def_hair_principled, "BSDF_HAIR_PRINCIPLED", BsdfHairPrincipled, "Principled Hair BSDF", "") DefNode( ShaderNode, SH_NODE_SUBSURFACE_SCATTERING, def_sh_subsurface, "SUBSURFACE_SCATTERING",SubsurfaceScattering,"Subsurface Scattering","") DefNode( ShaderNode, SH_NODE_VOLUME_ABSORPTION, 0, "VOLUME_ABSORPTION", VolumeAbsorption, "Volume Absorption", "" ) DefNode( ShaderNode, SH_NODE_VOLUME_SCATTER, 0, "VOLUME_SCATTER", VolumeScatter, "Volume Scatter", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c new file mode 100644 index 00000000000..c5029852033 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c @@ -0,0 +1,133 @@ +/* + * ***** 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) 2018 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Lukas Stockner, L. E. Segovia + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +/* Color, melanin and absorption coefficient default to approximately same brownish hair. */ +static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = { + { SOCK_RGBA, 1, N_("Color"), 0.017513f, 0.005763f, 0.002059f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Melanin"), 0.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Melanin Redness"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, N_("Tint"), 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Absorption Coefficient"), 0.245531f, 0.52f, 1.365f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 1, N_("Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 1, N_("Offset"), 2.f*((float)M_PI)/180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, + { SOCK_FLOAT, 1, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_FLOAT, 1, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" }, +}; + +static bNodeSocketTemplate sh_node_bsdf_hair_principled_out[] = { + { SOCK_SHADER, 0, N_("BSDF")}, + { -1, 0, "" } +}; + +/* Initialize the custom Parametrization property to Color. */ +static void node_shader_init_hair_principled(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_PRINCIPLED_HAIR_REFLECTANCE; +} + +/* Triggers (in)visibility of some sockets when changing Parametrization. */ +static void node_shader_update_hair_principled(bNodeTree *UNUSED(ntree), bNode *node) +{ + bNodeSocket *sock; + int parametrization = node->custom1; + + for (sock = node->inputs.first; sock; sock = sock->next) { + if (STREQ(sock->name, "Color")) { + if (parametrization == SHD_PRINCIPLED_HAIR_REFLECTANCE) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Melanin")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Melanin Redness")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Tint")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Absorption Coefficient")) { + if (parametrization == SHD_PRINCIPLED_HAIR_DIRECT_ABSORPTION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + else if (STREQ(sock->name, "Random Color")) { + if (parametrization == SHD_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION) { + sock->flag &= ~SOCK_UNAVAIL; + } + else { + sock->flag |= SOCK_UNAVAIL; + } + } + } +} + +/* node type definition */ +void register_node_type_sh_bsdf_hair_principled(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_BSDF_HAIR_PRINCIPLED, "Principled Hair BSDF", NODE_CLASS_SHADER, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_bsdf_hair_principled_in, sh_node_bsdf_hair_principled_out); + node_type_size_preset(&ntype, NODE_SIZE_LARGE); + node_type_init(&ntype, node_shader_init_hair_principled); + node_type_storage(&ntype, "", NULL, NULL); + node_type_update(&ntype, node_shader_update_hair_principled, NULL); + + nodeRegisterType(&ntype); +} -- cgit v1.2.3 From 257d072317f21861cdb7c168a60497bcb74d73d4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jul 2018 22:03:52 +1000 Subject: 3D View: show 3D axis-letter when pointing away While only the positive axis is shown, account for an exception when axis aligned. --- source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 238a956cf26..93617f22490 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -241,6 +241,9 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U ok = false; } if (ok) { + /* Check aligned, since the front axis won't display in this case, + * and we want to make sure all 3 axes have a character at all times. */ + const bool show_axis_char = (is_pos || (axis == axis_align)); const float v[3] = {0, 0, 3 * (is_pos ? 1 : -1)}; const float v_final[3] = { v[index_x] * scale_axis, @@ -278,7 +281,7 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U { GPU_matrix_push(); GPU_matrix_translate_3fv(v_final); - GPU_matrix_scale_1f(is_pos ? 0.22f : 0.18f); + GPU_matrix_scale_1f(show_axis_char ? 0.22f : 0.18f); GPUBatch *sphere = GPU_batch_preset_sphere(0); GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); @@ -288,7 +291,7 @@ static void axis_geom_draw(const wmGizmo *gz, const float color[4], const bool U } /* Axis XYZ Character. */ - if (is_pos) { + if (show_axis_char) { GPU_line_width(1.0f); float m3[3][3]; copy_m3_m4(m3, gz->matrix_offset); -- cgit v1.2.3 From f882df9e0f9de99c37558ce375ce681c148eac82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jul 2018 14:58:32 +0200 Subject: GPU: Fix build error on Mac and Windows. --- source/blender/gpu/GPU_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h index cb506c6b0bc..7d86a6ec8a5 100644 --- a/source/blender/gpu/GPU_common.h +++ b/source/blender/gpu/GPU_common.h @@ -43,9 +43,9 @@ #include #endif -#include #include #include +#include "BLI_sys_types.h" #if TRUST_NO_ONE #include -- cgit v1.2.3 From 428743a9b06cc09b4eb4dd3e7794d45d13457fb8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jul 2018 23:09:31 +1000 Subject: Cleanup: style for GPU module --- source/blender/gpu/GPU_batch.h | 84 ++++----- source/blender/gpu/GPU_context.h | 8 +- source/blender/gpu/GPU_element.h | 28 +-- source/blender/gpu/GPU_framebuffer.h | 3 +- source/blender/gpu/GPU_immediate.h | 32 ++-- source/blender/gpu/GPU_material.h | 7 +- source/blender/gpu/GPU_shader.h | 12 +- source/blender/gpu/GPU_shader_interface.h | 30 ++-- source/blender/gpu/GPU_state.h | 2 +- source/blender/gpu/GPU_vertex_array_id.h | 2 +- source/blender/gpu/GPU_vertex_buffer.h | 38 ++--- source/blender/gpu/GPU_vertex_format.h | 14 +- source/blender/gpu/intern/gpu_attr_binding.c | 12 +- source/blender/gpu/intern/gpu_basic_shader.c | 18 +- source/blender/gpu/intern/gpu_batch.c | 124 +++++++------- source/blender/gpu/intern/gpu_buffers.c | 66 ++++---- source/blender/gpu/intern/gpu_codegen.c | 207 +++++++++++++---------- source/blender/gpu/intern/gpu_draw.c | 138 ++++++++------- source/blender/gpu/intern/gpu_element.c | 34 ++-- source/blender/gpu/intern/gpu_framebuffer.c | 47 ++--- source/blender/gpu/intern/gpu_immediate.c | 92 +++++----- source/blender/gpu/intern/gpu_immediate_util.c | 46 ++--- source/blender/gpu/intern/gpu_material.c | 17 +- source/blender/gpu/intern/gpu_matrix.c | 2 +- source/blender/gpu/intern/gpu_select.c | 2 +- source/blender/gpu/intern/gpu_shader.c | 104 +++++++----- source/blender/gpu/intern/gpu_shader_interface.c | 92 +++++----- source/blender/gpu/intern/gpu_state.c | 9 +- source/blender/gpu/intern/gpu_texture.c | 26 +-- source/blender/gpu/intern/gpu_vertex_buffer.c | 58 +++---- source/blender/gpu/intern/gpu_vertex_format.c | 28 +-- 31 files changed, 739 insertions(+), 643 deletions(-) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index bd0e3b43e6c..bb67a90d619 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -51,15 +51,15 @@ typedef enum { typedef struct GPUBatch { /* geometry */ - GPUVertBuf* verts[GPU_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ - GPUVertBuf* inst; /* instance attribs */ - GPUIndexBuf* elem; /* NULL if element list not needed */ + GPUVertBuf *verts[GPU_BATCH_VBO_MAX_LEN]; /* verts[0] is required, others can be NULL */ + GPUVertBuf *inst; /* instance attribs */ + GPUIndexBuf *elem; /* NULL if element list not needed */ uint32_t gl_prim_type; /* cached values (avoid dereferencing later) */ uint32_t vao_id; uint32_t program; - const struct GPUShaderInterface* interface; + const struct GPUShaderInterface *interface; /* book-keeping */ uint owns_flag; @@ -74,21 +74,21 @@ typedef struct GPUBatch { union { /* Static handle count */ struct { - const struct GPUShaderInterface* interfaces[GPU_BATCH_VAO_STATIC_LEN]; + const struct GPUShaderInterface *interfaces[GPU_BATCH_VAO_STATIC_LEN]; uint32_t vao_ids[GPU_BATCH_VAO_STATIC_LEN]; } static_vaos; /* Dynamic handle count */ struct { uint count; - const struct GPUShaderInterface** interfaces; - uint32_t* vao_ids; + const struct GPUShaderInterface **interfaces; + uint32_t *vao_ids; } dynamic_vaos; }; /* XXX This is the only solution if we want to have some data structure using * batches as key to identify nodes. We must destroy these nodes with this callback. */ - void (*free_callback)(struct GPUBatch*, void*); - void* callback_data; + void (*free_callback)(struct GPUBatch *, void *); + void *callback_data; } GPUBatch; enum { @@ -98,55 +98,55 @@ enum { GPU_BATCH_OWNS_INDEX = (1 << 31), }; -GPUBatch* GPU_batch_create_ex(GPUPrimType, GPUVertBuf*, GPUIndexBuf*, uint owns_flag); -void GPU_batch_init_ex(GPUBatch*, GPUPrimType, GPUVertBuf*, GPUIndexBuf*, uint owns_flag); -GPUBatch* GPU_batch_duplicate(GPUBatch* batch_src); +GPUBatch *GPU_batch_create_ex(GPUPrimType, GPUVertBuf *, GPUIndexBuf *, uint owns_flag); +void GPU_batch_init_ex(GPUBatch *, GPUPrimType, GPUVertBuf *, GPUIndexBuf *, uint owns_flag); +GPUBatch *GPU_batch_duplicate(GPUBatch *batch_src); #define GPU_batch_create(prim, verts, elem) \ GPU_batch_create_ex(prim, verts, elem, 0) #define GPU_batch_init(batch, prim, verts, elem) \ GPU_batch_init_ex(batch, prim, verts, elem, 0) -void GPU_batch_discard(GPUBatch*); /* verts & elem are not discarded */ +void GPU_batch_discard(GPUBatch *); /* verts & elem are not discarded */ -void GPU_batch_vao_cache_clear(GPUBatch*); +void GPU_batch_vao_cache_clear(GPUBatch *); -void GPU_batch_callback_free_set(GPUBatch*, void (*callback)(GPUBatch*, void*), void*); +void GPU_batch_callback_free_set(GPUBatch *, void (*callback)(GPUBatch *, void *), void *); -void GPU_batch_instbuf_set(GPUBatch*, GPUVertBuf*, bool own_vbo); /* Instancing */ +void GPU_batch_instbuf_set(GPUBatch *, GPUVertBuf *, bool own_vbo); /* Instancing */ -int GPU_batch_vertbuf_add_ex(GPUBatch*, GPUVertBuf*, bool own_vbo); +int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); #define GPU_batch_vertbuf_add(batch, verts) \ GPU_batch_vertbuf_add_ex(batch, verts, false) -void GPU_batch_program_set_no_use(GPUBatch*, uint32_t program, const GPUShaderInterface*); -void GPU_batch_program_set(GPUBatch*, uint32_t program, const GPUShaderInterface*); +void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *); +void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *); void GPU_batch_program_set_builtin(GPUBatch *batch, GPUBuiltinShader shader_id); /* Entire batch draws with one shader program, but can be redrawn later with another program. */ /* Vertex shader's inputs must be compatible with the batch's vertex format. */ -void GPU_batch_program_use_begin(GPUBatch*); /* call before Batch_Uniform (temp hack?) */ -void GPU_batch_program_use_end(GPUBatch*); - -void GPU_batch_uniform_1ui(GPUBatch*, const char* name, int value); -void GPU_batch_uniform_1i(GPUBatch*, const char* name, int value); -void GPU_batch_uniform_1b(GPUBatch*, const char* name, bool value); -void GPU_batch_uniform_1f(GPUBatch*, const char* name, float value); -void GPU_batch_uniform_2f(GPUBatch*, const char* name, float x, float y); -void GPU_batch_uniform_3f(GPUBatch*, const char* name, float x, float y, float z); -void GPU_batch_uniform_4f(GPUBatch*, const char* name, float x, float y, float z, float w); -void GPU_batch_uniform_2fv(GPUBatch*, const char* name, const float data[2]); -void GPU_batch_uniform_3fv(GPUBatch*, const char* name, const float data[3]); -void GPU_batch_uniform_4fv(GPUBatch*, const char* name, const float data[4]); -void GPU_batch_uniform_2fv_array(GPUBatch*, const char* name, int len, const float *data); -void GPU_batch_uniform_4fv_array(GPUBatch*, const char* name, int len, const float *data); -void GPU_batch_uniform_mat4(GPUBatch*, const char* name, const float data[4][4]); - -void GPU_batch_draw(GPUBatch*); +void GPU_batch_program_use_begin(GPUBatch *); /* call before Batch_Uniform (temp hack?) */ +void GPU_batch_program_use_end(GPUBatch *); + +void GPU_batch_uniform_1ui(GPUBatch *, const char *name, int value); +void GPU_batch_uniform_1i(GPUBatch *, const char *name, int value); +void GPU_batch_uniform_1b(GPUBatch *, const char *name, bool value); +void GPU_batch_uniform_1f(GPUBatch *, const char *name, float value); +void GPU_batch_uniform_2f(GPUBatch *, const char *name, float x, float y); +void GPU_batch_uniform_3f(GPUBatch *, const char *name, float x, float y, float z); +void GPU_batch_uniform_4f(GPUBatch *, const char *name, float x, float y, float z, float w); +void GPU_batch_uniform_2fv(GPUBatch *, const char *name, const float data[2]); +void GPU_batch_uniform_3fv(GPUBatch *, const char *name, const float data[3]); +void GPU_batch_uniform_4fv(GPUBatch *, const char *name, const float data[4]); +void GPU_batch_uniform_2fv_array(GPUBatch *, const char *name, int len, const float *data); +void GPU_batch_uniform_4fv_array(GPUBatch *, const char *name, int len, const float *data); +void GPU_batch_uniform_mat4(GPUBatch *, const char *name, const float data[4][4]); + +void GPU_batch_draw(GPUBatch *); /* This does not bind/unbind shader and does not call GPU_matrix_bind() */ -void GPU_batch_draw_range_ex(GPUBatch*, int v_first, int v_count, bool force_instance); +void GPU_batch_draw_range_ex(GPUBatch *, int v_first, int v_count, bool force_instance); /* Does not even need batch */ void GPU_draw_primitive(GPUPrimType, int v_count); @@ -175,12 +175,12 @@ typedef struct BatchWithOwnVertexBufferAndElementList { GPUVertBuf verts; /* link batch.verts to this */ } BatchWithOwnVertexBufferAndElementList; -GPUBatch* create_BatchWithOwnVertexBuffer(GPUPrimType, GPUVertFormat*, uint v_len, GPUIndexBuf*); -GPUBatch* create_BatchWithOwnElementList(GPUPrimType, GPUVertBuf*, uint prim_len); -GPUBatch* create_BatchWithOwnVertexBufferAndElementList(GPUPrimType, GPUVertFormat*, uint v_len, uint prim_len); +GPUBatch *create_BatchWithOwnVertexBuffer(GPUPrimType, GPUVertFormat *, uint v_len, GPUIndexBuf *); +GPUBatch *create_BatchWithOwnElementList(GPUPrimType, GPUVertBuf *, uint prim_len); +GPUBatch *create_BatchWithOwnVertexBufferAndElementList(GPUPrimType, GPUVertFormat *, uint v_len, uint prim_len); /* verts: shared, own */ /* elem: none, shared, own */ -GPUBatch* create_BatchInGeneral(GPUPrimType, VertexBufferStuff, ElementListStuff); +GPUBatch *create_BatchInGeneral(GPUPrimType, VertexBufferStuff, ElementListStuff); #endif /* future plans */ diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h index 5f63c408801..3e32b64b281 100644 --- a/source/blender/gpu/GPU_context.h +++ b/source/blender/gpu/GPU_context.h @@ -42,11 +42,11 @@ extern "C" { typedef struct GPUContext GPUContext; -GPUContext* GPU_context_create(void); -void GPU_context_discard(GPUContext*); +GPUContext *GPU_context_create(void); +void GPU_context_discard(GPUContext *); -void GPU_context_active_set(GPUContext*); -GPUContext* GPU_context_active_get(void); +void GPU_context_active_set(GPUContext *); +GPUContext *GPU_context_active_get(void); #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_element.h b/source/blender/gpu/GPU_element.h index 508c079fcd3..adc705ab641 100644 --- a/source/blender/gpu/GPU_element.h +++ b/source/blender/gpu/GPU_element.h @@ -57,37 +57,37 @@ typedef struct GPUIndexBuf { bool use_prim_restart; } GPUIndexBuf; -void GPU_indexbuf_use(GPUIndexBuf*); -uint GPU_indexbuf_size_get(const GPUIndexBuf*); +void GPU_indexbuf_use(GPUIndexBuf *); +uint GPU_indexbuf_size_get(const GPUIndexBuf *); typedef struct GPUIndexBufBuilder { uint max_allowed_index; uint max_index_len; uint index_len; GPUPrimType prim_type; - uint* data; + uint *data; bool use_prim_restart; } GPUIndexBufBuilder; /* supports all primitive types. */ -void GPU_indexbuf_init_ex(GPUIndexBufBuilder*, GPUPrimType, uint index_len, uint vertex_len, bool use_prim_restart); +void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len, bool use_prim_restart); /* supports only GPU_PRIM_POINTS, GPU_PRIM_LINES and GPU_PRIM_TRIS. */ -void GPU_indexbuf_init(GPUIndexBufBuilder*, GPUPrimType, uint prim_len, uint vertex_len); +void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len); -void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder*, uint v); -void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder*); +void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v); +void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *); -void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder*, uint v); -void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder*, uint v1, uint v2); -void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder*, uint v1, uint v2, uint v3); -void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder*, uint v1, uint v2, uint v3, uint v4); +void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *, uint v); +void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *, uint v1, uint v2); +void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3); +void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *, uint v1, uint v2, uint v3, uint v4); -GPUIndexBuf* GPU_indexbuf_build(GPUIndexBufBuilder*); -void GPU_indexbuf_build_in_place(GPUIndexBufBuilder*, GPUIndexBuf*); +GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *); +void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *); -void GPU_indexbuf_discard(GPUIndexBuf*); +void GPU_indexbuf_discard(GPUIndexBuf *); /* Macros */ diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index ddf485c3c21..04357d6a927 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -179,7 +179,8 @@ void GPU_framebuffer_recursive_downsample( * - wrapper around framebuffer and texture for simple offscreen drawing */ -GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, +GPUOffScreen *GPU_offscreen_create( + int width, int height, int samples, bool depth, bool high_bitdepth, char err_out[256]); void GPU_offscreen_free(GPUOffScreen *ofs); void GPU_offscreen_bind(GPUOffScreen *ofs, bool save); diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h index a756687b557..c8a4ea6a837 100644 --- a/source/blender/gpu/GPU_immediate.h +++ b/source/blender/gpu/GPU_immediate.h @@ -40,9 +40,9 @@ #include "GPU_immediate_util.h" #include "GPU_shader.h" -GPUVertFormat* immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ +GPUVertFormat *immVertexFormat(void); /* returns a cleared vertex format, ready for add_attrib. */ -void immBindProgram(uint32_t program, const GPUShaderInterface*); /* every immBegin must have a program bound first. */ +void immBindProgram(uint32_t program, const GPUShaderInterface *); /* every immBegin must have a program bound first. */ void immUnbindProgram(void); /* call after your last immEnd, or before binding another program. */ void immBegin(GPUPrimType, uint vertex_len); /* must supply exactly vertex_len vertices. */ @@ -52,8 +52,8 @@ void immEnd(void); /* finishes and draws. */ /* ImmBegin a batch, then use standard immFunctions as usual. */ /* ImmEnd will finalize the batch instead of drawing. */ /* Then you can draw it as many times as you like! Partially replaces the need for display lists. */ -GPUBatch* immBeginBatch(GPUPrimType, uint vertex_len); -GPUBatch* immBeginBatchAtMost(GPUPrimType, uint vertex_len); +GPUBatch *immBeginBatch(GPUPrimType, uint vertex_len); +GPUBatch *immBeginBatchAtMost(GPUPrimType, uint vertex_len); /* Provide attribute values that can change per vertex. */ /* First vertex after immBegin must have all its attributes specified. */ @@ -99,18 +99,18 @@ void immVertex3fv(uint attrib_id, const float data[3]); void immVertex2iv(uint attrib_id, const int data[2]); /* Provide uniform values that don't change for the entire draw call. */ -void immUniform1i(const char* name, int x); -void immUniform4iv(const char* name, const int data[4]); -void immUniform1f(const char* name, float x); -void immUniform2f(const char* name, float x, float y); -void immUniform2fv(const char* name, const float data[2]); -void immUniform3f(const char* name, float x, float y, float z); -void immUniform3fv(const char* name, const float data[3]); -void immUniformArray3fv(const char* name, const float *data, int count); -void immUniform4f(const char* name, float x, float y, float z, float w); -void immUniform4fv(const char* name, const float data[4]); -void immUniformArray4fv(const char* bare_name, const float *data, int count); -void immUniformMatrix4fv(const char* name, const float data[4][4]); +void immUniform1i(const char *name, int x); +void immUniform4iv(const char *name, const int data[4]); +void immUniform1f(const char *name, float x); +void immUniform2f(const char *name, float x, float y); +void immUniform2fv(const char *name, const float data[2]); +void immUniform3f(const char *name, float x, float y, float z); +void immUniform3fv(const char *name, const float data[3]); +void immUniformArray3fv(const char *name, const float *data, int count); +void immUniform4f(const char *name, float x, float y, float z, float w); +void immUniform4fv(const char *name, const float data[4]); +void immUniformArray4fv(const char *bare_name, const float *data, int count); +void immUniformMatrix4fv(const char *name, const float data[4][4]); /* Convenience functions for setting "uniform vec4 color". */ /* The rgb functions have implicit alpha = 1.0. */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 8ddb7b87c4a..4e264defbd4 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -104,7 +104,7 @@ typedef enum GPUBuiltin { GPU_AUTO_BUMPSCALE = (1 << 7), GPU_CAMERA_TEXCO_FACTORS = (1 << 8), GPU_PARTICLE_SCALAR_PROPS = (1 << 9), - GPU_PARTICLE_LOCATION = (1 << 10), + GPU_PARTICLE_LOCATION = (1 << 10), GPU_PARTICLE_VELOCITY = (1 << 11), GPU_PARTICLE_ANG_VELOCITY = (1 << 12), GPU_LOC_TO_VIEW_MATRIX = (1 << 13), @@ -268,8 +268,9 @@ GPUMaterialStatus GPU_material_status(GPUMaterial *mat); struct GPUUniformBuffer *GPU_material_uniform_buffer_get(GPUMaterial *material); void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs); -void GPU_material_vertex_attributes(GPUMaterial *material, - struct GPUVertexAttribs *attrib); +void GPU_material_vertex_attributes( + GPUMaterial *material, + struct GPUVertexAttribs *attrib); bool GPU_material_do_color_management(GPUMaterial *mat); bool GPU_material_use_domain_surface(GPUMaterial *mat); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index f831d495ad0..b1a05faf863 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -89,10 +89,12 @@ void *GPU_shader_get_interface(GPUShader *shader); int GPU_shader_get_uniform(GPUShader *shader, const char *name); int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin); int GPU_shader_get_uniform_block(GPUShader *shader, const char *name); -void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, - int arraysize, const float *value); -void GPU_shader_uniform_vector_int(GPUShader *shader, int location, int length, - int arraysize, const int *value); +void GPU_shader_uniform_vector( + GPUShader *shader, int location, int length, + int arraysize, const float *value); +void GPU_shader_uniform_vector_int( + GPUShader *shader, int location, int length, + int arraysize, const int *value); void GPU_shader_uniform_buffer(GPUShader *shader, int location, struct GPUUniformBuffer *ubo); void GPU_shader_uniform_texture(GPUShader *shader, int location, struct GPUTexture *tex); @@ -375,7 +377,7 @@ typedef struct GPUVertexAttribs { int glinfoindoex; int gltexco; int attribid; - char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ } layer[GPU_MAX_ATTRIB]; int totlayer; diff --git a/source/blender/gpu/GPU_shader_interface.h b/source/blender/gpu/GPU_shader_interface.h index c80cc1021ec..458a49a366b 100644 --- a/source/blender/gpu/GPU_shader_interface.h +++ b/source/blender/gpu/GPU_shader_interface.h @@ -65,7 +65,7 @@ typedef enum { } GPUUniformBuiltin; typedef struct GPUShaderInput { - struct GPUShaderInput* next; + struct GPUShaderInput *next; uint32_t name_offset; uint name_hash; GPUUniformBuiltin builtin_type; /* only for uniform inputs */ @@ -80,25 +80,25 @@ typedef struct GPUShaderInput { typedef struct GPUShaderInterface { int32_t program; uint32_t name_buffer_offset; - GPUShaderInput* attrib_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; - GPUShaderInput* uniform_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; - GPUShaderInput* ubo_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; - GPUShaderInput* builtin_uniforms[GPU_NUM_UNIFORMS]; - char* name_buffer; - struct GPUBatch** batches; /* references to batches using this interface */ + GPUShaderInput *attrib_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput *uniform_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput *ubo_buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]; + GPUShaderInput *builtin_uniforms[GPU_NUM_UNIFORMS]; + char *name_buffer; + struct GPUBatch **batches; /* references to batches using this interface */ uint batches_len; } GPUShaderInterface; -GPUShaderInterface* GPU_shaderinterface_create(int32_t program_id); -void GPU_shaderinterface_discard(GPUShaderInterface*); +GPUShaderInterface *GPU_shaderinterface_create(int32_t program_id); +void GPU_shaderinterface_discard(GPUShaderInterface *); -const GPUShaderInput* GPU_shaderinterface_uniform(const GPUShaderInterface*, const char* name); -const GPUShaderInput* GPU_shaderinterface_uniform_builtin(const GPUShaderInterface*, GPUUniformBuiltin); -const GPUShaderInput* GPU_shaderinterface_ubo(const GPUShaderInterface*, const char* name); -const GPUShaderInput* GPU_shaderinterface_attr(const GPUShaderInterface*, const char* name); +const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *, const char *name); +const GPUShaderInput *GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *, GPUUniformBuiltin); +const GPUShaderInput *GPU_shaderinterface_ubo(const GPUShaderInterface *, const char *name); +const GPUShaderInput *GPU_shaderinterface_attr(const GPUShaderInterface *, const char *name); /* keep track of batches using this interface */ -void GPU_shaderinterface_add_batch_ref(GPUShaderInterface*, struct GPUBatch*); -void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface*, struct GPUBatch*); +void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *, struct GPUBatch *); +void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface *, struct GPUBatch *); #endif /* __GPU_SHADER_INTERFACE_H__ */ diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h index 2d7ab6cd54c..16627fec42b 100644 --- a/source/blender/gpu/GPU_state.h +++ b/source/blender/gpu/GPU_state.h @@ -27,7 +27,7 @@ #ifndef __GPU_STATE_H__ #define __GPU_STATE_H__ - /* These map directly to the GL_ blend functions, to minimize API add as needed*/ +/* These map directly to the GL_ blend functions, to minimize API add as needed*/ typedef enum GPUBlendFunction { GPU_ONE, GPU_SRC_ALPHA, diff --git a/source/blender/gpu/GPU_vertex_array_id.h b/source/blender/gpu/GPU_vertex_array_id.h index 3b3fdc1709d..ff84a290a5a 100644 --- a/source/blender/gpu/GPU_vertex_array_id.h +++ b/source/blender/gpu/GPU_vertex_array_id.h @@ -46,7 +46,7 @@ extern "C" { GLuint GPU_vao_default(void); GLuint GPU_vao_alloc(void); -void GPU_vao_free(GLuint vao_id, GPUContext*); +void GPU_vao_free(GLuint vao_id, GPUContext *); #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index 896de387065..db1309bcede 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -55,54 +55,54 @@ typedef struct GPUVertBuf { uint vertex_len; /* number of verts we want to draw */ uint vertex_alloc; /* number of verts data */ bool dirty; - unsigned char* data; /* NULL indicates data in VRAM (unmapped) */ + unsigned char *data; /* NULL indicates data in VRAM (unmapped) */ uint32_t vbo_id; /* 0 indicates not yet allocated */ GPUUsageType usage; /* usage hint for GL optimisation */ } GPUVertBuf; -GPUVertBuf* GPU_vertbuf_create(GPUUsageType); -GPUVertBuf* GPU_vertbuf_create_with_format_ex(const GPUVertFormat*, GPUUsageType); +GPUVertBuf *GPU_vertbuf_create(GPUUsageType); +GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *, GPUUsageType); #define GPU_vertbuf_create_with_format(format) \ GPU_vertbuf_create_with_format_ex(format, GPU_USAGE_STATIC) -void GPU_vertbuf_discard(GPUVertBuf*); +void GPU_vertbuf_discard(GPUVertBuf *); -void GPU_vertbuf_init(GPUVertBuf*, GPUUsageType); -void GPU_vertbuf_init_with_format_ex(GPUVertBuf*, const GPUVertFormat*, GPUUsageType); +void GPU_vertbuf_init(GPUVertBuf *, GPUUsageType); +void GPU_vertbuf_init_with_format_ex(GPUVertBuf *, const GPUVertFormat *, GPUUsageType); #define GPU_vertbuf_init_with_format(verts, format) \ GPU_vertbuf_init_with_format_ex(verts, format, GPU_USAGE_STATIC) -uint GPU_vertbuf_size_get(const GPUVertBuf*); -void GPU_vertbuf_data_alloc(GPUVertBuf*, uint v_len); -void GPU_vertbuf_data_resize(GPUVertBuf*, uint v_len); -void GPU_vertbuf_vertex_count_set(GPUVertBuf*, uint v_len); +uint GPU_vertbuf_size_get(const GPUVertBuf *); +void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len); +void GPU_vertbuf_data_resize(GPUVertBuf *, uint v_len); +void GPU_vertbuf_vertex_count_set(GPUVertBuf *, uint v_len); /* The most important set_attrib variant is the untyped one. Get it right first. */ /* It takes a void* so the app developer is responsible for matching their app data types */ /* to the vertex attribute's type and component count. They're in control of both, so this */ /* should not be a problem. */ -void GPU_vertbuf_attr_set(GPUVertBuf*, uint a_idx, uint v_idx, const void* data); -void GPU_vertbuf_attr_fill(GPUVertBuf*, uint a_idx, const void* data); /* tightly packed, non interleaved input data */ -void GPU_vertbuf_attr_fill_stride(GPUVertBuf*, uint a_idx, uint stride, const void* data); +void GPU_vertbuf_attr_set(GPUVertBuf *, uint a_idx, uint v_idx, const void *data); +void GPU_vertbuf_attr_fill(GPUVertBuf *, uint a_idx, const void *data); /* tightly packed, non interleaved input data */ +void GPU_vertbuf_attr_fill_stride(GPUVertBuf *, uint a_idx, uint stride, const void *data); /* For low level access only */ typedef struct GPUVertBufRaw { uint size; uint stride; - unsigned char* data; - unsigned char* data_init; + unsigned char *data; + unsigned char *data_init; #if TRUST_NO_ONE /* Only for overflow check */ - unsigned char* _data_end; + unsigned char *_data_end; #endif } GPUVertBufRaw; GPU_INLINE void *GPU_vertbuf_raw_step(GPUVertBufRaw *a) { - unsigned char* data = a->data; + unsigned char *data = a->data; a->data += a->stride; #if TRUST_NO_ONE assert(data < a->_data_end); @@ -115,7 +115,7 @@ GPU_INLINE uint GPU_vertbuf_raw_used(GPUVertBufRaw *a) return ((a->data - a->data_init) / a->stride); } -void GPU_vertbuf_attr_get_raw_data(GPUVertBuf*, uint a_idx, GPUVertBufRaw *access); +void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access); /* TODO: decide whether to keep the functions below */ /* doesn't immediate mode satisfy these needs? */ @@ -128,7 +128,7 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf*, uint a_idx, GPUVertBufRaw *acces /* void setAttrib3ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b); */ /* void setAttrib4ub(unsigned a_idx, unsigned v_idx, unsigned char r, unsigned char g, unsigned char b, unsigned char a); */ -void GPU_vertbuf_use(GPUVertBuf*); +void GPU_vertbuf_use(GPUVertBuf *); /* Metrics */ uint GPU_vertbuf_get_memory_usage(void); diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h index 7ae8118a928..7e0038e3473 100644 --- a/source/blender/gpu/GPU_vertex_format.h +++ b/source/blender/gpu/GPU_vertex_format.h @@ -67,7 +67,7 @@ typedef struct GPUVertAttr { uint sz; /* size in bytes, 1 to 64 */ uint offset; /* from beginning of vertex, in bytes */ uint name_len; /* up to GPU_VERT_ATTR_MAX_NAMES */ - const char* name[GPU_VERT_ATTR_MAX_NAMES]; + const char *name[GPU_VERT_ATTR_MAX_NAMES]; } GPUVertAttr; typedef struct GPUVertFormat { @@ -80,11 +80,13 @@ typedef struct GPUVertFormat { GPUVertAttr attribs[GPU_VERT_ATTR_MAX_LEN]; /* TODO: variable-size attribs array */ } GPUVertFormat; -void GPU_vertformat_clear(GPUVertFormat*); -void GPU_vertformat_copy(GPUVertFormat* dest, const GPUVertFormat* src); +void GPU_vertformat_clear(GPUVertFormat *); +void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src); -uint GPU_vertformat_attr_add(GPUVertFormat*, const char* name, GPUVertCompType, uint comp_len, GPUVertFetchMode); -void GPU_vertformat_alias_add(GPUVertFormat*, const char* alias); +uint GPU_vertformat_attr_add( + GPUVertFormat *, const char *name, + GPUVertCompType, uint comp_len, GPUVertFetchMode); +void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias); /* format conversion */ @@ -92,7 +94,7 @@ typedef struct GPUPackedNormal { int x : 10; int y : 10; int z : 10; - int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ + int w : 2; /* 0 by default, can manually set to { -2, -1, 0, 1 } */ } GPUPackedNormal; GPUPackedNormal GPU_normal_convert_i10_v3(const float data[3]); diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.c index 9ac38578792..e66fac390f1 100644 --- a/source/blender/gpu/intern/gpu_attr_binding.c +++ b/source/blender/gpu/intern/gpu_attr_binding.c @@ -38,13 +38,13 @@ #error "attrib binding code assumes GPU_VERT_ATTR_MAX_LEN = 16" #endif -void AttribBinding_clear(GPUAttrBinding* binding) +void AttribBinding_clear(GPUAttrBinding *binding) { binding->loc_bits = 0; binding->enabled_bits = 0; } -uint read_attrib_location(const GPUAttrBinding* binding, uint a_idx) +uint read_attrib_location(const GPUAttrBinding *binding, uint a_idx) { #if TRUST_NO_ONE assert(a_idx < GPU_VERT_ATTR_MAX_LEN); @@ -53,7 +53,7 @@ uint read_attrib_location(const GPUAttrBinding* binding, uint a_idx) return (binding->loc_bits >> (4 * a_idx)) & 0xF; } -static void write_attrib_location(GPUAttrBinding* binding, uint a_idx, uint location) +static void write_attrib_location(GPUAttrBinding *binding, uint a_idx, uint location) { #if TRUST_NO_ONE assert(a_idx < GPU_VERT_ATTR_MAX_LEN); @@ -67,14 +67,14 @@ static void write_attrib_location(GPUAttrBinding* binding, uint a_idx, uint loca binding->enabled_bits |= 1 << a_idx; } -void get_attrib_locations(const GPUVertFormat* format, GPUAttrBinding* binding, const GPUShaderInterface* shaderface) +void get_attrib_locations(const GPUVertFormat *format, GPUAttrBinding *binding, const GPUShaderInterface *shaderface) { AttribBinding_clear(binding); for (uint a_idx = 0; a_idx < format->attr_len; ++a_idx) { - const GPUVertAttr* a = format->attribs + a_idx; + const GPUVertAttr *a = format->attribs + a_idx; for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const GPUShaderInput* input = GPU_shaderinterface_attr(shaderface, a->name[n_idx]); + const GPUShaderInput *input = GPU_shaderinterface_attr(shaderface, a->name[n_idx]); #if TRUST_NO_ONE assert(input != NULL); /* TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program */ diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c index b720bed2d0c..61e8cf87038 100644 --- a/source/blender/gpu/intern/gpu_basic_shader.c +++ b/source/blender/gpu/intern/gpu_basic_shader.c @@ -82,7 +82,8 @@ const GLubyte stipple_halftone[128] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, - 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55}; + 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, +}; const GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, @@ -92,7 +93,8 @@ const GLubyte stipple_quarttone[128] = { 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, - 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0}; + 136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0, +}; const GLubyte stipple_diag_stripes_pos[128] = { 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe, @@ -110,7 +112,8 @@ const GLubyte stipple_diag_stripes_pos[128] = { 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f, - 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f}; + 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f, +}; const GLubyte stipple_diag_stripes_neg[128] = { 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01, @@ -128,7 +131,8 @@ const GLubyte stipple_diag_stripes_neg[128] = { 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe, 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8, 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0, - 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80}; + 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80, +}; const GLubyte stipple_checker_8px[128] = { 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, @@ -138,7 +142,8 @@ const GLubyte stipple_checker_8px[128] = { 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, - 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255}; + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, +}; const GLubyte stipple_hexagon[128] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, @@ -156,7 +161,8 @@ const GLubyte stipple_hexagon[128] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, +}; /* ********************************************* */ /* Init / exit */ diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 4d455f6f464..a11eefee078 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -44,9 +44,9 @@ #include #include -static void batch_update_program_bindings(GPUBatch* batch, uint v_first); +static void batch_update_program_bindings(GPUBatch *batch, uint v_first); -void GPU_batch_vao_cache_clear(GPUBatch* batch) +void GPU_batch_vao_cache_clear(GPUBatch *batch) { if (batch->context == NULL) { return; @@ -82,17 +82,17 @@ void GPU_batch_vao_cache_clear(GPUBatch* batch) batch->context = NULL; } -GPUBatch* GPU_batch_create_ex( - GPUPrimType prim_type, GPUVertBuf* verts, GPUIndexBuf* elem, +GPUBatch *GPU_batch_create_ex( + GPUPrimType prim_type, GPUVertBuf *verts, GPUIndexBuf *elem, uint owns_flag) { - GPUBatch* batch = calloc(1, sizeof(GPUBatch)); + GPUBatch *batch = calloc(1, sizeof(GPUBatch)); GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } void GPU_batch_init_ex( - GPUBatch* batch, GPUPrimType prim_type, GPUVertBuf* verts, GPUIndexBuf* elem, + GPUBatch *batch, GPUPrimType prim_type, GPUVertBuf *verts, GPUIndexBuf *elem, uint owns_flag) { #if TRUST_NO_ONE @@ -113,9 +113,9 @@ void GPU_batch_init_ex( } /* This will share the VBOs with the new batch. */ -GPUBatch* GPU_batch_duplicate(GPUBatch* batch_src) +GPUBatch *GPU_batch_duplicate(GPUBatch *batch_src) { - GPUBatch* batch = GPU_batch_create_ex(GPU_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, batch_src->verts[0], batch_src->elem, 0); batch->gl_prim_type = batch_src->gl_prim_type; for (int v = 1; v < GPU_BATCH_VBO_MAX_LEN; ++v) { @@ -124,7 +124,7 @@ GPUBatch* GPU_batch_duplicate(GPUBatch* batch_src) return batch; } -void GPU_batch_discard(GPUBatch* batch) +void GPU_batch_discard(GPUBatch *batch) { if (batch->owns_flag & GPU_BATCH_OWNS_INDEX) { GPU_indexbuf_discard(batch->elem); @@ -150,13 +150,13 @@ void GPU_batch_discard(GPUBatch* batch) free(batch); } -void GPU_batch_callback_free_set(GPUBatch* batch, void (*callback)(GPUBatch*, void*), void* user_data) +void GPU_batch_callback_free_set(GPUBatch *batch, void (*callback)(GPUBatch *, void *), void *user_data) { batch->free_callback = callback; batch->callback_data = user_data; } -void GPU_batch_instbuf_set(GPUBatch* batch, GPUVertBuf* inst, bool own_vbo) +void GPU_batch_instbuf_set(GPUBatch *batch, GPUVertBuf *inst, bool own_vbo) { #if TRUST_NO_ONE assert(inst != NULL); @@ -179,7 +179,7 @@ void GPU_batch_instbuf_set(GPUBatch* batch, GPUVertBuf* inst, bool own_vbo) /* Returns the index of verts in the batch. */ int GPU_batch_vertbuf_add_ex( - GPUBatch* batch, GPUVertBuf* verts, + GPUBatch *batch, GPUVertBuf *verts, bool own_vbo) { /* redo the bindings */ @@ -238,7 +238,7 @@ static GLuint batch_vao_get(GPUBatch *batch) GLuint new_vao = 0; if (!batch->is_dynamic_vao_count) { int i; /* find first unused slot */ - for (i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) + for (i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) if (batch->static_vaos.vao_ids[i] == 0) break; @@ -251,12 +251,12 @@ static GLuint batch_vao_get(GPUBatch *batch) batch->is_dynamic_vao_count = true; /* Erase previous entries, they will be added back if drawn again. */ for (int j = 0; j < GPU_BATCH_VAO_STATIC_LEN; ++j) { - GPU_shaderinterface_remove_batch_ref((GPUShaderInterface*)batch->static_vaos.interfaces[j], batch); + GPU_shaderinterface_remove_batch_ref((GPUShaderInterface *)batch->static_vaos.interfaces[j], batch); GPU_vao_free(batch->static_vaos.vao_ids[j], batch->context); } /* Init dynamic arrays and let the branch below set the values. */ batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(GPUShaderInterface*)); + batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(GPUShaderInterface *)); batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); } } @@ -271,16 +271,16 @@ static GLuint batch_vao_get(GPUBatch *batch) /* Not enough place, realloc the array. */ i = batch->dynamic_vaos.count; batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(GPUShaderInterface*) * batch->dynamic_vaos.count); + batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count); batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); - memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(GPUShaderInterface*) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); + memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(GPUShaderInterface *) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); } batch->dynamic_vaos.interfaces[i] = batch->interface; batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc(); } - GPU_shaderinterface_add_batch_ref((GPUShaderInterface*)batch->interface, batch); + GPU_shaderinterface_add_batch_ref((GPUShaderInterface *)batch->interface, batch); #if TRUST_NO_ONE assert(new_vao != 0); @@ -294,7 +294,7 @@ static GLuint batch_vao_get(GPUBatch *batch) return new_vao; } -void GPU_batch_program_set_no_use(GPUBatch* batch, uint32_t program, const GPUShaderInterface* shaderface) +void GPU_batch_program_set_no_use(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface) { #if TRUST_NO_ONE assert(glIsProgram(shaderface->program)); @@ -305,13 +305,13 @@ void GPU_batch_program_set_no_use(GPUBatch* batch, uint32_t program, const GPUSh batch->vao_id = batch_vao_get(batch); } -void GPU_batch_program_set(GPUBatch* batch, uint32_t program, const GPUShaderInterface* shaderface) +void GPU_batch_program_set(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface) { GPU_batch_program_set_no_use(batch, program, shaderface); GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */ } -void gpu_batch_remove_interface_ref(GPUBatch* batch, const GPUShaderInterface* interface) +void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface) { if (batch->is_dynamic_vao_count) { for (int i = 0; i < batch->dynamic_vaos.count; ++i) { @@ -337,10 +337,10 @@ void gpu_batch_remove_interface_ref(GPUBatch* batch, const GPUShaderInterface* i } static void create_bindings( - GPUVertBuf* verts, const GPUShaderInterface* interface, - uint v_first, const bool use_instancing) + GPUVertBuf *verts, const GPUShaderInterface *interface, + uint v_first, const bool use_instancing) { - const GPUVertFormat* format = &verts->format; + const GPUVertFormat *format = &verts->format; const uint attr_len = format->attr_len; const uint stride = format->stride; @@ -348,11 +348,11 @@ static void create_bindings( GPU_vertbuf_use(verts); for (uint a_idx = 0; a_idx < attr_len; ++a_idx) { - const GPUVertAttr* a = format->attribs + a_idx; - const GLvoid* pointer = (const GLubyte*)0 + a->offset + v_first * stride; + const GPUVertAttr *a = format->attribs + a_idx; + const GLvoid *pointer = (const GLubyte *)0 + a->offset + v_first * stride; for (uint n_idx = 0; n_idx < a->name_len; ++n_idx) { - const GPUShaderInput* input = GPU_shaderinterface_attr(interface, a->name[n_idx]); + const GPUShaderInput *input = GPU_shaderinterface_attr(interface, a->name[n_idx]); if (input == NULL) continue; @@ -365,11 +365,10 @@ static void create_bindings( glEnableVertexAttribArray(input->location + i); glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0); glVertexAttribPointer(input->location + i, 4, a->gl_comp_type, GL_FALSE, stride, - (const GLubyte*)pointer + i * 16); + (const GLubyte *)pointer + i * 16); } } - else - { + else { glEnableVertexAttribArray(input->location); glVertexAttribDivisor(input->location, (use_instancing) ? 1 : 0); @@ -390,7 +389,7 @@ static void create_bindings( } } -static void batch_update_program_bindings(GPUBatch* batch, uint v_first) +static void batch_update_program_bindings(GPUBatch *batch, uint v_first) { for (int v = 0; v < GPU_BATCH_VBO_MAX_LEN && batch->verts[v] != NULL; ++v) { create_bindings(batch->verts[v], batch->interface, (batch->inst) ? 0 : v_first, false); @@ -403,7 +402,7 @@ static void batch_update_program_bindings(GPUBatch* batch, uint v_first) } } -void GPU_batch_program_use_begin(GPUBatch* batch) +void GPU_batch_program_use_begin(GPUBatch *batch) { /* NOTE: use_program & done_using_program are fragile, depend on staying in sync with * the GL context's active program. use_program doesn't mark other programs as "not used". */ @@ -415,7 +414,7 @@ void GPU_batch_program_use_begin(GPUBatch* batch) } } -void GPU_batch_program_use_end(GPUBatch* batch) +void GPU_batch_program_use_end(GPUBatch *batch) { if (batch->program_in_use) { #if PROGRAM_NO_OPTI @@ -426,84 +425,84 @@ void GPU_batch_program_use_end(GPUBatch* batch) } #if TRUST_NO_ONE - #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(batch->interface, name); assert(uniform); +# define GET_UNIFORM const GPUShaderInput *uniform = GPU_shaderinterface_uniform(batch->interface, name); assert(uniform); #else - #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(batch->interface, name); +# define GET_UNIFORM const GPUShaderInput *uniform = GPU_shaderinterface_uniform(batch->interface, name); #endif -void GPU_batch_uniform_1ui(GPUBatch* batch, const char* name, int value) +void GPU_batch_uniform_1ui(GPUBatch *batch, const char *name, int value) { GET_UNIFORM glUniform1ui(uniform->location, value); } -void GPU_batch_uniform_1i(GPUBatch* batch, const char* name, int value) +void GPU_batch_uniform_1i(GPUBatch *batch, const char *name, int value) { GET_UNIFORM glUniform1i(uniform->location, value); } -void GPU_batch_uniform_1b(GPUBatch* batch, const char* name, bool value) +void GPU_batch_uniform_1b(GPUBatch *batch, const char *name, bool value) { GET_UNIFORM glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE); } -void GPU_batch_uniform_2f(GPUBatch* batch, const char* name, float x, float y) +void GPU_batch_uniform_2f(GPUBatch *batch, const char *name, float x, float y) { GET_UNIFORM glUniform2f(uniform->location, x, y); } -void GPU_batch_uniform_3f(GPUBatch* batch, const char* name, float x, float y, float z) +void GPU_batch_uniform_3f(GPUBatch *batch, const char *name, float x, float y, float z) { GET_UNIFORM glUniform3f(uniform->location, x, y, z); } -void GPU_batch_uniform_4f(GPUBatch* batch, const char* name, float x, float y, float z, float w) +void GPU_batch_uniform_4f(GPUBatch *batch, const char *name, float x, float y, float z, float w) { GET_UNIFORM glUniform4f(uniform->location, x, y, z, w); } -void GPU_batch_uniform_1f(GPUBatch* batch, const char* name, float x) +void GPU_batch_uniform_1f(GPUBatch *batch, const char *name, float x) { GET_UNIFORM glUniform1f(uniform->location, x); } -void GPU_batch_uniform_2fv(GPUBatch* batch, const char* name, const float data[2]) +void GPU_batch_uniform_2fv(GPUBatch *batch, const char *name, const float data[2]) { GET_UNIFORM glUniform2fv(uniform->location, 1, data); } -void GPU_batch_uniform_3fv(GPUBatch* batch, const char* name, const float data[3]) +void GPU_batch_uniform_3fv(GPUBatch *batch, const char *name, const float data[3]) { GET_UNIFORM glUniform3fv(uniform->location, 1, data); } -void GPU_batch_uniform_4fv(GPUBatch* batch, const char* name, const float data[4]) +void GPU_batch_uniform_4fv(GPUBatch *batch, const char *name, const float data[4]) { GET_UNIFORM glUniform4fv(uniform->location, 1, data); } -void GPU_batch_uniform_2fv_array(GPUBatch* batch, const char* name, const int len, const float *data) +void GPU_batch_uniform_2fv_array(GPUBatch *batch, const char *name, const int len, const float *data) { GET_UNIFORM glUniform2fv(uniform->location, len, data); } -void GPU_batch_uniform_4fv_array(GPUBatch* batch, const char* name, const int len, const float *data) +void GPU_batch_uniform_4fv_array(GPUBatch *batch, const char *name, const int len, const float *data) { GET_UNIFORM glUniform4fv(uniform->location, len, data); } -void GPU_batch_uniform_mat4(GPUBatch* batch, const char* name, const float data[4][4]) +void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[4][4]) { GET_UNIFORM glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (const float *)data); @@ -530,7 +529,7 @@ static void primitive_restart_disable(void) glDisable(GL_PRIMITIVE_RESTART); } -void GPU_batch_draw(GPUBatch* batch) +void GPU_batch_draw(GPUBatch *batch) { #if TRUST_NO_ONE assert(batch->phase == GPU_BATCH_READY_TO_DRAW); @@ -544,7 +543,7 @@ void GPU_batch_draw(GPUBatch* batch) GPU_batch_program_use_end(batch); } -void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool force_instance) +void GPU_batch_draw_range_ex(GPUBatch *batch, int v_first, int v_count, bool force_instance) { #if TRUST_NO_ONE assert(!(force_instance && (batch->inst == NULL)) || v_count > 0); // we cannot infer length if force_instance @@ -567,7 +566,7 @@ void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool for } if (batch->elem) { - const GPUIndexBuf* el = batch->elem; + const GPUIndexBuf *el = batch->elem; if (el->use_prim_restart) { primitive_restart_enable(el); @@ -597,7 +596,7 @@ void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool for } if (batch->elem) { - const GPUIndexBuf* el = batch->elem; + const GPUIndexBuf *el = batch->elem; if (el->use_prim_restart) { primitive_restart_enable(el); @@ -605,13 +604,14 @@ void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool for #if GPU_TRACK_INDEX_RANGE if (el->base_index) { - glDrawRangeElementsBaseVertex(batch->gl_prim_type, - el->min_index, - el->max_index, - v_count, - el->gl_index_type, - 0, - el->base_index); + glDrawRangeElementsBaseVertex( + batch->gl_prim_type, + el->min_index, + el->max_index, + v_count, + el->gl_index_type, + 0, + el->base_index); } else { glDrawRangeElements(batch->gl_prim_type, el->min_index, el->max_index, v_count, el->gl_index_type, 0); @@ -635,7 +635,7 @@ void GPU_batch_draw_range_ex(GPUBatch* batch, int v_first, int v_count, bool for /* just draw some vertices and let shader place them where we want. */ void GPU_draw_primitive(GPUPrimType prim_type, int v_count) - { +{ /* we cannot draw without vao ... annoying ... */ glBindVertexArray(GPU_vao_default()); @@ -645,7 +645,7 @@ void GPU_draw_primitive(GPUPrimType prim_type, int v_count) /* Performance hog if you are drawing with the same vao multiple time. * Only activate for debugging.*/ // glBindVertexArray(0); - } +} /* -------------------------------------------------------------------- */ @@ -674,4 +674,4 @@ void gpu_batch_exit(void) gpu_batch_presets_exit(); } -/** \} */ \ No newline at end of file +/** \} */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index d466fa87388..16590785af6 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -522,42 +522,42 @@ void GPU_pbvh_grid_buffers_update( /* Build the element array buffer of grid indices using either * unsigned shorts or unsigned ints. */ #define FILL_QUAD_BUFFER(max_vert_, tot_quad_, buffer_) \ - { \ - int offset = 0; \ - int i, j, k; \ + { \ + int offset = 0; \ + int i, j, k; \ \ - GPUIndexBufBuilder elb; \ - GPU_indexbuf_init( \ - &elb, GPU_PRIM_TRIS, tot_quad_ * 2, max_vert_); \ + GPUIndexBufBuilder elb; \ + GPU_indexbuf_init( \ + &elb, GPU_PRIM_TRIS, tot_quad_ * 2, max_vert_); \ \ - /* Fill the buffer */ \ - for (i = 0; i < totgrid; ++i) { \ - BLI_bitmap *gh = NULL; \ - if (grid_hidden) \ - gh = grid_hidden[(grid_indices)[i]]; \ + /* Fill the buffer */ \ + for (i = 0; i < totgrid; ++i) { \ + BLI_bitmap *gh = NULL; \ + if (grid_hidden) \ + gh = grid_hidden[(grid_indices)[i]]; \ \ - for (j = 0; j < gridsize - 1; ++j) { \ - for (k = 0; k < gridsize - 1; ++k) { \ - /* Skip hidden grid face */ \ - if (gh && paint_is_grid_face_hidden( \ - gh, gridsize, k, j)) \ - { \ - continue; \ - } \ - GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ - GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k); \ - GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ - \ - GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k + 1); \ - GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ - GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ - } \ - } \ + for (j = 0; j < gridsize - 1; ++j) { \ + for (k = 0; k < gridsize - 1; ++k) { \ + /* Skip hidden grid face */ \ + if (gh && paint_is_grid_face_hidden( \ + gh, gridsize, k, j)) \ + { \ + continue; \ + } \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k); \ + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ \ - offset += gridsize * gridsize; \ - } \ - buffer_ = GPU_indexbuf_build(&elb); \ - } (void)0 + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + j * gridsize + k + 1); \ + GPU_indexbuf_add_generic_vert(&elb, offset + (j + 1) * gridsize + k); \ + } \ + } \ + \ + offset += gridsize * gridsize; \ + } \ + buffer_ = GPU_indexbuf_build(&elb); \ + } (void)0 /* end FILL_QUAD_BUFFER */ static GPUIndexBuf *gpu_get_grid_buffer( @@ -912,7 +912,7 @@ void GPU_pbvh_bmesh_buffers_update( BM_face_as_array_vert_tri(f, v); GPU_indexbuf_add_tri_verts( - &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2])); + &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2])); } } diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 51f21d01a9f..3b9d2e08769 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -615,10 +615,11 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, if ((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)) { /* create exactly one sampler for each texture */ if (codegen_input_has_texture(input) && input->bindtex) { - BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", - (input->textype == GPU_TEX2D) ? "sampler2D" : - (input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow", - input->texid); + BLI_dynstr_appendf( + ds, "uniform %s samp%d;\n", + (input->textype == GPU_TEX2D) ? "sampler2D" : + (input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow", + input->texid); } } else if (input->source == GPU_SOURCE_BUILTIN) { @@ -635,13 +636,15 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, } } else if (gpu_str_prefix(name, "unf")) { - BLI_dynstr_appendf(ds, "uniform %s %s;\n", - GPU_DATATYPE_STR[input->type], name); + BLI_dynstr_appendf( + ds, "uniform %s %s;\n", + GPU_DATATYPE_STR[input->type], name); } else { - BLI_dynstr_appendf(ds, "%s %s %s;\n", - GLEW_VERSION_3_0 ? "in" : "varying", - GPU_DATATYPE_STR[input->type], name); + BLI_dynstr_appendf( + ds, "%s %s %s;\n", + GLEW_VERSION_3_0 ? "in" : "varying", + GPU_DATATYPE_STR[input->type], name); } } } @@ -658,12 +661,14 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, } else if (input->dynamicvec) { /* only create uniforms for dynamic vectors */ - BLI_dynstr_appendf(ds, "uniform %s unf%d;\n", - GPU_DATATYPE_STR[input->type], input->id); + BLI_dynstr_appendf( + ds, "uniform %s unf%d;\n", + GPU_DATATYPE_STR[input->type], input->id); } else { - BLI_dynstr_appendf(ds, "const %s cons%d = ", - GPU_DATATYPE_STR[input->type], input->id); + BLI_dynstr_appendf( + ds, "const %s cons%d = ", + GPU_DATATYPE_STR[input->type], input->id); codegen_print_datatype(ds, input->type, input->vec); BLI_dynstr_append(ds, ";\n"); } @@ -675,9 +680,10 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n"); } #endif - BLI_dynstr_appendf(ds, "%s %s var%d;\n", - GLEW_VERSION_3_0 ? "in" : "varying", - GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf( + ds, "%s %s var%d;\n", + GLEW_VERSION_3_0 ? "in" : "varying", + GPU_DATATYPE_STR[input->type], input->attribid); #ifdef WITH_OPENSUBDIV if (skip_opensubdiv) { BLI_dynstr_appendf(ds, "#endif\n"); @@ -696,8 +702,9 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, for (LinkData *link = ubo_inputs.first; link; link = link->next) { input = link->data; - BLI_dynstr_appendf(ds, "\t%s unf%d;\n", - GPU_DATATYPE_STR[input->type], input->id); + BLI_dynstr_appendf( + ds, "\t%s unf%d;\n", + GPU_DATATYPE_STR[input->type], input->id); } BLI_dynstr_append(ds, "};\n"); BLI_freelistN(&ubo_inputs); @@ -719,9 +726,11 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes) for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_TEX_PIXEL) { if (codegen_input_has_texture(input) && input->definetex) { - BLI_dynstr_appendf(ds, "\tvec4 tex%d = texture2D(", input->texid); - BLI_dynstr_appendf(ds, "samp%d, gl_TexCoord[%d].st);\n", - input->texid, input->texid); + BLI_dynstr_appendf( + ds, "\tvec4 tex%d = texture2D(", input->texid); + BLI_dynstr_appendf( + ds, "samp%d, gl_TexCoord[%d].st);\n", + input->texid, input->texid); } } } @@ -729,11 +738,13 @@ static void codegen_declare_tmps(DynStr *ds, ListBase *nodes) /* declare temporary variables for node output storage */ for (output = node->outputs.first; output; output = output->next) { if (output->type == GPU_CLOSURE) { - BLI_dynstr_appendf(ds, "\tClosure tmp%d;\n", output->id); + BLI_dynstr_appendf( + ds, "\tClosure tmp%d;\n", output->id); } else { - BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", - GPU_DATATYPE_STR[output->type], output->id); + BLI_dynstr_appendf( + ds, "\t%s tmp%d;\n", + GPU_DATATYPE_STR[output->type], output->id); } } } @@ -757,8 +768,9 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final BLI_dynstr_appendf(ds, ", gl_TexCoord[%d].st", input->texid); } else if (input->source == GPU_SOURCE_TEX_PIXEL) { - codegen_convert_datatype(ds, input->link->output->type, input->type, - "tmp", input->link->output->id); + codegen_convert_datatype( + ds, input->link->output->type, input->type, + "tmp", input->link->output->id); } else if (input->source == GPU_SOURCE_BUILTIN) { if (input->builtin == GPU_INVERSE_VIEW_MATRIX) @@ -862,10 +874,12 @@ static char *code_generate_fragment(GPUMaterial *material, ListBase *nodes, GPUO for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { - BLI_dynstr_appendf(ds, "#ifdef USE_OPENSUBDIV\n"); - BLI_dynstr_appendf(ds, "\t%s var%d;\n", - GPU_DATATYPE_STR[input->type], - input->attribid); + BLI_dynstr_appendf( + ds, "#ifdef USE_OPENSUBDIV\n"); + BLI_dynstr_appendf( + ds, "\t%s var%d;\n", + GPU_DATATYPE_STR[input->type], + input->attribid); if (has_tangent == false) { BLI_dynstr_appendf(ds, "\tvec3 Q1 = dFdx(inpt.v.position.xyz);\n"); BLI_dynstr_appendf(ds, "\tvec3 Q2 = dFdy(inpt.v.position.xyz);\n"); @@ -929,12 +943,13 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u char *code; /* Hairs uv and col attribs are passed by bufferTextures. */ - BLI_dynstr_append(ds, - "#ifdef HAIR_SHADER\n" - "#define DEFINE_ATTRIB(type, attr) uniform samplerBuffer attr\n" - "#else\n" - "#define DEFINE_ATTRIB(type, attr) in type attr\n" - "#endif\n" + BLI_dynstr_append( + ds, + "#ifdef HAIR_SHADER\n" + "#define DEFINE_ATTRIB(type, attr) uniform samplerBuffer attr\n" + "#else\n" + "#define DEFINE_ATTRIB(type, attr) in type attr\n" + "#endif\n" ); for (node = nodes->first; node; node = node->next) { @@ -952,10 +967,12 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u } else { unsigned int hash = BLI_ghashutil_strhash_p(input->attribname); - BLI_dynstr_appendf(ds, "DEFINE_ATTRIB(%s, %s%u);\n", - GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype), hash); - BLI_dynstr_appendf(ds, "#define att%d %s%u\n", - input->attribid, attrib_prefix_get(input->attribtype), hash); + BLI_dynstr_appendf( + ds, "DEFINE_ATTRIB(%s, %s%u);\n", + GPU_DATATYPE_STR[input->type], attrib_prefix_get(input->attribtype), hash); + BLI_dynstr_appendf( + ds, "#define att%d %s%u\n", + input->attribid, attrib_prefix_get(input->attribtype), hash); /* Auto attrib can be vertex color byte buffer. * We need to know and convert them to linear space in VS. */ if (!use_geom && input->attribtype == CD_AUTO_FROM_NAME) { @@ -963,33 +980,36 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u BLI_dynstr_appendf(ds, "#define att%d_is_srgb ba%u\n", input->attribid, hash); } } - BLI_dynstr_appendf(ds, "out %s var%d%s;\n", - GPU_DATATYPE_STR[input->type], input->attribid, use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, "out %s var%d%s;\n", + GPU_DATATYPE_STR[input->type], input->attribid, use_geom ? "g" : ""); } } } BLI_dynstr_append(ds, "\n"); - BLI_dynstr_append(ds, - "#define ATTRIB\n" - "uniform mat3 NormalMatrix;\n" - "uniform mat4 ModelMatrixInverse;\n" - "vec3 srgb_to_linear_attrib(vec3 c) {\n" - "\tc = max(c, vec3(0.0));\n" - "\tvec3 c1 = c * (1.0 / 12.92);\n" - "\tvec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));\n" - "\treturn mix(c1, c2, step(vec3(0.04045), c));\n" - "}\n\n" + BLI_dynstr_append( + ds, + "#define ATTRIB\n" + "uniform mat3 NormalMatrix;\n" + "uniform mat4 ModelMatrixInverse;\n" + "vec3 srgb_to_linear_attrib(vec3 c) {\n" + "\tc = max(c, vec3(0.0));\n" + "\tvec3 c1 = c * (1.0 / 12.92);\n" + "\tvec3 c2 = pow((c + 0.055) * (1.0 / 1.055), vec3(2.4));\n" + "\treturn mix(c1, c2, step(vec3(0.04045), c));\n" + "}\n\n" ); /* Prototype because defined later. */ - BLI_dynstr_append(ds, - "vec2 hair_get_customdata_vec2(const samplerBuffer);\n" - "vec3 hair_get_customdata_vec3(const samplerBuffer);\n" - "vec4 hair_get_customdata_vec4(const samplerBuffer);\n" - "vec3 hair_get_strand_pos(void);\n" - "\n" + BLI_dynstr_append( + ds, + "vec2 hair_get_customdata_vec2(const samplerBuffer);\n" + "vec3 hair_get_customdata_vec3(const samplerBuffer);\n" + "vec4 hair_get_customdata_vec4(const samplerBuffer);\n" + "vec3 hair_get_strand_pos(void);\n" + "\n" ); BLI_dynstr_append(ds, "void pass_attrib(in vec3 position) {\n"); @@ -1001,16 +1021,19 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { if (input->attribtype == CD_TANGENT) { /* Not supported by hairs */ - BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", - input->attribid, use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, "\tvar%d%s = vec4(0.0);\n", + input->attribid, use_geom ? "g" : ""); } else if (input->attribtype == CD_ORCO) { - BLI_dynstr_appendf(ds, "\tvar%d%s = OrcoTexCoFactors[0] + (ModelMatrixInverse * vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1];\n", - input->attribid, use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, "\tvar%d%s = OrcoTexCoFactors[0] + (ModelMatrixInverse * vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1];\n", + input->attribid, use_geom ? "g" : ""); } else { - BLI_dynstr_appendf(ds, "\tvar%d%s = hair_get_customdata_%s(att%d);\n", - input->attribid, use_geom ? "g" : "", GPU_DATATYPE_STR[input->type], input->attribid); + BLI_dynstr_appendf( + ds, "\tvar%d%s = hair_get_customdata_%s(att%d);\n", + input->attribid, use_geom ? "g" : "", GPU_DATATYPE_STR[input->type], input->attribid); } } } @@ -1030,21 +1053,25 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u input->attribid, use_geom ? "g" : "", input->attribid); } else if (input->attribtype == CD_ORCO) { - BLI_dynstr_appendf(ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n", - input->attribid, use_geom ? "g" : ""); + BLI_dynstr_appendf( + ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n", + input->attribid, use_geom ? "g" : ""); } else if (input->attribtype == CD_MCOL) { - BLI_dynstr_appendf(ds, "\tvar%d%s = srgb_to_linear_attrib(att%d);\n", - input->attribid, use_geom ? "g" : "", input->attribid); + BLI_dynstr_appendf( + ds, "\tvar%d%s = srgb_to_linear_attrib(att%d);\n", + input->attribid, use_geom ? "g" : "", input->attribid); } else if (input->attribtype == CD_AUTO_FROM_NAME) { - BLI_dynstr_appendf(ds, "\tvar%d%s = (att%d_is_srgb) ? srgb_to_linear_attrib(att%d) : att%d;\n", - input->attribid, use_geom ? "g" : "", - input->attribid, input->attribid, input->attribid); + BLI_dynstr_appendf( + ds, "\tvar%d%s = (att%d_is_srgb) ? srgb_to_linear_attrib(att%d) : att%d;\n", + input->attribid, use_geom ? "g" : "", + input->attribid, input->attribid, input->attribid); } else { - BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", - input->attribid, use_geom ? "g" : "", input->attribid); + BLI_dynstr_appendf( + ds, "\tvar%d%s = att%d;\n", + input->attribid, use_geom ? "g" : "", input->attribid); } } } @@ -1083,12 +1110,14 @@ static char *code_generate_geometry(ListBase *nodes, const char *geom_code) for (node = nodes->first; node; node = node->next) { for (input = node->inputs.first; input; input = input->next) { if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) { - BLI_dynstr_appendf(ds, "in %s var%dg[];\n", - GPU_DATATYPE_STR[input->type], - input->attribid); - BLI_dynstr_appendf(ds, "out %s var%d;\n", - GPU_DATATYPE_STR[input->type], - input->attribid); + BLI_dynstr_appendf( + ds, "in %s var%dg[];\n", + GPU_DATATYPE_STR[input->type], + input->attribid); + BLI_dynstr_appendf( + ds, "out %s var%d;\n", + GPU_DATATYPE_STR[input->type], + input->attribid); } } } @@ -1382,8 +1411,8 @@ static const char *gpu_uniform_set_function_from_type(eNodeSocketDatatype type) case SOCK_RGBA: return "set_rgba"; default: - BLI_assert(!"No gpu function for non-supported eNodeSocketDatatype"); - return NULL; + BLI_assert(!"No gpu function for non-supported eNodeSocketDatatype"); + return NULL; } } @@ -1553,8 +1582,9 @@ void GPU_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *attribs) attribs->layer[a].type = input->attribtype; attribs->layer[a].attribid = input->attribid; - BLI_strncpy(attribs->layer[a].name, input->attribname, - sizeof(attribs->layer[a].name)); + BLI_strncpy( + attribs->layer[a].name, input->attribname, + sizeof(attribs->layer[a].name)); } else { input->attribid = attribs->layer[a].attribid; @@ -1966,11 +1996,12 @@ GPUPass *GPU_generate_pass_new( void GPU_pass_compile(GPUPass *pass) { if (!pass->compiled) { - pass->shader = GPU_shader_create(pass->vertexcode, - pass->fragmentcode, - pass->geometrycode, - NULL, - pass->defines); + pass->shader = GPU_shader_create( + pass->vertexcode, + pass->fragmentcode, + pass->geometrycode, + NULL, + pass->defines); pass->compiled = true; } } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index e2c83d6fadf..965caba0955 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -107,7 +107,7 @@ static bool is_over_resolution_limit(GLenum textarget, int w, int h) int size = (textarget == GL_TEXTURE_2D) ? GPU_max_texture_size() : GPU_max_cube_map_size(); int reslimit = (U.glreslimit != 0) ? - min_ii(U.glreslimit, size) : size; + min_ii(U.glreslimit, size) : size; return (w > reslimit || h > reslimit); } @@ -239,42 +239,48 @@ typedef struct VerifyThreadData { float *srgb_frect; } VerifyThreadData; -static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect, - ImBuf *ibuf, - const int start_line, - const int height) +static void gpu_verify_high_bit_srgb_buffer_slice( + float *srgb_frect, + ImBuf *ibuf, + const int start_line, + const int height) { size_t offset = ibuf->channels * start_line * ibuf->x; float *current_srgb_frect = srgb_frect + offset; float *current_rect_float = ibuf->rect_float + offset; - IMB_buffer_float_from_float(current_srgb_frect, - current_rect_float, - ibuf->channels, - IB_PROFILE_SRGB, - IB_PROFILE_LINEAR_RGB, true, - ibuf->x, height, - ibuf->x, ibuf->x); + IMB_buffer_float_from_float( + current_srgb_frect, + current_rect_float, + ibuf->channels, + IB_PROFILE_SRGB, + IB_PROFILE_LINEAR_RGB, true, + ibuf->x, height, + ibuf->x, ibuf->x); IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height); } -static void verify_thread_do(void *data_v, - int start_scanline, - int num_scanlines) +static void verify_thread_do( + void *data_v, + int start_scanline, + int num_scanlines) { VerifyThreadData *data = (VerifyThreadData *)data_v; - gpu_verify_high_bit_srgb_buffer_slice(data->srgb_frect, - data->ibuf, - start_scanline, - num_scanlines); + gpu_verify_high_bit_srgb_buffer_slice( + data->srgb_frect, + data->ibuf, + start_scanline, + num_scanlines); } -static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, - ImBuf *ibuf) +static void gpu_verify_high_bit_srgb_buffer( + float *srgb_frect, + ImBuf *ibuf) { if (ibuf->y < 64) { - gpu_verify_high_bit_srgb_buffer_slice(srgb_frect, - ibuf, - 0, ibuf->y); + gpu_verify_high_bit_srgb_buffer_slice( + srgb_frect, + ibuf, + 0, ibuf->y); } else { VerifyThreadData data; @@ -284,11 +290,12 @@ static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, } } -GPUTexture *GPU_texture_from_blender(Image *ima, - ImageUser *iuser, - int textarget, - bool is_data, - double UNUSED(time)) +GPUTexture *GPU_texture_from_blender( + Image *ima, + ImageUser *iuser, + int textarget, + bool is_data, + double UNUSED(time)) { if (ima == NULL) { return NULL; @@ -363,11 +370,14 @@ GPUTexture *GPU_texture_from_blender(Image *ima, const bool mipmap = GPU_get_mipmap(); #ifdef WITH_DDS - if (ibuf->ftype == IMB_FTYPE_DDS) + if (ibuf->ftype == IMB_FTYPE_DDS) { GPU_create_gl_tex_compressed(&bindcode, rect, rectw, recth, textarget, mipmap, ima, ibuf); + } else #endif + { GPU_create_gl_tex(&bindcode, rect, frect, rectw, recth, textarget, mipmap, use_high_bit_depth, ima); + } /* mark as non-color data texture */ if (bindcode) { @@ -556,8 +566,9 @@ void GPU_create_gl_tex( if (mip_cube_map) { for (int j = 0; j < 6; j++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, - informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, + informat, mipw, miph, 0, GL_RGBA, type, mip_cube_map[j]); } } gpu_del_cube_map(mip_cube_map); @@ -639,8 +650,9 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf) size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize; - glCompressedTexImage2D(GL_TEXTURE_2D, i, format, width, height, - 0, size, ibuf->dds_data.data + offset); + glCompressedTexImage2D( + GL_TEXTURE_2D, i, format, width, height, + 0, size, ibuf->dds_data.data + offset); offset += size; width >>= 1; @@ -755,8 +767,9 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, ImBuf *ibuf_scale = IMB_allocFromBuffer(NULL, frect, w, h); IMB_scaleImBuf(ibuf_scale, rectw, recth); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, - GL_FLOAT, ibuf_scale->rect_float); + glTexSubImage2D( + GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, + GL_FLOAT, ibuf_scale->rect_float); IMB_freeImBuf(ibuf_scale); } @@ -775,8 +788,9 @@ static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, } } - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, - GL_UNSIGNED_BYTE, scalerect); + glTexSubImage2D( + GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA, + GL_UNSIGNED_BYTE, scalerect); MEM_freeN(scalerect); } @@ -860,8 +874,9 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i glPixelStorei(GL_UNPACK_SKIP_PIXELS, x); glPixelStorei(GL_UNPACK_SKIP_ROWS, y); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, - GL_UNSIGNED_BYTE, ibuf->rect); + glTexSubImage2D( + GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, + GL_UNSIGNED_BYTE, ibuf->rect); glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length); glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_pixels); @@ -913,8 +928,9 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) } /* density only */ else { - sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], - GPU_R8, smoke_get_density(sds->fluid), NULL); + sds->tex = GPU_texture_create_3D( + sds->res[0], sds->res[1], sds->res[2], + GPU_R8, smoke_get_density(sds->fluid), NULL); /* Swizzle the RGBA components to read the Red channel so * that the shader stay the same for colored and non color @@ -926,10 +942,12 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED); GPU_texture_unbind(sds->tex); } - sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? - GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], - GPU_R8, smoke_get_flame(sds->fluid), NULL) : - NULL; + sds->tex_flame = ( + smoke_has_fuel(sds->fluid) ? + GPU_texture_create_3D( + sds->res[0], sds->res[1], sds->res[2], + GPU_R8, smoke_get_flame(sds->fluid), NULL) : + NULL); } else if (!sds->tex && highres) { /* rgba texture for color + density */ @@ -941,8 +959,9 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) } /* density only */ else { - sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], - GPU_R8, smoke_turbulence_get_density(sds->wt), NULL); + sds->tex = GPU_texture_create_3D( + sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], + GPU_R8, smoke_turbulence_get_density(sds->wt), NULL); /* Swizzle the RGBA components to read the Red channel so * that the shader stay the same for colored and non color @@ -954,14 +973,17 @@ void GPU_create_smoke(SmokeModifierData *smd, int highres) glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED); GPU_texture_unbind(sds->tex); } - sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? - GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], - GPU_R8, smoke_turbulence_get_flame(sds->wt), NULL) : - NULL; + sds->tex_flame = ( + smoke_turbulence_has_fuel(sds->wt) ? + GPU_texture_create_3D( + sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], + GPU_R8, smoke_turbulence_get_flame(sds->wt), NULL) : + NULL); } - sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], - GPU_R8, sds->shadow, NULL); + sds->tex_shadow = GPU_texture_create_3D( + sds->res[0], sds->res[1], sds->res[2], + GPU_R8, sds->shadow, NULL); } #else // WITH_SMOKE (void)highres; @@ -1301,10 +1323,10 @@ void GPU_select_to_index_array(unsigned int *col, const unsigned int size) { #define INDEX_BUF_ARRAY(INDEX_FROM_BUF_BITS) \ for (i = size; i--; col++) { \ - if ((c = *col)) { \ - *col = INDEX_FROM_BUF_BITS(c); \ - } \ - } ((void)0) + if ((c = *col)) { \ + *col = INDEX_FROM_BUF_BITS(c); \ + } \ + } ((void)0) if (size > 0) { unsigned int i, c; diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 1b5a08ac35c..9abfed2db05 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -46,7 +46,7 @@ static GLenum convert_index_type_to_gl(GPUIndexBufType type) return table[type]; } -uint GPU_indexbuf_size_get(const GPUIndexBuf* elem) +uint GPU_indexbuf_size_get(const GPUIndexBuf *elem) { #if GPU_TRACK_INDEX_RANGE static const uint table[] = { @@ -61,7 +61,7 @@ uint GPU_indexbuf_size_get(const GPUIndexBuf* elem) } void GPU_indexbuf_init_ex( - GPUIndexBufBuilder* builder, GPUPrimType prim_type, + GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint index_len, uint vertex_len, bool use_prim_restart) { builder->use_prim_restart = use_prim_restart; @@ -72,7 +72,7 @@ void GPU_indexbuf_init_ex( builder->data = calloc(builder->max_index_len, sizeof(uint)); } -void GPU_indexbuf_init(GPUIndexBufBuilder* builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) +void GPU_indexbuf_init(GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) { uint verts_per_prim = 0; switch (prim_type) { @@ -98,7 +98,7 @@ void GPU_indexbuf_init(GPUIndexBufBuilder* builder, GPUPrimType prim_type, uint GPU_indexbuf_init_ex(builder, prim_type, prim_len * verts_per_prim, vertex_len, false); } -void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder* builder, uint v) +void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v) { #if TRUST_NO_ONE assert(builder->data != NULL); @@ -108,7 +108,7 @@ void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder* builder, uint v) builder->data[builder->index_len++] = v; } -void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder* builder) +void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *builder) { #if TRUST_NO_ONE assert(builder->data != NULL); @@ -118,7 +118,7 @@ void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder* builder) builder->data[builder->index_len++] = GPU_PRIM_RESTART; } -void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder* builder, uint v) +void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder *builder, uint v) { #if TRUST_NO_ONE assert(builder->prim_type == GPU_PRIM_POINTS); @@ -126,7 +126,7 @@ void GPU_indexbuf_add_point_vert(GPUIndexBufBuilder* builder, uint v) GPU_indexbuf_add_generic_vert(builder, v); } -void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder* builder, uint v1, uint v2) +void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder *builder, uint v1, uint v2) { #if TRUST_NO_ONE assert(builder->prim_type == GPU_PRIM_LINES); @@ -136,7 +136,7 @@ void GPU_indexbuf_add_line_verts(GPUIndexBufBuilder* builder, uint v1, uint v2) GPU_indexbuf_add_generic_vert(builder, v2); } -void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder* builder, uint v1, uint v2, uint v3) +void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder *builder, uint v1, uint v2, uint v3) { #if TRUST_NO_ONE assert(builder->prim_type == GPU_PRIM_TRIS); @@ -147,7 +147,7 @@ void GPU_indexbuf_add_tri_verts(GPUIndexBufBuilder* builder, uint v1, uint v2, u GPU_indexbuf_add_generic_vert(builder, v3); } -void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder* builder, uint v1, uint v2, uint v3, uint v4) +void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder *builder, uint v1, uint v2, uint v3, uint v4) { #if TRUST_NO_ONE assert(builder->prim_type == GPU_PRIM_LINES_ADJ); @@ -163,7 +163,7 @@ void GPU_indexbuf_add_line_adj_verts(GPUIndexBufBuilder* builder, uint v1, uint /* Everything remains 32 bit while building to keep things simple. * Find min/max after, then convert to smallest index type possible. */ -static uint index_range(const uint values[], uint value_len, uint* min_out, uint* max_out) +static uint index_range(const uint values[], uint value_len, uint *min_out, uint *max_out) { if (value_len == 0) { *min_out = 0; @@ -186,7 +186,7 @@ static uint index_range(const uint values[], uint value_len, uint* min_out, uint return max_value - min_value; } -static void squeeze_indices_byte(GPUIndexBufBuilder *builder, GPUIndexBuf* elem) +static void squeeze_indices_byte(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) { const uint *values = builder->data; const uint index_len = elem->index_len; @@ -212,7 +212,7 @@ static void squeeze_indices_byte(GPUIndexBufBuilder *builder, GPUIndexBuf* elem) } } -static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf* elem) +static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) { const uint *values = builder->data; const uint index_len = elem->index_len; @@ -240,14 +240,14 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf* elem #endif /* GPU_TRACK_INDEX_RANGE */ -GPUIndexBuf* GPU_indexbuf_build(GPUIndexBufBuilder* builder) +GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder) { - GPUIndexBuf* elem = calloc(1, sizeof(GPUIndexBuf)); + GPUIndexBuf *elem = calloc(1, sizeof(GPUIndexBuf)); GPU_indexbuf_build_in_place(builder, elem); return elem; } -void GPU_indexbuf_build_in_place(GPUIndexBufBuilder* builder, GPUIndexBuf* elem) +void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) { #if TRUST_NO_ONE assert(builder->data != NULL); @@ -294,12 +294,12 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder* builder, GPUIndexBuf* elem) /* other fields are safe to leave */ } -void GPU_indexbuf_use(GPUIndexBuf* elem) +void GPU_indexbuf_use(GPUIndexBuf *elem) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem->vbo_id); } -void GPU_indexbuf_discard(GPUIndexBuf* elem) +void GPU_indexbuf_discard(GPUIndexBuf *elem) { if (elem->vbo_id) { GPU_buf_id_free(elem->vbo_id); diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index ffc72718e42..d28b82ac3cd 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -121,7 +121,7 @@ static GPUTexture *framebuffer_get_depth_tex(GPUFrameBuffer *fb) if (fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex) return fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex; else - return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex;; + return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex; } static GPUTexture *framebuffer_get_color_tex(GPUFrameBuffer *fb, int slot) @@ -167,12 +167,12 @@ static void gpu_print_framebuffer_error(GLenum status, char err_out[256]) void gpu_framebuffer_module_init(void) { - BLI_thread_local_create(g_currentfb); + BLI_thread_local_create(g_currentfb); } void gpu_framebuffer_module_exit(void) { - BLI_thread_local_delete(g_currentfb); + BLI_thread_local_delete(g_currentfb); } static uint gpu_framebuffer_current_get(void) @@ -340,8 +340,9 @@ static void gpu_framebuffer_attachment_attach(GPUAttachment *attach, GPUAttachme if (attach->layer > -1) { if (GPU_texture_cube(attach->tex)) { - glFramebufferTexture2D(GL_FRAMEBUFFER, gl_attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + attach->layer, - tex_bind, attach->mip); + glFramebufferTexture2D( + GL_FRAMEBUFFER, gl_attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + attach->layer, + tex_bind, attach->mip); } else { glFramebufferTextureLayer(GL_FRAMEBUFFER, gl_attachment, tex_bind, attach->mip, attach->layer); @@ -518,7 +519,7 @@ void GPU_framebuffer_read_color( case 1: type = GL_RED; break; case 2: type = GL_RG; break; case 3: type = GL_RGB; break; - case 4: type = GL_RGBA; break; + case 4: type = GL_RGBA; break; default: BLI_assert(false && "wrong number of read channels"); return; @@ -549,12 +550,14 @@ void GPU_framebuffer_blit( const bool do_depth = (blit_buffers & GPU_DEPTH_BIT); const bool do_stencil = (blit_buffers & GPU_STENCIL_BIT); - GPUTexture *read_tex = (do_depth || do_stencil) - ? framebuffer_get_depth_tex(fb_read) - : framebuffer_get_color_tex(fb_read, read_slot); - GPUTexture *write_tex = (do_depth || do_stencil) - ? framebuffer_get_depth_tex(fb_write) - : framebuffer_get_color_tex(fb_write, read_slot); + GPUTexture *read_tex = ( + (do_depth || do_stencil) ? + framebuffer_get_depth_tex(fb_read) : + framebuffer_get_color_tex(fb_read, read_slot)); + GPUTexture *write_tex = ( + (do_depth || do_stencil) ? + framebuffer_get_depth_tex(fb_write) : + framebuffer_get_color_tex(fb_write, read_slot)); if (do_depth) { BLI_assert(GPU_texture_depth(read_tex) && GPU_texture_depth(write_tex)); @@ -585,9 +588,10 @@ void GPU_framebuffer_blit( GLbitfield mask = convert_buffer_bits_to_gl(blit_buffers); - glBlitFramebuffer(0, 0, fb_read->width, fb_read->height, - 0, 0, fb_write->width, fb_write->height, - mask, GL_NEAREST); + glBlitFramebuffer( + 0, 0, fb_read->width, fb_read->height, + 0, 0, fb_write->width, fb_write->height, + mask, GL_NEAREST); /* Restore previous framebuffer */ if (fb_write->object == prev_fb) { @@ -679,7 +683,8 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, int samples, bool dept ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen"); - ofs->color = GPU_texture_create_2D_multisample(width, height, + ofs->color = GPU_texture_create_2D_multisample( + width, height, (high_bitdepth) ? GPU_RGBA16F : GPU_RGBA8, NULL, samples, err_out); if (depth) { @@ -776,14 +781,16 @@ void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels) /* create texture for new 'fbo_blit' */ glGenTextures(1, &tex_blit); glBindTexture(GL_TEXTURE_2D, tex_blit); - glTexImage2D(GL_TEXTURE_2D, 0, (type == GL_FLOAT) ? GL_RGBA16F : GL_RGBA8, - w, h, 0, GL_RGBA, type, 0); + glTexImage2D( + GL_TEXTURE_2D, 0, (type == GL_FLOAT) ? GL_RGBA16F : GL_RGBA8, + w, h, 0, GL_RGBA, type, 0); /* write into new single-sample buffer */ glGenFramebuffers(1, &fbo_blit); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_blit); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tex_blit, 0); + glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, tex_blit, 0); GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index a320935919a..06b487fbb25 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -45,17 +45,17 @@ #include /* necessary functions from matrix API */ -extern void GPU_matrix_bind(const GPUShaderInterface*); +extern void GPU_matrix_bind(const GPUShaderInterface *); extern bool GPU_matrix_dirty_get(void); typedef struct { /* TODO: organize this struct by frequency of change (run-time) */ - GPUBatch* batch; - GPUContext* context; + GPUBatch *batch; + GPUContext *context; /* current draw call */ - GLubyte* buffer_data; + GLubyte *buffer_data; uint buffer_offset; uint buffer_bytes_mapped; uint vertex_len; @@ -66,14 +66,14 @@ typedef struct { /* current vertex */ uint vertex_idx; - GLubyte* vertex_data; + GLubyte *vertex_data; uint16_t unassigned_attrib_bits; /* which attributes of current vertex have not been given values? */ GLuint vbo_id; GLuint vao_id; GLuint bound_program; - const GPUShaderInterface* shader_interface; + const GPUShaderInterface *shader_interface; GPUAttrBinding attrib_binding; uint16_t prev_enabled_attrib_bits; /* <-- only affects this VAO, so we're ok */ } Immediate; @@ -131,13 +131,13 @@ void immDestroy(void) initialized = false; } -GPUVertFormat* immVertexFormat(void) +GPUVertFormat *immVertexFormat(void) { GPU_vertformat_clear(&imm.vertex_format); return &imm.vertex_format; } -void immBindProgram(GLuint program, const GPUShaderInterface* shaderface) +void immBindProgram(GLuint program, const GPUShaderInterface *shaderface) { #if TRUST_NO_ONE assert(imm.bound_program == 0); @@ -261,7 +261,7 @@ void immBeginAtMost(GPUPrimType prim_type, uint vertex_len) } -GPUBatch* immBeginBatch(GPUPrimType prim_type, uint vertex_len) +GPUBatch *immBeginBatch(GPUPrimType prim_type, uint vertex_len) { #if TRUST_NO_ONE assert(initialized); @@ -273,7 +273,7 @@ GPUBatch* immBeginBatch(GPUPrimType prim_type, uint vertex_len) imm.vertex_idx = 0; imm.unassigned_attrib_bits = imm.attrib_binding.enabled_bits; - GPUVertBuf* verts = GPU_vertbuf_create_with_format(&imm.vertex_format); + GPUVertBuf *verts = GPU_vertbuf_create_with_format(&imm.vertex_format); GPU_vertbuf_data_alloc(verts, vertex_len); imm.buffer_bytes_mapped = GPU_vertbuf_size_get(verts); @@ -285,7 +285,7 @@ GPUBatch* immBeginBatch(GPUPrimType prim_type, uint vertex_len) return imm.batch; } -GPUBatch* immBeginBatchAtMost(GPUPrimType prim_type, uint vertex_len) +GPUBatch *immBeginBatchAtMost(GPUPrimType prim_type, uint vertex_len) { imm.strict_vertex_len = false; return immBeginBatch(prim_type, vertex_len); @@ -316,10 +316,10 @@ static void immDrawSetup(void) const uint stride = imm.vertex_format.stride; for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { - const GPUVertAttr* a = imm.vertex_format.attribs + a_idx; + const GPUVertAttr *a = imm.vertex_format.attribs + a_idx; const uint offset = imm.buffer_offset + a->offset; - const GLvoid* pointer = (const GLubyte*)0 + offset; + const GLvoid *pointer = (const GLubyte *)0 + offset; const uint loc = read_attrib_location(&imm.attrib_binding, a_idx); @@ -413,7 +413,7 @@ static void setAttribValueBit(uint attrib_id) void immAttrib1f(uint attrib_id, float x) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_F32); @@ -423,7 +423,7 @@ void immAttrib1f(uint attrib_id, float x) #endif setAttribValueBit(attrib_id); - float* data = (float*)(imm.vertex_data + attrib->offset); + float *data = (float *)(imm.vertex_data + attrib->offset); /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; @@ -431,7 +431,7 @@ void immAttrib1f(uint attrib_id, float x) void immAttrib2f(uint attrib_id, float x, float y) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_F32); @@ -441,7 +441,7 @@ void immAttrib2f(uint attrib_id, float x, float y) #endif setAttribValueBit(attrib_id); - float* data = (float*)(imm.vertex_data + attrib->offset); + float *data = (float *)(imm.vertex_data + attrib->offset); /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; @@ -450,7 +450,7 @@ void immAttrib2f(uint attrib_id, float x, float y) void immAttrib3f(uint attrib_id, float x, float y, float z) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_F32); @@ -460,7 +460,7 @@ void immAttrib3f(uint attrib_id, float x, float y, float z) #endif setAttribValueBit(attrib_id); - float* data = (float*)(imm.vertex_data + attrib->offset); + float *data = (float *)(imm.vertex_data + attrib->offset); /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; @@ -470,7 +470,7 @@ void immAttrib3f(uint attrib_id, float x, float y, float z) void immAttrib4f(uint attrib_id, float x, float y, float z, float w) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_F32); @@ -480,7 +480,7 @@ void immAttrib4f(uint attrib_id, float x, float y, float z, float w) #endif setAttribValueBit(attrib_id); - float* data = (float*)(imm.vertex_data + attrib->offset); + float *data = (float *)(imm.vertex_data + attrib->offset); /* printf("%s %td %p\n", __FUNCTION__, (GLubyte*)data - imm.buffer_data, data); */ data[0] = x; @@ -491,7 +491,7 @@ void immAttrib4f(uint attrib_id, float x, float y, float z, float w) void immAttrib1u(uint attrib_id, uint x) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_U32); @@ -501,14 +501,14 @@ void immAttrib1u(uint attrib_id, uint x) #endif setAttribValueBit(attrib_id); - uint* data = (uint*)(imm.vertex_data + attrib->offset); + uint *data = (uint *)(imm.vertex_data + attrib->offset); data[0] = x; } void immAttrib2i(uint attrib_id, int x, int y) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_I32); @@ -518,7 +518,7 @@ void immAttrib2i(uint attrib_id, int x, int y) #endif setAttribValueBit(attrib_id); - int* data = (int*)(imm.vertex_data + attrib->offset); + int *data = (int *)(imm.vertex_data + attrib->offset); data[0] = x; data[1] = y; @@ -526,7 +526,7 @@ void immAttrib2i(uint attrib_id, int x, int y) void immAttrib2s(uint attrib_id, short x, short y) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_I16); @@ -536,7 +536,7 @@ void immAttrib2s(uint attrib_id, short x, short y) #endif setAttribValueBit(attrib_id); - short* data = (short*)(imm.vertex_data + attrib->offset); + short *data = (short *)(imm.vertex_data + attrib->offset); data[0] = x; data[1] = y; @@ -559,7 +559,7 @@ void immAttrib4fv(uint attrib_id, const float data[4]) void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_U8); @@ -569,7 +569,7 @@ void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned cha #endif setAttribValueBit(attrib_id); - GLubyte* data = imm.vertex_data + attrib->offset; + GLubyte *data = imm.vertex_data + attrib->offset; /* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ data[0] = r; @@ -579,7 +579,7 @@ void immAttrib3ub(uint attrib_id, unsigned char r, unsigned char g, unsigned cha void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - GPUVertAttr* attrib = imm.vertex_format.attribs + attrib_id; + GPUVertAttr *attrib = imm.vertex_format.attribs + attrib_id; #if TRUST_NO_ONE assert(attrib_id < imm.vertex_format.attr_len); assert(attrib->comp_type == GPU_COMP_U8); @@ -589,7 +589,7 @@ void immAttrib4ub(uint attrib_id, unsigned char r, unsigned char g, unsigned cha #endif setAttribValueBit(attrib_id); - GLubyte* data = imm.vertex_data + attrib->offset; + GLubyte *data = imm.vertex_data + attrib->offset; /* printf("%s %td %p\n", __FUNCTION__, data - imm.buffer_data, data); */ data[0] = r; @@ -633,11 +633,11 @@ static void immEndVertex(void) /* and move on to the next vertex */ #endif for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { if ((imm.unassigned_attrib_bits >> a_idx) & 1) { - const GPUVertAttr* a = imm.vertex_format.attribs + a_idx; + const GPUVertAttr *a = imm.vertex_format.attribs + a_idx; /* printf("copying %s from vertex %u to %u\n", a->name, imm.vertex_idx - 1, imm.vertex_idx); */ - GLubyte* data = imm.vertex_data + a->offset; + GLubyte *data = imm.vertex_data + a->offset; memcpy(data, data - imm.vertex_format.stride, a->sz); /* TODO: consolidate copy of adjacent attributes */ } @@ -714,31 +714,31 @@ void immVertex2iv(uint attrib_id, const int data[2]) #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; #endif -void immUniform1f(const char* name, float x) +void immUniform1f(const char *name, float x) { GET_UNIFORM glUniform1f(uniform->location, x); } -void immUniform2f(const char* name, float x, float y) +void immUniform2f(const char *name, float x, float y) { GET_UNIFORM glUniform2f(uniform->location, x, y); } -void immUniform2fv(const char* name, const float data[2]) +void immUniform2fv(const char *name, const float data[2]) { GET_UNIFORM glUniform2fv(uniform->location, 1, data); } -void immUniform3f(const char* name, float x, float y, float z) +void immUniform3f(const char *name, float x, float y, float z) { GET_UNIFORM glUniform3f(uniform->location, x, y, z); } -void immUniform3fv(const char* name, const float data[3]) +void immUniform3fv(const char *name, const float data[3]) { GET_UNIFORM glUniform3fv(uniform->location, 1, data); @@ -747,7 +747,7 @@ void immUniform3fv(const char* name, const float data[3]) /* can increase this limit or move to another file */ #define MAX_UNIFORM_NAME_LEN 60 -void immUniformArray3fv(const char* bare_name, const float *data, int count) +void immUniformArray3fv(const char *bare_name, const float *data, int count) { /* look up "name[0]" when given "name" */ const size_t len = strlen(bare_name); @@ -765,19 +765,19 @@ void immUniformArray3fv(const char* bare_name, const float *data, int count) glUniform3fv(uniform->location, count, data); } -void immUniform4f(const char* name, float x, float y, float z, float w) +void immUniform4f(const char *name, float x, float y, float z, float w) { GET_UNIFORM glUniform4f(uniform->location, x, y, z, w); } -void immUniform4fv(const char* name, const float data[4]) +void immUniform4fv(const char *name, const float data[4]) { GET_UNIFORM glUniform4fv(uniform->location, 1, data); } -void immUniformArray4fv(const char* bare_name, const float *data, int count) +void immUniformArray4fv(const char *bare_name, const float *data, int count) { /* look up "name[0]" when given "name" */ const size_t len = strlen(bare_name); @@ -795,19 +795,19 @@ void immUniformArray4fv(const char* bare_name, const float *data, int count) glUniform4fv(uniform->location, count, data); } -void immUniformMatrix4fv(const char* name, const float data[4][4]) +void immUniformMatrix4fv(const char *name, const float data[4][4]) { GET_UNIFORM glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data); } -void immUniform1i(const char* name, int x) +void immUniform1i(const char *name, int x) { GET_UNIFORM glUniform1i(uniform->location, x); } -void immUniform4iv(const char* name, const int data[4]) +void immUniform4iv(const char *name, const int data[4]) { GET_UNIFORM glUniform4iv(uniform->location, 1, data); @@ -817,7 +817,7 @@ void immUniform4iv(const char* name, const int data[4]) void immUniformColor4f(float r, float g, float b, float a) { - const GPUShaderInput* uniform = GPU_shaderinterface_uniform_builtin(imm.shader_interface, GPU_UNIFORM_COLOR); + const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(imm.shader_interface, GPU_UNIFORM_COLOR); #if TRUST_NO_ONE assert(uniform != NULL); #endif diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index b794048087a..cf594367bdf 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -269,14 +269,14 @@ void imm_draw_circle_fill_3d(unsigned pos, float x, float y, float rad, int nseg } /** -* Draw a lined box. -* -* \param pos The vertex attribute number for position. -* \param x1 left. -* \param y1 bottom. -* \param x2 right. -* \param y2 top. -*/ + * Draw a lined box. + * + * \param pos The vertex attribute number for position. + * \param x1 left. + * \param y1 bottom. + * \param x2 right. + * \param y2 top. + */ void imm_draw_box_wire_2d(unsigned pos, float x1, float y1, float x2, float y2) { immBegin(GPU_PRIM_LINE_LOOP, 4); @@ -353,17 +353,17 @@ void imm_draw_cube_wire_3d(uint pos, const float co[3], const float aspect[3]) } /** -* Draw a cylinder. Replacement for gluCylinder. -* _warning_ : Slow, better use it only if you no other choices. -* -* \param pos The vertex attribute number for position. -* \param nor The vertex attribute number for normal. -* \param base Specifies the radius of the cylinder at z = 0. -* \param top Specifies the radius of the cylinder at z = height. -* \param height Specifies the height of the cylinder. -* \param slices Specifies the number of subdivisions around the z axis. -* \param stacks Specifies the number of subdivisions along the z axis. -*/ + * Draw a cylinder. Replacement for gluCylinder. + * _warning_ : Slow, better use it only if you no other choices. + * + * \param pos The vertex attribute number for position. + * \param nor The vertex attribute number for normal. + * \param base Specifies the radius of the cylinder at z = 0. + * \param top Specifies the radius of the cylinder at z = height. + * \param height Specifies the height of the cylinder. + * \param slices Specifies the number of subdivisions around the z axis. + * \param stacks Specifies the number of subdivisions along the z axis. + */ void imm_draw_cylinder_fill_normal_3d( unsigned int pos, unsigned int nor, float base, float top, float height, int slices, int stacks) { @@ -384,10 +384,10 @@ void imm_draw_cylinder_fill_normal_3d( float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); - float v1[3] = {r1 *cos2, r1 * sin2, h1}; - float v2[3] = {r2 *cos2, r2 * sin2, h2}; - float v3[3] = {r2 *cos1, r2 * sin1, h2}; - float v4[3] = {r1 *cos1, r1 * sin1, h1}; + float v1[3] = {r1 * cos2, r1 * sin2, h1}; + float v2[3] = {r2 * cos2, r2 * sin2, h2}; + float v3[3] = {r2 * cos1, r2 * sin1, h2}; + float v4[3] = {r1 * cos1, r1 * sin1, h1}; float n1[3], n2[3]; /* calc normals */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index bd0e35f5ab6..9566f091ada 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -659,14 +659,15 @@ GPUMaterial *GPU_material_from_nodetree( GPU_nodes_prune(&mat->nodes, mat->outlink); GPU_nodes_get_vertex_attributes(&mat->nodes, &mat->attribs); /* Create source code and search pass cache for an already compiled version. */ - mat->pass = GPU_generate_pass_new(mat, - mat->outlink, - &mat->attribs, - &mat->nodes, - vert_code, - geom_code, - frag_lib, - defines); + mat->pass = GPU_generate_pass_new( + mat, + mat->outlink, + &mat->attribs, + &mat->nodes, + vert_code, + geom_code, + frag_lib, + defines); if (mat->pass == NULL) { /* We had a cache hit and the shader has already failed to compile. */ diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c index 87fcc5f25a3..0fa4a158c00 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.c @@ -110,7 +110,7 @@ static void checkmat(cosnt float *m) } } -#define CHECKMAT(m) checkmat((const float*)m) +#define CHECKMAT(m) checkmat((const float *)m) #else diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index 7023e44d289..1c0e7ed4c1c 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -242,7 +242,7 @@ bool GPU_select_is_cached(void) const uint *GPU_select_buffer_near(const uint *buffer, int hits) { const uint *buffer_near = NULL; - uint depth_min = (uint)-1; + uint depth_min = (uint) - 1; for (int i = 0; i < hits; i++) { if (buffer[1] < depth_min) { BLI_assert(buffer[3] != -1); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index c5325b6ff21..1eae073d9c0 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -214,8 +214,9 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) } } -static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], - bool use_opensubdiv) +static void gpu_shader_standard_defines( + char defines[MAX_DEFINE_LENGTH], + bool use_opensubdiv) { /* some useful defines to detect GPU type */ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) { @@ -244,11 +245,12 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], * a global typedef which we don't have better place to define * in yet. */ - strcat(defines, "struct VertexData {\n" - " vec4 position;\n" - " vec3 normal;\n" - " vec2 uv;" - "};\n"); + strcat(defines, + "struct VertexData {\n" + " vec4 position;\n" + " vec3 normal;\n" + " vec2 uv;" + "};\n"); } #else UNUSED_VARS(use_opensubdiv); @@ -257,21 +259,23 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], return; } -GPUShader *GPU_shader_create(const char *vertexcode, - const char *fragcode, - const char *geocode, - const char *libcode, - const char *defines) +GPUShader *GPU_shader_create( + const char *vertexcode, + const char *fragcode, + const char *geocode, + const char *libcode, + const char *defines) { - return GPU_shader_create_ex(vertexcode, - fragcode, - geocode, - libcode, - defines, - GPU_SHADER_FLAGS_NONE, - GPU_SHADER_TFB_NONE, - NULL, - 0); + return GPU_shader_create_ex( + vertexcode, + fragcode, + geocode, + libcode, + defines, + GPU_SHADER_FLAGS_NONE, + GPU_SHADER_TFB_NONE, + NULL, + 0); } #define DEBUG_SHADER_NONE "" @@ -321,15 +325,16 @@ static void gpu_dump_shaders(const char **code, const int num_shaders, const cha printf("Shader file written to disk: %s\n", shader_path); } -GPUShader *GPU_shader_create_ex(const char *vertexcode, - const char *fragcode, - const char *geocode, - const char *libcode, - const char *defines, - const int flags, - const GPUShaderTFBType tf_type, - const char **tf_names, - const int tf_count) +GPUShader *GPU_shader_create_ex( + const char *vertexcode, + const char *fragcode, + const char *geocode, + const char *libcode, + const char *defines, + const int flags, + const GPUShaderTFBType tf_type, + const char **tf_names, + const int tf_count) { #ifdef WITH_OPENSUBDIV bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0; @@ -366,8 +371,9 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, return NULL; } - gpu_shader_standard_defines(standard_defines, - use_opensubdiv); + gpu_shader_standard_defines( + standard_defines, + use_opensubdiv); gpu_shader_standard_extensions(standard_extensions); if (vertexcode) { @@ -410,12 +416,13 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, #ifdef WITH_OPENSUBDIV /* TODO(sergey): Move to fragment shader source code generation. */ if (use_opensubdiv) { - source[num_source++] = + source[num_source++] = ( "#ifdef USE_OPENSUBDIV\n" "in block {\n" " VertexData v;\n" "} inpt;\n" - "#endif\n"; + "#endif\n" + ); } #endif @@ -502,13 +509,15 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, /* TODO(sergey): Find a better place for this. */ if (use_opensubdiv) { if (GLEW_VERSION_4_1) { - glProgramUniform1i(shader->program, - GPU_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, - 30); /* GL_TEXTURE30 */ - - glProgramUniform1i(shader->program, - GPU_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, - 31); /* GL_TEXTURE31 */ + glProgramUniform1i( + shader->program, + GPU_shaderinterface_uniform(shader->interface, "FVarDataOffsetBuffer")->location, + 30); /* GL_TEXTURE30 */ + + glProgramUniform1i( + shader->program, + GPU_shaderinterface_uniform(shader->interface, "FVarDataBuffer")->location, + 31); /* GL_TEXTURE31 */ } else { glUseProgram(shader->program); @@ -903,17 +912,20 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) if (shader == GPU_SHADER_EDGES_FRONT_BACK_PERSP && !GLEW_VERSION_3_2) { /* TODO: remove after switch to core profile (maybe) */ - static const GPUShaderStages legacy_fancy_edges = - { datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl, - datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl }; + static const GPUShaderStages legacy_fancy_edges = { + datatoc_gpu_shader_edges_front_back_persp_legacy_vert_glsl, + datatoc_gpu_shader_flat_color_alpha_test_0_frag_glsl, + }; stages = &legacy_fancy_edges; } if (shader == GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR && !GLEW_VERSION_3_2) { /* Dashed need geometry shader, which are not supported by legacy OpenGL, fallback to solid lines. */ /* TODO: remove after switch to core profile (maybe) */ - static const GPUShaderStages legacy_dashed_lines = { datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl, - datatoc_gpu_shader_2D_line_dashed_frag_glsl }; + static const GPUShaderStages legacy_dashed_lines = { + datatoc_gpu_shader_3D_line_dashed_uniform_color_legacy_vert_glsl, + datatoc_gpu_shader_2D_line_dashed_frag_glsl, + }; stages = &legacy_dashed_lines; } diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index ec2f52a2a2d..7e1d942da2d 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -42,9 +42,9 @@ #include #endif -static const char* BuiltinUniform_name(GPUUniformBuiltin u) +static const char *BuiltinUniform_name(GPUUniformBuiltin u) { - static const char* names[] = { + static const char *names[] = { [GPU_UNIFORM_NONE] = NULL, [GPU_UNIFORM_MODEL] = "ModelMatrix", @@ -76,7 +76,7 @@ static const char* BuiltinUniform_name(GPUUniformBuiltin u) return names[u]; } -GPU_INLINE bool match(const char* a, const char* b) +GPU_INLINE bool match(const char *a, const char *b) { return strcmp(a, b) == 0; } @@ -90,28 +90,31 @@ GPU_INLINE uint hash_string(const char *str) return i; } -GPU_INLINE void set_input_name(GPUShaderInterface* shaderface, GPUShaderInput* input, - const char* name, uint32_t name_len) +GPU_INLINE void set_input_name( + GPUShaderInterface *shaderface, GPUShaderInput *input, + const char *name, uint32_t name_len) { input->name_offset = shaderface->name_buffer_offset; input->name_hash = hash_string(name); shaderface->name_buffer_offset += name_len + 1; /* include NULL terminator */ } -GPU_INLINE void shader_input_to_bucket(GPUShaderInput* input, - GPUShaderInput* buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) +GPU_INLINE void shader_input_to_bucket( + GPUShaderInput *input, + GPUShaderInput *buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) { const uint bucket_index = input->name_hash % GPU_NUM_SHADERINTERFACE_BUCKETS; input->next = buckets[bucket_index]; buckets[bucket_index] = input; } -GPU_INLINE const GPUShaderInput* buckets_lookup(GPUShaderInput* const buckets[GPU_NUM_SHADERINTERFACE_BUCKETS], - const char *name_buffer, const char *name) +GPU_INLINE const GPUShaderInput *buckets_lookup( + GPUShaderInput *const buckets[GPU_NUM_SHADERINTERFACE_BUCKETS], + const char *name_buffer, const char *name) { const uint name_hash = hash_string(name); const uint bucket_index = name_hash % GPU_NUM_SHADERINTERFACE_BUCKETS; - const GPUShaderInput* input = buckets[bucket_index]; + const GPUShaderInput *input = buckets[bucket_index]; if (input == NULL) { /* Requested uniform is not found at all. */ return NULL; @@ -129,7 +132,7 @@ GPU_INLINE const GPUShaderInput* buckets_lookup(GPUShaderInput* const buckets[GP return NULL; } /* Work through possible collisions. */ - const GPUShaderInput* next = input; + const GPUShaderInput *next = input; while (next != NULL) { input = next; next = input->next; @@ -143,7 +146,7 @@ GPU_INLINE const GPUShaderInput* buckets_lookup(GPUShaderInput* const buckets[GP return NULL; /* not found */ } -GPU_INLINE void buckets_free(GPUShaderInput* buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) +GPU_INLINE void buckets_free(GPUShaderInput *buckets[GPU_NUM_SHADERINTERFACE_BUCKETS]) { for (uint bucket_index = 0; bucket_index < GPU_NUM_SHADERINTERFACE_BUCKETS; ++bucket_index) { GPUShaderInput *input = buckets[bucket_index]; @@ -155,13 +158,13 @@ GPU_INLINE void buckets_free(GPUShaderInput* buckets[GPU_NUM_SHADERINTERFACE_BUC } } -static bool setup_builtin_uniform(GPUShaderInput* input, const char* name) +static bool setup_builtin_uniform(GPUShaderInput *input, const char *name) { /* TODO: reject DOUBLE, IMAGE, ATOMIC_COUNTER gl_types */ /* detect built-in uniforms (name must match) */ for (GPUUniformBuiltin u = GPU_UNIFORM_NONE + 1; u < GPU_UNIFORM_CUSTOM; ++u) { - const char* builtin_name = BuiltinUniform_name(u); + const char *builtin_name = BuiltinUniform_name(u); if (match(name, builtin_name)) { input->builtin_type = u; return true; @@ -171,15 +174,15 @@ static bool setup_builtin_uniform(GPUShaderInput* input, const char* name) return false; } -static const GPUShaderInput* add_uniform(GPUShaderInterface* shaderface, const char* name) +static const GPUShaderInput *add_uniform(GPUShaderInterface *shaderface, const char *name) { - GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); input->location = glGetUniformLocation(shaderface->program, name); uint name_len = strlen(name); shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ - char* name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; + char *name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; strcpy(name_buffer, name); set_input_name(shaderface, input, name, name_len); @@ -192,17 +195,18 @@ static const GPUShaderInput* add_uniform(GPUShaderInterface* shaderface, const c shaderface->builtin_uniforms[input->builtin_type] = input; } #if DEBUG_SHADER_INTERFACE - printf("GPUShaderInterface %p, program %d, uniform[] '%s' at location %d\n", shaderface, - shaderface->program, - name, - input->location); + printf("GPUShaderInterface %p, program %d, uniform[] '%s' at location %d\n", + shaderface, + shaderface->program, + name, + input->location); #endif return input; } -GPUShaderInterface* GPU_shaderinterface_create(int32_t program) +GPUShaderInterface *GPU_shaderinterface_create(int32_t program) { - GPUShaderInterface* shaderface = calloc(1, sizeof(GPUShaderInterface)); + GPUShaderInterface *shaderface = calloc(1, sizeof(GPUShaderInterface)); shaderface->program = program; #if DEBUG_SHADER_INTERFACE @@ -223,16 +227,16 @@ GPUShaderInterface* GPU_shaderinterface_create(int32_t program) /* Attributes */ for (uint32_t i = 0; i < attr_len; ++i) { - GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; - char* name = shaderface->name_buffer + shaderface->name_buffer_offset; + char *name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; glGetActiveAttrib(program, i, remaining_buffer, &name_len, &input->size, &input->gl_type, name); /* remove "[0]" from array name */ - if (name[name_len-1] == ']') { - name[name_len-3] = '\0'; + if (name[name_len - 1] == ']') { + name[name_len - 3] = '\0'; name_len -= 3; } @@ -250,9 +254,9 @@ GPUShaderInterface* GPU_shaderinterface_create(int32_t program) } /* Uniform Blocks */ for (uint32_t i = 0; i < ubo_len; ++i) { - GPUShaderInput* input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; - char* name = shaderface->name_buffer + shaderface->name_buffer_offset; + char *name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name); @@ -269,19 +273,19 @@ GPUShaderInterface* GPU_shaderinterface_create(int32_t program) } /* Builtin Uniforms */ for (GPUUniformBuiltin u = GPU_UNIFORM_NONE + 1; u < GPU_UNIFORM_CUSTOM; ++u) { - const char* builtin_name = BuiltinUniform_name(u); + const char *builtin_name = BuiltinUniform_name(u); if (glGetUniformLocation(program, builtin_name) != -1) { - add_uniform((GPUShaderInterface*)shaderface, builtin_name); + add_uniform((GPUShaderInterface *)shaderface, builtin_name); } } /* Batches ref buffer */ shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = calloc(shaderface->batches_len, sizeof(GPUBatch*)); + shaderface->batches = calloc(shaderface->batches_len, sizeof(GPUBatch *)); return shaderface; } -void GPU_shaderinterface_discard(GPUShaderInterface* shaderface) +void GPU_shaderinterface_discard(GPUShaderInterface *shaderface) { /* Free memory used by buckets and has entries. */ buckets_free(shaderface->uniform_buckets); @@ -300,19 +304,19 @@ void GPU_shaderinterface_discard(GPUShaderInterface* shaderface) free(shaderface); } -const GPUShaderInput* GPU_shaderinterface_uniform(const GPUShaderInterface* shaderface, const char* name) +const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *shaderface, const char *name) { /* TODO: Warn if we find a matching builtin, since these can be looked up much quicker. */ - const GPUShaderInput* input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); + const GPUShaderInput *input = buckets_lookup(shaderface->uniform_buckets, shaderface->name_buffer, name); /* If input is not found add it so it's found next time. */ if (input == NULL) { - input = add_uniform((GPUShaderInterface*)shaderface, name); + input = add_uniform((GPUShaderInterface *)shaderface, name); } return (input->location != -1) ? input : NULL; } -const GPUShaderInput* GPU_shaderinterface_uniform_builtin( - const GPUShaderInterface* shaderface, GPUUniformBuiltin builtin) +const GPUShaderInput *GPU_shaderinterface_uniform_builtin( + const GPUShaderInterface *shaderface, GPUUniformBuiltin builtin) { #if TRUST_NO_ONE assert(builtin != GPU_UNIFORM_NONE); @@ -322,17 +326,17 @@ const GPUShaderInput* GPU_shaderinterface_uniform_builtin( return shaderface->builtin_uniforms[builtin]; } -const GPUShaderInput* GPU_shaderinterface_ubo(const GPUShaderInterface* shaderface, const char* name) +const GPUShaderInput *GPU_shaderinterface_ubo(const GPUShaderInterface *shaderface, const char *name) { return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name); } -const GPUShaderInput* GPU_shaderinterface_attr(const GPUShaderInterface* shaderface, const char* name) +const GPUShaderInput *GPU_shaderinterface_attr(const GPUShaderInterface *shaderface, const char *name) { return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name); } -void GPU_shaderinterface_add_batch_ref(GPUShaderInterface* shaderface, GPUBatch* batch) +void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch *batch) { int i; /* find first unused slot */ for (i = 0; i < shaderface->batches_len; ++i) { @@ -344,13 +348,13 @@ void GPU_shaderinterface_add_batch_ref(GPUShaderInterface* shaderface, GPUBatch* /* Not enough place, realloc the array. */ i = shaderface->batches_len; shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = realloc(shaderface->batches, sizeof(GPUBatch*) * shaderface->batches_len); - memset(shaderface->batches + i, 0, sizeof(GPUBatch*) * GPU_SHADERINTERFACE_REF_ALLOC_COUNT); + shaderface->batches = realloc(shaderface->batches, sizeof(GPUBatch *) * shaderface->batches_len); + memset(shaderface->batches + i, 0, sizeof(GPUBatch *) * GPU_SHADERINTERFACE_REF_ALLOC_COUNT); } shaderface->batches[i] = batch; } -void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface* shaderface, GPUBatch* batch) +void GPU_shaderinterface_remove_batch_ref(GPUShaderInterface *shaderface, GPUBatch *batch) { for (int i = 0; i < shaderface->batches_len; ++i) { if (shaderface->batches[i] == batch) { diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.c index 588d61640bd..68d846ccfba 100644 --- a/source/blender/gpu/intern/gpu_state.c +++ b/source/blender/gpu/intern/gpu_state.c @@ -66,10 +66,11 @@ void GPU_blend_set_func_separate( GPUBlendFunction src_rgb, GPUBlendFunction dst_rgb, GPUBlendFunction src_alpha, GPUBlendFunction dst_alpha) { - glBlendFuncSeparate(gpu_get_gl_blendfunction(src_rgb), - gpu_get_gl_blendfunction(dst_rgb), - gpu_get_gl_blendfunction(src_alpha), - gpu_get_gl_blendfunction(dst_alpha)); + glBlendFuncSeparate( + gpu_get_gl_blendfunction(src_rgb), + gpu_get_gl_blendfunction(dst_rgb), + gpu_get_gl_blendfunction(src_alpha), + gpu_get_gl_blendfunction(dst_alpha)); } void GPU_depth_test(bool enable) diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 52afe17d885..4465136dd0f 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -160,9 +160,10 @@ static int gpu_get_component_count(GPUTextureFormat format) /* Definitely not complete, edit according to the gl specification. */ static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format) { - if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, - GPU_DEPTH_COMPONENT16, - GPU_DEPTH_COMPONENT32F)) + if (ELEM(tex_format, + GPU_DEPTH_COMPONENT24, + GPU_DEPTH_COMPONENT16, + GPU_DEPTH_COMPONENT32F)) { BLI_assert(data_format == GPU_DATA_FLOAT); } @@ -196,9 +197,10 @@ static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_format) { - if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, - GPU_DEPTH_COMPONENT16, - GPU_DEPTH_COMPONENT32F)) + if (ELEM(tex_format, + GPU_DEPTH_COMPONENT24, + GPU_DEPTH_COMPONENT16, + GPU_DEPTH_COMPONENT32F)) { return GPU_DATA_FLOAT; } @@ -232,9 +234,10 @@ static GPUDataFormat gpu_get_data_format_from_tex_format(GPUTextureFormat tex_fo /* Definitely not complete, edit according to the gl specification. */ static GLenum gpu_get_gl_dataformat(GPUTextureFormat data_type, GPUTextureFormatFlag *format_flag) { - if (ELEM(data_type, GPU_DEPTH_COMPONENT24, - GPU_DEPTH_COMPONENT16, - GPU_DEPTH_COMPONENT32F)) + if (ELEM(data_type, + GPU_DEPTH_COMPONENT24, + GPU_DEPTH_COMPONENT16, + GPU_DEPTH_COMPONENT32F)) { *format_flag |= GPU_FORMAT_DEPTH; return GL_DEPTH_COMPONENT; @@ -1161,8 +1164,9 @@ void GPU_texture_bind(GPUTexture *tex, int number) if ((G.debug & G_DEBUG)) { for (int i = 0; i < GPU_TEX_MAX_FBO_ATTACHED; ++i) { if (tex->fb[i] && GPU_framebuffer_bound(tex->fb[i])) { - fprintf(stderr, "Feedback loop warning!: Attempting to bind " - "texture attached to current framebuffer!\n"); + fprintf(stderr, + "Feedback loop warning!: Attempting to bind " + "texture attached to current framebuffer!\n"); BLI_assert(0); /* Should never happen! */ break; } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index 5b29913800d..b25d9fc3a2c 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -49,16 +49,16 @@ static GLenum convert_usage_type_to_gl(GPUUsageType type) return table[type]; } -GPUVertBuf* GPU_vertbuf_create(GPUUsageType usage) +GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage) { - GPUVertBuf* verts = malloc(sizeof(GPUVertBuf)); + GPUVertBuf *verts = malloc(sizeof(GPUVertBuf)); GPU_vertbuf_init(verts, usage); return verts; } -GPUVertBuf* GPU_vertbuf_create_with_format_ex(const GPUVertFormat* format, GPUUsageType usage) +GPUVertBuf *GPU_vertbuf_create_with_format_ex(const GPUVertFormat *format, GPUUsageType usage) { - GPUVertBuf* verts = GPU_vertbuf_create(usage); + GPUVertBuf *verts = GPU_vertbuf_create(usage); GPU_vertformat_copy(&verts->format, format); if (!format->packed) { VertexFormat_pack(&verts->format); @@ -69,14 +69,14 @@ GPUVertBuf* GPU_vertbuf_create_with_format_ex(const GPUVertFormat* format, GPUUs /* TODO: implement those memory savings */ } -void GPU_vertbuf_init(GPUVertBuf* verts, GPUUsageType usage) +void GPU_vertbuf_init(GPUVertBuf *verts, GPUUsageType usage) { memset(verts, 0, sizeof(GPUVertBuf)); verts->usage = usage; verts->dirty = true; } -void GPU_vertbuf_init_with_format_ex(GPUVertBuf* verts, const GPUVertFormat* format, GPUUsageType usage) +void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, const GPUVertFormat *format, GPUUsageType usage) { GPU_vertbuf_init(verts, usage); GPU_vertformat_copy(&verts->format, format); @@ -85,7 +85,7 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf* verts, const GPUVertFormat* for } } -void GPU_vertbuf_discard(GPUVertBuf* verts) +void GPU_vertbuf_discard(GPUVertBuf *verts) { if (verts->vbo_id) { GPU_buf_id_free(verts->vbo_id); @@ -99,15 +99,15 @@ void GPU_vertbuf_discard(GPUVertBuf* verts) free(verts); } -uint GPU_vertbuf_size_get(const GPUVertBuf* verts) +uint GPU_vertbuf_size_get(const GPUVertBuf *verts) { return vertex_buffer_size(&verts->format, verts->vertex_len); } /* create a new allocation, discarding any existing data */ -void GPU_vertbuf_data_alloc(GPUVertBuf* verts, uint v_len) +void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) { - GPUVertFormat* format = &verts->format; + GPUVertFormat *format = &verts->format; if (!format->packed) { VertexFormat_pack(format); } @@ -133,7 +133,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf* verts, uint v_len) } /* resize buffer keeping existing data */ -void GPU_vertbuf_data_resize(GPUVertBuf* verts, uint v_len) +void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) { #if TRUST_NO_ONE assert(verts->data != NULL); @@ -152,7 +152,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf* verts, uint v_len) /* Set vertex count but does not change allocation. * Only this many verts will be uploaded to the GPU and rendered. * This is usefull for streaming data. */ -void GPU_vertbuf_vertex_count_set(GPUVertBuf* verts, uint v_len) +void GPU_vertbuf_vertex_count_set(GPUVertBuf *verts, uint v_len) { #if TRUST_NO_ONE assert(verts->data != NULL); /* only for dynamic data */ @@ -166,10 +166,10 @@ void GPU_vertbuf_vertex_count_set(GPUVertBuf* verts, uint v_len) verts->vertex_len = v_len; } -void GPU_vertbuf_attr_set(GPUVertBuf* verts, uint a_idx, uint v_idx, const void* data) +void GPU_vertbuf_attr_set(GPUVertBuf *verts, uint a_idx, uint v_idx, const void *data) { - const GPUVertFormat* format = &verts->format; - const GPUVertAttr* a = format->attribs + a_idx; + const GPUVertFormat *format = &verts->format; + const GPUVertAttr *a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -177,13 +177,13 @@ void GPU_vertbuf_attr_set(GPUVertBuf* verts, uint a_idx, uint v_idx, const void* assert(verts->data != NULL); #endif verts->dirty = true; - memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz); + memcpy((GLubyte *)verts->data + a->offset + v_idx * format->stride, data, a->sz); } -void GPU_vertbuf_attr_fill(GPUVertBuf* verts, uint a_idx, const void* data) +void GPU_vertbuf_attr_fill(GPUVertBuf *verts, uint a_idx, const void *data) { - const GPUVertFormat* format = &verts->format; - const GPUVertAttr* a = format->attribs + a_idx; + const GPUVertFormat *format = &verts->format; + const GPUVertAttr *a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -193,10 +193,10 @@ void GPU_vertbuf_attr_fill(GPUVertBuf* verts, uint a_idx, const void* data) GPU_vertbuf_attr_fill_stride(verts, a_idx, stride, data); } -void GPU_vertbuf_attr_fill_stride(GPUVertBuf* verts, uint a_idx, uint stride, const void* data) +void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts, uint a_idx, uint stride, const void *data) { - const GPUVertFormat* format = &verts->format; - const GPUVertAttr* a = format->attribs + a_idx; + const GPUVertFormat *format = &verts->format; + const GPUVertAttr *a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -212,15 +212,15 @@ void GPU_vertbuf_attr_fill_stride(GPUVertBuf* verts, uint a_idx, uint stride, co else { /* we must copy it per vertex */ for (uint v = 0; v < vertex_len; ++v) { - memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz); + memcpy((GLubyte *)verts->data + a->offset + v * format->stride, (const GLubyte *)data + v * stride, a->sz); } } } -void GPU_vertbuf_attr_get_raw_data(GPUVertBuf* verts, uint a_idx, GPUVertBufRaw *access) +void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts, uint a_idx, GPUVertBufRaw *access) { - const GPUVertFormat* format = &verts->format; - const GPUVertAttr* a = format->attribs + a_idx; + const GPUVertFormat *format = &verts->format; + const GPUVertAttr *a = format->attribs + a_idx; #if TRUST_NO_ONE assert(a_idx < format->attr_len); @@ -231,14 +231,14 @@ void GPU_vertbuf_attr_get_raw_data(GPUVertBuf* verts, uint a_idx, GPUVertBufRaw access->size = a->sz; access->stride = format->stride; - access->data = (GLubyte*)verts->data + a->offset; + access->data = (GLubyte *)verts->data + a->offset; access->data_init = access->data; #if TRUST_NO_ONE access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride); #endif } -static void VertBuffer_upload_data(GPUVertBuf* verts) +static void VertBuffer_upload_data(GPUVertBuf *verts) { uint buffer_sz = GPU_vertbuf_size_get(verts); @@ -254,7 +254,7 @@ static void VertBuffer_upload_data(GPUVertBuf* verts) verts->dirty = false; } -void GPU_vertbuf_use(GPUVertBuf* verts) +void GPU_vertbuf_use(GPUVertBuf *verts) { glBindBuffer(GL_ARRAY_BUFFER, verts->vbo_id); if (verts->dirty) { diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index d0a907bcd0d..f1f75f449d4 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -40,7 +40,7 @@ #include #endif -void GPU_vertformat_clear(GPUVertFormat* format) +void GPU_vertformat_clear(GPUVertFormat *format) { #if TRUST_NO_ONE memset(format, 0, sizeof(GPUVertFormat)); @@ -56,7 +56,7 @@ void GPU_vertformat_clear(GPUVertFormat* format) #endif } -void GPU_vertformat_copy(GPUVertFormat* dest, const GPUVertFormat* src) +void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src) { /* copy regular struct fields */ memcpy(dest, src, sizeof(GPUVertFormat)); @@ -90,7 +90,7 @@ static unsigned comp_sz(GPUVertCompType type) #if TRUST_NO_ONE assert(type <= GPU_COMP_F32); /* other types have irregular sizes (not bytes) */ #endif - const GLubyte sizes[] = {1,1,2,2,4,4,4}; + const GLubyte sizes[] = {1, 1, 2, 2, 4, 4, 4}; return sizes[type]; } @@ -116,7 +116,7 @@ static unsigned attrib_align(const GPUVertAttr *a) } } -unsigned vertex_buffer_size(const GPUVertFormat* format, unsigned vertex_len) +unsigned vertex_buffer_size(const GPUVertFormat *format, unsigned vertex_len) { #if TRUST_NO_ONE assert(format->packed && format->stride > 0); @@ -124,10 +124,10 @@ unsigned vertex_buffer_size(const GPUVertFormat* format, unsigned vertex_len) return format->stride * vertex_len; } -static const char* copy_attrib_name(GPUVertFormat* format, const char* name) +static const char *copy_attrib_name(GPUVertFormat *format, const char *name) { /* strncpy does 110% of what we need; let's do exactly 100% */ - char* name_copy = format->names + format->name_offset; + char *name_copy = format->names + format->name_offset; unsigned available = GPU_VERT_ATTR_NAMES_BUF_LEN - format->name_offset; bool terminated = false; @@ -149,7 +149,9 @@ static const char* copy_attrib_name(GPUVertFormat* format, const char* name) return name_copy; } -unsigned GPU_vertformat_attr_add(GPUVertFormat* format, const char* name, GPUVertCompType comp_type, unsigned comp_len, GPUVertFetchMode fetch_mode) +unsigned GPU_vertformat_attr_add( + GPUVertFormat *format, const char *name, + GPUVertCompType comp_type, unsigned comp_len, GPUVertFetchMode fetch_mode) { #if TRUST_NO_ONE assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ @@ -178,7 +180,7 @@ unsigned GPU_vertformat_attr_add(GPUVertFormat* format, const char* name, GPUVer format->name_len++; /* multiname support */ const unsigned attrib_id = format->attr_len++; - GPUVertAttr* attrib = format->attribs + attrib_id; + GPUVertAttr *attrib = format->attribs + attrib_id; attrib->name[attrib->name_len++] = copy_attrib_name(format, name); attrib->comp_type = comp_type; @@ -191,9 +193,9 @@ unsigned GPU_vertformat_attr_add(GPUVertFormat* format, const char* name, GPUVer return attrib_id; } -void GPU_vertformat_alias_add(GPUVertFormat* format, const char* alias) +void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias) { - GPUVertAttr* attrib = format->attribs + (format->attr_len - 1); + GPUVertAttr *attrib = format->attribs + (format->attr_len - 1); #if TRUST_NO_ONE assert(format->name_len < GPU_VERT_ATTR_MAX_LEN); /* there's room for more */ assert(attrib->name_len < GPU_VERT_ATTR_MAX_NAMES); @@ -221,7 +223,7 @@ static void show_pack(unsigned a_idx, unsigned sz, unsigned pad) } #endif -void VertexFormat_pack(GPUVertFormat* format) +void VertexFormat_pack(GPUVertFormat *format) { /* For now, attributes are packed in the order they were added, * making sure each attrib is naturally aligned (add padding where necessary) @@ -231,7 +233,7 @@ void VertexFormat_pack(GPUVertFormat* format) /* TODO: realloc just enough to hold the final combo string. And just enough to * hold used attribs, not all 16. */ - GPUVertAttr* a0 = format->attribs + 0; + GPUVertAttr *a0 = format->attribs + 0; a0->offset = 0; unsigned offset = a0->sz; @@ -240,7 +242,7 @@ void VertexFormat_pack(GPUVertFormat* format) #endif for (unsigned a_idx = 1; a_idx < format->attr_len; ++a_idx) { - GPUVertAttr* a = format->attribs + a_idx; + GPUVertAttr *a = format->attribs + a_idx; unsigned mid_padding = padding(offset, attrib_align(a)); offset += mid_padding; a->offset = offset; -- cgit v1.2.3 From c64262a05ab0e9a7c5b69fc83ea53fb5825f442c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jul 2018 18:06:32 +0200 Subject: OpenSubdiv: Add API to evaluate face-varying data There are move changes along the line to keep everything working from from C. --- .../internal/opensubdiv_converter_factory.cc | 2 + .../internal/opensubdiv_converter_internal.cc | 26 ++++++++++ .../internal/opensubdiv_converter_internal.h | 5 ++ .../internal/opensubdiv_topology_refiner.cc | 60 ++++++++++++++++++++-- intern/opensubdiv/opensubdiv_capi_type.h | 15 ++++++ intern/opensubdiv/opensubdiv_converter_capi.h | 15 +----- .../opensubdiv/opensubdiv_topology_refiner_capi.h | 43 +++++++++++++++- 7 files changed, 148 insertions(+), 18 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index bd6edbb9648..48516cc80b7 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -383,6 +383,8 @@ TopologyRefinerFactory::assignFaceVaryingTopology( const int num_uvs = converter->getNumUVCoordinates(converter); // Fill in per-corner index of the UV. const int channel = createBaseFVarChannel(refiner, num_uvs); + // TODO(sergey): Need to check whether converter changed the winding of + // face to match OpenSubdiv's expectations. for (int face_index = 0; face_index < num_faces; ++face_index) { Far::IndexArray dst_face_uvs = getBaseFaceFVarValues(refiner, face_index, channel); diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc index 56b5657121d..32815dc34dc 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc @@ -49,6 +49,10 @@ getFVarLinearInterpolationFromCAPI( return Options::FVAR_LINEAR_NONE; case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: return Options::FVAR_LINEAR_CORNERS_ONLY; + case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1: + return Options::FVAR_LINEAR_CORNERS_PLUS1; + case OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2: + return Options::FVAR_LINEAR_CORNERS_PLUS2; case OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: return Options::FVAR_LINEAR_BOUNDARIES; case OSD_FVAR_LINEAR_INTERPOLATION_ALL: @@ -58,6 +62,28 @@ getFVarLinearInterpolationFromCAPI( return Options::FVAR_LINEAR_NONE; } +OpenSubdiv_FVarLinearInterpolation +getCAPIFVarLinearInterpolationFromOSD( + OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation) { + typedef OpenSubdiv::Sdc::Options Options; + switch (linear_interpolation) { + case Options::FVAR_LINEAR_NONE: + return OSD_FVAR_LINEAR_INTERPOLATION_NONE; + case Options::FVAR_LINEAR_CORNERS_ONLY: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + case Options::FVAR_LINEAR_CORNERS_PLUS1: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1; + case Options::FVAR_LINEAR_CORNERS_PLUS2: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2; + case Options::FVAR_LINEAR_BOUNDARIES: + return OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES; + case Options::FVAR_LINEAR_ALL: + return OSD_FVAR_LINEAR_INTERPOLATION_ALL; + } + assert(!"Unknown fvar linear interpolation passed via C-API"); + return OSD_FVAR_LINEAR_INTERPOLATION_NONE; +} + float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, int edge_index) { if (converter->getNumEdgeFaces(converter, edge_index) == 2) { diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h index 68518d67884..c47cdd1004d 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_internal.h +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h @@ -41,6 +41,11 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFromCAPI( OpenSubdiv_FVarLinearInterpolation linear_interpolation); +// Similar to above, just other way around. +OpenSubdiv_FVarLinearInterpolation +getCAPIFVarLinearInterpolationFromOSD( + OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation); + // Get edge sharpness in a way which makes OpenSubdiv happy. float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, int edge_index); diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc index aa6ba953ef9..93f6fdc14a1 100644 --- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc @@ -46,6 +46,9 @@ bool getIsAdaptive(const OpenSubdiv_TopologyRefiner* topology_refiner) { return topology_refiner->internal->settings.is_adaptive; } +//////////////////////////////////////////////////////////////////////////////// +// Query basic topology information from base level. + int getNumVertices(const OpenSubdiv_TopologyRefiner* topology_refiner) { return getOSDTopologyBaseLevel(topology_refiner)->GetNumVertices(); } @@ -58,6 +61,9 @@ int getNumFaces(const OpenSubdiv_TopologyRefiner* topology_refiner) { return getOSDTopologyBaseLevel(topology_refiner)->GetNumFaces(); } +//////////////////////////////////////////////////////////////////////////////// +// PTex face geometry queries. + int getNumFaceVertices(const OpenSubdiv_TopologyRefiner* topology_refiner, const int face_index) { const OpenSubdiv::Far::TopologyLevel* base_level = @@ -97,18 +103,59 @@ void fillFacePtexIndexOffset(const OpenSubdiv_TopologyRefiner* topology_refiner, } } +////////////////////////////////////////////////////////////////////////////// +// Face-varying data. + +int getNumFVarChannels( + const struct OpenSubdiv_TopologyRefiner* topology_refiner) { + const OpenSubdiv::Far::TopologyLevel* base_level = + getOSDTopologyBaseLevel(topology_refiner); + return base_level->GetNumFVarChannels(); +} + +OpenSubdiv_FVarLinearInterpolation getFVarLinearInterpolation( + const struct OpenSubdiv_TopologyRefiner* topology_refiner) { + return opensubdiv_capi::getCAPIFVarLinearInterpolationFromOSD( + getOSDTopologyRefiner(topology_refiner)->GetFVarLinearInterpolation()); +} + +int getNumFVarValues( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int channel) { + const OpenSubdiv::Far::TopologyLevel* base_level = + getOSDTopologyBaseLevel(topology_refiner); + return base_level->GetNumFVarValues(channel); +} + +const int* getFaceFVarValueIndices( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index, + const int channel) { + const OpenSubdiv::Far::TopologyLevel* base_level = + getOSDTopologyBaseLevel(topology_refiner); + return &base_level->GetFaceFVarValues(face_index, channel)[0]; +} + +////////////////////////////////////////////////////////////////////////////// +// Internal helpers. + void assignFunctionPointers(OpenSubdiv_TopologyRefiner* topology_refiner) { topology_refiner->getSubdivisionLevel = getSubdivisionLevel; topology_refiner->getIsAdaptive = getIsAdaptive; - + // Basic topology information. topology_refiner->getNumVertices = getNumVertices; topology_refiner->getNumEdges = getNumEdges; topology_refiner->getNumFaces = getNumFaces; topology_refiner->getNumFaceVertices = getNumFaceVertices; - + // PTex face geometry. topology_refiner->getNumFacePtexFaces = getNumFacePtexFaces; topology_refiner->getNumPtexFaces = getNumPtexFaces; topology_refiner->fillFacePtexIndexOffset = fillFacePtexIndexOffset; + // Face-varying data. + topology_refiner->getNumFVarChannels = getNumFVarChannels; + topology_refiner->getFVarLinearInterpolation = getFVarLinearInterpolation; + topology_refiner->getNumFVarValues = getNumFVarValues; + topology_refiner->getFaceFVarValueIndices = getFaceFVarValueIndices; } OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() { @@ -125,9 +172,14 @@ OpenSubdiv_TopologyRefiner* allocateTopologyRefiner() { OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter( OpenSubdiv_Converter* converter, const OpenSubdiv_TopologyRefinerSettings* settings) { - OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner(); - topology_refiner->internal->osd_topology_refiner = + OpenSubdiv::Far::TopologyRefiner* osd_topology_refiner = opensubdiv_capi::createOSDTopologyRefinerFromConverter(converter); + if (osd_topology_refiner == NULL) { + // Happens on empty or bad topology. + return NULL; + } + OpenSubdiv_TopologyRefiner* topology_refiner = allocateTopologyRefiner(); + topology_refiner->internal->osd_topology_refiner = osd_topology_refiner; // Store setting which we want to keep track of and which can not be stored // in OpenSubdiv's descriptor yet. topology_refiner->internal->settings = *settings; diff --git a/intern/opensubdiv/opensubdiv_capi_type.h b/intern/opensubdiv/opensubdiv_capi_type.h index 04fe2afff53..b326e53e168 100644 --- a/intern/opensubdiv/opensubdiv_capi_type.h +++ b/intern/opensubdiv/opensubdiv_capi_type.h @@ -34,6 +34,21 @@ typedef enum eOpenSubdivEvaluator { OPENSUBDIV_EVALUATOR_GLSL_COMPUTE = (1 << 5), } eOpenSubdivEvaluator; +typedef enum OpenSubdiv_SchemeType { + OSD_SCHEME_BILINEAR, + OSD_SCHEME_CATMARK, + OSD_SCHEME_LOOP, +} OpenSubdiv_SchemeType; + +typedef enum OpenSubdiv_FVarLinearInterpolation { + OSD_FVAR_LINEAR_INTERPOLATION_NONE, + OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, + OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS1, + OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_PLUS2, + OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, + OSD_FVAR_LINEAR_INTERPOLATION_ALL, +} OpenSubdiv_FVarLinearInterpolation; + #ifdef __cplusplus } #endif diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index b16d6eb6c8f..a939f1117e0 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -19,23 +19,12 @@ #ifndef OPENSUBDIV_CONVERTER_CAPI_H_ #define OPENSUBDIV_CONVERTER_CAPI_H_ +#include "opensubdiv_capi_type.h" + #ifdef __cplusplus extern "C" { #endif -typedef enum OpenSubdiv_SchemeType { - OSD_SCHEME_BILINEAR, - OSD_SCHEME_CATMARK, - OSD_SCHEME_LOOP, -} OpenSubdiv_SchemeType; - -typedef enum OpenSubdiv_FVarLinearInterpolation { - OSD_FVAR_LINEAR_INTERPOLATION_NONE, - OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, - OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, - OSD_FVAR_LINEAR_INTERPOLATION_ALL, -} OpenSubdiv_FVarLinearInterpolation; - typedef struct OpenSubdiv_Converter { OpenSubdiv_SchemeType (*getSchemeType)( const struct OpenSubdiv_Converter* converter); diff --git a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h index 103ccd2c1f9..fe4db0ca67c 100644 --- a/intern/opensubdiv/opensubdiv_topology_refiner_capi.h +++ b/intern/opensubdiv/opensubdiv_topology_refiner_capi.h @@ -21,6 +21,8 @@ #include // for bool +#include "opensubdiv_capi_type.h" + #ifdef __cplusplus extern "C" { #endif @@ -45,7 +47,16 @@ typedef struct OpenSubdiv_TopologyRefiner { bool (*getIsAdaptive)( const struct OpenSubdiv_TopologyRefiner* topology_refiner); + // NOTE: All queries are querying base level. + // + // TODO(sergey): Consider making it more obvious in function naming, + // but since it's unlikely (or at least, will be uncommon use) for API + // which queries final geometry, we should be fine with this name for + // now. + + ////////////////////////////////////////////////////////////////////////////// // Query basic topology information from base level. + int (*getNumVertices)( const struct OpenSubdiv_TopologyRefiner* topology_refiner); int (*getNumEdges)( @@ -56,6 +67,9 @@ typedef struct OpenSubdiv_TopologyRefiner { const struct OpenSubdiv_TopologyRefiner* topology_refiner, const int face_index); + ////////////////////////////////////////////////////////////////////////////// + // PTex face geometry queries. + // Ptex face corresponds to OpenSubdiv's internal "patch" and to Blender's // subdivision grid. The rule commes as: // - Triangle face consist of 3 ptex faces, ordered in the order of @@ -79,6 +93,31 @@ typedef struct OpenSubdiv_TopologyRefiner { const struct OpenSubdiv_TopologyRefiner* topology_refiner, int* face_ptex_index_offset); + ////////////////////////////////////////////////////////////////////////////// + // Face-varying data. + + // Number of face-varying channels (or how they are called in Blender layers). + int (*getNumFVarChannels)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + // Get face-varying interpolation type. + OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner); + // Get total number of face-varying values in a particular channel. + int (*getNumFVarValues)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int channel); + // Get face-varying value indices associated with a particular face. + // + // This is an array of indices inside of face-varying array, array elements + // are aligned with face corners (or loops in Blender terminology). + const int* (*getFaceFVarValueIndices)( + const struct OpenSubdiv_TopologyRefiner* topology_refiner, + const int face_index, + const int channel); + + ////////////////////////////////////////////////////////////////////////////// + // Internal use. + // Internal storage for the use in this module only. // // Tease: Contains actual OpenSubdiv's refiner and (optionally) some other @@ -86,6 +125,8 @@ typedef struct OpenSubdiv_TopologyRefiner { struct OpenSubdiv_TopologyRefinerInternal* internal; } OpenSubdiv_TopologyRefiner; +// NOTE: Will return NULL in cases of bad topology. +// NOTE: Mesh without faces is considered a bad topology. OpenSubdiv_TopologyRefiner* openSubdiv_createTopologyRefinerFromConverter( struct OpenSubdiv_Converter* converter, const OpenSubdiv_TopologyRefinerSettings* settings); @@ -101,7 +142,7 @@ void openSubdiv_deleteTopologyRefiner( // complicated parts of subdivision process. bool openSubdiv_topologyRefinerCompareWithConverter( const OpenSubdiv_TopologyRefiner* topology_refiner, - const OpenSubdiv_Converter* converter); + const struct OpenSubdiv_Converter* converter); #ifdef __cplusplus } -- cgit v1.2.3 From 433bb9bbcb52fc30aa44def202ca38b4a6e7abac Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jul 2018 18:07:26 +0200 Subject: Subsurf: Begin new subdivision surface module The idea is to use this as a replacement of old CCG, now it is based on OpenSubdiv. The goal is to reduce any possible overhead which was happening with OpenSubdiv used by CCG. Currently implemented/supported: - Creation from mesh, including topology on OpenSubdiv side, its refinement. - Evaluation of limit point, first order derivatives, normal, and face-varying data for individual coarse position. - Evaluation of whole patches. Currently not optimized, uses evaluation of individual coarse positions. - Creation of Mesh from subdiv, with all geometry being real: all mvert, medge, mloop, and mpoly. This includes custom data interpolation, but all faces currently are getting separated (they are converted to ptex patches, which we need to weld back together). Still need to support lighter weights grids and such, but this is already a required part to have subsurf working in the middle of modifier stack. Annoying part is ifdef all over the place, to keep it compilable when OpenSubdiv is disabled. More cleaner approach would be to have stub API for OpenSubdiv, so everything gets ifdef-ed in a much fewer places. --- source/blender/blenkernel/BKE_subdiv.h | 184 +++++ source/blender/blenkernel/intern/subdiv.c | 114 +++ .../blender/blenkernel/intern/subdiv_converter.c | 65 ++ .../blender/blenkernel/intern/subdiv_converter.h | 57 ++ .../blenkernel/intern/subdiv_converter_mesh.c | 471 +++++++++++ source/blender/blenkernel/intern/subdiv_eval.c | 319 ++++++++ source/blender/blenkernel/intern/subdiv_mesh.c | 910 +++++++++++++++++++++ 7 files changed, 2120 insertions(+) create mode 100644 source/blender/blenkernel/BKE_subdiv.h create mode 100644 source/blender/blenkernel/intern/subdiv.c create mode 100644 source/blender/blenkernel/intern/subdiv_converter.c create mode 100644 source/blender/blenkernel/intern/subdiv_converter.h create mode 100644 source/blender/blenkernel/intern/subdiv_converter_mesh.c create mode 100644 source/blender/blenkernel/intern/subdiv_eval.c create mode 100644 source/blender/blenkernel/intern/subdiv_mesh.c diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h new file mode 100644 index 00000000000..92fb1167f55 --- /dev/null +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -0,0 +1,184 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __BKE_SUBDIV_H__ +#define __BKE_SUBDIV_H__ + +#include "BLI_sys_types.h" + +struct Mesh; +struct OpenSubdiv_Converter; +struct OpenSubdiv_Evaluator; +struct OpenSubdiv_TopologyRefiner; + +/** \file BKE_subdiv.h + * \ingroup bke + * \since July 2018 + * \author Sergey Sharybin + */ + +typedef enum { + SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE, + SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY, + SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES, + SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL, +} eSubdivFVarLinearInterpolation; + +typedef struct SubdivSettings { + bool is_simple; + bool is_adaptive; + int level; + eSubdivFVarLinearInterpolation fvar_linear_interpolation; +} SubdivSettings; + +typedef struct Subdiv { + /* Settings this subdivision surface is created for. + * + * It is read-only after assignment in BKE_subdiv_new_from_FOO(). + */ + SubdivSettings settings; + + /* Total number of ptex faces on subdivision level 0. + * + * Ptex face is what is internally used by OpenSubdiv for evaluator. It is + * a quad face, which corresponds to Blender's legacy Catmull Clark grids. + * + * Basically, here is a correspondence between polygons and ptex faces: + * - Triangle consists of 3 PTex faces. + * - Quad is a single PTex face. + * - N-gon is N PTex faces. + * + * This value is initialized in BKE_subdiv_new_from_FOO() and is read-only + * after this. + */ + int num_ptex_faces; + + /* Indexed by base face index, element indicates total number of ptex faces + * created for preceding base faces. + */ + int *face_ptex_offset; + + /* Topology refiner includes all the glue logic to feed Blender side + * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh + * drawer. + */ + struct OpenSubdiv_TopologyRefiner *topology_refiner; + + /* CPU side evaluator. */ + struct OpenSubdiv_Evaluator *evaluator; +} Subdiv; + +/* ============================== CONSTRUCTION ============================== */ + +Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, + struct OpenSubdiv_Converter *converter); + +Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, + struct Mesh *mesh); + +void BKE_subdiv_free(Subdiv *subdiv); + +/* ============================= EVALUATION API ============================= */ + +void BKE_subdiv_eval_begin(Subdiv *subdiv); +void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const struct Mesh *mesh); + +/* Single point queries. */ + +void BKE_subdiv_eval_limit_point( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3]); +void BKE_subdiv_eval_limit_point_and_derivatives( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], float dPdu[3], float dPdv[3]); +void BKE_subdiv_eval_limit_point_and_normal( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], float N[3]); +void BKE_subdiv_eval_limit_point_and_short_normal( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], short N[3]); + +void BKE_subdiv_eval_face_varying( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float varying[2]); + +/* Patch queries at given resolution. + * + * Will evaluate patch at uniformly distributed (u, v) coordinates on a grid + * of given resolution, producing resolution^2 evaluation points. The order + * goes as u in rows, v in columns. + */ + +void BKE_subdiv_eval_limit_patch_resolution_point( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *buffer, const int offset, const int stride); +void BKE_subdiv_eval_limit_patch_resolution_point_and_derivatives( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *du_buffer, const int du_offset, const int du_stride, + void *dv_buffer, const int dv_offset, const int dv_stride); +void BKE_subdiv_eval_limit_patch_resolution_point_and_normal( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *normal_buffer, const int normal_offset, const int normal_stride); +void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *normal_buffer, const int normal_offset, const int normal_stride); + +/* =========================== SUBDIV TO MESH API =========================== */ + +typedef struct SubdivToMeshSettings { + /* Resolution at which ptex are being evaluated. + * This defines how many vertices final mesh will have: every ptex has + * resolution^2 vertices. + */ + int resolution; +} SubdivToMeshSettings; + +/* Create real hi-res mesh from subdivision, all geometry is "real". */ +struct Mesh *BKE_subdiv_to_mesh( + Subdiv *subdiv, + const SubdivToMeshSettings *settings, + const struct Mesh *coarse_mesh); + +#endif /* __BKE_SUBDIV_H__ */ diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c new file mode 100644 index 00000000000..72cd39983b9 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv.c @@ -0,0 +1,114 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/subdiv.c + * \ingroup bke + */ + +#include "BKE_subdiv.h" + +#include "BLI_utildefines.h" + +#include "MEM_guardedalloc.h" + +#include "subdiv_converter.h" + +#ifdef WITH_OPENSUBDIV +# include "opensubdiv_capi.h" +# include "opensubdiv_converter_capi.h" +# include "opensubdiv_evaluator_capi.h" +# include "opensubdiv_topology_refiner_capi.h" +#endif + +#ifdef WITH_OPENSUBDIV +static void update_subdiv_after_topology_change(Subdiv *subdiv) +{ + /* Count ptex faces. */ + subdiv->num_ptex_faces = subdiv->topology_refiner->getNumPtexFaces( + subdiv->topology_refiner); + /* Initialize offset of base faces in ptex indices. */ + MEM_SAFE_FREE(subdiv->face_ptex_offset); + subdiv->face_ptex_offset = MEM_malloc_arrayN(subdiv->num_ptex_faces, + sizeof(int), + "subdiv ptex offset"); + subdiv->topology_refiner->fillFacePtexIndexOffset( + subdiv->topology_refiner, + subdiv->face_ptex_offset); +} +#endif + +Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, + struct OpenSubdiv_Converter *converter) +{ +#ifdef WITH_OPENSUBDIV + OpenSubdiv_TopologyRefinerSettings topology_refiner_settings; + topology_refiner_settings.level = settings->level; + topology_refiner_settings.is_adaptive = settings->is_adaptive; + struct OpenSubdiv_TopologyRefiner *osd_topology_refiner = + openSubdiv_createTopologyRefinerFromConverter( + converter, &topology_refiner_settings); + if (osd_topology_refiner == NULL) { + return NULL; + } + Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converetr"); + subdiv->settings = *settings; + subdiv->topology_refiner = osd_topology_refiner; + subdiv->evaluator = NULL; + update_subdiv_after_topology_change(subdiv); + return subdiv; +#else + UNUSED_VARS(settings, converter); + return NULL; +#endif +} + +Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, + struct Mesh *mesh) +{ +#ifdef WITH_OPENSUBDIV + OpenSubdiv_Converter converter; + BKE_subdiv_converter_init_for_mesh(&converter, settings, mesh); + Subdiv *subdiv = BKE_subdiv_new_from_converter(settings, &converter); + BKE_subdiv_converter_free(&converter); + return subdiv; +#else + UNUSED_VARS(settings, mesh); + return NULL; +#endif +} + +void BKE_subdiv_free(Subdiv *subdiv) +{ +#ifdef WITH_OPENSUBDIV + if (subdiv->evaluator != NULL) { + openSubdiv_deleteEvaluator(subdiv->evaluator); + } + if (subdiv->topology_refiner != NULL) { + openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner); + } + MEM_SAFE_FREE(subdiv->face_ptex_offset); + MEM_freeN(subdiv); +#endif +} diff --git a/source/blender/blenkernel/intern/subdiv_converter.c b/source/blender/blenkernel/intern/subdiv_converter.c new file mode 100644 index 00000000000..f6dabfa1c80 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_converter.c @@ -0,0 +1,65 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "subdiv_converter.h" + +#include "BLI_utildefines.h" + +#ifdef WITH_OPENSUBDIV +# include "opensubdiv_converter_capi.h" +#endif + +void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter) +{ +#ifdef WITH_OPENSUBDIV + if (converter->freeUserData) { + converter->freeUserData(converter); + } +#else + UNUSED_VARS(converter); +#endif +} + +/*OpenSubdiv_FVarLinearInterpolation*/ int +BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings) +{ +#ifdef WITH_OPENSUBDIV + switch (settings->fvar_linear_interpolation) { + case SUBDIV_FVAR_LINEAR_INTERPOLATION_NONE: + return OSD_FVAR_LINEAR_INTERPOLATION_NONE; + case SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY: + return OSD_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY; + case SUBDIV_FVAR_LINEAR_INTERPOLATION_BOUNDARIES: + return OSD_FVAR_LINEAR_INTERPOLATION_BOUNDARIES; + case SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL: + return OSD_FVAR_LINEAR_INTERPOLATION_ALL; + } + BLI_assert(!"Unknown fvar linear interpolation"); + return OSD_FVAR_LINEAR_INTERPOLATION_NONE; +#else + UNUSED_VARS(settings); + return 0; +#endif +} diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h new file mode 100644 index 00000000000..748d97f4178 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_converter.h @@ -0,0 +1,57 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BKE_SUBDIV_CONVERTER_H__ +#define __BKE_SUBDIV_CONVERTER_H__ + +#include "BKE_subdiv.h" + +/* NOTE: Was initially used to get proper enumerator types, but this makes + * it tricky to compile without OpenSubdiv. + */ +/* #include "opensubdiv_converter_capi.h" */ + +struct Mesh; +struct OpenSubdiv_Converter; +struct SubdivSettings; + +void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter, + const struct SubdivSettings *settings, + const struct Mesh *mesh); + +/* NOTE: Frees converter data, but not converter itself. This means, that if + * converter was allocated on heap, it is up to the user to free that memory. + */ +void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter); + +/* ============================ INTERNAL HELPERS ============================ */ + +/* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation, + * without breaking compilation without OpenSubdiv. + */ +int BKE_subdiv_converter_fvar_linear_from_settings( + const SubdivSettings *settings); + +#endif /* __BKE_SUBDIV_CONVERTER_H__ */ diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c new file mode 100644 index 00000000000..1a2c26b3564 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -0,0 +1,471 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "subdiv_converter.h" + +#include + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" + +#include "BKE_customdata.h" +#include "BKE_mesh_mapping.h" +#include "BKE_subdiv.h" + +#include "MEM_guardedalloc.h" + +#ifdef WITH_OPENSUBDIV +# include "opensubdiv_capi.h" +# include "opensubdiv_converter_capi.h" +#endif + +/* Use mesh element mapping structures during conversion. + * Uses more memory but is much faster than naive algorithm. + */ +#define USE_MESH_ELEMENT_MAPPING + +#ifdef WITH_OPENSUBDIV +typedef struct ConverterStorage { + SubdivSettings settings; + const Mesh *mesh; + +#ifdef USE_MESH_ELEMENT_MAPPING + MeshElemMap *vert_edge_map; + MeshElemMap *vert_poly_map; + MeshElemMap *edge_poly_map; + int *vert_edge_mem; + int *vert_poly_mem; + int *edge_poly_mem; +#endif + + /* Indexed by loop index, value denotes index of face-varying vertex + * which corresponds to the UV coordinate. + */ + int *loop_uv_indices; + int num_uv_coordinates; +} ConverterStorage; + +static OpenSubdiv_SchemeType get_scheme_type( + const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + if (storage->settings.is_simple) { + return OSD_SCHEME_BILINEAR; + } + else { + return OSD_SCHEME_CATMARK; + } +} + +static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation( + const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + return BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings); +} + +static int get_num_faces(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + return storage->mesh->totpoly; +} + +static int get_num_edges(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + return storage->mesh->totedge; +} + +static int get_num_verts(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + return storage->mesh->totvert; +} + +static int get_num_face_verts(const OpenSubdiv_Converter *converter, int face) +{ + ConverterStorage *storage = converter->user_data; + return storage->mesh->mpoly[face].totloop; +} + +static void get_face_verts(const OpenSubdiv_Converter *converter, + int face, + int *face_verts) +{ + ConverterStorage *storage = converter->user_data; + const MPoly *mp = &storage->mesh->mpoly[face]; + const MLoop *mloop = storage->mesh->mloop; + for (int loop = 0; loop < mp->totloop; loop++) { + face_verts[loop] = mloop[mp->loopstart + loop].v; + } +} + +static void get_face_edges(const OpenSubdiv_Converter *converter, + int face, + int *face_edges) +{ + ConverterStorage *storage = converter->user_data; + const MPoly *mp = &storage->mesh->mpoly[face]; + const MLoop *mloop = storage->mesh->mloop; + for (int loop = 0; loop < mp->totloop; loop++) { + face_edges[loop] = mloop[mp->loopstart + loop].e; + } +} + +static void get_edge_verts(const OpenSubdiv_Converter *converter, + int edge, + int *edge_verts) +{ + ConverterStorage *storage = converter->user_data; + const MEdge *me = &storage->mesh->medge[edge]; + edge_verts[0] = me->v1; + edge_verts[1] = me->v2; +} + +static int get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + return storage->edge_poly_map[edge].count; +#else + const Mesh *mesh = storage->mesh; + const MPoly *mpoly = mesh->mpoly; + const MLoop *mloop = mesh->mloop; + int num = 0; + for (int poly = 0; poly < mesh->totpoly; poly++) { + const MPoly *mp = &mpoly[poly]; + for (int loop = 0; loop < mp->totloop; loop++) { + const MLoop *ml = &mloop[mp->loopstart + loop]; + if (ml->e == edge) { + ++num; + break; + } + } + } + return num; +#endif +} + +static void get_edge_faces(const OpenSubdiv_Converter *converter, + int edge, + int *edge_faces) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + memcpy(edge_faces, + storage->edge_poly_map[edge].indices, + sizeof(int) * storage->edge_poly_map[edge].count); +#else + const Mesh *mesh = storage->mesh; + const MPoly *mpoly = mesh->mpoly; + const MLoop *mloop = mesh->mloop; + int num = 0; + for (int poly = 0; poly < mesh->totpoly; poly++) { + const MPoly *mp = &mpoly[poly]; + for (int loop = 0; loop < mpoly->totloop; loop++) { + const MLoop *ml = &mloop[mp->loopstart + loop]; + if (ml->e == edge) { + edge_faces[num++] = poly; + break; + } + } + } +#endif +} + +static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge) +{ + ConverterStorage *storage = converter->user_data; + const MEdge *medge = storage->mesh->medge; + const float edge_crease = (float)medge[edge].crease / 255.0f; + return edge_crease * storage->settings.level; +} + +static int get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + return storage->vert_edge_map[vert].count; +#else + const Mesh *mesh = storage->mesh; + const MEdge *medge = mesh->medge; + int num = 0; + for (int edge = 0; edge < mesh->totedge; edge++) { + const MEdge *me = &medge[edge]; + if (me->v1 == vert || me->v2 == vert) { + ++num; + } + } + return num; +#endif +} + +static void get_vert_edges(const OpenSubdiv_Converter *converter, + int vert, + int *vert_edges) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + memcpy(vert_edges, + storage->vert_edge_map[vert].indices, + sizeof(int) * storage->vert_edge_map[vert].count); +#else + const Mesh *mesh = storage->mesh; + const MEdge *medge = mesh->medge; + int num = 0; + for (int edge = 0; edge < mesh->totedge; edge++) { + const MEdge *me = &medge[edge]; + if (me->v1 == vert || me->v2 == vert) { + vert_edges[num++] = edge; + } + } +#endif +} + +static int get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + return storage->vert_poly_map[vert].count; +#else + const Mesh *mesh = storage->mesh; + const MPoly *mpoly = mesh->mpoly; + const MLoop *mloop = mesh->mloop; + int num = 0; + for (int poly = 0; poly < mesh->totpoly; poly++) { + const MPoly *mp = &mpoly[poly]; + for (int loop = 0; loop < mpoly->totloop; loop++) { + const MLoop *ml = &mloop[mp->loopstart + loop]; + if (ml->v == vert) { + ++num; + break; + } + } + } + return num; +#endif +} + +static void get_vert_faces(const OpenSubdiv_Converter *converter, + int vert, + int *vert_faces) +{ + ConverterStorage *storage = converter->user_data; +#ifdef USE_MESH_ELEMENT_MAPPING + memcpy(vert_faces, + storage->vert_poly_map[vert].indices, + sizeof(int) * storage->vert_poly_map[vert].count); +#else + const Mesh *mesh = storage->mesh; + const MPoly *mpoly = mesh->mpoly; + const MLoop *mloop = mesh->mloop; + int num = 0; + for (int poly = 0; poly < mesh->totpoly; poly++) { + const MPoly *mp = &mpoly[poly]; + for (int loop = 0; loop < mpoly->totloop; loop++) { + const MLoop *ml = &mloop[mp->loopstart + loop]; + if (ml->v == vert) { + vert_faces[num++] = poly; + break; + } + } + } +#endif +} + +static int get_num_uv_layers(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + const Mesh *mesh = storage->mesh; + return CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); +} + +static void precalc_uv_layer(const OpenSubdiv_Converter *converter, + const int layer_index) +{ + ConverterStorage *storage = converter->user_data; + const Mesh *mesh = storage->mesh; + const MPoly *mpoly = mesh->mpoly; + const MLoop *mloop = mesh->mloop; + const MLoopUV *mloopuv = CustomData_get_layer_n( + &mesh->ldata, CD_MLOOPUV, layer_index); + const int num_poly = mesh->totpoly; + const int num_vert = mesh->totvert; + const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; + /* Initialize memory required for the operations. */ + if (storage->loop_uv_indices == NULL) { + storage->loop_uv_indices = MEM_malloc_arrayN( + mesh->totloop, sizeof(int), "loop uv vertex index"); + } + UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( + mpoly, mloop, mloopuv, + num_poly, num_vert, + limit, + false, true); + /* NOTE: First UV vertex is supposed to be always marked as separate. */ + storage->num_uv_coordinates = -1; + for (int vertex_index = 0; vertex_index < num_vert; ++vertex_index) { + const UvMapVert *uv_vert = BKE_mesh_uv_vert_map_get_vert(uv_vert_map, + vertex_index); + while (uv_vert != NULL) { + if (uv_vert->separate) { + storage->num_uv_coordinates++; + } + const MPoly *mp = &mpoly[uv_vert->poly_index]; + const int global_loop_index = mp->loopstart + + uv_vert->loop_of_poly_index; + storage->loop_uv_indices[global_loop_index] = + storage->num_uv_coordinates; + uv_vert = uv_vert->next; + } + } + /* So far this value was used as a 0-based index, actual number of UV + * vertices is 1 more. + */ + storage->num_uv_coordinates += 1; + BKE_mesh_uv_vert_map_free(uv_vert_map); +} + +static void finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter)) +{ +} + +static int get_num_uvs(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *storage = converter->user_data; + return storage->num_uv_coordinates; +} + +static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter, + const int face_index, + const int corner) +{ + ConverterStorage *storage = converter->user_data; + const MPoly *mp = &storage->mesh->mpoly[face_index]; + return storage->loop_uv_indices[mp->loopstart + corner]; +} + +static void free_user_data(const OpenSubdiv_Converter *converter) +{ + ConverterStorage *user_data = converter->user_data; + MEM_SAFE_FREE(user_data->loop_uv_indices); +#ifdef USE_MESH_ELEMENT_MAPPING + MEM_freeN(user_data->vert_edge_map); + MEM_freeN(user_data->vert_edge_mem); + MEM_freeN(user_data->vert_poly_map); + MEM_freeN(user_data->vert_poly_mem); + MEM_freeN(user_data->edge_poly_map); + MEM_freeN(user_data->edge_poly_mem); +#endif + MEM_freeN(user_data); +} + +static void init_functions(OpenSubdiv_Converter *converter) +{ + converter->getSchemeType = get_scheme_type; + + converter->getFVarLinearInterpolation = get_fvar_linear_interpolation; + + converter->getNumFaces = get_num_faces; + converter->getNumEdges = get_num_edges; + converter->getNumVertices = get_num_verts; + + converter->getNumFaceVertices = get_num_face_verts; + converter->getFaceVertices = get_face_verts; + converter->getFaceEdges = get_face_edges; + + converter->getEdgeVertices = get_edge_verts; + converter->getNumEdgeFaces = get_num_edge_faces; + converter->getEdgeFaces = get_edge_faces; + converter->getEdgeSharpness = get_edge_sharpness; + + converter->getNumVertexEdges = get_num_vert_edges; + converter->getVertexEdges = get_vert_edges; + converter->getNumVertexFaces = get_num_vert_faces; + converter->getVertexFaces = get_vert_faces; + + converter->getNumUVLayers = get_num_uv_layers; + converter->precalcUVLayer = precalc_uv_layer; + converter->finishUVLayer = finish_uv_layer; + converter->getNumUVCoordinates = get_num_uvs; + converter->getFaceCornerUVIndex = get_face_corner_uv_index; + + converter->freeUserData = free_user_data; +} + +static void create_element_maps_if_needed(ConverterStorage *storage) +{ +#ifdef USE_MESH_ELEMENT_MAPPING + const Mesh *mesh = storage->mesh; + BKE_mesh_vert_edge_map_create(&storage->vert_edge_map, + &storage->vert_edge_mem, + mesh->medge, + mesh->totvert, + mesh->totedge); + BKE_mesh_vert_poly_map_create(&storage->vert_poly_map, + &storage->vert_poly_mem, + mesh->mpoly, + mesh->mloop, + mesh->totvert, + mesh->totpoly, + mesh->totloop); + BKE_mesh_edge_poly_map_create(&storage->edge_poly_map, + &storage->edge_poly_mem, + mesh->medge, mesh->totedge, + mesh->mpoly, mesh->totpoly, + mesh->mloop, mesh->totloop); +#else + (void) storage; /* Ignored. */ +#endif +} + +static void init_user_data(OpenSubdiv_Converter *converter, + const SubdivSettings *settings, + const Mesh *mesh) +{ + ConverterStorage *user_data = + MEM_mallocN(sizeof(ConverterStorage), __func__); + user_data->settings = *settings; + user_data->mesh = mesh; + user_data->loop_uv_indices = NULL; + create_element_maps_if_needed(user_data); + converter->user_data = user_data; +} +#endif + +void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter, + const SubdivSettings *settings, + const Mesh *mesh) +{ +#ifdef WITH_OPENSUBDIV + init_functions(converter); + init_user_data(converter, settings, mesh); +#else + UNUSED_VARS(converter, settings, mesh); +#endif +} diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c new file mode 100644 index 00000000000..0ab19fc8df5 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -0,0 +1,319 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/subdiv_eval.c + * \ingroup bke + */ + +#include "BKE_subdiv.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" + +#include "BKE_customdata.h" + +#ifdef WITH_OPENSUBDIV +# include "opensubdiv_evaluator_capi.h" +# include "opensubdiv_topology_refiner_capi.h" +#endif + +void BKE_subdiv_eval_begin(Subdiv *subdiv) +{ +#ifdef WITH_OPENSUBDIV + if (subdiv->evaluator == NULL) { + subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( + subdiv->topology_refiner); + } + else { + /* TODO(sergey): Check for topology change. */ + } +#else + UNUSED_VARS(subdiv); +#endif +} + +#ifdef WITH_OPENSUBDIV +static void set_face_varying_data_from_uv(Subdiv *subdiv, + const MLoopUV *mloopuv, + const int layer_index) +{ + OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; + OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; + const int num_faces = topology_refiner->getNumFaces(topology_refiner); + const MLoopUV *mluv = mloopuv; + /* TODO(sergey): OpenSubdiv's C-API converter can change winding of + * loops of a face, need to watch for that, to prevent wrong UVs assigned. + */ + for (int face_index = 0; face_index < num_faces; ++face_index) { + const int num_face_vertices = topology_refiner->getNumFaceVertices( + topology_refiner, face_index); + const int *uv_indicies = topology_refiner->getFaceFVarValueIndices( + topology_refiner, face_index, layer_index); + for (int vertex_index = 0; + vertex_index < num_face_vertices; + vertex_index++, mluv++) + { + evaluator->setFaceVaryingData(evaluator, + mluv->uv, + uv_indicies[vertex_index], + 1); + } + } +} +#endif + +void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) +{ +#ifdef WITH_OPENSUBDIV + BKE_subdiv_eval_begin(subdiv); + /* Set coordinates of base mesh vertices. */ + subdiv->evaluator->setCoarsePositionsFromBuffer( + subdiv->evaluator, + mesh->mvert, + offsetof(MVert, co), + sizeof(MVert), + 0, mesh->totvert); + /* Set face-varyign data to UV maps. */ + const int num_uv_layers = + CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); + for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { + const MLoopUV *mloopuv = CustomData_get_layer_n( + &mesh->ldata, CD_MLOOPUV, layer_index); + set_face_varying_data_from_uv(subdiv, mloopuv, layer_index); + /* NOTE: Currently evaluator can only handle single face varying layer. + * This is a limitation of C-API and some underlying helper classes from + * our side which will get fixed. + */ + break; + } + /* Update evaluator to the new coarse geometry. */ + subdiv->evaluator->refine(subdiv->evaluator); +#else + UNUSED_VARS(subdiv, mesh); +#endif +} + +/* ========================== Single point queries ========================== */ + +void BKE_subdiv_eval_limit_point( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3]) +{ + BKE_subdiv_eval_limit_point_and_derivatives(subdiv, + ptex_face_index, + u, v, + P, NULL, NULL); +} + +void BKE_subdiv_eval_limit_point_and_derivatives( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], float dPdu[3], float dPdv[3]) +{ +#ifdef WITH_OPENSUBDIV + subdiv->evaluator->evaluateLimit(subdiv->evaluator, + ptex_face_index, + u, v, + P, dPdu, dPdv); +#else + UNUSED_VARS(subdiv, ptex_face_index, u, v, P, dPdu, dPdv); +#endif +} + +void BKE_subdiv_eval_limit_point_and_normal( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], float N[3]) +{ + float dPdu[3], dPdv[3]; + BKE_subdiv_eval_limit_point_and_derivatives(subdiv, + ptex_face_index, + u, v, + P, dPdu, dPdv); + cross_v3_v3v3(N, dPdu, dPdv); + normalize_v3(N); +} + +void BKE_subdiv_eval_limit_point_and_short_normal( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float P[3], short N[3]) +{ + float N_float[3]; + BKE_subdiv_eval_limit_point_and_normal(subdiv, + ptex_face_index, + u, v, + P, N_float); + normal_float_to_short_v3(N, N_float); +} + +void BKE_subdiv_eval_face_varying( + Subdiv *subdiv, + const int ptex_face_index, + const float u, const float v, + float face_varying[2]) +{ +#ifdef WITH_OPENSUBDIV + subdiv->evaluator->evaluateFaceVarying(subdiv->evaluator, + ptex_face_index, + u, v, + face_varying); +#else + UNUSED_VARS(subdiv, ptex_face_index, u, v, face_varying); +#endif +} + +/* =================== Patch queries at given resolution =================== */ + +/* Move buffer forward by a given number of bytes. */ +static void buffer_apply_offset(void **buffer, const int offset) +{ + *buffer = ((unsigned char *)*buffer) + offset; +} + +/* Write given number of floats to the beginning of given buffer. */ +static void buffer_write_float_value(void **buffer, + const float *values_buffer, int num_values) +{ + memcpy(*buffer, values_buffer, sizeof(float) * num_values); +} + +/* Similar to above, just operates with short values. */ +static void buffer_write_short_value(void **buffer, + const short *values_buffer, int num_values) +{ + memcpy(*buffer, values_buffer, sizeof(short) * num_values); +} + +void BKE_subdiv_eval_limit_patch_resolution_point( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *buffer, const int offset, const int stride) +{ + buffer_apply_offset(&buffer, offset); + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + for (int y = 0; y < resolution; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution; x++) { + const float u = x * inv_resolution_1; + BKE_subdiv_eval_limit_point(subdiv, + ptex_face_index, + u, v, + buffer); + buffer_apply_offset(&buffer, stride); + } + } +} + +void BKE_subdiv_eval_limit_patch_resolution_point_and_derivatives( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *du_buffer, const int du_offset, const int du_stride, + void *dv_buffer, const int dv_offset, const int dv_stride) +{ + buffer_apply_offset(&point_buffer, point_offset); + buffer_apply_offset(&du_buffer, du_offset); + buffer_apply_offset(&dv_buffer, dv_offset); + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + for (int y = 0; y < resolution; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution; x++) { + const float u = x * inv_resolution_1; + BKE_subdiv_eval_limit_point_and_derivatives( + subdiv, + ptex_face_index, + u, v, + point_buffer, du_buffer, dv_buffer); + buffer_apply_offset(&point_buffer, point_stride); + buffer_apply_offset(&du_buffer, du_stride); + buffer_apply_offset(&dv_buffer, dv_stride); + } + } +} + +void BKE_subdiv_eval_limit_patch_resolution_point_and_normal( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *normal_buffer, const int normal_offset, const int normal_stride) +{ + buffer_apply_offset(&point_buffer, point_offset); + buffer_apply_offset(&normal_buffer, normal_offset); + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + for (int y = 0; y < resolution; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution; x++) { + const float u = x * inv_resolution_1; + float normal[3]; + BKE_subdiv_eval_limit_point_and_normal( + subdiv, + ptex_face_index, + u, v, + point_buffer, normal); + buffer_write_float_value(&normal_buffer, normal, 3); + buffer_apply_offset(&point_buffer, point_stride); + buffer_apply_offset(&normal_buffer, normal_stride); + } + } +} + +void BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal( + Subdiv *subdiv, + const int ptex_face_index, + const int resolution, + void *point_buffer, const int point_offset, const int point_stride, + void *normal_buffer, const int normal_offset, const int normal_stride) +{ + buffer_apply_offset(&point_buffer, point_offset); + buffer_apply_offset(&normal_buffer, normal_offset); + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + for (int y = 0; y < resolution; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution; x++) { + const float u = x * inv_resolution_1; + short normal[3]; + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + u, v, + point_buffer, normal); + buffer_write_short_value(&normal_buffer, normal, 3); + buffer_apply_offset(&point_buffer, point_stride); + buffer_apply_offset(&normal_buffer, normal_stride); + } + } +} diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c new file mode 100644 index 00000000000..8a58605ba19 --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -0,0 +1,910 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/subdiv_mesh.c + * \ingroup bke + */ + +#include "BKE_subdiv.h" + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_alloca.h" +#include "BLI_math_vector.h" +#include "BLI_task.h" + +#include "BKE_mesh.h" + +/* TODO(sergey): Somehow move this to subdiv code? */ +static int mpoly_ptex_faces_count_get(const MPoly *mp) +{ + if (mp->totloop == 4) { + return 1; + } + else { + return mp->totloop; + } +} + +static int num_edges_per_ptex_get(const int resolution) +{ + return 2 * (resolution - 1) * resolution; +} + +static int num_polys_per_ptex_get(const int resolution) +{ + return (resolution - 1) * (resolution - 1); +} + +typedef struct SubdivMeshContext { + const Mesh *coarse_mesh; + Subdiv *subdiv; + Mesh *subdiv_mesh; + const SubdivToMeshSettings *settings; + /* Cached custom data arrays for fastter access. */ + int *vert_origindex; + int *edge_origindex; + int *loop_origindex; + int *poly_origindex; + /* UV layers interpolation. */ + int num_uv_layers; + MLoopUV *uv_layers[MAX_MTFACE]; +} SubdivMeshContext; + +typedef struct LoopsOfPtex { + /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */ + const MLoop *first_loop; + /* Last loop of the ptex, starts at ptex (0, 0) and goes in v direction. */ + const MLoop *last_loop; + /* For quad coarse faces only. */ + const MLoop *second_loop; + const MLoop *third_loop; +} LoopsOfPtex; + +static void loops_of_ptex_get( + const SubdivMeshContext *ctx, + LoopsOfPtex *loops_of_ptex, + const MPoly *coarse_poly, + const int ptex_face_index) +{ + const MLoop *coarse_mloop = ctx->coarse_mesh->mloop; + const int first_ptex_loop_index = coarse_poly->loopstart + ptex_face_index; + /* Loop which look in the (opposite) V direction of the current + * ptex face. + * + * TOOD(sergey): Get rid of using module on every iteration. + */ + const int last_ptex_loop_index = + coarse_poly->loopstart + + (ptex_face_index + coarse_poly->totloop - 1) % coarse_poly->totloop; + loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index]; + loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index]; + if (coarse_poly->totloop == 4) { + loops_of_ptex->second_loop = loops_of_ptex->first_loop + 1; + loops_of_ptex->third_loop = loops_of_ptex->first_loop + 2; + } + else { + loops_of_ptex->second_loop = NULL; + loops_of_ptex->third_loop = NULL; + } +} + +typedef struct EdgesOfPtex { + /* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */ + const MEdge *first_edge; + /* Last edge of the ptex, starts at ptex (0, 0) and goes in v direction. */ + const MEdge *last_edge; + /* For quad coarse faces only. */ + const MEdge *second_edge; + const MEdge *third_edge; +} EdgesOfPtex; + +static void edges_of_ptex_get( + const SubdivMeshContext *ctx, + EdgesOfPtex *edges_of_ptex, + const MPoly *coarse_poly, + const int ptex_face_index) +{ + const MEdge *coarse_medge = ctx->coarse_mesh->medge; + LoopsOfPtex loops_of_ptex; + loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index); + edges_of_ptex->first_edge = &coarse_medge[loops_of_ptex.first_loop->e]; + edges_of_ptex->last_edge = &coarse_medge[loops_of_ptex.last_loop->e]; + if (coarse_poly->totloop == 4) { + edges_of_ptex->second_edge = + &coarse_medge[loops_of_ptex.second_loop->e]; + edges_of_ptex->third_edge = + &coarse_medge[loops_of_ptex.third_loop->e]; + } + else { + edges_of_ptex->second_edge = NULL; + edges_of_ptex->third_edge = NULL; + } +} + +/* TODO(sergey): Somehow de-duplicate with loops storage, without too much + * exception cases all over the code. + */ + +typedef struct VerticesForInterpolation { + /* This field points to a vertex data which is to be used for interpolation. + * The idea is to avoid unnecessary allocations for regular faces, where + * we can simply + */ + const CustomData *vertex_data; + /* Vertices data calculated for ptex corners. There are always 4 elements + * in this custom data, aligned the following way: + * + * index 0 -> uv (0, 0) + * index 1 -> uv (0, 1) + * index 2 -> uv (1, 1) + * index 3 -> uv (1, 0) + * + * Is allocated for non-regular faces (triangles and n-gons). + */ + CustomData vertex_data_storage; + bool vertex_data_storage_allocated; + /* Infices within vertex_data to interpolate for. The indices are aligned + * with uv coordinates in a similar way as indices in loop_data_storage. + */ + int vertex_indices[4]; +} VerticesForInterpolation; + +static void vertex_interpolation_init( + const SubdivMeshContext *ctx, + VerticesForInterpolation *vertex_interpolation, + const MPoly *coarse_poly) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MLoop *coarse_mloop = coarse_mesh->mloop; + if (coarse_poly->totloop == 4) { + vertex_interpolation->vertex_data = &coarse_mesh->vdata; + vertex_interpolation->vertex_indices[0] = + coarse_mloop[coarse_poly->loopstart + 0].v; + vertex_interpolation->vertex_indices[1] = + coarse_mloop[coarse_poly->loopstart + 1].v; + vertex_interpolation->vertex_indices[2] = + coarse_mloop[coarse_poly->loopstart + 2].v; + vertex_interpolation->vertex_indices[3] = + coarse_mloop[coarse_poly->loopstart + 3].v; + vertex_interpolation->vertex_data_storage_allocated = false; + } + else { + vertex_interpolation->vertex_data = + &vertex_interpolation->vertex_data_storage; + /* Allocate storage for loops corresponding to ptex corners. */ + CustomData_copy(&ctx->coarse_mesh->vdata, + &vertex_interpolation->vertex_data_storage, + CD_MASK_EVERYTHING, + CD_CALLOC, + 4); + /* Initialize indices. */ + vertex_interpolation->vertex_indices[0] = 0; + vertex_interpolation->vertex_indices[1] = 1; + vertex_interpolation->vertex_indices[2] = 2; + vertex_interpolation->vertex_indices[3] = 3; + vertex_interpolation->vertex_data_storage_allocated = true; + /* Interpolate center of poly right away, it stays unchanged for all + * ptex faces. + */ + const float weight = 1.0f / (float)coarse_poly->totloop; + float *weights = BLI_array_alloca(weights, coarse_poly->totloop); + int *indices = BLI_array_alloca(indices, coarse_poly->totloop); + for (int i = 0; i < coarse_poly->totloop; ++i) { + weights[i] = weight; + indices[i] = coarse_poly->loopstart + i; + } + CustomData_interp(&coarse_mesh->vdata, + &vertex_interpolation->vertex_data_storage, + indices, + weights, NULL, + coarse_poly->totloop, + 2); + } +} + +static void vertex_interpolation_from_ptex( + const SubdivMeshContext *ctx, + VerticesForInterpolation *vertex_interpolation, + const MPoly *coarse_poly, + const int ptex_face_index) +{ + if (coarse_poly->totloop == 4) { + /* Nothing to do, all indices and data is already assigned. */ + } else { + const CustomData *vertex_data = &ctx->coarse_mesh->vdata; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MLoop *coarse_mloop = coarse_mesh->mloop; + LoopsOfPtex loops_of_ptex; + loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index); + /* Ptex face corner corresponds to a poly loop with same index. */ + CustomData_copy_data( + vertex_data, + &vertex_interpolation->vertex_data_storage, + coarse_mloop[coarse_poly->loopstart + ptex_face_index].v, + 0, + 1); + /* Interpolate remaining ptex face corners, which hits loops + * middle points. + * + * TODO(sergey): Re-use one of interpolation results from previous + * iteration. + */ + const float weights[2] = {0.5f, 0.5f}; + const int first_indices[2] = { + coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v, + coarse_mloop[(loops_of_ptex.first_loop + 1 - coarse_mloop) % + coarse_poly->totloop].v}; + const int last_indices[2] = { + coarse_mloop[loops_of_ptex.last_loop - coarse_mloop].v, + coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v}; + CustomData_interp(vertex_data, + &vertex_interpolation->vertex_data_storage, + first_indices, + weights, NULL, + 2, + 1); + CustomData_interp(vertex_data, + &vertex_interpolation->vertex_data_storage, + last_indices, + weights, NULL, + 2, + 3); + } +} + +static void vertex_interpolation_end( + VerticesForInterpolation *vertex_interpolation) +{ + if (vertex_interpolation->vertex_data_storage_allocated) { + CustomData_free(&vertex_interpolation->vertex_data_storage, 4); + } +} + +typedef struct LoopsForInterpolation { + /* This field points to a loop data which is to be used for interpolation. + * The idea is to avoid unnecessary allocations for regular faces, where + * we can simply + */ + const CustomData *loop_data; + /* Loops data calculated for ptex corners. There are always 4 elements + * in this custom data, aligned the following way: + * + * index 0 -> uv (0, 0) + * index 1 -> uv (0, 1) + * index 2 -> uv (1, 1) + * index 3 -> uv (1, 0) + * + * Is allocated for non-regular faces (triangles and n-gons). + */ + CustomData loop_data_storage; + bool loop_data_storage_allocated; + /* Infices within loop_data to interpolate for. The indices are aligned with + * uv coordinates in a similar way as indices in loop_data_storage. + */ + int loop_indices[4]; +} LoopsForInterpolation; + +static void loop_interpolation_init( + const SubdivMeshContext *ctx, + LoopsForInterpolation *loop_interpolation, + const MPoly *coarse_poly) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + if (coarse_poly->totloop == 4) { + loop_interpolation->loop_data = &coarse_mesh->ldata; + loop_interpolation->loop_indices[0] = coarse_poly->loopstart + 0; + loop_interpolation->loop_indices[1] = coarse_poly->loopstart + 1; + loop_interpolation->loop_indices[2] = coarse_poly->loopstart + 2; + loop_interpolation->loop_indices[3] = coarse_poly->loopstart + 3; + loop_interpolation->loop_data_storage_allocated = false; + } + else { + loop_interpolation->loop_data = &loop_interpolation->loop_data_storage; + /* Allocate storage for loops corresponding to ptex corners. */ + CustomData_copy(&ctx->coarse_mesh->ldata, + &loop_interpolation->loop_data_storage, + CD_MASK_EVERYTHING, + CD_CALLOC, + 4); + /* Initialize indices. */ + loop_interpolation->loop_indices[0] = 0; + loop_interpolation->loop_indices[1] = 1; + loop_interpolation->loop_indices[2] = 2; + loop_interpolation->loop_indices[3] = 3; + loop_interpolation->loop_data_storage_allocated = true; + /* Interpolate center of poly right away, it stays unchanged for all + * ptex faces. + */ + const float weight = 1.0f / (float)coarse_poly->totloop; + float *weights = BLI_array_alloca(weights, coarse_poly->totloop); + int *indices = BLI_array_alloca(indices, coarse_poly->totloop); + for (int i = 0; i < coarse_poly->totloop; ++i) { + weights[i] = weight; + indices[i] = coarse_poly->loopstart + i; + } + CustomData_interp(&coarse_mesh->ldata, + &loop_interpolation->loop_data_storage, + indices, + weights, NULL, + coarse_poly->totloop, + 2); + } +} + +static void loop_interpolation_from_ptex( + const SubdivMeshContext *ctx, + LoopsForInterpolation *loop_interpolation, + const MPoly *coarse_poly, + const int ptex_face_index) +{ + if (coarse_poly->totloop == 4) { + /* Nothing to do, all indices and data is already assigned. */ + } else { + const CustomData *loop_data = &ctx->coarse_mesh->ldata; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MLoop *coarse_mloop = coarse_mesh->mloop; + LoopsOfPtex loops_of_ptex; + loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index); + /* Ptex face corner corresponds to a poly loop with same index. */ + CustomData_copy_data(loop_data, + &loop_interpolation->loop_data_storage, + coarse_poly->loopstart + ptex_face_index, + 0, + 1); + /* Interpolate remaining ptex face corners, which hits loops + * middle points. + * + * TODO(sergey): Re-use one of interpolation results from previous + * iteration. + */ + const float weights[2] = {0.5f, 0.5f}; + const int first_indices[2] = { + loops_of_ptex.first_loop - coarse_mloop, + (loops_of_ptex.first_loop + 1 - coarse_mloop) % + coarse_poly->totloop}; + const int last_indices[2] = { + loops_of_ptex.last_loop - coarse_mloop, + loops_of_ptex.first_loop - coarse_mloop}; + CustomData_interp(loop_data, + &loop_interpolation->loop_data_storage, + first_indices, + weights, NULL, + 2, + 1); + CustomData_interp(loop_data, + &loop_interpolation->loop_data_storage, + last_indices, + weights, NULL, + 2, + 3); + } +} + +static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) +{ + if (loop_interpolation->loop_data_storage_allocated) { + CustomData_free(&loop_interpolation->loop_data_storage, 4); + } +} + +static void subdiv_copy_vertex_data( + const SubdivMeshContext *ctx, + MVert *subdiv_vertex, + const VerticesForInterpolation *vertex_interpolation, + const float u, const float v) +{ + const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert; + const float weights[4] = {(1.0f - u) * (1.0f - v), + u * (1.0f - v), + u * v, + (1.0f - u) * v}; + CustomData_interp(vertex_interpolation->vertex_data, + &ctx->subdiv_mesh->vdata, + vertex_interpolation->vertex_indices, + weights, NULL, + 4, + subdiv_vertex_index); + /* TODO(sergey): Set ORIGINDEX. */ +} + +static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, + const int poly_index) +{ + Subdiv *subdiv = ctx->subdiv; + const int resolution = ctx->settings->resolution; + const int resolution2 = resolution * resolution; + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_polyoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_polyoly[poly_index]; + const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + /* Hi-poly subdivided mesh. */ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_vertert = subdiv_mesh->mvert; + const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; + /* Actual evaluation. */ + VerticesForInterpolation vertex_interpolation; + vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly); + MVert *subdiv_vert = &subdiv_vertert[ptex_face_index * resolution2]; + for (int ptex_of_poly_index = 0; + ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index++) + { + vertex_interpolation_from_ptex(ctx, + &vertex_interpolation, + coarse_poly, + ptex_of_poly_index); + const int current_ptex_face_index = + ptex_face_index + ptex_of_poly_index; + BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal( + subdiv, + current_ptex_face_index, + resolution, + subdiv_vert, offsetof(MVert, co), sizeof(MVert), + subdiv_vert, offsetof(MVert, no), sizeof(MVert)); + for (int y = 0; y < resolution; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution; x++, subdiv_vert++) { + const float u = x * inv_resolution_1; + subdiv_copy_vertex_data(ctx, + subdiv_vert, + &vertex_interpolation, + u, v); + } + } + } + vertex_interpolation_end(&vertex_interpolation); +} + +static void subdiv_copy_edge_data(SubdivMeshContext *ctx, + MEdge *subdiv_edge, + const MEdge *coarse_edge) +{ + if (coarse_edge == NULL) { + subdiv_edge->crease = 0; + subdiv_edge->bweight = 0; + subdiv_edge->flag = 0; + return; + } + const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge; + const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge; + CustomData_copy_data(&ctx->coarse_mesh->edata, + &ctx->subdiv_mesh->edata, + coarse_edge_index, + subdiv_edge_index, + 1); + if (ctx->edge_origindex != NULL) { + ctx->edge_origindex[subdiv_edge_index] = coarse_edge_index; + } +} + +static MEdge *subdiv_create_edges_row(SubdivMeshContext *ctx, + MEdge *subdiv_edge, + const MEdge *coarse_edge, + const int start_vertex_index, + const int resolution) +{ + int vertex_index = start_vertex_index; + for (int edge_index = 0; + edge_index < resolution - 1; + edge_index++, subdiv_edge++) + { + subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); + subdiv_edge->v1 = vertex_index; + subdiv_edge->v2 = vertex_index + 1; + vertex_index += 1; + } + return subdiv_edge; +} + +static MEdge *subdiv_create_edges_column(SubdivMeshContext *ctx, + MEdge *subdiv_edge, + const MEdge *coarse_start_edge, + const MEdge *coarse_end_edge, + const int start_vertex_index, + const int resolution) +{ + int vertex_index = start_vertex_index; + for (int edge_index = 0; + edge_index < resolution; + edge_index++, subdiv_edge++) + { + const MEdge *coarse_edge = NULL; + if (edge_index == 0) { + coarse_edge = coarse_start_edge; + } + else if (edge_index == resolution - 1) { + coarse_edge = coarse_end_edge; + } + subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); + subdiv_edge->v1 = vertex_index; + subdiv_edge->v2 = vertex_index + resolution; + vertex_index += 1; + } + return subdiv_edge; +} + +static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) +{ + Subdiv *subdiv = ctx->subdiv; + const int resolution = ctx->settings->resolution; + const int resolution2 = resolution * resolution; + const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; + const int num_edges_per_ptex = num_edges_per_ptex_get(resolution); + const int start_edge_index = ptex_face_index * num_edges_per_ptex; + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_polyoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_polyoly[poly_index]; + const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + /* Hi-poly subdivided mesh. */ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MEdge *subdiv_medge = subdiv_mesh->medge; + MEdge *subdiv_edge = &subdiv_medge[start_edge_index]; + const int start_poly_vertex_index = ptex_face_index * resolution2; + /* Consider a subdivision of base face at level 1: + * + * y + * ^ + * | (6) ---- (7) ---- (8) + * | | | | + * | (3) ---- (4) ---- (5) + * | | | | + * | (0) ---- (1) ---- (2) + * o---------------------------> x + * + * This is illustrate which parts of geometry is created by code below. + */ + for (int i = 0; i < num_poly_ptex_faces; i++) { + const int start_ptex_face_vertex_index = + start_poly_vertex_index + i * resolution2; + EdgesOfPtex edges_of_ptex; + edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, i); + /* Create bottom row of edges (0-1, 1-2). */ + subdiv_edge = subdiv_create_edges_row(ctx, + subdiv_edge, + edges_of_ptex.first_edge, + start_ptex_face_vertex_index, + resolution); + /* Create remaining edges. */ + for (int row = 0; row < resolution - 1; row++) { + const int start_row_vertex_index = + start_ptex_face_vertex_index + row * resolution; + /* Create vertical columns. + * + * At first iteration it will be edges (0-3. 1-4, 2-5), then it + * will be (3-6, 4-7, 5-8) and so on. + */ + subdiv_edge = subdiv_create_edges_column( + ctx, + subdiv_edge, + edges_of_ptex.last_edge, + edges_of_ptex.second_edge, + start_row_vertex_index, + resolution); + /* Create horizontal edge row. + * + * At first iteration it will be edges (3-4, 4-5), then it will be + * (6-7, 7-8) and so on. + */ + subdiv_edge = subdiv_create_edges_row( + ctx, + subdiv_edge, + (row == resolution - 2) ? edges_of_ptex.third_edge + : NULL, + start_row_vertex_index + resolution, + resolution); + } + } +} + +static void subdiv_copy_loop_data( + const SubdivMeshContext *ctx, + MLoop *subdiv_loop, + const LoopsForInterpolation *loop_interpolation, + const float u, const float v) +{ + const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop; + const float weights[4] = {(1.0f - u) * (1.0f - v), + u * (1.0f - v), + u * v, + (1.0f - u) * v}; + CustomData_interp(loop_interpolation->loop_data, + &ctx->subdiv_mesh->ldata, + loop_interpolation->loop_indices, + weights, NULL, + 4, + subdiv_loop_index); + /* TODO(sergey): Set ORIGINDEX. */ +} + +static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, + MLoop *subdiv_loop, + const int ptex_face_index, + const float u, const float v, + const float inv_resolution_1) +{ + if (ctx->num_uv_layers == 0) { + return; + } + Subdiv *subdiv = ctx->subdiv; + const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop; + const float du = inv_resolution_1; + const float dv = inv_resolution_1; + for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { + MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index]; + BKE_subdiv_eval_face_varying(subdiv, + ptex_face_index, + u, v, + subdiv_loopuv[0].uv); + BKE_subdiv_eval_face_varying(subdiv, + ptex_face_index, + u + du, v, + subdiv_loopuv[1].uv); + BKE_subdiv_eval_face_varying(subdiv, + ptex_face_index, + u + du, v + dv, + subdiv_loopuv[2].uv); + BKE_subdiv_eval_face_varying(subdiv, + ptex_face_index, + u, v + dv, + subdiv_loopuv[3].uv); + /* TODO(sergey): Currently evaluator only has single UV layer, so can + * not evaluate more than that. Need to be solved. + */ + break; + } +} + +static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) +{ + Subdiv *subdiv = ctx->subdiv; + const int resolution = ctx->settings->resolution; + const int resolution2 = resolution * resolution; + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; + const int num_edges_per_ptex = num_edges_per_ptex_get(resolution); + const int start_edge_index = ptex_face_index * num_edges_per_ptex; + const int num_polys_per_ptex = num_polys_per_ptex_get(resolution); + const int start_poly_index = ptex_face_index * num_polys_per_ptex; + const int start_loop_index = 4 * start_poly_index; + const int start_vert_index = ptex_face_index * resolution2; + const float du = inv_resolution_1; + const float dv = inv_resolution_1; + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_polyoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_polyoly[poly_index]; + const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + /* Hi-poly subdivided mesh. */ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MLoop *subdiv_loopoop = subdiv_mesh->mloop; + MLoop *subdiv_loop = &subdiv_loopoop[start_loop_index]; + LoopsForInterpolation loop_interpolation; + loop_interpolation_init(ctx, &loop_interpolation, coarse_poly); + for (int ptex_of_poly_index = 0; + ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index++) + { + loop_interpolation_from_ptex(ctx, + &loop_interpolation, + coarse_poly, + ptex_of_poly_index); + const int current_ptex_face_index = + ptex_face_index + ptex_of_poly_index; + for (int y = 0; y < resolution - 1; y++) { + const float v = y * inv_resolution_1; + for (int x = 0; x < resolution - 1; x++, subdiv_loop += 4) { + const float u = x * inv_resolution_1; + /* Vertex indicies ordered counter-clockwise. */ + const int v0 = start_vert_index + + (ptex_of_poly_index * resolution2) + + (y * resolution + x); + const int v1 = v0 + 1; + const int v2 = v0 + resolution + 1; + const int v3 = v0 + resolution; + /* Edge indicies ordered counter-clockwise. */ + const int e0 = start_edge_index + + (ptex_of_poly_index * num_edges_per_ptex) + + (y * (2 * resolution - 1) + x); + const int e1 = e0 + resolution; + const int e2 = e0 + (2 * resolution - 1); + const int e3 = e0 + resolution - 1; + /* Initialize 4 loops of corresponding hi-poly poly. */ + /* TODO(sergey): For ptex boundaries we should use loops from + * coarse mesh. + */ + subdiv_copy_loop_data(ctx, + &subdiv_loop[0], + &loop_interpolation, + u, v); + subdiv_loop[0].v = v0; + subdiv_loop[0].e = e0; + subdiv_copy_loop_data(ctx, + &subdiv_loop[1], + &loop_interpolation, + u + du, v); + subdiv_loop[1].v = v1; + subdiv_loop[1].e = e1; + subdiv_copy_loop_data(ctx, + &subdiv_loop[2], + &loop_interpolation, + u + du, v + dv); + subdiv_loop[2].v = v2; + subdiv_loop[2].e = e2; + subdiv_copy_loop_data(ctx, + &subdiv_loop[3], + &loop_interpolation, + u, v + dv); + subdiv_loop[3].v = v3; + subdiv_loop[3].e = e3; + /* Interpolate UV layers using OpenSubdiv. */ + subdiv_eval_uv_layer(ctx, + subdiv_loop, + current_ptex_face_index, + u, v, + inv_resolution_1); + } + } + } + loop_interpolation_end(&loop_interpolation); +} + +static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, + MPoly *subdiv_poly, + const MPoly *coarse_poly) +{ + const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly; + const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly; + CustomData_copy_data(&ctx->coarse_mesh->pdata, + &ctx->subdiv_mesh->pdata, + coarse_poly_index, + subdiv_poly_index, + 1); + if (ctx->poly_origindex != NULL) { + ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index; + } +} + +static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) +{ + Subdiv *subdiv = ctx->subdiv; + const int resolution = ctx->settings->resolution; + const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; + const int num_polys_per_ptex = num_polys_per_ptex_get(resolution); + const int num_loops_per_ptex = 4 * num_polys_per_ptex; + const int start_poly_index = ptex_face_index * num_polys_per_ptex; + const int start_loop_index = 4 * start_poly_index; + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_polyoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_polyoly[poly_index]; + const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + /* Hi-poly subdivided mesh. */ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MPoly *subdiv_mpoly = subdiv_mesh->mpoly; + MPoly *subdiv_mp = &subdiv_mpoly[start_poly_index]; + for (int ptex_of_poly_index = 0; + ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index++) + { + for (int subdiv_poly_index = 0; + subdiv_poly_index < num_polys_per_ptex; + subdiv_poly_index++, subdiv_mp++) + { + subdiv_copy_poly_data(ctx, subdiv_mp, coarse_poly); + subdiv_mp->loopstart = start_loop_index + + (ptex_of_poly_index * num_loops_per_ptex) + + (subdiv_poly_index * 4); + subdiv_mp->totloop = 4; + } + } +} + +static void subdiv_eval_task( + void *__restrict userdata, + const int poly_index, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SubdivMeshContext *data = userdata; + /* Evaluate hi-poly vertex coordinates and normals. */ + subdiv_evaluate_vertices(data, poly_index); + /* Create mesh geometry for the given base poly index. */ + subdiv_create_edges(data, poly_index); + subdiv_create_loops(data, poly_index); + subdiv_create_polys(data, poly_index); +} + +static void cache_uv_layers(SubdivMeshContext *ctx) +{ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + ctx->num_uv_layers = + CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV); + for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) { + ctx->uv_layers[layer_index] = CustomData_get_layer_n( + &subdiv_mesh->ldata, CD_MLOOPUV, layer_index); + } +} + +static void cache_custom_data_layers(SubdivMeshContext *ctx) +{ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + /* Pointers to original indices layers. */ + ctx->vert_origindex = CustomData_get_layer( + &subdiv_mesh->vdata, CD_ORIGINDEX); + ctx->edge_origindex = CustomData_get_layer( + &subdiv_mesh->edata, CD_ORIGINDEX); + ctx->loop_origindex = CustomData_get_layer( + &subdiv_mesh->ldata, CD_ORIGINDEX); + ctx->poly_origindex = CustomData_get_layer( + &subdiv_mesh->pdata, CD_ORIGINDEX); + /* UV layers interpolation. */ + cache_uv_layers(ctx); +} + +Mesh *BKE_subdiv_to_mesh( + Subdiv *subdiv, + const SubdivToMeshSettings *settings, + const Mesh *coarse_mesh) +{ + /* Make sure evaluator is up to date with possible new topology, and that + * is is refined for the new positions of coarse vertices. + */ + BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh); + const int resolution = settings->resolution; + const int resolution2 = resolution * resolution; + const int num_result_verts = subdiv->num_ptex_faces * resolution2; + const int num_result_edges = + subdiv->num_ptex_faces * num_edges_per_ptex_get(resolution); + const int num_result_polys = + subdiv->num_ptex_faces * num_polys_per_ptex_get(resolution); + const int num_result_loops = 4 * num_result_polys; + /* Create mesh and its arrays. */ + Mesh *result = BKE_mesh_new_nomain_from_template( + coarse_mesh, + num_result_verts, + num_result_edges, + 0, + num_result_loops, + num_result_polys); + /* Evaluate subdivisions of base faces in threads. */ + SubdivMeshContext ctx; + ctx.coarse_mesh = coarse_mesh; + ctx.subdiv = subdiv; + ctx.subdiv_mesh = result; + ctx.settings = settings; + cache_custom_data_layers(&ctx); + /* Multi-threaded evaluation. */ + ParallelRangeSettings parallel_range_settings; + BLI_parallel_range_settings_defaults(¶llel_range_settings); + BLI_task_parallel_range(0, coarse_mesh->totpoly, + &ctx, + subdiv_eval_task, + ¶llel_range_settings); + return result; +} -- cgit v1.2.3 From 5fd677c83c80aa33cac9f4fe47dc149e61b96f67 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jul 2018 18:09:18 +0200 Subject: Subsurf: Add subdivision code which uses new module The code is ifdef-ed for now, since there is more work needed to be done before we can officially switch to it. Uses new subdiv module. --- source/blender/blenkernel/CMakeLists.txt | 9 +++- source/blender/makesdna/DNA_modifier_types.h | 19 ++++--- source/blender/makesrna/intern/rna_modifier.c | 4 +- source/blender/modifiers/intern/MOD_subsurf.c | 75 ++++++++++++++++++++++++++- 4 files changed, 95 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0578a3ecc69..0517eb8e732 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -186,6 +186,11 @@ set(SRC intern/sound.c intern/speaker.c intern/studiolight.c + intern/subdiv.c + intern/subdiv_converter.c + intern/subdiv_converter_mesh.c + intern/subdiv_eval.c + intern/subdiv_mesh.c intern/subsurf_ccg.c intern/suggestions.c intern/text.c @@ -306,6 +311,7 @@ set(SRC BKE_sound.h BKE_speaker.h BKE_studiolight.h + BKE_subdiv.h BKE_subsurf.h BKE_suggestions.h BKE_text.h @@ -323,8 +329,9 @@ set(SRC intern/CCGSubSurf.h intern/CCGSubSurf_inline.h intern/CCGSubSurf_intern.h - intern/pbvh_intern.h intern/data_transfer_intern.h + intern/pbvh_intern.h + intern/subdiv_converter.h ) if(WITH_BINRELOC) diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index ecece648ce1..803be15f03e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -123,13 +123,6 @@ typedef enum { eModifierFlag_SharedCaches = (1 << 1), } ModifierFlag; -typedef enum { - eSubsurfModifierFlag_Incremental = (1 << 0), - eSubsurfModifierFlag_DebugIncr = (1 << 1), - eSubsurfModifierFlag_ControlEdges = (1 << 2), - eSubsurfModifierFlag_SubsurfUv = (1 << 3), -} SubsurfModifierFlag; - /* not a real modifier */ typedef struct MappingInfoModifierData { ModifierData modifier; @@ -141,6 +134,18 @@ typedef struct MappingInfoModifierData { int texmapping; } MappingInfoModifierData; +typedef enum { + eSubsurfModifierFlag_Incremental = (1 << 0), + eSubsurfModifierFlag_DebugIncr = (1 << 1), + eSubsurfModifierFlag_ControlEdges = (1 << 2), + eSubsurfModifierFlag_SubsurfUv = (1 << 3), +} SubsurfModifierFlag; + +typedef enum { + SUBSURF_TYPE_CATMULL_CLARK = 0, + SUBSURF_TYPE_SIMPLE = 1, +} eSubsurfModifierType; + typedef struct SubsurfModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 57b12d6a3fd..d90a578d9f2 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1175,8 +1175,8 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr, co static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) { static const EnumPropertyItem prop_subdivision_type_items[] = { - {0, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, - {1, "SIMPLE", 0, "Simple", ""}, + {SUBSURF_TYPE_CATMULL_CLARK, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, + {SUBSURF_TYPE_SIMPLE, "SIMPLE", 0, "Simple", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index f532c168b04..c92845a24eb 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -35,8 +35,9 @@ #include -#include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_mesh_types.h" #ifdef WITH_OPENSUBDIV # include "DNA_userdef_types.h" @@ -44,9 +45,9 @@ #include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" #include "BKE_scene.h" +#include "BKE_subdiv.h" #include "BKE_subsurf.h" #include "DEG_depsgraph.h" @@ -56,6 +57,8 @@ #include "intern/CCGSubSurf.h" +// #define USE_OPENSUBDIV + static void initData(ModifierData *md) { SubsurfModifierData *smd = (SubsurfModifierData *) md; @@ -181,9 +184,73 @@ static DerivedMesh *applyModifierEM( #endif result = subsurf_make_derived_from_derived(derivedData, smd, scene, NULL, ss_flags); + return result; +} + +#ifdef USE_OPENSUBDIV +static int subdiv_levels_for_modifier_get(const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) +{ + Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER); + const int requested_levels = (use_render_params) ? smd->renderLevels + : smd->levels; + return get_render_subsurf_level(&scene->r, + requested_levels, + use_render_params); +} + +static void subdiv_settings_init(SubdivSettings *settings, + const SubsurfModifierData *smd, + const ModifierEvalContext *ctx) +{ + settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); + settings->is_adaptive = !settings->is_simple; + settings->level = subdiv_levels_for_modifier_get(smd, ctx); + settings->fvar_linear_interpolation = + (smd->flags & eSubsurfModifierFlag_SubsurfUv) + ? SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_ONLY + : SUBDIV_FVAR_LINEAR_INTERPOLATION_ALL; +} + +static void subdiv_mesh_settings_init(SubdivToMeshSettings *settings, + const SubdivSettings *subdiv_settings) +{ + settings->resolution = (1 << subdiv_settings->level) + 1; +} +static Mesh *applyModifier_subdiv(ModifierData *md, + const ModifierEvalContext *ctx, + Mesh *mesh) +{ + Mesh *result = mesh; + SubsurfModifierData *smd = (SubsurfModifierData *) md; + SubdivSettings subdiv_settings; + subdiv_settings_init(&subdiv_settings, smd, ctx); + if (subdiv_settings.level == 0) { + /* NOTE: Shouldn't really happen, is supposed to be catched by + * isDisabled() callback. + */ + return result; + } + /* TODO(sergey): Try to re-use subdiv when possible. */ + Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh); + if (subdiv == NULL) { + /* Happens on bad topology. */ + /* TODO(sergey): This also happens on meshes without faces, so probably + * need to handle those differently (i.e. set modifier error when + * topology itself is bad, and not do anything when there are no faces). + */ + return result; + } + SubdivToMeshSettings mesh_settings; + subdiv_mesh_settings_init(&mesh_settings, &subdiv_settings); + result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + /* TODO(sergey): Cache subdiv somehow. */ + BKE_subdiv_free(subdiv); return result; } +#endif static bool dependsOnNormals(ModifierData *md) { @@ -222,7 +289,11 @@ ModifierTypeInfo modifierType_Subsurf = { /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, +#ifdef USE_OPENSUBDIV + /* applyModifier */ applyModifier_subdiv, +#else /* applyModifier */ NULL, +#endif /* applyModifierEM */ NULL, /* initData */ initData, -- cgit v1.2.3 From 2604f281b7bd74f396b2479fbdb97cbf9dc27689 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 18 Jul 2018 16:09:19 +0200 Subject: Cycles: Fix missing nested particle systems when instanced multiple times Was only visible when doing command line, since it was happening due to cache-free policy which was aimed to bring memory usage down. The issue is that if object with particle system is used as a nested duplicator multiple times, it will only generate children first time, and after that its caches are freed. After that duplication system can not generate any instances, since the path cache is lost. Now we delay caches free to after all objects are synchronized, which ensures all instances are generated. This will increase a memory peak a bit during object synchronization time, but overall it shouldn't be that bad, since memory footprint after synchronization will stay the same as before this change. The ultimate thing to do here would be to drop the whole dependency graph away, but this will require: - API on engine side, to inform it to drop the dependency graph. - Changes in Cycles report system to NOT use evaluated scene to get scene name (evaluated scene will be gone with dependency graph). --- intern/cycles/blender/blender_mesh.cpp | 12 ------------ intern/cycles/blender/blender_sync.cpp | 26 ++++++++++++++++++++++++++ intern/cycles/blender/blender_sync.h | 3 +++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index b7d6c1bb36d..08206dd5521 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -1077,14 +1077,6 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph, bool object_updated, bool hide_tris) { - /* When viewport display is not needed during render we can force some - * caches to be releases from blender side in order to reduce peak memory - * footprint during synchronization process. - */ - const bool is_interface_locked = b_engine.render() && - b_engine.render().use_lock_interface(); - const bool can_free_caches = BlenderSession::headless || is_interface_locked; - /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data; @@ -1209,10 +1201,6 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph, if(view_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) sync_curves(mesh, b_mesh, b_ob, false); - if(can_free_caches) { - b_ob.cache_release(); - } - /* free derived mesh */ b_data.meshes.remove(b_mesh, false, true, false); } diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index cbca623ece7..3204e0cd3f2 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -207,6 +207,8 @@ void BlenderSync::sync_data(BL::RenderSettings& b_render, python_thread_state); mesh_synced.clear(); + + free_data_after_sync(b_depsgraph); } /* Integrator */ @@ -566,6 +568,30 @@ array BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay, return passes; } +void BlenderSync::free_data_after_sync(BL::Depsgraph& b_depsgraph) +{ + /* When viewport display is not needed during render we can force some + * caches to be releases from blender side in order to reduce peak memory + * footprint during synchronization process. + */ + const bool is_interface_locked = b_engine.render() && + b_engine.render().use_lock_interface(); + const bool can_free_caches = BlenderSession::headless || is_interface_locked; + if (!can_free_caches) { + return; + } + /* TODO(sergey): We can actually remove the whole dependency graph, + * but that will need some API support first. + */ + BL::Depsgraph::objects_iterator b_ob; + for(b_depsgraph.objects.begin(b_ob); + b_ob != b_depsgraph.objects.end(); + ++b_ob) + { + b_ob->cache_release(); + } +} + /* Scene Parameters */ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene, diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index cd1a37d3f13..0465f703c51 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -157,6 +157,9 @@ private: /* Images. */ void sync_images(); + /* Early data free. */ + void free_data_after_sync(BL::Depsgraph& b_depsgraph); + /* util */ void find_shader(BL::ID& id, vector& used_shaders, Shader *default_shader); bool BKE_object_is_modified(BL::Object& b_ob); -- cgit v1.2.3 From 9d514a4e6f12563426a94a682f70f3f51435c9fa Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jul 2018 18:11:59 +0200 Subject: Cleanup: remove debug comment. --- source/blender/draw/engines/workbench/workbench_deferred.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index cf53004e126..ce209af8527 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -842,7 +842,6 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - /* TODO. */ if (TAA_ENABLED(wpd)) { workbench_taa_draw_scene_start(vedata); } @@ -886,7 +885,6 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->volume_pass); } - /* TODO */ workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); } -- cgit v1.2.3 From 057b4a6acf974e7729cd3548e32e3441986c795f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jul 2018 18:45:36 +0200 Subject: Fix/workaround T56019: memory leak with preview renders. I would not expect the order of registration to matter, and ideally we want to order the engines in the UI menu differently, but this helps for now. --- source/blender/draw/intern/draw_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 92603a0ce53..2793410cd8e 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2240,8 +2240,8 @@ void DRW_engine_register(DrawEngineType *draw_engine_type) void DRW_engines_register(void) { - RE_engines_register(&DRW_engine_viewport_opengl_type); RE_engines_register(&DRW_engine_viewport_eevee_type); + RE_engines_register(&DRW_engine_viewport_opengl_type); DRW_engine_register(&draw_engine_workbench_solid); DRW_engine_register(&draw_engine_workbench_transparent); -- cgit v1.2.3 From c05a8460a6493429a8bd08973eec4615ed0c066f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jul 2018 19:09:05 +0200 Subject: Icon/Render Preview: Fix Race condition with BKE_*_localize When editing a Material the depsgraph can throw away the evaluated ID before the preview job localized the said ID. To fix this we localize the ID from the main thread. Also fix WM_OT_previews_ensure crashing because of no depsgraph. --- source/blender/editors/render/render_preview.c | 86 +++++++++++++++++++++----- 1 file changed, 72 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 04632838cf3..6ced3f2e430 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -158,7 +158,7 @@ typedef struct ShaderPreview { Scene *scene; Depsgraph *depsgraph; - ID *id; + ID *id, *id_copy; ID *parent; MTex *slot; @@ -189,7 +189,7 @@ typedef struct IconPreview { Scene *scene; Depsgraph *depsgraph; void *owner; - ID *id; + ID *id, *id_copy; ListBase sizes; } IconPreview; @@ -312,6 +312,29 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world) return sp->worldcopy; } +static ID *duplicate_ids(ID *id, Depsgraph *depsgraph) +{ + ID *id_eval = id; + + if (depsgraph) { + id_eval = DEG_get_evaluated_id(depsgraph, id); + } + + switch (GS(id->name)) { + case ID_MA: + return (ID *)BKE_material_localize((Material *)id_eval); + case ID_TE: + return (ID *)BKE_texture_localize((Tex *)id_eval); + case ID_LA: + return (ID *)BKE_lamp_localize((Lamp *)id_eval); + case ID_WO: + return (ID *)BKE_world_localize((World *)id_eval); + default: + BLI_assert(!"ID type preview not supported."); + return NULL; + } +} + /* call this with a pointer to initialize preview scene */ /* call this with NULL to restore assigned ID pointers in preview scene */ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_type, ShaderPreview *sp) @@ -373,8 +396,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (origmat) { /* work on a copy */ - mat = BKE_material_localize(origmat); - sp->matcopy = mat; + BLI_assert(sp->id_copy != NULL); + mat = sp->matcopy = (Material *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->mat, mat); /* use current scene world to light sphere */ @@ -400,13 +424,13 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origmat is not safe! */ BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, true); } } } else { sce->r.mode &= ~(R_OSA); - } for (Base *base = view_layer->object_bases.first; base; base = base->next) { @@ -432,16 +456,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty Tex *tex = NULL, *origtex = (Tex *)id; if (origtex) { - tex = BKE_texture_localize(origtex); - sp->texcopy = tex; + BLI_assert(sp->id_copy != NULL); + tex = sp->texcopy = (Tex *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->tex, tex); } set_preview_collection(sce, view_layer, MA_TEXTURE); 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); BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origtex is not safe! */ + BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true); } } else if (id_type == ID_LA) { @@ -449,8 +475,9 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty /* work on a copy */ if (origla) { - la = BKE_lamp_localize(origla); - sp->lampcopy = la; + BLI_assert(sp->id_copy != NULL); + la = sp->lampcopy = (Lamp *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->lamp, la); } @@ -473,16 +500,18 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ - BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true); BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origla is not safe! */ + BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, true); } } else if (id_type == ID_WO) { World *wrld = NULL, *origwrld = (World *)id; if (origwrld) { - wrld = BKE_world_localize(origwrld); - sp->worldcopy = wrld; + BLI_assert(sp->id_copy != NULL); + wrld = sp->worldcopy = (World *)sp->id_copy; + sp->id_copy = NULL; BLI_addtail(&pr_main->world, wrld); } @@ -492,6 +521,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, true); + /* WATCH: Accessing origwrld is not safe! */ BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, true); } } @@ -685,7 +715,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs char name[32]; int sizex; Main *pr_main = sp->pr_main; - ID *id_eval = DEG_get_evaluated_id(sp->depsgraph, id); + ID *id_eval = id; + + if (sp->depsgraph) { + id_eval = DEG_get_evaluated_id(sp->depsgraph, id); + } /* in case of split preview, use border render */ if (split) { @@ -794,6 +828,26 @@ static void shader_preview_free(void *customdata) ShaderPreview *sp = customdata; Main *pr_main = sp->pr_main; + if (sp->id_copy){ + switch (GS(sp->id_copy->name)) { + case ID_MA: + BKE_material_free((Material *)sp->id_copy); + break; + case ID_TE: + BKE_texture_free((Tex *)sp->id_copy); + break; + case ID_LA: + BKE_lamp_free((Lamp *)sp->id_copy); + break; + case ID_WO: + BKE_world_free((World *)sp->id_copy); + break; + default: + BLI_assert(!"ID type preview not supported."); + break; + } + MEM_freeN(sp->id_copy); + } if (sp->matcopy) { struct IDProperty *properties; @@ -1074,6 +1128,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; sp->pr_rect = cur_size->rect; sp->id = ip->id; + sp->id_copy = ip->id_copy; sp->bmain = ip->bmain; if (is_render) { @@ -1149,6 +1204,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec ip.scene = scene; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; + ip.id_copy = duplicate_ids(id, NULL); icon_preview_add_size(&ip, rect, sizex, sizey); @@ -1183,6 +1239,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r ip->depsgraph = CTX_data_depsgraph(C); ip->owner = owner; ip->id = id; + ip->id_copy = duplicate_ids(id, ip->depsgraph); icon_preview_add_size(ip, rect, sizex, sizey); @@ -1231,6 +1288,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->sizey = sizey; sp->pr_method = method; sp->id = id; + sp->id_copy = duplicate_ids(id, sp->depsgraph); sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); -- cgit v1.2.3 From e81dc0b7bc1c9373b5b4029c32b1d066429e5db8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jul 2018 22:23:29 +0200 Subject: Fix E key in Python console not working after recent changes. --- source/blender/editors/interface/interface_eyedropper_color.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c index bcb60013eda..5eb4359607a 100644 --- a/source/blender/editors/interface/interface_eyedropper_color.c +++ b/source/blender/editors/interface/interface_eyedropper_color.c @@ -297,7 +297,7 @@ static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( } else { eyedropper_exit(C, op); - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; } } @@ -315,7 +315,7 @@ static int eyedropper_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - return OPERATOR_CANCELLED; + return OPERATOR_PASS_THROUGH; } } -- cgit v1.2.3 From 20191980f49dd8d348c1065461060963b15ea64b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jul 2018 22:58:52 +0200 Subject: Cycles: increase volume stack to support 32 overlapping volumes. This increases stack memory usage some, and ideally we'd support a dynamic size. But this is quite difficult on the GPU and hopefully 32 is enough even for very complex cases. --- intern/cycles/kernel/kernel_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 69ee66b3dd5..85548484873 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -54,7 +54,7 @@ CCL_NAMESPACE_BEGIN #define PRIM_NONE (~0) #define LAMP_NONE (~0) -#define VOLUME_STACK_SIZE 16 +#define VOLUME_STACK_SIZE 32 /* Split kernel constants */ #define WORK_POOL_SIZE_GPU 64 -- cgit v1.2.3 From 51f14cfa43e5fe4bdea6fbd5c668a44919657f99 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 18 Jul 2018 20:00:34 -0600 Subject: make.bat : restore msvc2015 support. broke when i removed the 2013 support. --- build_files/windows/detect_msvc_classic.cmd | 69 +++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 build_files/windows/detect_msvc_classic.cmd diff --git a/build_files/windows/detect_msvc_classic.cmd b/build_files/windows/detect_msvc_classic.cmd new file mode 100644 index 00000000000..61bfcf92ddf --- /dev/null +++ b/build_files/windows/detect_msvc_classic.cmd @@ -0,0 +1,69 @@ +if NOT "%verbose%" == "" ( + echo Detecting msvc %BUILD_VS_YEAR% +) +set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC" +for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C +if DEFINED MSVC_VC_DIR ( + if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% on Win64 detected at "%MSVC_VC_DIR%" + ) + goto msvc_detect_finally +) + +REM Check 32 bits +set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%BUILD_VS_VER%.0\Setup\VC" +for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v ProductDir 2^>nul`) DO set MSVC_VC_DIR=%%C +if DEFINED MSVC_VC_DIR ( + if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% on Win32 detected at "%MSVC_VC_DIR%" + ) + goto msvc_detect_finally +) +if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% not found. +) +goto FAIL +:msvc_detect_finally +set VCVARS=%MSVC_VC_DIR%\vcvarsall.bat +if not exist "%VCVARS%" ( + echo "%VCVARS%" not found. + goto FAIL +) + +call "%vcvars%" %BUILD_ARCH% + +rem try msbuild +msbuild /version > NUL +if errorlevel 1 ( + if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% msbuild not found + ) + goto FAIL +) + +if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% msbuild found +) + +REM try the c++ compiler +cl 2> NUL 1>&2 +if errorlevel 1 ( + if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler not found + ) + goto FAIL +) + +if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% C/C++ Compiler found +) +goto DetectionComplete + +:FAIL +exit /b 1 + +:DetectionComplete +if NOT "%verbose%" == "" ( + echo Visual Studio %BUILD_VS_YEAR% Detected successfuly +) +exit /b 0 -- cgit v1.2.3 From 9df1e54079344ed4e2becef9e57cf1b925b46dff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jul 2018 16:06:37 +1000 Subject: Cleanup: style --- release/scripts/modules/rna_prop_ui.py | 2 +- release/scripts/startup/bl_operators/wm.py | 6 +-- .../startup/bl_ui/properties_physics_common.py | 6 +-- release/scripts/startup/bl_ui/properties_scene.py | 6 +-- .../blender/blenkernel/intern/subdiv_converter.h | 6 +-- source/blender/blenkernel/intern/subdiv_mesh.c | 32 ++++++------ source/blender/blenlib/intern/hash_mm3.c | 18 +++---- .../compositor/nodes/COM_CryptomatteNode.cpp | 10 ++-- .../operations/COM_CryptomatteOperation.cpp | 2 +- source/blender/depsgraph/DEG_depsgraph.h | 6 +-- .../depsgraph/intern/builder/deg_builder_map.cc | 15 ++++-- .../depsgraph/intern/builder/deg_builder_nodes.h | 2 +- .../draw/engines/workbench/workbench_data.c | 4 +- .../draw/engines/workbench/workbench_volume.c | 2 +- source/blender/draw/intern/draw_cache.c | 2 +- source/blender/editors/render/render_preview.c | 2 +- source/blender/gpu/GPU_common.h | 8 +-- source/blender/gpu/intern/gpu_attr_binding.c | 2 +- .../blender/gpu/intern/gpu_attr_binding_private.h | 8 +-- source/blender/gpu/intern/gpu_batch_private.h | 6 +-- source/blender/gpu/intern/gpu_buffer_id.cpp | 2 +- source/blender/gpu/intern/gpu_immediate.c | 12 ++--- source/blender/gpu/intern/gpu_immediate_util.c | 2 +- source/blender/gpu/intern/gpu_shader_interface.c | 2 +- source/blender/gpu/intern/gpu_vertex_array_id.cpp | 26 +++++----- source/blender/gpu/intern/gpu_vertex_format.c | 2 +- .../blender/gpu/intern/gpu_vertex_format_private.h | 4 +- source/blender/makesrna/intern/rna_nodetree.c | 5 +- .../composite/nodes/node_composite_cryptomatte.c | 58 +++++++++++----------- .../nodes/node_shader_bsdf_hair_principled.c | 2 +- source/blender/python/gpu/gpu_py_types.c | 2 - 31 files changed, 136 insertions(+), 126 deletions(-) diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 8453077be85..0d17c11456e 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -170,7 +170,7 @@ def draw(layout, context, context_member, property_type, use_edit=True): else: row = box.row(align=True) - row.alignment = "RIGHT" + row.alignment = 'RIGHT' row.label(text=key, translate=False) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 3f0cdfa606b..0ccdd3cf5c6 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2440,9 +2440,9 @@ class WM_OT_studiolight_install(Operator): ) orientation: EnumProperty( items=( - ("MATCAP", "MatCap", ""), - ("WORLD", "World", ""), - ("CAMERA", "Camera", ""), + ('MATCAP', "MatCap", ""), + ('WORLD', "World", ""), + ('CAMERA', "Camera", ""), ) ) diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index bed5617c76c..2da84ad84da 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -132,7 +132,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): cache_info = cache.info if cache_info: col = layout.column() - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.label(text=cache_info) else: if cachetype in {'SMOKE', 'DYNAMIC_PAINT'}: @@ -156,7 +156,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): cache_info = cache.info if cachetype != 'SMOKE' and cache_info: # avoid empty space. col = layout.column(align=True) - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.label(text=cache_info) can_bake = True @@ -186,7 +186,7 @@ def point_cache_ui(self, context, cache, enabled, cachetype): can_bake = False col = layout.column(align=True) - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.separator() diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 1b21ac8fcdf..38bfc6ad294 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -215,7 +215,7 @@ class SCENE_PT_keyframing_settings(SceneButtonsPanel, SceneKeyingSetsPanel, Pane flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=True) col = flow.column(align=True) - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.label(text="General Override") self.draw_keyframing_settings(context, col, ks, None) @@ -225,7 +225,7 @@ class SCENE_PT_keyframing_settings(SceneButtonsPanel, SceneKeyingSetsPanel, Pane col.separator() col = flow.column(align=True) - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.label(text="Active Set Override") self.draw_keyframing_settings(context, col, ks, ksp) @@ -272,7 +272,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel): ksp = ks.paths.active if ksp: col = flow.column(align=True) - col.alignment = "RIGHT" + col.alignment = 'RIGHT' col.template_any_ID(ksp, "id", "id_type", text="Target ID-Block") diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h index 748d97f4178..4c552a9164e 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.h +++ b/source/blender/blenkernel/intern/subdiv_converter.h @@ -23,8 +23,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BKE_SUBDIV_CONVERTER_H__ -#define __BKE_SUBDIV_CONVERTER_H__ +#ifndef __SUBDIV_CONVERTER_H__ +#define __SUBDIV_CONVERTER_H__ #include "BKE_subdiv.h" @@ -54,4 +54,4 @@ void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter); int BKE_subdiv_converter_fvar_linear_from_settings( const SubdivSettings *settings); -#endif /* __BKE_SUBDIV_CONVERTER_H__ */ +#endif /* __SUBDIV_CONVERTER_H__ */ diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 8a58605ba19..c2a10483e26 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -152,7 +152,7 @@ static void edges_of_ptex_get( typedef struct VerticesForInterpolation { /* This field points to a vertex data which is to be used for interpolation. * The idea is to avoid unnecessary allocations for regular faces, where - * we can simply + * we can simply */ const CustomData *vertex_data; /* Vertices data calculated for ptex corners. There are always 4 elements @@ -176,7 +176,7 @@ typedef struct VerticesForInterpolation { static void vertex_interpolation_init( const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, - const MPoly *coarse_poly) + const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; const MLoop *coarse_mloop = coarse_mesh->mloop; @@ -234,7 +234,8 @@ static void vertex_interpolation_from_ptex( { if (coarse_poly->totloop == 4) { /* Nothing to do, all indices and data is already assigned. */ - } else { + } + else { const CustomData *vertex_data = &ctx->coarse_mesh->vdata; const Mesh *coarse_mesh = ctx->coarse_mesh; const MLoop *coarse_mloop = coarse_mesh->mloop; @@ -287,7 +288,7 @@ static void vertex_interpolation_end( typedef struct LoopsForInterpolation { /* This field points to a loop data which is to be used for interpolation. * The idea is to avoid unnecessary allocations for regular faces, where - * we can simply + * we can simply */ const CustomData *loop_data; /* Loops data calculated for ptex corners. There are always 4 elements @@ -311,7 +312,7 @@ typedef struct LoopsForInterpolation { static void loop_interpolation_init( const SubdivMeshContext *ctx, LoopsForInterpolation *loop_interpolation, - const MPoly *coarse_poly) + const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; if (coarse_poly->totloop == 4) { @@ -363,7 +364,8 @@ static void loop_interpolation_from_ptex( { if (coarse_poly->totloop == 4) { /* Nothing to do, all indices and data is already assigned. */ - } else { + } + else { const CustomData *loop_data = &ctx->coarse_mesh->ldata; const Mesh *coarse_mesh = ctx->coarse_mesh; const MLoop *coarse_mloop = coarse_mesh->mloop; @@ -481,9 +483,10 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, vertex_interpolation_end(&vertex_interpolation); } -static void subdiv_copy_edge_data(SubdivMeshContext *ctx, - MEdge *subdiv_edge, - const MEdge *coarse_edge) +static void subdiv_copy_edge_data( + SubdivMeshContext *ctx, + MEdge *subdiv_edge, + const MEdge *coarse_edge) { if (coarse_edge == NULL) { subdiv_edge->crease = 0; @@ -586,11 +589,12 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) EdgesOfPtex edges_of_ptex; edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, i); /* Create bottom row of edges (0-1, 1-2). */ - subdiv_edge = subdiv_create_edges_row(ctx, - subdiv_edge, - edges_of_ptex.first_edge, - start_ptex_face_vertex_index, - resolution); + subdiv_edge = subdiv_create_edges_row( + ctx, + subdiv_edge, + edges_of_ptex.first_edge, + start_ptex_face_vertex_index, + resolution); /* Create remaining edges. */ for (int row = 0; row < resolution - 1; row++) { const int start_row_vertex_index = diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c index 5ead9ceca63..105c1f46832 100644 --- a/source/blender/blenlib/intern/hash_mm3.c +++ b/source/blender/blenlib/intern/hash_mm3.c @@ -92,7 +92,7 @@ BLI_INLINE uint64_t fmix64(uint64_t k) uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) { - const uint8_t *data = (const uint8_t*)in; + const uint8_t *data = (const uint8_t *)in; const int nblocks = len / 4; uint32_t h1 = seed; @@ -102,23 +102,23 @@ uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) /* body */ - const uint32_t *blocks = (const uint32_t *)(data + nblocks*4); + const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4); for (int i = -nblocks; i; i++) { - uint32_t k1 = getblock32(blocks,i); + uint32_t k1 = getblock32(blocks, i); k1 *= c1; - k1 = ROTL32(k1,15); + k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - h1 = ROTL32(h1,13); - h1 = h1*5+0xe6546b64; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; } /* tail */ - const uint8_t *tail = (const uint8_t*)(data + nblocks*4); + const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); uint32_t k1 = 0; @@ -132,10 +132,10 @@ uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) case 1: k1 ^= tail[0]; k1 *= c1; - k1 = ROTL32(k1,15); + k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - }; + } /* finalization */ diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp index bc115e66c20..648ea4556ad 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp @@ -62,7 +62,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos bNode *node = this->getbNode(); NodeCryptomatte *cryptoMatteSettings = (NodeCryptomatte *)node->storage; - CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets()-1); + CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets() - 1); if (cryptoMatteSettings) { if (cryptoMatteSettings->matte_id) { /* Split the string by commas, ignoring white space. */ @@ -83,7 +83,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos operation->addObjectIndex(atof(token.substr(1, token.length() - 2).c_str())); } else { - uint32_t hash = BLI_hash_mm3((const unsigned char*)token.c_str(), token.length(), 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)token.c_str(), token.length(), 0); operation->addObjectIndex(hash_to_float(hash)); } } @@ -93,14 +93,14 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos converter.addOperation(operation); - for (int i = 0; i < getNumberOfInputSockets()-1; ++i) { + for (int i = 0; i < getNumberOfInputSockets() - 1; ++i) { converter.mapInputSocket(this->getInputSocket(i + 1), operation->getInputSocket(i)); } SeparateChannelOperation *separateOperation = new SeparateChannelOperation; separateOperation->setChannel(3); converter.addOperation(separateOperation); - + SetAlphaOperation *operationAlpha = new SetAlphaOperation(); converter.addOperation(operationAlpha); @@ -117,5 +117,5 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos converter.mapOutputSocket(outputSocketMatte, separateOperation->getOutputSocket(0)); converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket(0)); converter.mapOutputSocket(outputSocketPick, clearAlphaOperation->getOutputSocket(0)); - + } diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp index 9dd36863d37..f3fa81075c6 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp @@ -63,7 +63,7 @@ void CryptomatteOperation::executePixel(float output[4], output[1] = ((float) ((m3hash << 8)) / (float) UINT32_MAX); output[2] = ((float) ((m3hash << 16)) / (float) UINT32_MAX); } - for(size_t i = 0; i < m_objectIndex.size(); i++) { + for (size_t i = 0; i < m_objectIndex.size(); i++) { if (m_objectIndex[i] == input[0]) { output[3] += input[1]; } diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 71376d94ca8..2e566752a6f 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -269,9 +269,9 @@ void DEG_debug_print_eval_parent_typed(struct Depsgraph *depsgraph, const void *parent_address); void DEG_debug_print_eval_time(struct Depsgraph *depsgraph, - const char* function_name, - const char* object_name, - const void* object_address, + const char *function_name, + const char *object_name, + const void *object_address, float time); #ifdef __cplusplus diff --git a/source/blender/depsgraph/intern/builder/deg_builder_map.cc b/source/blender/depsgraph/intern/builder/deg_builder_map.cc index 218483d1dc5..cde7b9721b7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_map.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_map.cc @@ -37,24 +37,29 @@ namespace DEG { -BuilderMap::BuilderMap() { +BuilderMap::BuilderMap() +{ set = BLI_gset_ptr_new("deg builder gset"); } -BuilderMap::~BuilderMap() { +BuilderMap::~BuilderMap() +{ BLI_gset_free(set, NULL); } -bool BuilderMap::checkIsBuilt(ID *id) { +bool BuilderMap::checkIsBuilt(ID *id) +{ return BLI_gset_haskey(set, id); } -void BuilderMap::tagBuild(ID *id) { +void BuilderMap::tagBuild(ID *id) +{ BLI_gset_insert(set, id); } -bool BuilderMap::checkIsBuiltAndTag(ID *id) { +bool BuilderMap::checkIsBuiltAndTag(ID *id) +{ void **key_p; if (!BLI_gset_ensure_p_ex(set, id, &key_p)) { *key_p = id; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 6899a86b3e9..66293a91e85 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -158,7 +158,7 @@ struct DepsgraphNodeBuilder { const char *name = "", int name_tag = -1); - void build_id(ID* id); + void build_id(ID *id); void build_layer_collections(ListBase *lb); void build_view_layer(Scene *scene, ViewLayer *view_layer, diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 07df067f324..5c3ab5f6688 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -33,11 +33,11 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) if (wpd->shading.light == V3D_LIGHTING_MATCAP) { wpd->studio_light = BKE_studiolight_find( - wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); + wpd->shading.matcap, STUDIOLIGHT_ORIENTATION_VIEWNORMAL); } else { wpd->studio_light = BKE_studiolight_find( - wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); + wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); } wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity; diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index f28bfd01ae8..ea4152486af 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -19,7 +19,7 @@ * */ -/** \file workbench_volumed.c +/** \file workbench_volume.c * \ingroup draw_engine */ diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index bb73a8c1b19..dff863b11bb 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -901,7 +901,7 @@ GPUBatch *DRW_cache_empty_capsule_cap_get(void) float v[3] = {0.0f, 0.0f, 0.0f}; copy_v2_v2(v, p[(i) % NSEGMENTS]); GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); - copy_v2_v2(v, p[(i+1) % NSEGMENTS]); + copy_v2_v2(v, p[(i + 1) % NSEGMENTS]); GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 6ced3f2e430..450897382dd 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -828,7 +828,7 @@ static void shader_preview_free(void *customdata) ShaderPreview *sp = customdata; Main *pr_main = sp->pr_main; - if (sp->id_copy){ + if (sp->id_copy) { switch (GS(sp->id_copy->name)) { case ID_MA: BKE_material_free((Material *)sp->id_copy); diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h index 7d86a6ec8a5..3acc7fad5c2 100644 --- a/source/blender/gpu/GPU_common.h +++ b/source/blender/gpu/GPU_common.h @@ -33,14 +33,14 @@ #define PROGRAM_NO_OPTI 0 #if defined(NDEBUG) - #define TRUST_NO_ONE 0 +# define TRUST_NO_ONE 0 #else /* strict error checking, enabled for debug builds during early development */ - #define TRUST_NO_ONE 1 +# define TRUST_NO_ONE 1 #endif #if defined(WITH_OPENGL) - #include +# include #endif #include @@ -48,7 +48,7 @@ #include "BLI_sys_types.h" #if TRUST_NO_ONE - #include +# include #endif /* GPU_INLINE */ diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.c index e66fac390f1..398b97c7f9d 100644 --- a/source/blender/gpu/intern/gpu_attr_binding.c +++ b/source/blender/gpu/intern/gpu_attr_binding.c @@ -35,7 +35,7 @@ #include #if GPU_VERT_ATTR_MAX_LEN != 16 - #error "attrib binding code assumes GPU_VERT_ATTR_MAX_LEN = 16" +# error "attrib binding code assumes GPU_VERT_ATTR_MAX_LEN = 16" #endif void AttribBinding_clear(GPUAttrBinding *binding) diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h index 240509de0d4..cb338b10aa4 100644 --- a/source/blender/gpu/intern/gpu_attr_binding_private.h +++ b/source/blender/gpu/intern/gpu_attr_binding_private.h @@ -35,9 +35,11 @@ #include "GPU_vertex_format.h" #include "GPU_shader_interface.h" -void AttribBinding_clear(GPUAttrBinding*); +void AttribBinding_clear(GPUAttrBinding *binding); -void get_attrib_locations(const GPUVertFormat*, GPUAttrBinding*, const GPUShaderInterface*); -unsigned read_attrib_location(const GPUAttrBinding*, unsigned a_idx); +void get_attrib_locations( + const GPUVertFormat *format, GPUAttrBinding *binding, const GPUShaderInterface *shaderface); +unsigned read_attrib_location( + const GPUAttrBinding *binding, unsigned a_idx); #endif /* __GPU_ATTR_BINDING_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h index 0b25c0aef05..51040ff751a 100644 --- a/source/blender/gpu/intern/gpu_batch_private.h +++ b/source/blender/gpu/intern/gpu_batch_private.h @@ -41,10 +41,10 @@ extern "C" { #include "GPU_context.h" #include "GPU_shader_interface.h" -void gpu_batch_remove_interface_ref(GPUBatch*, const GPUShaderInterface*); +void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface); -void gpu_context_add_batch(GPUContext*, GPUBatch*); -void gpu_context_remove_batch(GPUContext*, GPUBatch*); +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch); +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); #ifdef __cplusplus } diff --git a/source/blender/gpu/intern/gpu_buffer_id.cpp b/source/blender/gpu/intern/gpu_buffer_id.cpp index c1aaf1945aa..f3faba9c766 100644 --- a/source/blender/gpu/intern/gpu_buffer_id.cpp +++ b/source/blender/gpu/intern/gpu_buffer_id.cpp @@ -37,7 +37,7 @@ #define ORPHAN_DEBUG 0 #if ORPHAN_DEBUG - #include +# include #endif static std::vector orphaned_buffer_ids; diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 06b487fbb25..66a467e339e 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -701,17 +701,17 @@ void immVertex2iv(uint attrib_id, const int data[2]) /* --- generic uniform functions --- */ #if 0 - #if TRUST_NO_ONE - #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); - #else - #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); - #endif +# if TRUST_NO_ONE +# define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); assert(uniform); +# else +# define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); +# endif #else /* NOTE: It is possible to have uniform fully optimized out from the shader. * In this case we can't assert failure or allow NULL-pointer dereference. * TODO(sergey): How can we detect existing-but-optimized-out uniform but still * catch typos in uniform names passed to immUniform*() functions? */ - #define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; +# define GET_UNIFORM const GPUShaderInput* uniform = GPU_shaderinterface_uniform(imm.shader_interface, name); if (uniform == NULL) return; #endif void immUniform1f(const char *name, float x) diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index cf594367bdf..8384ef3b5d0 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -18,7 +18,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gpu_imm_util.c +/** \file blender/gpu/intern/gpu_immediate_util.c * \ingroup gpu * * GPU immediate mode drawing utilities diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index 7e1d942da2d..4b8413d0cc3 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -39,7 +39,7 @@ #define DEBUG_SHADER_INTERFACE 0 #if DEBUG_SHADER_INTERFACE - #include +# include #endif static const char *BuiltinUniform_name(GPUUniformBuiltin u) diff --git a/source/blender/gpu/intern/gpu_vertex_array_id.cpp b/source/blender/gpu/intern/gpu_vertex_array_id.cpp index 2f29bbfbc33..64f704bb107 100644 --- a/source/blender/gpu/intern/gpu_vertex_array_id.cpp +++ b/source/blender/gpu/intern/gpu_vertex_array_id.cpp @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/gpu_vertex_array_id.cpp +/** \file blender/gpu/intern/gpu_vertex_array_id.cpp * \ingroup gpu * * Manage GL vertex array IDs in a thread-safe way @@ -58,7 +58,7 @@ static bool thread_is_main() { struct GPUContext { GLuint default_vao; - std::unordered_set batches; /* Batches that have VAOs from this context */ + std::unordered_set batches; /* Batches that have VAOs from this context */ std::vector orphaned_vertarray_ids; std::mutex orphans_mutex; /* todo: try spinlock instead */ #if TRUST_NO_ONE @@ -73,12 +73,12 @@ struct GPUContext { #if defined(_MSC_VER) && (_MSC_VER == 1800) #define thread_local __declspec(thread) -thread_local GPUContext* active_ctx = NULL; +thread_local GPUContext *active_ctx = NULL; #else -static thread_local GPUContext* active_ctx = NULL; +static thread_local GPUContext *active_ctx = NULL; #endif -static void clear_orphans(GPUContext* ctx) +static void clear_orphans(GPUContext *ctx) { ctx->orphans_mutex.lock(); if (!ctx->orphaned_vertarray_ids.empty()) { @@ -89,19 +89,19 @@ static void clear_orphans(GPUContext* ctx) ctx->orphans_mutex.unlock(); } -GPUContext* GPU_context_create(void) +GPUContext *GPU_context_create(void) { #if TRUST_NO_ONE /* assert(thread_is_main()); */ #endif - GPUContext* ctx = new GPUContext; + GPUContext *ctx = new GPUContext; glGenVertexArrays(1, &ctx->default_vao); GPU_context_active_set(ctx); return ctx; } /* to be called after GPU_context_active_set(ctx_to_destroy) */ -void GPU_context_discard(GPUContext* ctx) +void GPU_context_discard(GPUContext *ctx) { #if TRUST_NO_ONE /* Make sure no other thread has locked it. */ @@ -120,7 +120,7 @@ void GPU_context_discard(GPUContext* ctx) } /* ctx can be NULL */ -void GPU_context_active_set(GPUContext* ctx) +void GPU_context_active_set(GPUContext *ctx) { #if TRUST_NO_ONE if (active_ctx) { @@ -140,7 +140,7 @@ void GPU_context_active_set(GPUContext* ctx) active_ctx = ctx; } -GPUContext* GPU_context_active_get(void) +GPUContext *GPU_context_active_get(void) { return active_ctx; } @@ -168,7 +168,7 @@ GLuint GPU_vao_alloc(void) } /* this can be called from multiple thread */ -void GPU_vao_free(GLuint vao_id, GPUContext* ctx) +void GPU_vao_free(GLuint vao_id, GPUContext *ctx) { #if TRUST_NO_ONE assert(ctx); @@ -183,12 +183,12 @@ void GPU_vao_free(GLuint vao_id, GPUContext* ctx) } } -void gpu_context_add_batch(GPUContext* ctx, GPUBatch* batch) +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch) { ctx->batches.emplace(batch); } -void gpu_context_remove_batch(GPUContext* ctx, GPUBatch* batch) +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch) { ctx->orphans_mutex.lock(); ctx->batches.erase(batch); diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c index f1f75f449d4..eef4945d9ef 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.c +++ b/source/blender/gpu/intern/gpu_vertex_format.c @@ -37,7 +37,7 @@ #define PACK_DEBUG 0 #if PACK_DEBUG - #include +# include #endif void GPU_vertformat_clear(GPUVertFormat *format) diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h index 4ce3ebba714..e4fe61e8697 100644 --- a/source/blender/gpu/intern/gpu_vertex_format_private.h +++ b/source/blender/gpu/intern/gpu_vertex_format_private.h @@ -32,8 +32,8 @@ #ifndef __GPU_VERTEX_FORMAT_PRIVATE_H__ #define __GPU_VERTEX_FORMAT_PRIVATE_H__ -void VertexFormat_pack(GPUVertFormat*); +void VertexFormat_pack(GPUVertFormat *format); uint padding(uint offset, uint alignment); -uint vertex_buffer_size(const GPUVertFormat*, uint vertex_len); +uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len); #endif /* __GPU_VERTEX_FORMAT_PRIVATE_H__ */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e672ae0e6f7..b9a8f306baf 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -6976,8 +6976,9 @@ static void def_cmp_cryptomatte(StructRNA *srna) RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage"); prop = RNA_def_property(srna, "matte_id", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs(prop, "rna_NodeCryptomatte_matte_get", "rna_NodeCryptomatte_matte_length", - "rna_NodeCryptomatte_matte_set"); + RNA_def_property_string_funcs( + prop, "rna_NodeCryptomatte_matte_get", "rna_NodeCryptomatte_matte_length", + "rna_NodeCryptomatte_matte_set"); RNA_def_property_ui_text(prop, "Matte Objects", "List of object and material crypto IDs to include in matte"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c index 0231e4717b2..bf9ab4a5064 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -39,10 +39,10 @@ static inline float hash_to_float(uint32_t hash) { - uint32_t mantissa = hash & (( 1 << 23) - 1); + uint32_t mantissa = hash & ((1 << 23) - 1); uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); - exponent = MAX2(exponent, (uint32_t) 1); - exponent = MIN2(exponent, (uint32_t) 254); + exponent = MAX2(exponent, (uint32_t)1); + exponent = MIN2(exponent, (uint32_t)254); exponent = exponent << 23; uint32_t sign = (hash >> 31); sign = sign << 31; @@ -54,7 +54,7 @@ static inline float hash_to_float(uint32_t hash) return f; } -static void cryptomatte_add(NodeCryptomatte* n, float f) +static void cryptomatte_add(NodeCryptomatte *n, float f) { /* Turn the number into a string. */ char number[32]; @@ -72,16 +72,16 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) } /* Find the next seprator. */ - char* token_end = strchr(n->matte_id+start, ','); - if (token_end == NULL || token_end == n->matte_id+start) { - token_end = n->matte_id+end; + char *token_end = strchr(n->matte_id + start, ','); + if (token_end == NULL || token_end == n->matte_id + start) { + token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ token_len = token_end - (n->matte_id + start); /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ if (n->matte_id[start] == '<') { - if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + if (strncmp(n->matte_id + start, number, strlen(number)) == 0) { /* This number is already there, so continue. */ return; } @@ -89,16 +89,16 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) else { /* Remove trailing white space */ size_t name_len = token_len; - while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + while (n->matte_id[start + name_len] == ' ' && name_len > 0) { name_len--; } /* Calculate the hash of the token and compare. */ - uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0); if (f == hash_to_float(hash)) { return; } } - start += token_len+1; + start += token_len + 1; } } @@ -107,12 +107,12 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) return; } - if(n->matte_id) { + if (n->matte_id) { BLI_dynstr_append(new_matte, n->matte_id); MEM_freeN(n->matte_id); } - if(BLI_dynstr_get_len(new_matte) > 0) { + if (BLI_dynstr_get_len(new_matte) > 0) { BLI_dynstr_append(new_matte, ","); } BLI_dynstr_append(new_matte, number); @@ -120,7 +120,7 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) BLI_dynstr_free(new_matte); } -static void cryptomatte_remove(NodeCryptomatte*n, float f) +static void cryptomatte_remove(NodeCryptomatte *n, float f) { if (n->matte_id == NULL || strlen(n->matte_id) == 0) { /* Empty string, nothing to remove. */ @@ -150,9 +150,9 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) } /* Find the next seprator. */ - char* token_end = strchr(n->matte_id+start+1, ','); - if (token_end == NULL || token_end == n->matte_id+start) { - token_end = n->matte_id+end; + char *token_end = strchr(n->matte_id + start + 1, ','); + if (token_end == NULL || token_end == n->matte_id + start) { + token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ token_len = token_end - (n->matte_id + start); @@ -162,7 +162,7 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) } /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ else if (n->matte_id[start] == '<') { - if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + if (strncmp(n->matte_id + start, number, strlen(number)) == 0) { /* This number is already there, so skip it. */ skip = true; } @@ -170,11 +170,11 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) else { /* Remove trailing white space */ size_t name_len = token_len; - while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + while (n->matte_id[start + name_len] == ' ' && name_len > 0) { name_len--; } /* Calculate the hash of the token and compare. */ - uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0); if (f == hash_to_float(hash)) { skip = true; } @@ -186,26 +186,26 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) else { BLI_dynstr_append(new_matte, ", "); } - BLI_dynstr_nappend(new_matte, n->matte_id+start, token_len); + BLI_dynstr_nappend(new_matte, n->matte_id + start, token_len); } - start += token_len+1; + start += token_len + 1; } - if(n->matte_id) { + if (n->matte_id) { MEM_freeN(n->matte_id); n->matte_id = NULL; } - if(BLI_dynstr_get_len(new_matte) > 0) { + if (BLI_dynstr_get_len(new_matte) > 0) { n->matte_id = BLI_dynstr_get_cstring(new_matte); } BLI_dynstr_free(new_matte); } static bNodeSocketTemplate outputs[] = { - { SOCK_RGBA, 0, N_("Image")}, - { SOCK_FLOAT, 0, N_("Matte")}, - { SOCK_RGBA, 0, N_("Pick")}, - { -1, 0, "" } + { SOCK_RGBA, 0, N_("Image")}, + { SOCK_FLOAT, 0, N_("Matte")}, + { SOCK_RGBA, 0, N_("Pick")}, + { -1, 0, "" } }; void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *UNUSED(ntree), bNode *node) @@ -235,7 +235,7 @@ bNodeSocket *ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node) NodeCryptomatte *n = node->storage; char sockname[32]; n->num_inputs++; - BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs-1); + BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs - 1); bNodeSocket *sock = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, NULL, sockname); return sock; } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c index 5fff2548ba1..83e4bf1731b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c @@ -40,7 +40,7 @@ static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = { { SOCK_FLOAT, 1, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, - { SOCK_FLOAT, 1, N_("Offset"), 2.f*((float)M_PI)/180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, + { SOCK_FLOAT, 1, N_("Offset"), 2.0f * ((float)M_PI) / 180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, { SOCK_FLOAT, 1, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, diff --git a/source/blender/python/gpu/gpu_py_types.c b/source/blender/python/gpu/gpu_py_types.c index 0a21da5682b..4e564fdf849 100644 --- a/source/blender/python/gpu/gpu_py_types.c +++ b/source/blender/python/gpu/gpu_py_types.c @@ -32,8 +32,6 @@ #include "BLI_math.h" -#include "GPU_batch.h" - #include "MEM_guardedalloc.h" #include "../generic/py_capi_utils.h" -- cgit v1.2.3 From 64bbfaf42144e26718bfb789cba81a409536cf73 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 18 Jul 2018 17:34:44 +0200 Subject: Subsurf: Set original index for high-poly vertices --- source/blender/blenkernel/BKE_subdiv.h | 1 + source/blender/blenkernel/intern/subdiv_mesh.c | 39 ++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 92fb1167f55..45316e3cc91 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -22,6 +22,7 @@ * * ***** END GPL LICENSE BLOCK ***** */ + #ifndef __BKE_SUBDIV_H__ #define __BKE_SUBDIV_H__ diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index c2a10483e26..9090ebe9f0f 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -416,7 +416,10 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) static void subdiv_copy_vertex_data( const SubdivMeshContext *ctx, MVert *subdiv_vertex, + const Mesh *coarse_mesh, + const MPoly *coarse_poly, const VerticesForInterpolation *vertex_interpolation, + const int ptex_of_poly_index, const float u, const float v) { const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert; @@ -430,7 +433,34 @@ static void subdiv_copy_vertex_data( weights, NULL, 4, subdiv_vertex_index); - /* TODO(sergey): Set ORIGINDEX. */ + if (ctx->vert_origindex != NULL) { + ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; + if (coarse_poly->totloop == 4) { + if (u == 0.0f && v == 0.0f) { + ctx->vert_origindex[subdiv_vertex_index] = + vertex_interpolation->vertex_indices[0]; + } + else if (u == 1.0f && v == 0.0f) { + ctx->vert_origindex[subdiv_vertex_index] = + vertex_interpolation->vertex_indices[1]; + } + else if (u == 1.0f && v == 1.0f) { + ctx->vert_origindex[subdiv_vertex_index] = + vertex_interpolation->vertex_indices[2]; + } + else if (u == 0.0f && v == 1.0f) { + ctx->vert_origindex[subdiv_vertex_index] = + vertex_interpolation->vertex_indices[3]; + } + } else { + if (u == 0.0f && v == 0.0f) { + const MLoop *coarse_mloop = coarse_mesh->mloop; + ctx->vert_origindex[subdiv_vertex_index] = + coarse_mloop[coarse_poly->loopstart + + ptex_of_poly_index].v; + } + } + } } static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, @@ -447,12 +477,12 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); /* Hi-poly subdivided mesh. */ Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_vertert = subdiv_mesh->mvert; + MVert *subdiv_vertex = subdiv_mesh->mvert; const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; /* Actual evaluation. */ VerticesForInterpolation vertex_interpolation; vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly); - MVert *subdiv_vert = &subdiv_vertert[ptex_face_index * resolution2]; + MVert *subdiv_vert = &subdiv_vertex[ptex_face_index * resolution2]; for (int ptex_of_poly_index = 0; ptex_of_poly_index < num_poly_ptex_faces; ptex_of_poly_index++) @@ -475,7 +505,10 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, const float u = x * inv_resolution_1; subdiv_copy_vertex_data(ctx, subdiv_vert, + coarse_mesh, + coarse_poly, &vertex_interpolation, + ptex_of_poly_index, u, v); } } -- cgit v1.2.3 From 3882d0943b33c42d1dbe67d10d2432c0e7191959 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 18 Jul 2018 17:49:12 +0200 Subject: Subsurf: Fix wrong edge original index --- source/blender/blenkernel/intern/subdiv_mesh.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 9090ebe9f0f..7baf03e7265 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -521,14 +521,17 @@ static void subdiv_copy_edge_data( MEdge *subdiv_edge, const MEdge *coarse_edge) { + const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge; if (coarse_edge == NULL) { subdiv_edge->crease = 0; subdiv_edge->bweight = 0; subdiv_edge->flag = 0; + if (ctx->edge_origindex != NULL) { + ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE; + } return; } const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge; - const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge; CustomData_copy_data(&ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, -- cgit v1.2.3 From b6b185691f018f6b175ffb58c65418991cda75f2 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Thu, 19 Jul 2018 19:27:45 +0530 Subject: Code cleanup and fixes --- source/blender/bmesh/tools/bmesh_bevel.c | 44 ++++++++++++++-------------- source/blender/editors/mesh/editmesh_bevel.c | 10 ++++--- source/blender/makesdna/DNA_modifier_types.h | 1 - source/blender/modifiers/intern/MOD_bevel.c | 40 ++++++++++++------------- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 8a72ffc775f..bcf44ad4384 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -152,7 +152,7 @@ typedef struct BoundVert { Profile profile; /* edge profile between this and next BoundVert */ bool any_seam; /* are any of the edges attached here seams? */ bool visited; /* used during delta adjust pass */ - int add_seam; + int seam_len; int sharp_len; // int _pad; } BoundVert; @@ -1532,18 +1532,18 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin co[2] = z; } -#define EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag)) +#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag)) static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) { EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; - while ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag)))) { + while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) { e = e->next; if (e == efirst) break; } - if ((!neg && !EDGE_DATA_CHECK(e, flag) || (neg && EDGE_DATA_CHECK(e, flag)))) + if ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) return; efirst = e; @@ -1551,17 +1551,17 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) int flag_count = 0; EdgeHalf *ne = e->next; - while ((!neg && !EDGE_DATA_CHECK(ne, flag) || (neg && EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { + while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { if (ne->is_bev) flag_count++; ne = ne->next; } - if (ne == e || (ne == efirst && (!neg && !EDGE_DATA_CHECK(efirst, flag) || - (neg && EDGE_DATA_CHECK(efirst, flag))))) { + if (ne == e || (ne == efirst && (!neg && !BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag) || + (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) { break; } if (flag == BM_ELEM_SEAM) - e->rightv->add_seam = flag_count; + e->rightv->seam_len = flag_count; else if (flag == BM_ELEM_SMOOTH) e->rightv->sharp_len = flag_count; e = ne; @@ -1576,11 +1576,11 @@ static void bevel_extend_edge_data(BevVert *bv) BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; do { - if (bcur->add_seam) { - if (!bv->vmesh->boundstart->add_seam && start == bv->vmesh->boundstart) + if (bcur->seam_len) { + if (!bv->vmesh->boundstart->seam_len && start == bv->vmesh->boundstart) start = bcur; - int idxlen = bcur->index + bcur->add_seam; + int idxlen = bcur->index + bcur->seam_len; for (int i = bcur->index; i < idxlen; i++) { BMVert *v1 = mesh_vert(vm, i % vm->count, 0, 0)->v, *v2; BMEdge *e; @@ -1659,7 +1659,6 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B { if (bp->hnmode == BEVEL_HN_NONE) return; - int mode = 1; VMesh *vm = bv->vmesh; BoundVert *bcur = vm->boundstart, *bstart = bcur; @@ -1672,7 +1671,7 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B float n_final[3] = { 0.0f, 0.0f, 0.0f }; if (bp->hnmode == BEVEL_HN_FACE) { - GHash *faceHash = BLI_ghash_int_new(__func__); + GHash *tempfaceHash = BLI_ghash_int_new(__func__); BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_TAG)) { @@ -1680,25 +1679,25 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B BMFace *f_a, *f_b; BM_edge_face_pair(e, &f_a, &f_b); - if(f_a && !BLI_ghash_haskey(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)))) { + if(f_a && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)))) { int f_area = BM_face_calc_area(f_a); float f_no[3]; copy_v3_v3(f_no, f_a->no); mul_v3_fl(f_no, f_area); add_v3_v3(n_final, f_no); - BLI_ghash_insert(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)), NULL); + BLI_ghash_insert(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)), NULL); } - if(f_b && !BLI_ghash_haskey(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)))) { + if(f_b && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)))) { int f_area = BM_face_calc_area(f_b); float f_no[3]; copy_v3_v3(f_no, f_b->no); mul_v3_fl(f_no, f_area); add_v3_v3(n_final, f_no); - BLI_ghash_insert(faceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)), NULL); + BLI_ghash_insert(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)), NULL); } } } - BLI_ghash_free(faceHash, NULL, NULL); + BLI_ghash_free(tempfaceHash, NULL, NULL); normalize_v3(n_final); } else if (bp->hnmode == BEVEL_HN_ADJ) { @@ -1718,11 +1717,11 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B do { if (BMO_slot_map_contains(nslot, bcur->nv.v) != true) { - float(*custom_normal) = MEM_callocN(sizeof(*custom_normal) * 3, __func__); - add_v3_v3(custom_normal, n_final); - normalize_v3(custom_normal); + float(*vert_normal) = MEM_callocN(sizeof(*vert_normal) * 3, __func__); + add_v3_v3(vert_normal, n_final); + normalize_v3(vert_normal); - BMO_slot_map_insert(op, nslot, bcur->nv.v, custom_normal); + BMO_slot_map_insert(op, nslot, bcur->nv.v, vert_normal); } bcur = bcur->next; } while (bcur != bstart); @@ -5662,6 +5661,7 @@ void BM_mesh_bevel( BLI_memarena_use_calloc(bp.mem_arena); set_profile_spacing(&bp); + /* Stores BMOp if executed through tool else stores BevelModNorEditData */ if (bm->use_toolflags) op = mod_bmop_customdata; else { diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index f6b69beac71..83da84357dc 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -140,7 +140,7 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st { BKE_editmesh_lnorspace_update(em); BM_normals_loops_edges_tag(em->bm, true); - int cd_clnors_offset = CustomData_get_offset(&em->bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_clnors_offset = CustomData_get_offset(&em->bm->ldata, CD_CUSTOMLOOPNORMAL); BMesh *bm = em->bm; BMFace *f; @@ -181,10 +181,12 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st else { e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e; } + BLI_SMALLSTACK_PUSH(loops, lfan_pivot); float cur[3]; mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); + if(BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT)) add_v3_v3(cn_unwght, cur); @@ -310,7 +312,7 @@ static bool edbm_bevel_calc(wmOperator *op) const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide"); const bool mark_seam = RNA_boolean_get(op->ptr, "mark_seam"); const bool mark_sharp = RNA_boolean_get(op->ptr, "mark_sharp"); - const float strength = RNA_float_get(op->ptr, "strength"); + const float hn_strength = RNA_float_get(op->ptr, "strength"); const int hnmode = RNA_enum_get(op->ptr, "hnmode"); @@ -330,7 +332,7 @@ static bool edbm_bevel_calc(wmOperator *op) "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b strength=%f hnmode=%i", BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide, mark_seam, mark_sharp, strength, hnmode); + clamp_overlap, material, loop_slide, mark_seam, mark_sharp, hn_strength, hnmode); BMO_op_exec(em->bm, &bmop); @@ -342,7 +344,7 @@ static bool edbm_bevel_calc(wmOperator *op) } if(hnmode != BEVEL_HN_NONE) - bevel_harden_normals(em, &bmop, strength, hnmode); + bevel_harden_normals(em, &bmop, hn_strength, hnmode); /* no need to de-select existing geometry */ if (!EDBM_op_finish(em, &bmop, op, true)) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 5e8ead09d91..fec73c267ce 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -318,7 +318,6 @@ enum { typedef struct BevelModNorEditData { struct GHash *faceHash; - struct GHash *vert_hash; } BevelModNorEditData; typedef struct BevelModifierData { diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 06c4f8c57fd..1ada8b215c5 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -108,9 +108,9 @@ static void bevel_set_weighted_normal_face_strength(BMesh *bm, Scene *scene) } } -static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn_strength, int hnmode, MDeformVert *dvert, int vgroup) +static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const float hn_strength, const int hnmode, MDeformVert *dvert, int vgroup) { - if (bmd->res > 20) + if (bmd->res > 20 || bmd->value == 0) return; BM_mesh_normals_update(bm); @@ -118,8 +118,8 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn BM_normals_loops_edges_tag(bm, true); const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; - int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); - bool do_normal_to_recon = (hn_strength == 1.0f); + const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const bool do_normal_to_recon = (hn_strength == 1.0f); BMFace *f; BMLoop *l, *l_cur, *l_first; @@ -127,9 +127,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn GHash *faceHash = bmd->clnordata.faceHash; BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { - if (!BLI_ghash_haskey(faceHash, f)) { - BM_elem_flag_set(f, BM_ELEM_HIDDEN, true); - } + l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && @@ -234,6 +232,10 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, float hn static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *bm) { + const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; + if (bmd->value == 0 || bmd->clnordata.faceHash == NULL && vertex_only) + return; + BM_mesh_normals_update(bm); BM_lnorspace_update(bm); @@ -242,7 +244,7 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b BMLoop *l; BMIter liter, eiter; - int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + const int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); const float hn_strength = bmd->hn_strength; float ref = 10.0f; @@ -250,12 +252,12 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b BMFace *f_a, *f_b; BM_edge_face_pair(e, &f_a, &f_b); - bool _f_a = false, _f_b = false; + bool has_f_a = false, has_f_b = false; if (f_a) - _f_a = BLI_ghash_haskey(faceHash, f_a); + has_f_a = BLI_ghash_haskey(faceHash, f_a); if (f_b) - _f_b = BLI_ghash_haskey(faceHash, f_b); - if (_f_a ^ _f_b) { + has_f_b = BLI_ghash_haskey(faceHash, f_b); + if (has_f_a ^ has_f_b) { for (int i = 0; i < 2; i++) { BMVert *v = (i == 0) ? e->v1 : e->v2; @@ -269,7 +271,7 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b zero_v3(n_final); copy_v3_v3(pow_a, f_a->no); copy_v3_v3(pow_b, f_b->no); - if (_f_a) { + if (has_f_a) { mul_v3_fl(pow_a, bmd->res / ref); mul_v3_fl(pow_b, ref / bmd->res); } @@ -286,7 +288,7 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b } } } - else if(_f_a == true && _f_b == true) { + else if(has_f_a == true && has_f_b == true) { for (int i = 0; i < 2; i++) { BMVert *v = (i == 0) ? e->v1 : e->v2; BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { @@ -409,13 +411,11 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, bmd->hnmode, &bmd->clnordata); - if (bmd->value > 0 && bmd->hnmode != MOD_BEVEL_HN_NONE) { - if (bmd->hnmode != BEVEL_HN_FIX_SHA) - bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); - else if(bmd->clnordata.faceHash && !vertex_only) - bevel_fix_normal_shading_continuity(bmd, bm); + if (bmd->hnmode != BEVEL_HN_FIX_SHA && bmd->hnmode != MOD_BEVEL_HN_NONE) { + bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); } - + if(bmd->hnmode == BEVEL_HN_FIX_SHA) + bevel_fix_normal_shading_continuity(bmd, bm); if(set_wn_strength) bevel_set_weighted_normal_face_strength(bm, scene); -- cgit v1.2.3 From 5037dd8abdf9335e998141336d4e15f81580c491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 19 Jul 2018 15:48:13 +0200 Subject: GPU: Add GC to FBOs and UBOs and centralize all GCs GPUFrameBuffers were being free when no context was attached or in the wrong gl context. This make sure this does not happen again. You can now safely free any gl resource from any thread (well as long as it's not used anymore!). --- source/blender/draw/DRW_engine.h | 4 + source/blender/draw/intern/draw_manager.c | 20 +- source/blender/gpu/CMakeLists.txt | 6 +- source/blender/gpu/GPU_buffer_id.h | 53 ---- source/blender/gpu/GPU_material.h | 5 - source/blender/gpu/GPU_texture.h | 5 - source/blender/gpu/GPU_vertex_array_id.h | 55 ---- source/blender/gpu/intern/gpu_batch.c | 3 +- source/blender/gpu/intern/gpu_batch_private.h | 3 - source/blender/gpu/intern/gpu_buffer_id.cpp | 90 ------ source/blender/gpu/intern/gpu_context.cpp | 315 +++++++++++++++++++++ source/blender/gpu/intern/gpu_context_private.h | 68 +++++ source/blender/gpu/intern/gpu_element.c | 7 +- source/blender/gpu/intern/gpu_framebuffer.c | 15 +- source/blender/gpu/intern/gpu_immediate.c | 7 +- source/blender/gpu/intern/gpu_init_exit.c | 5 - source/blender/gpu/intern/gpu_material.c | 39 +-- source/blender/gpu/intern/gpu_private.h | 3 + source/blender/gpu/intern/gpu_shader.c | 2 + source/blender/gpu/intern/gpu_shader_interface.c | 6 +- source/blender/gpu/intern/gpu_texture.c | 58 +--- source/blender/gpu/intern/gpu_uniformbuffer.c | 7 +- source/blender/gpu/intern/gpu_vertex_array_id.cpp | 196 ------------- source/blender/gpu/intern/gpu_vertex_buffer.c | 8 +- source/blender/windowmanager/intern/wm_init_exit.c | 5 +- source/blender/windowmanager/intern/wm_window.c | 2 - 26 files changed, 458 insertions(+), 529 deletions(-) delete mode 100644 source/blender/gpu/GPU_buffer_id.h delete mode 100644 source/blender/gpu/GPU_vertex_array_id.h delete mode 100644 source/blender/gpu/intern/gpu_buffer_id.cpp create mode 100644 source/blender/gpu/intern/gpu_context.cpp create mode 100644 source/blender/gpu/intern/gpu_context_private.h delete mode 100644 source/blender/gpu/intern/gpu_vertex_array_id.cpp diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index eb037d081e1..4d4b486d247 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -136,6 +136,10 @@ void DRW_opengl_context_destroy(void); void DRW_opengl_context_enable(void); void DRW_opengl_context_disable(void); +/* Never use this. Only for closing blender. */ +void DRW_opengl_context_enable_ex(bool restore); +void DRW_opengl_context_disable_ex(bool restore); + void DRW_opengl_render_context_enable(void *re_gl_context); void DRW_opengl_render_context_disable(void *re_gl_context); void DRW_gawain_render_context_enable(void *re_gpu_context); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2793410cd8e..cc4f8ec7947 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2374,21 +2374,21 @@ void DRW_opengl_context_destroy(void) } } -void DRW_opengl_context_enable(void) +void DRW_opengl_context_enable_ex(bool restore) { if (DST.gl_context != NULL) { /* IMPORTANT: We dont support immediate mode in render mode! * This shall remain in effect until immediate mode supports * multiple threads. */ BLI_ticket_mutex_lock(DST.gl_context_mutex); - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { if (!G.background) { immDeactivate(); } } WM_opengl_context_activate(DST.gl_context); GPU_context_active_set(DST.gpu_context); - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { if (!G.background) { immActivate(); } @@ -2397,7 +2397,7 @@ void DRW_opengl_context_enable(void) } } -void DRW_opengl_context_disable(void) +void DRW_opengl_context_disable_ex(bool restore) { if (DST.gl_context != NULL) { #ifdef __APPLE__ @@ -2406,7 +2406,7 @@ void DRW_opengl_context_disable(void) glFlush(); #endif - if (BLI_thread_is_main()) { + if (BLI_thread_is_main() && restore) { wm_window_reset_drawable(); } else { @@ -2418,6 +2418,16 @@ void DRW_opengl_context_disable(void) } } +void DRW_opengl_context_enable(void) +{ + DRW_opengl_context_enable_ex(true); +} + +void DRW_opengl_context_disable(void) +{ + DRW_opengl_context_disable_ex(true); +} + void DRW_opengl_render_context_enable(void *re_gl_context) { /* If thread is main you should use DRW_opengl_context_enable(). */ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 58295ae9329..8273f3f1992 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -62,9 +62,9 @@ set(SRC intern/gpu_batch.c intern/gpu_batch_presets.c intern/gpu_batch_utils.c - intern/gpu_buffer_id.cpp intern/gpu_buffers.c intern/gpu_codegen.c + intern/gpu_context.cpp intern/gpu_debug.c intern/gpu_draw.c intern/gpu_element.c @@ -84,7 +84,6 @@ set(SRC intern/gpu_state.c intern/gpu_texture.c intern/gpu_uniformbuffer.c - intern/gpu_vertex_array_id.cpp intern/gpu_vertex_buffer.c intern/gpu_vertex_format.c intern/gpu_viewport.c @@ -113,7 +112,6 @@ set(SRC GPU_attr_binding.h GPU_basic_shader.h GPU_batch.h - GPU_buffer_id.h GPU_buffers.h GPU_common.h GPU_debug.h @@ -135,7 +133,6 @@ set(SRC GPU_state.h GPU_texture.h GPU_uniformbuffer.h - GPU_vertex_array_id.h GPU_vertex_buffer.h GPU_vertex_format.h GPU_viewport.h @@ -143,6 +140,7 @@ set(SRC intern/gpu_attr_binding_private.h intern/gpu_batch_private.h intern/gpu_codegen.h + intern/gpu_context_private.h intern/gpu_primitive_private.h intern/gpu_private.h intern/gpu_select_private.h diff --git a/source/blender/gpu/GPU_buffer_id.h b/source/blender/gpu/GPU_buffer_id.h deleted file mode 100644 index 4615e9e2c66..00000000000 --- a/source/blender/gpu/GPU_buffer_id.h +++ /dev/null @@ -1,53 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/GPU_buffer_id.h - * \ingroup gpu - * - * GPU buffer IDs - */ - -#ifndef __GPU_BUFFER_ID_H__ -#define __GPU_BUFFER_ID_H__ - -/* Manage GL buffer IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from main thread - * - free can be called from any thread */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "GPU_common.h" - -GLuint GPU_buf_id_alloc(void); -void GPU_buf_id_free(GLuint buffer_id); - -#ifdef __cplusplus -} -#endif - -#endif /* __GPU_BUFFER_ID_H__ */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 4e264defbd4..f2c029f643e 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -254,11 +254,6 @@ void GPU_material_free(struct ListBase *gpumaterial); void GPU_materials_free(struct Main *bmain); -void GPU_material_orphans_init(void); -void GPU_material_orphans_exit(void); -/* This has to be called from a thread with an ogl context bound. */ -void GPU_material_orphans_delete(void); - struct Scene *GPU_material_scene(GPUMaterial *material); GPUMatType GPU_Material_get_type(GPUMaterial *material); struct GPUPass *GPU_material_get_pass(GPUMaterial *material); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index e3db18f1358..1ddf801e166 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -198,11 +198,6 @@ void GPU_invalid_tex_free(void); void GPU_texture_free(GPUTexture *tex); -void GPU_texture_orphans_init(void); -void GPU_texture_orphans_exit(void); -/* This has to be called from a thread with an ogl context bound. */ -void GPU_texture_orphans_delete(void); - void GPU_texture_ref(GPUTexture *tex); void GPU_texture_bind(GPUTexture *tex, int number); void GPU_texture_unbind(GPUTexture *tex); diff --git a/source/blender/gpu/GPU_vertex_array_id.h b/source/blender/gpu/GPU_vertex_array_id.h deleted file mode 100644 index ff84a290a5a..00000000000 --- a/source/blender/gpu/GPU_vertex_array_id.h +++ /dev/null @@ -1,55 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/GPU_vertex_array_id.h - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#ifndef __GPU_VERTEX_ARRAY_ID_H__ -#define __GPU_VERTEX_ARRAY_ID_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "GPU_common.h" -#include "GPU_context.h" - -GLuint GPU_vao_default(void); -GLuint GPU_vao_alloc(void); -void GPU_vao_free(GLuint vao_id, GPUContext *); - -#ifdef __cplusplus -} -#endif - -#endif /* __GPU_VERTEX_ARRAY_ID_H__ */ diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index a11eefee078..9b433a37a72 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -32,12 +32,11 @@ #include "GPU_batch.h" #include "GPU_batch_presets.h" -#include "GPU_buffer_id.h" #include "GPU_matrix.h" #include "GPU_shader.h" -#include "GPU_vertex_array_id.h" #include "gpu_batch_private.h" +#include "gpu_context_private.h" #include "gpu_primitive_private.h" #include "gpu_shader_private.h" diff --git a/source/blender/gpu/intern/gpu_batch_private.h b/source/blender/gpu/intern/gpu_batch_private.h index 51040ff751a..3a05e243065 100644 --- a/source/blender/gpu/intern/gpu_batch_private.h +++ b/source/blender/gpu/intern/gpu_batch_private.h @@ -43,9 +43,6 @@ extern "C" { void gpu_batch_remove_interface_ref(GPUBatch *batch, const GPUShaderInterface *interface); -void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch); -void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); - #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_buffer_id.cpp b/source/blender/gpu/intern/gpu_buffer_id.cpp deleted file mode 100644 index f3faba9c766..00000000000 --- a/source/blender/gpu/intern/gpu_buffer_id.cpp +++ /dev/null @@ -1,90 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gpu_buffer_id.cpp - * \ingroup gpu - * - * GPU buffer IDs - */ - -#include "GPU_buffer_id.h" - -#include -#include - -#define ORPHAN_DEBUG 0 - -#if ORPHAN_DEBUG -# include -#endif - -static std::vector orphaned_buffer_ids; - -static std::mutex orphan_mutex; - -extern "C" { -extern int BLI_thread_is_main(void); /* Blender-specific function */ -} - -static bool thread_is_main() -{ - /* "main" here means the GL context's thread */ - return BLI_thread_is_main(); -} - -GLuint GPU_buf_id_alloc() -{ - /* delete orphaned IDs */ - orphan_mutex.lock(); - if (!orphaned_buffer_ids.empty()) { - const auto orphaned_buffer_len = (uint)orphaned_buffer_ids.size(); -#if ORPHAN_DEBUG - printf("deleting %u orphaned VBO%s\n", orphaned_buffer_len, orphaned_buffer_len == 1 ? "" : "s"); -#endif - glDeleteBuffers(orphaned_buffer_len, orphaned_buffer_ids.data()); - orphaned_buffer_ids.clear(); - } - orphan_mutex.unlock(); - - GLuint new_buffer_id = 0; - glGenBuffers(1, &new_buffer_id); - return new_buffer_id; -} - -void GPU_buf_id_free(GLuint buffer_id) -{ - if (thread_is_main()) { - glDeleteBuffers(1, &buffer_id); - } - else { - /* add this ID to the orphaned list */ - orphan_mutex.lock(); -#if ORPHAN_DEBUG - printf("orphaning VBO %u\n", buffer_id); -#endif - orphaned_buffer_ids.emplace_back(buffer_id); - orphan_mutex.unlock(); - } -} diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp new file mode 100644 index 00000000000..6a42552c2fd --- /dev/null +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -0,0 +1,315 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation, Clément Foucault + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gpu_vertex_array_id.cpp + * \ingroup gpu + * + * Manage GL vertex array IDs in a thread-safe way + * Use these instead of glGenBuffers & its friends + * - alloc must be called from a thread that is bound + * to the context that will be used for drawing with + * this vao. + * - free can be called from any thread + */ + +#include "BLI_assert.h" +#include "BLI_utildefines.h" + +#include "GPU_context.h" +#include "GPU_framebuffer.h" + +#include "gpu_batch_private.h" +#include "gpu_context_private.h" + +#include +#include +#include +#include +#include + +#if TRUST_NO_ONE +#if 0 +extern "C" { +extern int BLI_thread_is_main(void); /* Blender-specific function */ +} + +static bool thread_is_main() { + /* "main" here means the GL context's thread */ + return BLI_thread_is_main(); +} +#endif +#endif + +static std::vector orphaned_buffer_ids; +static std::vector orphaned_texture_ids; + +static std::mutex orphans_mutex; + +struct GPUContext { + GLuint default_vao; + std::unordered_set batches; /* Batches that have VAOs from this context */ +#ifdef DEBUG + std::unordered_set framebuffers; /* Framebuffers that have FBO from this context */ +#endif + std::vector orphaned_vertarray_ids; + std::vector orphaned_framebuffer_ids; + std::mutex orphans_mutex; /* todo: try spinlock instead */ +#if TRUST_NO_ONE + pthread_t thread; /* Thread on which this context is active. */ + bool thread_is_used; + + GPUContext() { + thread_is_used = false; + } +#endif +}; + +#if defined(_MSC_VER) && (_MSC_VER == 1800) +#define thread_local __declspec(thread) +thread_local GPUContext *active_ctx = NULL; +#else +static thread_local GPUContext *active_ctx = NULL; +#endif + +static void orphans_add(GPUContext *ctx, std::vector *orphan_list, GLuint id) +{ + std::mutex *mutex = (ctx) ? &ctx->orphans_mutex : &orphans_mutex; + + mutex->lock(); + orphan_list->emplace_back(id); + mutex->unlock(); +} + +static void orphans_clear(GPUContext *ctx) +{ + BLI_assert(ctx); /* need at least an active context */ + BLI_assert(pthread_equal(pthread_self(), ctx->thread)); /* context has been activated by another thread! */ + + ctx->orphans_mutex.lock(); + if (!ctx->orphaned_vertarray_ids.empty()) { + uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size(); + glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data()); + ctx->orphaned_vertarray_ids.clear(); + } + if (!ctx->orphaned_framebuffer_ids.empty()) { + uint orphan_len = (uint)ctx->orphaned_framebuffer_ids.size(); + glDeleteFramebuffers(orphan_len, ctx->orphaned_framebuffer_ids.data()); + ctx->orphaned_framebuffer_ids.clear(); + } + + ctx->orphans_mutex.unlock(); + + orphans_mutex.lock(); + if (!orphaned_buffer_ids.empty()) { + uint orphan_len = (uint)orphaned_buffer_ids.size(); + glDeleteBuffers(orphan_len, orphaned_buffer_ids.data()); + orphaned_buffer_ids.clear(); + } + if (!orphaned_texture_ids.empty()) { + uint orphan_len = (uint)orphaned_texture_ids.size(); + glDeleteTextures(orphan_len, orphaned_texture_ids.data()); + orphaned_texture_ids.clear(); + } + orphans_mutex.unlock(); +} + +GPUContext *GPU_context_create(void) +{ + /* BLI_assert(thread_is_main()); */ + GPUContext *ctx = new GPUContext; + glGenVertexArrays(1, &ctx->default_vao); + GPU_context_active_set(ctx); + return ctx; +} + +/* to be called after GPU_context_active_set(ctx_to_destroy) */ +void GPU_context_discard(GPUContext *ctx) +{ + /* Make sure no other thread has locked it. */ + BLI_assert(ctx == active_ctx); + BLI_assert(pthread_equal(pthread_self(), ctx->thread)); + BLI_assert(ctx->orphaned_vertarray_ids.empty()); + /* For now don't allow GPUFrameBuffers to be reuse in another ctx. */ + BLI_assert(ctx->framebuffers.empty()); + /* delete remaining vaos */ + while (!ctx->batches.empty()) { + /* this removes the array entry */ + GPU_batch_vao_cache_clear(*ctx->batches.begin()); + } + glDeleteVertexArrays(1, &ctx->default_vao); + delete ctx; + active_ctx = NULL; +} + +/* ctx can be NULL */ +void GPU_context_active_set(GPUContext *ctx) +{ +#if TRUST_NO_ONE + if (active_ctx) { + active_ctx->thread_is_used = false; + } + /* Make sure no other context is already bound to this thread. */ + if (ctx) { + /* Make sure no other thread has locked it. */ + assert(ctx->thread_is_used == false); + ctx->thread = pthread_self(); + ctx->thread_is_used = true; + } +#endif + if (ctx) { + orphans_clear(ctx); + } + active_ctx = ctx; +} + +GPUContext *GPU_context_active_get(void) +{ + return active_ctx; +} + +GLuint GPU_vao_default(void) +{ + BLI_assert(active_ctx); /* need at least an active context */ + BLI_assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ + return active_ctx->default_vao; +} + +GLuint GPU_vao_alloc(void) +{ + GLuint new_vao_id = 0; + orphans_clear(active_ctx); + glGenVertexArrays(1, &new_vao_id); + return new_vao_id; +} + +GLuint GPU_fbo_alloc(void) +{ + GLuint new_fbo_id = 0; + orphans_clear(active_ctx); + glGenFramebuffers(1, &new_fbo_id); + return new_fbo_id; +} + +GLuint GPU_buf_alloc(void) +{ + GLuint new_buffer_id = 0; + orphans_clear(active_ctx); + glGenBuffers(1, &new_buffer_id); + return new_buffer_id; +} + +GLuint GPU_tex_alloc(void) +{ + GLuint new_texture_id = 0; + orphans_clear(active_ctx); + glGenTextures(1, &new_texture_id); + return new_texture_id; +} + +void GPU_vao_free(GLuint vao_id, GPUContext *ctx) +{ + BLI_assert(ctx); + if (ctx == active_ctx) { + glDeleteVertexArrays(1, &vao_id); + } + else { + orphans_add(ctx, &ctx->orphaned_vertarray_ids, vao_id); + } +} + +void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx) +{ + BLI_assert(ctx); + if (ctx == active_ctx) { + glDeleteFramebuffers(1, &fbo_id); + } + else { + orphans_add(ctx, &ctx->orphaned_framebuffer_ids, fbo_id); + } +} + +void GPU_buf_free(GLuint buf_id) +{ + if (active_ctx) { + glDeleteBuffers(1, &buf_id); + } + else { + orphans_add(NULL, &orphaned_buffer_ids, buf_id); + } +} + +void GPU_tex_free(GLuint tex_id) +{ + if (active_ctx) { + glDeleteTextures(1, &tex_id); + } + else { + orphans_add(NULL, &orphaned_texture_ids, tex_id); + } +} + +/* GPUBatch & GPUFrameBuffer contains respectively VAO & FBO indices + * which are not shared across contexts. So we need to keep track of + * ownership. */ + +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch) +{ + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->batches.emplace(batch); + ctx->orphans_mutex.unlock(); +} + +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch) +{ + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->batches.erase(batch); + ctx->orphans_mutex.unlock(); +} + +void gpu_context_add_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb) +{ +#ifdef DEBUG + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->framebuffers.emplace(fb); + ctx->orphans_mutex.unlock(); +#else + UNUSED_VARS(ctx, fb); +#endif +} + +void gpu_context_remove_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb) +{ +#ifdef DEBUG + BLI_assert(ctx); + ctx->orphans_mutex.lock(); + ctx->framebuffers.erase(fb); + ctx->orphans_mutex.unlock(); +#else + UNUSED_VARS(ctx, fb); +#endif +} diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h new file mode 100644 index 00000000000..4881a892e38 --- /dev/null +++ b/source/blender/gpu/intern/gpu_context_private.h @@ -0,0 +1,68 @@ +/* + * ***** 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) 2016 by Mike Erwin. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/gpu/intern/gpu_context_private.h + * \ingroup gpu + * + * This interface allow GPU to manage GL objects for mutiple context and threads. + */ + +#ifndef __GPU_CONTEXT_PRIVATE_H__ +#define __GPU_CONTEXT_PRIVATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "GPU_context.h" + +struct GPUFrameBuffer; + +GLuint GPU_vao_default(void); + +/* These require a gl ctx bound. */ +GLuint GPU_buf_alloc(void); +GLuint GPU_tex_alloc(void); +GLuint GPU_vao_alloc(void); +GLuint GPU_fbo_alloc(void); + +/* These can be called any threads even without gl ctx. */ +void GPU_buf_free(GLuint buf_id); +void GPU_tex_free(GLuint tex_id); +/* These two need the ctx the id was created with. */ +void GPU_vao_free(GLuint vao_id, GPUContext *ctx); +void GPU_fbo_free(GLuint fbo_id, GPUContext *ctx); + +void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch); +void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); + +void gpu_context_add_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); +void gpu_context_remove_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); + +#ifdef __cplusplus +} +#endif + +#endif /* __GPU_CONTEXT_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 9abfed2db05..901e09443d1 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -30,7 +30,8 @@ */ #include "GPU_element.h" -#include "GPU_buffer_id.h" + +#include "gpu_context_private.h" #include @@ -279,7 +280,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) #endif if (elem->vbo_id == 0) { - elem->vbo_id = GPU_buf_id_alloc(); + elem->vbo_id = GPU_buf_alloc(); } /* send data to GPU */ /* GL_ELEMENT_ARRAY_BUFFER changes the state of the last VAO bound, @@ -302,7 +303,7 @@ void GPU_indexbuf_use(GPUIndexBuf *elem) void GPU_indexbuf_discard(GPUIndexBuf *elem) { if (elem->vbo_id) { - GPU_buf_id_free(elem->vbo_id); + GPU_buf_free(elem->vbo_id); } free(elem); } diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index d28b82ac3cd..ba8dcb04269 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -42,7 +42,8 @@ #include "GPU_shader.h" #include "GPU_texture.h" -#include "intern/gpu_private.h" +#include "gpu_private.h" +#include "gpu_context_private.h" static ThreadLocal(void *) g_currentfb; @@ -69,6 +70,7 @@ typedef enum { #define GPU_FB_ATTACHEMENT_SET_DIRTY(flag, type) (flag |= (1 << type)) struct GPUFrameBuffer { + GPUContext *ctx; GLuint object; GPUAttachment attachments[GPU_FB_MAX_ATTACHEMENT]; uint16_t dirty_flag; @@ -196,7 +198,9 @@ GPUFrameBuffer *GPU_framebuffer_create(void) static void gpu_framebuffer_init(GPUFrameBuffer *fb) { - glGenFramebuffers(1, &fb->object); + fb->object = GPU_fbo_alloc(); + fb->ctx = GPU_context_active_get(); + gpu_context_add_framebuffer(fb->ctx, fb); } void GPU_framebuffer_free(GPUFrameBuffer *fb) @@ -207,8 +211,11 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb) } } - /* This restores the framebuffer if it was bound */ - glDeleteFramebuffers(1, &fb->object); + if (fb->object != 0) { + /* This restores the framebuffer if it was bound */ + GPU_fbo_free(fb->object, fb->ctx); + gpu_context_remove_framebuffer(fb->ctx, fb); + } if (gpu_framebuffer_current_get() == fb->object) { gpu_framebuffer_current_set(0); diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 66a467e339e..9674cf0b9f7 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -32,11 +32,10 @@ #include "UI_resources.h" #include "GPU_attr_binding.h" -#include "GPU_buffer_id.h" #include "GPU_immediate.h" -#include "GPU_vertex_array_id.h" #include "gpu_attr_binding_private.h" +#include "gpu_context_private.h" #include "gpu_primitive_private.h" #include "gpu_shader_private.h" #include "gpu_vertex_format_private.h" @@ -91,7 +90,7 @@ void immInit(void) #endif memset(&imm, 0, sizeof(Immediate)); - imm.vbo_id = GPU_buf_id_alloc(); + imm.vbo_id = GPU_buf_alloc(); glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); @@ -127,7 +126,7 @@ void immDeactivate(void) void immDestroy(void) { - GPU_buf_id_free(imm.vbo_id); + GPU_buf_free(imm.vbo_id); initialized = false; } diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 78d4f491b66..55d0466c929 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -57,8 +57,6 @@ void GPU_init(void) gpu_extensions_init(); /* must come first */ - GPU_texture_orphans_init(); - GPU_material_orphans_init(); gpu_codegen_init(); gpu_framebuffer_module_init(); @@ -84,9 +82,6 @@ void GPU_exit(void) gpu_batch_exit(); - GPU_texture_orphans_exit(); - GPU_material_orphans_exit(); - if (G.debug & G_DEBUG_GPU) gpu_debug_exit(); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9566f091ada..92aff91da32 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -75,9 +75,6 @@ # include "BKE_DerivedMesh.h" #endif -static ListBase g_orphaned_mat = {NULL, NULL}; -static ThreadMutex g_orphan_lock; - /* Structs */ struct GPUMaterial { @@ -175,44 +172,12 @@ void GPU_material_free(ListBase *gpumaterial) { for (LinkData *link = gpumaterial->first; link; link = link->next) { GPUMaterial *material = link->data; - - /* TODO(fclem): Check if the thread has an ogl context. */ - if (BLI_thread_is_main()) { - gpu_material_free_single(material); - MEM_freeN(material); - } - else { - BLI_mutex_lock(&g_orphan_lock); - BLI_addtail(&g_orphaned_mat, BLI_genericNodeN(material)); - BLI_mutex_unlock(&g_orphan_lock); - } + gpu_material_free_single(material); + MEM_freeN(material); } BLI_freelistN(gpumaterial); } -void GPU_material_orphans_init(void) -{ - BLI_mutex_init(&g_orphan_lock); -} - -void GPU_material_orphans_delete(void) -{ - BLI_mutex_lock(&g_orphan_lock); - LinkData *link; - while ((link = BLI_pophead(&g_orphaned_mat))) { - gpu_material_free_single((GPUMaterial *)link->data); - MEM_freeN(link->data); - MEM_freeN(link); - } - BLI_mutex_unlock(&g_orphan_lock); -} - -void GPU_material_orphans_exit(void) -{ - GPU_material_orphans_delete(); - BLI_mutex_end(&g_orphan_lock); -} - GPUBuiltin GPU_get_material_builtins(GPUMaterial *material) { return material->builtins; diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h index 996ba9c63a1..df55f7922b3 100644 --- a/source/blender/gpu/intern/gpu_private.h +++ b/source/blender/gpu/intern/gpu_private.h @@ -25,6 +25,9 @@ #ifndef __GPU_PRIVATE_H__ #define __GPU_PRIVATE_H__ +struct GPUContext; +struct GPUFrameBuffer; + /* call this before running any of the functions below */ void gpu_extensions_init(void); void gpu_extensions_exit(void); diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 1eae073d9c0..04b43d03c83 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -38,6 +38,7 @@ #include "DNA_space_types.h" #include "GPU_extensions.h" +#include "GPU_context.h" #include "GPU_matrix.h" #include "GPU_shader.h" #include "GPU_texture.h" @@ -572,6 +573,7 @@ void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) void GPU_shader_free(GPUShader *shader) { + BLI_assert(GPU_context_active_get() != NULL); BLI_assert(shader); if (shader->vertex) diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index 4b8413d0cc3..54c5f41bbd3 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -29,9 +29,11 @@ * GPU shader interface (C --> GLSL) */ -#include "gpu_batch_private.h" #include "GPU_shader_interface.h" -#include "GPU_vertex_array_id.h" + +#include "gpu_batch_private.h" +#include "gpu_context_private.h" + #include #include #include diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 4465136dd0f..5ac746ec9c1 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -38,22 +38,22 @@ #include "BKE_global.h" #include "GPU_batch.h" +#include "GPU_context.h" #include "GPU_debug.h" #include "GPU_draw.h" #include "GPU_extensions.h" -#include "GPU_framebuffer.h" #include "GPU_glew.h" +#include "GPU_framebuffer.h" #include "GPU_texture.h" +#include "gpu_context_private.h" + static struct GPUTextureGlobal { GPUTexture *invalid_tex_1D; /* texture used in place of invalid textures (not loaded correctly, missing) */ GPUTexture *invalid_tex_2D; GPUTexture *invalid_tex_3D; } GG = {NULL, NULL, NULL}; -static ListBase g_orphaned_tex = {NULL, NULL}; -static ThreadMutex g_orphan_lock; - /* Maximum number of FBOs a texture can be attached to. */ #define GPU_TEX_MAX_FBO_ATTACHED 8 @@ -535,7 +535,7 @@ GPUTexture *GPU_texture_create_nD( gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { if (err_out) @@ -668,7 +668,7 @@ static GPUTexture *GPU_texture_cube_create( gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { if (err_out) @@ -752,7 +752,7 @@ GPUTexture *GPU_texture_create_buffer(GPUTextureFormat tex_format, const GLuint } /* Generate Texture object */ - glGenTextures(1, &tex->bindcode); + tex->bindcode = GPU_tex_alloc(); if (!tex->bindcode) { fprintf(stderr, "GPUTexture: texture create failed\n"); @@ -1301,17 +1301,6 @@ void GPU_texture_filters(GPUTexture *tex, GPUFilterFunction min_filter, GPUFilte glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, gpu_get_gl_filterfunction(mag_filter)); } - -static void gpu_texture_delete(GPUTexture *tex) -{ - if (tex->bindcode) - glDeleteTextures(1, &tex->bindcode); - - gpu_texture_memory_footprint_remove(tex); - - MEM_freeN(tex); -} - void GPU_texture_free(GPUTexture *tex) { tex->refcount--; @@ -1326,38 +1315,13 @@ void GPU_texture_free(GPUTexture *tex) } } - /* TODO(fclem): Check if the thread has an ogl context. */ - if (BLI_thread_is_main()) { - gpu_texture_delete(tex); - } - else { - BLI_mutex_lock(&g_orphan_lock); - BLI_addtail(&g_orphaned_tex, BLI_genericNodeN(tex)); - BLI_mutex_unlock(&g_orphan_lock); - } - } -} + if (tex->bindcode) + GPU_tex_free(tex->bindcode); -void GPU_texture_orphans_init(void) -{ - BLI_mutex_init(&g_orphan_lock); -} + gpu_texture_memory_footprint_remove(tex); -void GPU_texture_orphans_delete(void) -{ - BLI_mutex_lock(&g_orphan_lock); - LinkData *link; - while ((link = BLI_pophead(&g_orphaned_tex))) { - gpu_texture_delete((GPUTexture *)link->data); - MEM_freeN(link); + MEM_freeN(tex); } - BLI_mutex_unlock(&g_orphan_lock); -} - -void GPU_texture_orphans_exit(void) -{ - GPU_texture_orphans_delete(); - BLI_mutex_end(&g_orphan_lock); } void GPU_texture_ref(GPUTexture *tex) diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c index 1e39b2ea5b7..9b8441efd08 100644 --- a/source/blender/gpu/intern/gpu_uniformbuffer.c +++ b/source/blender/gpu/intern/gpu_uniformbuffer.c @@ -35,6 +35,7 @@ #include "BLI_blenlib.h" #include "gpu_codegen.h" +#include "gpu_context_private.h" #include "GPU_extensions.h" #include "GPU_glew.h" @@ -88,7 +89,7 @@ GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_ ubo->bindpoint = -1; /* Generate Buffer object */ - glGenBuffers(1, &ubo->bindcode); + ubo->bindcode = GPU_buf_alloc(); if (!ubo->bindcode) { if (err_out) @@ -127,7 +128,7 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou ubo->flag = GPU_UBO_FLAG_DIRTY; /* Generate Buffer object. */ - glGenBuffers(1, &ubo->buffer.bindcode); + ubo->buffer.bindcode = GPU_buf_alloc(); if (!ubo->buffer.bindcode) { if (err_out) @@ -190,7 +191,7 @@ void GPU_uniformbuffer_free(GPUUniformBuffer *ubo) gpu_uniformbuffer_dynamic_free(ubo); } - glDeleteBuffers(1, &ubo->bindcode); + GPU_buf_free(ubo->bindcode); MEM_freeN(ubo); } diff --git a/source/blender/gpu/intern/gpu_vertex_array_id.cpp b/source/blender/gpu/intern/gpu_vertex_array_id.cpp deleted file mode 100644 index 64f704bb107..00000000000 --- a/source/blender/gpu/intern/gpu_vertex_array_id.cpp +++ /dev/null @@ -1,196 +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) 2016 by Mike Erwin. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Clément Foucault - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/gpu/intern/gpu_vertex_array_id.cpp - * \ingroup gpu - * - * Manage GL vertex array IDs in a thread-safe way - * Use these instead of glGenBuffers & its friends - * - alloc must be called from a thread that is bound - * to the context that will be used for drawing with - * this vao. - * - free can be called from any thread - */ - -#include "gpu_batch_private.h" -#include "GPU_vertex_array_id.h" -#include "GPU_context.h" -#include -#include -#include -#include -#include - -#if TRUST_NO_ONE -#if 0 -extern "C" { -extern int BLI_thread_is_main(void); /* Blender-specific function */ -} - -static bool thread_is_main() { - /* "main" here means the GL context's thread */ - return BLI_thread_is_main(); -} -#endif -#endif - -struct GPUContext { - GLuint default_vao; - std::unordered_set batches; /* Batches that have VAOs from this context */ - std::vector orphaned_vertarray_ids; - std::mutex orphans_mutex; /* todo: try spinlock instead */ -#if TRUST_NO_ONE - pthread_t thread; /* Thread on which this context is active. */ - bool thread_is_used; - - GPUContext() { - thread_is_used = false; - } -#endif -}; - -#if defined(_MSC_VER) && (_MSC_VER == 1800) -#define thread_local __declspec(thread) -thread_local GPUContext *active_ctx = NULL; -#else -static thread_local GPUContext *active_ctx = NULL; -#endif - -static void clear_orphans(GPUContext *ctx) -{ - ctx->orphans_mutex.lock(); - if (!ctx->orphaned_vertarray_ids.empty()) { - uint orphan_len = (uint)ctx->orphaned_vertarray_ids.size(); - glDeleteVertexArrays(orphan_len, ctx->orphaned_vertarray_ids.data()); - ctx->orphaned_vertarray_ids.clear(); - } - ctx->orphans_mutex.unlock(); -} - -GPUContext *GPU_context_create(void) -{ -#if TRUST_NO_ONE - /* assert(thread_is_main()); */ -#endif - GPUContext *ctx = new GPUContext; - glGenVertexArrays(1, &ctx->default_vao); - GPU_context_active_set(ctx); - return ctx; -} - -/* to be called after GPU_context_active_set(ctx_to_destroy) */ -void GPU_context_discard(GPUContext *ctx) -{ -#if TRUST_NO_ONE - /* Make sure no other thread has locked it. */ - assert(ctx == active_ctx); - assert(pthread_equal(pthread_self(), ctx->thread)); - assert(ctx->orphaned_vertarray_ids.empty()); -#endif - /* delete remaining vaos */ - while (!ctx->batches.empty()) { - /* this removes the array entry */ - GPU_batch_vao_cache_clear(*ctx->batches.begin()); - } - glDeleteVertexArrays(1, &ctx->default_vao); - delete ctx; - active_ctx = NULL; -} - -/* ctx can be NULL */ -void GPU_context_active_set(GPUContext *ctx) -{ -#if TRUST_NO_ONE - if (active_ctx) { - active_ctx->thread_is_used = false; - } - /* Make sure no other context is already bound to this thread. */ - if (ctx) { - /* Make sure no other thread has locked it. */ - assert(ctx->thread_is_used == false); - ctx->thread = pthread_self(); - ctx->thread_is_used = true; - } -#endif - if (ctx) { - clear_orphans(ctx); - } - active_ctx = ctx; -} - -GPUContext *GPU_context_active_get(void) -{ - return active_ctx; -} - -GLuint GPU_vao_default(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - return active_ctx->default_vao; -} - -GLuint GPU_vao_alloc(void) -{ -#if TRUST_NO_ONE - assert(active_ctx); /* need at least an active context */ - assert(pthread_equal(pthread_self(), active_ctx->thread)); /* context has been activated by another thread! */ -#endif - clear_orphans(active_ctx); - - GLuint new_vao_id = 0; - glGenVertexArrays(1, &new_vao_id); - return new_vao_id; -} - -/* this can be called from multiple thread */ -void GPU_vao_free(GLuint vao_id, GPUContext *ctx) -{ -#if TRUST_NO_ONE - assert(ctx); -#endif - if (ctx == active_ctx) { - glDeleteVertexArrays(1, &vao_id); - } - else { - ctx->orphans_mutex.lock(); - ctx->orphaned_vertarray_ids.emplace_back(vao_id); - ctx->orphans_mutex.unlock(); - } -} - -void gpu_context_add_batch(GPUContext *ctx, GPUBatch *batch) -{ - ctx->batches.emplace(batch); -} - -void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch) -{ - ctx->orphans_mutex.lock(); - ctx->batches.erase(batch); - ctx->orphans_mutex.unlock(); -} diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index b25d9fc3a2c..d605378bf0e 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -30,8 +30,10 @@ */ #include "GPU_vertex_buffer.h" -#include "GPU_buffer_id.h" + +#include "gpu_context_private.h" #include "gpu_vertex_format_private.h" + #include #include @@ -88,7 +90,7 @@ void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts, const GPUVertFormat *for void GPU_vertbuf_discard(GPUVertBuf *verts) { if (verts->vbo_id) { - GPU_buf_id_free(verts->vbo_id); + GPU_buf_free(verts->vbo_id); #if VRAM_USAGE vbo_memory_usage -= GPU_vertbuf_size_get(verts); #endif @@ -117,7 +119,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) #endif /* only create the buffer the 1st time */ if (verts->vbo_id == 0) { - verts->vbo_id = GPU_buf_id_alloc(); + verts->vbo_id = GPU_buf_alloc(); } /* discard previous data if any */ if (verts->data) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 0c7c85e0d94..f7d6561e17f 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -119,6 +119,7 @@ #include "GPU_material.h" #include "GPU_draw.h" +#include "GPU_immediate.h" #include "GPU_init_exit.h" #include "BKE_sound.h" @@ -515,9 +516,11 @@ void WM_exit_ext(bContext *C, const bool do_python) BLF_exit(); if (opengl_is_init) { + DRW_opengl_context_enable_ex(false); GPU_pass_cache_free(); - DRW_opengl_context_destroy(); GPU_exit(); + DRW_opengl_context_disable_ex(false); + DRW_opengl_context_destroy(); } #ifdef WITH_INTERNATIONAL diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index b87ae7e076c..c1006db34ef 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1921,8 +1921,6 @@ void wm_window_raise(wmWindow *win) void wm_window_swap_buffers(wmWindow *win) { - GPU_texture_orphans_delete(); /* XXX should be done elsewhere. */ - GPU_material_orphans_delete(); /* XXX Amen to that. */ GHOST_SwapWindowBuffers(win->ghostwin); } -- cgit v1.2.3 From ca0ecf4c08681753b640482c03dfb3239a37157e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jul 2018 16:27:44 +0200 Subject: Fix crash with previews of non-IDs, like pose library thumbnails. --- source/blender/editors/render/render_preview.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 450897382dd..884e8d6625b 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -314,6 +314,11 @@ static World *preview_get_localized_world(ShaderPreview *sp, World *world) static ID *duplicate_ids(ID *id, Depsgraph *depsgraph) { + if (id == NULL) { + /* Non-ID preview render. */ + return NULL; + } + ID *id_eval = id; if (depsgraph) { -- cgit v1.2.3 From 0bf8096501a8e7883f4061ba3e425966ba7517cd Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 7 Jul 2018 23:21:20 +0300 Subject: Resolve the opposite vector ambiguity in Damped Track constraint. Damped Track by specification attempts to arrive at the desired direction via the shortest rotation. However with opposite vectors there are infinitely many valid 180 degree rotations. Currently it gives up and does nothing. I think that it would be more reasonable to resolve the ambiguity arbitrarily, so that Damped Track won't have a weird dead zone. To make it more predictable I use a local axis. In addition, the singularity area vicinity has some floating point precision problems that result in significant jitter. This applies workarounds for two causes of instability. Differential Revision: https://developer.blender.org/D3530 --- source/blender/blenkernel/intern/constraint.c | 32 ++++++++++++++++++++-- source/blender/blenlib/BLI_math_vector.h | 1 + source/blender/blenlib/intern/math_vector_inline.c | 10 +++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 2a5a0cf9ae7..7d861658993 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3709,7 +3709,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t * - the min/max wrappers around (obvec . tarvec) result (stored temporarily in rangle) * are used to ensure that the smallest angle is chosen */ - cross_v3_v3v3(raxis, obvec, tarvec); + cross_v3_v3v3_hi_prec(raxis, obvec, tarvec); rangle = dot_v3v3(obvec, tarvec); rangle = acosf(max_ff(-1.0f, min_ff(1.0f, rangle))); @@ -3717,7 +3717,35 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t /* construct rotation matrix from the axis-angle rotation found above * - this call takes care to make sure that the axis provided is a unit vector first */ - axis_angle_to_mat3(rmat, raxis, rangle); + float norm = normalize_v3(raxis); + + if (norm < FLT_EPSILON) { + /* if dot product is nonzero, while cross is zero, we have two opposite vectors! + * - this is an ambiguity in the math that needs to be resolved arbitrarily, + * or there will be a case where damped track strangely does nothing + * - to do that, rotate around a different local axis + */ + float tmpvec[3]; + + if (fabsf(rangle) < M_PI - 0.01f) { + return; + } + + rangle = M_PI; + copy_v3_v3(tmpvec, track_dir_vecs[(data->trackflag + 1) % 6]); + mul_mat3_m4_v3(cob->matrix, tmpvec); + cross_v3_v3v3(raxis, obvec, tmpvec); + + if (normalize_v3(raxis) == 0.0f) { + return; + } + } + else if (norm < 0.1f) { + /* near 0 and Pi arcsin has way better precision than arccos */ + rangle = (rangle > M_PI_2) ? M_PI - asinf(norm) : asinf(norm); + } + + axis_angle_normalized_to_mat3(rmat, raxis, rangle); /* rotate the owner in the way defined by this rotation matrix, then reapply the location since * we may have destroyed that in the process of multiplying the matrix diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 3f603311530..39625346756 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -169,6 +169,7 @@ MINLINE double dot_v3db_v3fl(const double a[3], const float b[3]) ATTR_WARN_UNUS MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT; MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]); +MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]); MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 08687a1ab47..715e2e65c96 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -753,6 +753,16 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]) r[2] = a[0] * b[1] - a[1] * b[0]; } +/* cross product suffers from severe precision loss when vectors are + * nearly parallel or opposite; doing the computation in double helps a lot */ +MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]) +{ + BLI_assert(r != a && r != b); + r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]); + r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]); + r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]); +} + /* Newell's Method */ /* excuse this fairly specific function, * its used for polygon normals all over the place -- cgit v1.2.3 From 44c7a7cf8bb64f58739b808ef6e80a224bfa9015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 19 Jul 2018 17:18:08 +0200 Subject: Fix compilation error with MSVC --- source/blender/windowmanager/intern/wm_init_exit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index f7d6561e17f..7643086e30a 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -36,6 +36,7 @@ #ifdef _WIN32 # include +# undef interface /* fix conflict with GPU_batch.h */ #endif #include "MEM_guardedalloc.h" -- cgit v1.2.3 From 94722121e572bc8ac4863ae7cdaf26386695202d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 19 Jul 2018 17:20:48 +0200 Subject: Fix MSVC compilation error in a less hacky way --- source/blender/windowmanager/intern/wm_init_exit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 7643086e30a..c51d4c5534a 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -35,8 +35,8 @@ #include #ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN # include -# undef interface /* fix conflict with GPU_batch.h */ #endif #include "MEM_guardedalloc.h" -- cgit v1.2.3 From 8a42b3909f33d90b065eec2b8eb342df0a1fb659 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 19 Jul 2018 16:27:18 +0200 Subject: Subsurf: Add basic statistics to help benchmarking --- source/blender/blenkernel/BKE_subdiv.h | 45 ++++++++++++++ source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/intern/subdiv.c | 5 ++ source/blender/blenkernel/intern/subdiv_eval.c | 4 ++ source/blender/blenkernel/intern/subdiv_mesh.c | 2 + source/blender/blenkernel/intern/subdiv_stats.c | 80 +++++++++++++++++++++++++ source/blender/modifiers/intern/MOD_subsurf.c | 1 + 7 files changed, 138 insertions(+) create mode 100644 source/blender/blenkernel/intern/subdiv_stats.c diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 45316e3cc91..a1792866255 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -53,6 +53,40 @@ typedef struct SubdivSettings { eSubdivFVarLinearInterpolation fvar_linear_interpolation; } SubdivSettings; +/* NOTE: Order of enumerators MUST match order of values in SubdivStats. */ +typedef enum eSubdivStatsValue { + SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME = 0, + SUBDIV_STATS_SUBDIV_TO_MESH, + SUBDIV_STATS_EVALUATOR_CREATE, + SUBDIV_STATS_EVALUATOR_REFINE, + + NUM_SUBDIV_STATS_VALUES, +} eSubdivStatsValue; + +typedef struct SubdivStats { + union { + struct { + /* Time spend on creating topology refiner, which includes time + * spend on conversion from Blender data to OpenSubdiv data, and + * time spend on topology orientation on OpenSubdiv C-API side. + */ + double topology_refiner_creation_time; + /* Total time spent in BKE_subdiv_to_mesh(). */ + double subdiv_to_mesh_time; + /* Time spent on evaluator creation from topology refiner. */ + double evaluator_creation_time; + /* Time spent on evaluator->refine(). */ + double evaluator_refine_time; + }; + double values_[NUM_SUBDIV_STATS_VALUES]; + }; + + /* Per-value timestamp on when corresponding BKE_subdiv_stats_begin() was + * called. + */ + double begin_timestamp_[NUM_SUBDIV_STATS_VALUES]; +} SubdivStats; + typedef struct Subdiv { /* Settings this subdivision surface is created for. * @@ -88,8 +122,19 @@ typedef struct Subdiv { /* CPU side evaluator. */ struct OpenSubdiv_Evaluator *evaluator; + + SubdivStats stats; } Subdiv; +/* =============================== STATISTICS =============================== */ + +void BKE_subdiv_stats_init(SubdivStats *stats); + +void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value); +void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value); + +void BKE_subdiv_stats_print(const SubdivStats *stats); + /* ============================== CONSTRUCTION ============================== */ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 0517eb8e732..01910bffdb0 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -191,6 +191,7 @@ set(SRC intern/subdiv_converter_mesh.c intern/subdiv_eval.c intern/subdiv_mesh.c + intern/subdiv_stats.c intern/subsurf_ccg.c intern/suggestions.c intern/text.c diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 72cd39983b9..794da2d3477 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -63,6 +63,9 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, struct OpenSubdiv_Converter *converter) { #ifdef WITH_OPENSUBDIV + SubdivStats stats; + BKE_subdiv_stats_init(&stats); + BKE_subdiv_stats_begin(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME); OpenSubdiv_TopologyRefinerSettings topology_refiner_settings; topology_refiner_settings.level = settings->level; topology_refiner_settings.is_adaptive = settings->is_adaptive; @@ -77,6 +80,8 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, subdiv->topology_refiner = osd_topology_refiner; subdiv->evaluator = NULL; update_subdiv_after_topology_change(subdiv); + BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME); + subdiv->stats = stats; return subdiv; #else UNUSED_VARS(settings, converter); diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 0ab19fc8df5..4c2ed07cdfa 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -46,8 +46,10 @@ void BKE_subdiv_eval_begin(Subdiv *subdiv) { #ifdef WITH_OPENSUBDIV if (subdiv->evaluator == NULL) { + BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( subdiv->topology_refiner); + BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); } else { /* TODO(sergey): Check for topology change. */ @@ -112,7 +114,9 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) break; } /* Update evaluator to the new coarse geometry. */ + BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); subdiv->evaluator->refine(subdiv->evaluator); + BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); #else UNUSED_VARS(subdiv, mesh); #endif diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 7baf03e7265..83f2069ea0f 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -912,6 +912,7 @@ Mesh *BKE_subdiv_to_mesh( const SubdivToMeshSettings *settings, const Mesh *coarse_mesh) { + BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); /* Make sure evaluator is up to date with possible new topology, and that * is is refined for the new positions of coarse vertices. */ @@ -946,5 +947,6 @@ Mesh *BKE_subdiv_to_mesh( &ctx, subdiv_eval_task, ¶llel_range_settings); + BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); return result; } diff --git a/source/blender/blenkernel/intern/subdiv_stats.c b/source/blender/blenkernel/intern/subdiv_stats.c new file mode 100644 index 00000000000..5da63fdbacb --- /dev/null +++ b/source/blender/blenkernel/intern/subdiv_stats.c @@ -0,0 +1,80 @@ +/* + * ***** 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) 2018 by Blender Foundation. + * All rights reserved. + * + * Contributor(s): Sergey Sharybin. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/subdiv_stats.c + * \ingroup bke + */ + +#include "BKE_subdiv.h" + +#include + +#include "PIL_time.h" + +void BKE_subdiv_stats_init(SubdivStats *stats) +{ + stats->topology_refiner_creation_time = 0.0; + stats->subdiv_to_mesh_time = 0.0; + stats->evaluator_creation_time = 0.0; + stats->evaluator_refine_time = 0.0; +} + +void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value) +{ + stats->begin_timestamp_[value] = PIL_check_seconds_timer(); +} + +void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value) +{ + stats->values_[value] = + PIL_check_seconds_timer() - stats->begin_timestamp_[value]; +} + +void BKE_subdiv_stats_print(const SubdivStats *stats) +{ +#define STATS_PRINT_TIME(stats, value, description) \ + do { \ + if ((stats)->value > 0.0) { \ + printf(" %s: %f (sec)\n", description, (stats)->value); \ + } \ + } while (false) + + printf("Subdivision surface statistics:\n"); + + STATS_PRINT_TIME(stats, + topology_refiner_creation_time, + "Topology refiner creation time"); + STATS_PRINT_TIME(stats, + subdiv_to_mesh_time, + "Subdivision to mesh time"); + STATS_PRINT_TIME(stats, + evaluator_creation_time, + "Evaluator creation time"); + STATS_PRINT_TIME(stats, + evaluator_refine_time, + "Evaluator refine time"); + +#undef STATS_PRINT_TIME +} diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index c92845a24eb..08dc7c92693 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -247,6 +247,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, subdiv_mesh_settings_init(&mesh_settings, &subdiv_settings); result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); /* TODO(sergey): Cache subdiv somehow. */ + // BKE_subdiv_stats_print(&subdiv->stats); BKE_subdiv_free(subdiv); return result; } -- cgit v1.2.3 From c205de020365eddbbc0f0cde0ad02dda91126807 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 19 Jul 2018 16:48:21 +0200 Subject: Fix T55973: [2.8] Crash when 'apply pose as rest pose' when bone scale is 0,0,0. `BKE_pose_rebuild()` should (ideally) always trigger a rebuild of the depsgraph, since it can add or remove posechannels. This function now takes a Main parameter to ensure that related depsgraphes are tagged as dirty (kept it optional, for some corner cases). We should also probably double-check calls to that function, think in theory it should only be called from depsgraph itself? But for now... --- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/BKE_object.h | 2 +- source/blender/blenkernel/intern/armature.c | 32 ++++++++++++++++------ source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenkernel/intern/object.c | 14 ++++++---- source/blender/blenkernel/intern/scene.c | 2 +- .../intern/builder/deg_builder_nodes_rig.cc | 3 +- source/blender/draw/intern/draw_armature.c | 2 +- source/blender/editors/armature/armature_utils.c | 2 +- source/blender/editors/object/object_add.c | 2 +- source/blender/editors/object/object_relations.c | 4 +-- source/blender/makesrna/intern/rna_object.c | 8 ++++-- 12 files changed, 47 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index e1bfb05fb59..21d880cf2a7 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -100,7 +100,7 @@ void BKE_armature_where_is(struct bArmature *arm); void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion); void BKE_pose_clear_pointers(struct bPose *pose); void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose); -void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm); +void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm); void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 0122185fd2a..79e4f1d448a 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -75,7 +75,7 @@ bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifie void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src); void BKE_object_free_modifiers(struct Object *ob, const int flag); -void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob); +void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob); void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target); bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index bd9ee7c9e5f..6be4574a62e 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -71,6 +71,8 @@ #include "BKE_object.h" #include "BKE_scene.h" +#include "DEG_depsgraph_build.h" + #include "BIK_api.h" /* **************** Generic Functions, data level *************** */ @@ -1951,9 +1953,14 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose) BLI_ghash_free(bone_hash, NULL, NULL); } -/* only after leave editmode, duplicating, validating older files, library syncing */ -/* NOTE: pose->flag is set for it */ -void BKE_pose_rebuild(Object *ob, bArmature *arm) +/** + * Only after leave editmode, duplicating, validating older files, library syncing. + * + * \note pose->flag is set for it. + * + * \param bmain May be NULL, only used to tag depsgraph as being dirty... + */ +void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm) { Bone *bone; bPose *pose; @@ -1998,12 +2005,17 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected); } - BKE_pose_update_constraint_flags(ob->pose); /* for IK detection for example */ + BKE_pose_update_constraint_flags(pose); /* for IK detection for example */ + + pose->flag &= ~POSE_RECALC; + pose->flag |= POSE_WAS_REBUILT; - ob->pose->flag &= ~POSE_RECALC; - ob->pose->flag |= POSE_WAS_REBUILT; + BKE_pose_channels_hash_make(pose); - BKE_pose_channels_hash_make(ob->pose); + /* Rebuilding poses forces us to also rebuild the dependency graph, since there is one node per pose/bone... */ + if (bmain != NULL) { + DEG_relations_tag_update(bmain); + } } /* ********************** THE POSE SOLVER ******************* */ @@ -2277,8 +2289,10 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) if (ELEM(NULL, arm, scene)) return; - if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) - BKE_pose_rebuild(ob, arm); + if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) { + /* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - hopefully this is OK. */ + BKE_pose_rebuild(NULL, ob, arm); + } ctime = BKE_scene_frame_get(scene); /* not accurate... */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index c2cdc8df1e6..351214ed72b 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -2464,7 +2464,7 @@ void BKE_library_make_local( * Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL && ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 14794bd7061..33ea13c9a38 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1150,7 +1150,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src) * * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). */ -void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_src, const int flag) +void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag) { ModifierData *md; @@ -1180,7 +1180,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_ copy_object_pose(ob_dst, ob_src, flag_subdata); /* backwards compat... non-armatures can get poses in older files? */ if (ob_src->type == OB_ARMATURE) - BKE_pose_rebuild(ob_dst, ob_dst->data); + BKE_pose_rebuild(bmain, ob_dst, ob_dst->data); } defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase); BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps); @@ -1359,7 +1359,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target) /* local_object->proxy == pointer to library object, saved in files and read */ /* local_object->proxy_group == pointer to collection dupli-object, saved in files and read */ -void BKE_object_make_proxy(Object *ob, Object *target, Object *cob) +void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob) { /* paranoia checks */ if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) { @@ -1434,7 +1434,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *cob) if (target->type == OB_ARMATURE) { copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */ BKE_pose_rest(ob->pose); /* clear all transforms in channels */ - BKE_pose_rebuild(ob, ob->data); /* set all internal links */ + BKE_pose_rebuild(bmain, ob, ob->data); /* set all internal links */ armature_set_id_extern(ob); } @@ -2698,8 +2698,10 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph, * with poses we do it ahead of BKE_object_where_is_calc to ensure animation * is evaluated on the rebuilt pose, otherwise we get incorrect poses * on file load */ - if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) - BKE_pose_rebuild(ob, ob->data); + if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { + /* No need to pass bmain here, we assume we do not need to rebuild DEG from here... */ + BKE_pose_rebuild(NULL, ob, ob->data); + } } } /* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers, diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f99a30b75d0..3650fa21c1c 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1288,7 +1288,7 @@ static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgrap for (ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) { if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild(ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data); } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 00d7a5da455..043148a0f70 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -161,7 +161,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object) build_armature(armature); /* Rebuild pose if not up to date. */ if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild(object, armature); + /* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */ + BKE_pose_rebuild(NULL, object, armature); /* XXX: Without this animation gets lost in certain circumstances * after loading file. Need to investigate further since it does * not happen with simple scenes.. diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index b49ca4d0d00..8b90d328541 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -1623,7 +1623,7 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) /* We can't safely draw non-updated pose, might contain NULL bone pointers... */ if (ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(ob, arm); + BKE_pose_rebuild(NULL, ob, arm); } // if (!(base->flag & OB_FROMDUPLI)) // TODO diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 02d45a4e041..c93bfb5d8c3 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -681,7 +681,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) /* so all users of this armature should get rebuilt */ for (obt = bmain->object.first; obt; obt = obt->id.next) { if (obt->data == arm) { - BKE_pose_rebuild(obt, arm); + BKE_pose_rebuild(bmain, obt, arm); } } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index a8917f4c4aa..8c60dd01e89 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2222,7 +2222,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer ID_NEW_REMAP_US2(obn->data) else { obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data)); - BKE_pose_rebuild(obn, obn->data); + BKE_pose_rebuild(bmain, obn, obn->data); didit = 1; } id_us_min(id); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 324b6eca34a..2c3ff8b6afe 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -360,7 +360,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op) newob = BKE_object_add_from(bmain, scene, view_layer, OB_EMPTY, name, gob ? gob : ob); /* set layers OK */ - BKE_object_make_proxy(newob, ob, gob); + BKE_object_make_proxy(bmain, newob, ob, gob); /* Set back pointer immediately so dependency graph knows that this is * is a proxy and will act accordingly. Otherwise correctness of graph @@ -1809,7 +1809,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer case OB_ARMATURE: DEG_id_tag_update(&ob->id, OB_RECALC_DATA); ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data)); - BKE_pose_rebuild(ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data); break; case OB_SPEAKER: ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data)); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 2bdfbade53a..ac1a6d512c3 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -356,10 +356,12 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) ob->data = id; test_object_materials(G_MAIN, ob, id); - if (GS(id->name) == ID_CU) + if (GS(id->name) == ID_CU) { BKE_curve_type_test(ob); - else if (ob->type == OB_ARMATURE) - BKE_pose_rebuild(ob, ob->data); + } + else if (ob->type == OB_ARMATURE) { + BKE_pose_rebuild(G_MAIN, ob, ob->data); + } } } -- cgit v1.2.3 From 2de283615f081fa76fb05ac0bf81f831651f9e51 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 19 Jul 2018 16:52:49 +0200 Subject: Make `draw_armature()` abort in case pose is not up-to-date. Previously it was calling `BKE_pose_rebuild()`, such thing shall never be called from drawing code! Hopefully this now works as expected and that horrible hack is not needed anymore. --- source/blender/draw/intern/draw_armature.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 8b90d328541..f0a32dfc8e0 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -1623,7 +1623,7 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) /* We can't safely draw non-updated pose, might contain NULL bone pointers... */ if (ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(NULL, ob, arm); + return; } // if (!(base->flag & OB_FROMDUPLI)) // TODO -- cgit v1.2.3 From f48e81e720c1e5fcc93ba6da11f862263da9cadc Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 20 Jul 2018 12:01:38 +0200 Subject: Fix T55414: waveforms are reprocessed when undoing Add new tag to bSound (runtime flags), and make read code to set a 'no reload waveform' new tag, since it uses a mapping to get existing waveform in undo case... --- source/blender/blenkernel/intern/sound.c | 18 +++++++++++------- source/blender/blenloader/intern/readfile.c | 2 ++ source/blender/makesdna/DNA_sound_types.h | 10 +++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 6aa44cde0e0..709a0022767 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -757,15 +757,19 @@ int BKE_sound_scene_playing(struct Scene *scene) void BKE_sound_free_waveform(bSound *sound) { - SoundWaveform *waveform = sound->waveform; - if (waveform) { - if (waveform->data) { - MEM_freeN(waveform->data); + if ((sound->tags & SOUND_TAGS_WAVEFORM_NO_RELOAD) == 0) { + SoundWaveform *waveform = sound->waveform; + if (waveform) { + if (waveform->data) { + MEM_freeN(waveform->data); + } + MEM_freeN(waveform); } - MEM_freeN(waveform); - } - sound->waveform = NULL; + sound->waveform = NULL; + } + /* This tag is only valid once. */ + sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD; } void BKE_sound_read_waveform(bSound *sound, short *stop) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1def462b1ca..1d772a15efd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7542,6 +7542,7 @@ static void direct_link_speaker(FileData *fd, Speaker *spk) static void direct_link_sound(FileData *fd, bSound *sound) { + sound->tags = 0; sound->handle = NULL; sound->playback_handle = NULL; @@ -7553,6 +7554,7 @@ static void direct_link_sound(FileData *fd, bSound *sound) if (fd->soundmap) { sound->waveform = newsoundadr(fd, sound->waveform); + sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD; } else { sound->waveform = NULL; diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index aefe1a7d5a3..7778582b82d 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -65,13 +65,15 @@ typedef struct bSound { */ struct PackedFile *newpackedfile; struct Ipo *ipo; + float volume; float attenuation; float pitch; float min_gain; float max_gain; float distance; - int flags; + short flags; + short tags; /* Runtime only, always reset in readfile. */ int pad; /* unused currently @@ -116,6 +118,7 @@ enum { SND_CFRA_NUM = 2, }; +/* bSound->flags */ enum { #ifdef DNA_DEPRECATED SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */ @@ -125,6 +128,11 @@ enum { SOUND_FLAGS_WAVEFORM_LOADING = (1 << 6), }; +/* bSound->tags */ +enum { + SOUND_TAGS_WAVEFORM_NO_RELOAD = 1 << 0, /* Do not free/reset waveform on sound load, only used by undo code. */ +}; + /* to DNA_sound_types.h*/ #endif -- cgit v1.2.3 From 710a05954990c347932b9f540a1b220ea2c5c0da Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 20 Jul 2018 12:11:34 +0200 Subject: Cleanup: Move 'WAVEFORM_LOADING' of sounds from flags to tags. This is purely runtime data, so move it to new tags. ;) --- source/blender/blenkernel/intern/sound.c | 4 ++-- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/editors/space_sequencer/sequencer_draw.c | 4 ++-- source/blender/editors/space_sequencer/sequencer_preview.c | 2 +- source/blender/makesdna/DNA_sound_types.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 709a0022767..d21055ada6a 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -798,7 +798,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop) } MEM_freeN(waveform); BLI_spin_lock(sound->spinlock); - sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); return; } @@ -807,7 +807,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop) BLI_spin_lock(sound->spinlock); sound->waveform = waveform; - sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1d772a15efd..bdfae79a1d0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7565,7 +7565,7 @@ static void direct_link_sound(FileData *fd, bSound *sound) BLI_spin_init(sound->spinlock); } /* clear waveform loading flag */ - sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING; sound->packedfile = direct_link_packedfile(fd, sound->packedfile); sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 97c42cc11e0..915e2466d54 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -220,9 +220,9 @@ static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequenc BLI_spin_lock(sound->spinlock); if (!sound->waveform) { - if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) { + if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) { /* prevent sounds from reloading */ - sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING; + sound->tags |= SOUND_TAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); sequencer_preview_add_sound(C, seq); } diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c index c58c05b67c0..ae011e48538 100644 --- a/source/blender/editors/space_sequencer/sequencer_preview.c +++ b/source/blender/editors/space_sequencer/sequencer_preview.c @@ -96,7 +96,7 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p /* make sure we cleanup the loading flag! */ BLI_spin_lock(sound->spinlock); - sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING; + sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING; BLI_spin_unlock(sound->spinlock); BLI_mutex_lock(pj->mutex); diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h index 7778582b82d..02d3aa928c7 100644 --- a/source/blender/makesdna/DNA_sound_types.h +++ b/source/blender/makesdna/DNA_sound_types.h @@ -125,12 +125,12 @@ enum { #endif SOUND_FLAGS_CACHING = (1 << 4), SOUND_FLAGS_MONO = (1 << 5), - SOUND_FLAGS_WAVEFORM_LOADING = (1 << 6), }; /* bSound->tags */ enum { SOUND_TAGS_WAVEFORM_NO_RELOAD = 1 << 0, /* Do not free/reset waveform on sound load, only used by undo code. */ + SOUND_TAGS_WAVEFORM_LOADING = (1 << 6), }; /* to DNA_sound_types.h*/ -- cgit v1.2.3 From 61c00802d0a9d1698f85633ba1c121b1a17e6425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 12:30:23 +0200 Subject: Basic Draw Engine: Cleanup unused code. This engine is only used for selection and draw depth so no need for anything else. Also add backface culling support to selection. --- source/blender/draw/engines/basic/basic_engine.c | 65 ++---------------------- 1 file changed, 3 insertions(+), 62 deletions(-) diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index a9c758d5b6f..57553d98d5d 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -42,9 +42,6 @@ #define BASIC_ENGINE "BLENDER_BASIC" -/* we may want this later? */ -#define USE_DEPTH - /* *********** LISTS *********** */ /* GPUViewport.storage @@ -54,11 +51,8 @@ typedef struct BASIC_StorageList { } BASIC_StorageList; typedef struct BASIC_PassList { -#ifdef USE_DEPTH struct DRWPass *depth_pass; struct DRWPass *depth_pass_cull; -#endif - struct DRWPass *color_pass; } BASIC_PassList; typedef struct BASIC_Data { @@ -72,38 +66,24 @@ typedef struct BASIC_Data { /* *********** STATIC *********** */ static struct { -#ifdef USE_DEPTH /* Depth Pre Pass */ struct GPUShader *depth_sh; -#endif - /* Shading Pass */ - struct GPUShader *color_sh; } e_data = {NULL}; /* Engine data */ typedef struct BASIC_PrivateData { -#ifdef USE_DEPTH DRWShadingGroup *depth_shgrp; DRWShadingGroup *depth_shgrp_cull; DRWShadingGroup *depth_shgrp_hair; -#endif - DRWShadingGroup *color_shgrp; } BASIC_PrivateData; /* Transient data */ /* Functions */ static void basic_engine_init(void *UNUSED(vedata)) { -#ifdef USE_DEPTH /* Depth prepass */ if (!e_data.depth_sh) { e_data.depth_sh = DRW_shader_create_3D_depth_only(); } -#endif - - /* Shading pass */ - if (!e_data.color_sh) { - e_data.color_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); - } } static void basic_cache_init(void *vedata) @@ -116,8 +96,6 @@ static void basic_cache_init(void *vedata) stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); } -#ifdef USE_DEPTH - /* Depth Pass */ { psl->depth_pass = DRW_pass_create( "Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE); @@ -128,13 +106,6 @@ static void basic_cache_init(void *vedata) DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK); stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull); } -#endif - - /* Color Pass */ - { - psl->color_pass = DRW_pass_create("Color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - stl->g_data->color_shgrp = DRW_shgroup_create(e_data.color_sh, psl->color_pass); - } } static void basic_cache_populate(void *vedata, Object *ob) @@ -168,13 +139,9 @@ static void basic_cache_populate(void *vedata, Object *ob) struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { - bool do_cull = false; /* TODO (we probably wan't to take this from the viewport?) */ -#ifdef USE_DEPTH + const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING)); /* Depth Prepass */ DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat); -#endif - /* Shading */ - DRW_shgroup_call_add(stl->g_data->color_shgrp, geom, ob->obmat); } } @@ -187,36 +154,10 @@ static void basic_cache_finish(void *vedata) static void basic_draw_scene(void *vedata) { - BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl; - const bool is_select = DRW_state_is_select(); - - bool use_color = true; - bool use_depth = true; - bool use_depth_cull = true; - if (is_select) { - /* Needed for depth-picking, - * for other selection types there are no need for extra passes either. */ - use_color = false; - use_depth_cull = false; - } - -#ifdef USE_DEPTH - /* Pass 1 : Depth pre-pass */ - if (use_depth) { - DRW_draw_pass(psl->depth_pass); - } - - if (use_depth_cull) { - DRW_draw_pass(psl->depth_pass_cull); - } -#endif - - /* Pass 3 : Shading */ - if (use_color) { - DRW_draw_pass(psl->color_pass); - } + DRW_draw_pass(psl->depth_pass); + DRW_draw_pass(psl->depth_pass_cull); } static void basic_engine_free(void) -- cgit v1.2.3 From a185bf3b856846b2e300542bacdca3bc119e1bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 12:40:35 +0200 Subject: Workbench: Add backface culling support --- source/blender/draw/engines/workbench/workbench_deferred.c | 6 ++++-- source/blender/draw/engines/workbench/workbench_forward.c | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index ce209af8527..4e90a08a543 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -272,6 +272,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PassList *psl = vedata->psl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); if (!stl->g_data) { /* Alloc transient pointers */ @@ -381,7 +382,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) } { - const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; /* AO Samples Tex */ int num_iterations = workbench_taa_calculate_num_iterations(vedata); @@ -405,8 +405,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) /* Prepass */ { + const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING)); + int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; - psl->prepass_pass = DRW_pass_create("Prepass", state); + psl->prepass_pass = DRW_pass_create("Prepass", (do_cull) ? state | DRW_STATE_CULL_BACK : state); psl->prepass_hair_pass = DRW_pass_create("Prepass", state); } diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 2a65feeb28c..825b80ace52 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -243,6 +243,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_StorageList *stl = vedata->stl; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); DRWShadingGroup *grp; if (!stl->g_data) { @@ -322,15 +323,17 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) }); workbench_volume_cache_init(vedata); + const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING)); + const int cull_state = (do_cull) ? DRW_STATE_CULL_BACK : 0; /* Transparency Accum */ { - int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT; + int state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_OIT | cull_state; psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state); } /* Depth */ { - int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; + int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | cull_state; psl->object_outline_pass = DRW_pass_create("Object Outline Pass", state); } /* Composite */ -- cgit v1.2.3 From 244b825ccd563672516b985348361b7a311e0f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 12:54:57 +0200 Subject: Fix assert for Image & Brush icon preview --- source/blender/editors/render/render_preview.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 884e8d6625b..7270eb03c2e 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -334,6 +334,10 @@ static ID *duplicate_ids(ID *id, Depsgraph *depsgraph) return (ID *)BKE_lamp_localize((Lamp *)id_eval); case ID_WO: return (ID *)BKE_world_localize((World *)id_eval); + case ID_IM: + case ID_BR: + case ID_SCR: + return NULL; default: BLI_assert(!"ID type preview not supported."); return NULL; -- cgit v1.2.3 From 4a79b46b9c7a7800e7e333163e6e4d3f30285d28 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Jul 2018 13:35:08 +0200 Subject: Fix build error with release + debug info build. --- source/blender/gpu/intern/gpu_context.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp index 6a42552c2fd..3f2ce958332 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -151,8 +151,10 @@ void GPU_context_discard(GPUContext *ctx) BLI_assert(ctx == active_ctx); BLI_assert(pthread_equal(pthread_self(), ctx->thread)); BLI_assert(ctx->orphaned_vertarray_ids.empty()); +#ifdef DEBUG /* For now don't allow GPUFrameBuffers to be reuse in another ctx. */ BLI_assert(ctx->framebuffers.empty()); +#endif /* delete remaining vaos */ while (!ctx->batches.empty()) { /* this removes the array entry */ -- cgit v1.2.3 From 72cbf966fb9194edbe6fa82cfd02540dc306184a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 20 Jul 2018 15:13:48 +0200 Subject: Depsgraph: Fix missing relation from proxy_form's ID properties Hopefully this will fix issue with camera rig where camera properties (like, near/far clip) are driven by custom properties from bones, and those bones are actually belong to proxied armature. --- .../blender/depsgraph/intern/builder/deg_builder_nodes.cc | 11 +++++++++++ .../depsgraph/intern/builder/deg_builder_relations.cc | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index ab7ddb507a0..1b68a73bbd7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -829,8 +829,19 @@ void DepsgraphNodeBuilder::build_driver_variables(ID * id, FCurve *fcurve) LISTBASE_FOREACH (DriverVar *, dvar, &fcurve->driver->variables) { DRIVER_TARGETS_USED_LOOPER(dvar) { + if (dtar->id == NULL) { + continue; + } build_id(dtar->id); build_driver_id_property(dtar->id, dtar->rna_path); + /* Corresponds to dtar_id_ensure_proxy_from(). */ + if ((GS(dtar->id->name) == ID_OB) && + (((Object *)dtar->id)->proxy_from != NULL)) + { + Object *proxy_from = ((Object *)dtar->id)->proxy_from; + build_id(&proxy_from->id); + build_driver_id_property(&proxy_from->id, dtar->rna_path); + } } DRIVER_TARGETS_LOOPER_END } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index bba1ba67962..1a0c621ab43 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1351,6 +1351,14 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) continue; } build_id(dtar->id); + /* Initialize relations coming to proxy_from. */ + Object *proxy_from = NULL; + if ((GS(dtar->id->name) == ID_OB) && + (((Object *)dtar->id)->proxy_from != NULL)) + { + proxy_from = ((Object *)dtar->id)->proxy_from; + build_id(&proxy_from->id); + } /* Special handling for directly-named bones. */ if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (((Object *)dtar->id)->type == OB_ARMATURE) && @@ -1398,6 +1406,13 @@ void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu) continue; } add_relation(variable_key, driver_key, "RNA Target -> Driver"); + if (proxy_from != NULL) { + RNAPathKey proxy_from_variable_key(&proxy_from->id, + dtar->rna_path); + add_relation(proxy_from_variable_key, + variable_key, + "Proxy From -> Variable"); + } } else { if (dtar->id == id) { -- cgit v1.2.3 From b3b4b9fb8c255d2ec7cc7433ffcafef6311da6e9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Jul 2018 15:12:36 +0200 Subject: Fix WITH_HEADLESS build. --- intern/ghost/intern/GHOST_SystemNULL.h | 2 ++ source/blender/windowmanager/intern/wm_event_system.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h index 7c8d26d7486..ac3dfd71d63 100644 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ b/intern/ghost/intern/GHOST_SystemNULL.h @@ -53,6 +53,8 @@ public: void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ } void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const { /* nop */ } bool supportsNativeDialogs(void) { return false;} + GHOST_IContext *createOffscreenContext() { return NULL; } + GHOST_TSuccess disposeContext(GHOST_IContext *context) { return GHOST_kFailure; } GHOST_TSuccess init() { GHOST_TSuccess success = GHOST_System::init(); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e2247b2adff..8b1cce27502 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -4569,7 +4569,11 @@ bool WM_window_modal_keymap_status_draw( continue; } int icon_mod[4]; +#ifdef WITH_HEADLESS + int icon = 0; +#else int icon = UI_icon_from_keymap_item(kmi, icon_mod); +#endif if (icon != 0) { for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) { uiItemL(row, "", icon_mod[j]); -- cgit v1.2.3 From 9ad5eafe465e4ab0c9945e234b187dc210ac608a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Jul 2018 17:38:24 +0200 Subject: Fix incorrect magnification filter for text texture. Barely any visible difference, except when drawing big custom text with the Python API. --- source/blender/blenfont/intern/blf_glyph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 30e31bb2580..99be8539d24 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -244,7 +244,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) gc->textures[gc->texture_current] = tex; GPU_texture_bind(tex, 0); GPU_texture_wrap_mode(tex, false); - GPU_texture_filters(tex, GPU_NEAREST, GPU_LINEAR); + GPU_texture_filters(tex, GPU_NEAREST, GPU_NEAREST); GPU_texture_unbind(tex); } -- cgit v1.2.3 From a6f750dd4148b1c2549150128ee0c21db30039b6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Jul 2018 19:07:35 +0200 Subject: Fix T54455, T56053, T55564: Cycles OpenCL build error after recent changes. --- intern/cycles/kernel/svm/svm_voronoi.h | 3 ++- intern/cycles/util/util_math_float3.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h index e5e350bf76a..75af910d940 100644 --- a/intern/cycles/kernel/svm/svm_voronoi.h +++ b/intern/cycles/kernel/svm/svm_voronoi.h @@ -52,7 +52,7 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, case NODE_VORONOI_CHEBYCHEV: d = max3(fabs(vp - p)); break; - case NODE_VORONOI_MINKOWSKI: + case NODE_VORONOI_MINKOWSKI: { float3 n = fabs(vp - p); if(e == 0.5f) { d = sqr(reduce_add(sqrt(n))); @@ -61,6 +61,7 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, d = powf(reduce_add(pow3(n, e)), 1.0f/e); } break; + } } /* To keep the shortest four distances and associated points we have to keep them in sorted order. */ diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index ba1c117cdea..75265c1c9a2 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -280,11 +280,6 @@ ccl_device_inline float3 sqrt(const float3& a) #endif } -ccl_device_inline float3 pow3(const float3& a, float e) -{ - return make_float3(powf(a.x, e), powf(a.y, e), powf(a.z, e)); -} - ccl_device_inline float3 mix(const float3& a, const float3& b, float t) { return a + t*(b - a); @@ -382,6 +377,11 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b) #endif } +ccl_device_inline float3 pow3(float3 v, float e) +{ + return make_float3(powf(v.x, e), powf(v.y, e), powf(v.z, e)); +} + ccl_device_inline float3 exp3(float3 v) { return make_float3(expf(v.x), expf(v.y), expf(v.z)); -- cgit v1.2.3 From e7d8908f1405bbe54df2b5b51b4c1078200e5020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 15:25:20 +0200 Subject: GPUMaterial: Optimize and fix blending in box mapping Blending was done in srgb space and was not matching cycles. Optimized by using less branches and more vector operations. --- .../blender/gpu/shaders/gpu_shader_material.glsl | 116 ++++++++++----------- .../nodes/shader/nodes/node_shader_tex_image.c | 31 ++++-- 2 files changed, 78 insertions(+), 69 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index d1183c792f5..4b376160105 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1804,18 +1804,46 @@ void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) alpha = color.a; } +void tex_box_sample(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + color1 = texture(ima, uv); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + color2 = texture(ima, uv); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + color3 = texture(ima, uv); +} + void node_tex_image_box(vec3 texco, vec3 N, + vec4 color1, + vec4 color2, + vec4 color3, sampler2D ima, float blend, out vec4 color, out float alpha) { - vec3 signed_N = N; - /* project from direction vector to barycentric coordinates in triangles */ - N = vec3(abs(N.x), abs(N.y), abs(N.z)); - N /= (N.x + N.y + N.z); + N = abs(N); + N /= dot(N, vec3(1.0)); /* basic idea is to think of this as a triangle, each corner representing * one of the 3 faces of the cube. in the corners we have single textures, @@ -1825,72 +1853,36 @@ void node_tex_image_box(vec3 texco, * the Nxyz values are the barycentric coordinates in an equilateral * triangle, which in case of blending, in the middle has a smaller * equilateral triangle where 3 textures blend. this divides things into - * 7 zones, with an if () test for each zone */ + * 7 zones, with an if () test for each zone + * EDIT: Now there is only 4 if's. */ - vec3 weight = vec3(0.0, 0.0, 0.0); - float limit = 0.5 * (1.0 + blend); + float limit = 0.5 + 0.5 * blend; - /* first test for corners with single texture */ - if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) { - weight.x = 1.0; - } - else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) { - weight.y = 1.0; + vec3 weight; + weight.x = N.x / (N.x + N.y); + weight.y = N.y / (N.y + N.z); + weight.z = N.z / (N.x + N.z); + weight = clamp((weight - 0.5 * (1.0 - blend)) / max(1e-8, blend), 0.0, 1.0); + + /* test for mixes between two textures */ + if (N.z < (1.0 - limit) * (N.y + N.x)) { + weight.z = 0.0; + weight.y = 1.0 - weight.x; } - else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) { - weight.z = 1.0; + else if (N.x < (1.0 - limit) * (N.y + N.z)) { + weight.x = 0.0; + weight.z = 1.0 - weight.y; } - else if (blend > 0.0) { - /* in case of blending, test for mixes between two textures */ - if (N.z < (1.0 - limit) * (N.y + N.x)) { - weight.x = N.x / (N.x + N.y); - weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.y = 1.0 - weight.x; - } - else if (N.x < (1.0 - limit) * (N.y + N.z)) { - weight.y = N.y / (N.y + N.z); - weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.z = 1.0 - weight.y; - } - else if (N.y < (1.0 - limit) * (N.x + N.z)) { - weight.x = N.x / (N.x + N.z); - weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight.z = 1.0 - weight.x; - } - else { - /* last case, we have a mix between three */ - weight.x = ((2.0 - limit) * N.x + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.y = ((2.0 - limit) * N.y + (limit - 1.0)) / (2.0 * limit - 1.0); - weight.z = ((2.0 - limit) * N.z + (limit - 1.0)) / (2.0 * limit - 1.0); - } + else if (N.y < (1.0 - limit) * (N.x + N.z)) { + weight.y = 0.0; + weight.x = 1.0 - weight.z; } else { - /* Desperate mode, no valid choice anyway, fallback to one side.*/ - weight.x = 1.0; - } - color = vec4(0); - if (weight.x > 0.0) { - vec2 uv = texco.yz; - if(signed_N.x < 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.x * texture(ima, uv); - } - if (weight.y > 0.0) { - vec2 uv = texco.xz; - if(signed_N.y > 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.y * texture(ima, uv); - } - if (weight.z > 0.0) { - vec2 uv = texco.yx; - if(signed_N.z > 0.0) { - uv.x = 1.0 - uv.x; - } - color += weight.z * texture(ima, uv); + /* last case, we have a mix between three */ + weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, 2.0 * limit - 1.0); } + color = weight.x * color1 + weight.y * color2 + weight.z * color3; alpha = color.a; } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 2bbe3617bee..20753445aa6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -58,8 +58,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat Image *ima = (Image *)node->id; ImageUser *iuser = NULL; NodeTexImage *tex = node->storage; + bool do_color_correction = false; - GPUNodeLink *norm; + GPUNodeLink *norm, *col1, *col2, *col3; int isdata = tex->color_space == SHD_COLORSPACE_NONE; float blend = tex->projection_blend; @@ -67,6 +68,15 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat if (!ima) return GPU_stack_link(mat, node, "node_tex_image_empty", in, out); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); + if ((tex->color_space == SHD_COLORSPACE_COLOR) && + ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && + GPU_material_do_color_management(mat)) + { + do_color_correction = true; + } + BKE_image_release_ibuf(ima, ibuf, NULL); + if (!in[0].link) in[0].link = GPU_attribute(CD_MTFACE, ""); @@ -83,8 +93,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat GPU_link(mat, "direction_transform_m4v3", norm, GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), &norm); + GPU_link(mat, "tex_box_sample", in[0].link, + norm, + GPU_image(ima, iuser, isdata), + &col1, + &col2, + &col3); + if (do_color_correction) { + GPU_link(mat, "srgb_to_linearrgb", col1, &col1); + GPU_link(mat, "srgb_to_linearrgb", col2, &col2); + GPU_link(mat, "srgb_to_linearrgb", col3, &col3); + } GPU_link(mat, "node_tex_image_box", in[0].link, norm, + col1, col2, col3, GPU_image(ima, iuser, isdata), GPU_uniform(&blend), &out[0].link, @@ -102,14 +124,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat break; } - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL); - if ((tex->color_space == SHD_COLORSPACE_COLOR) && - ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 && - GPU_material_do_color_management(mat)) - { + if (do_color_correction && (tex->projection != SHD_PROJ_BOX)) { GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link); } - BKE_image_release_ibuf(ima, ibuf, NULL); return true; } -- cgit v1.2.3 From 26b6b5871ea83dea372495b56ac2768bb63e88b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 15:45:59 +0200 Subject: GPUMaterial: Texture Node: support for nearest (closest) filtering method Add placeholder for cubic and smart filtering for now. --- .../blender/gpu/shaders/gpu_shader_material.glsl | 72 +++++++++++++++++++++- .../nodes/shader/nodes/node_shader_tex_image.c | 34 +++++++--- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 4b376160105..7f2475f0aab 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1798,13 +1798,31 @@ void node_tex_environment_empty(vec3 co, out vec4 color) color = vec4(1.0, 0.0, 1.0, 1.0); } -void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) +void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha) { color = texture(ima, co.xy); alpha = color.a; } -void tex_box_sample(vec3 texco, +void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + ivec2 pix = ivec2(co.xy * textureSize(ima, 0).xy); + color = texelFetch(ima, pix, 0); + alpha = color.a; +} + +void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + node_tex_image_linear(co, ima, color, alpha); +} + +void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + /* use cubic for now */ + node_tex_image_cubic(co, ima, color, alpha); +} + +void tex_box_sample_linear(vec3 texco, vec3 N, sampler2D ima, out vec4 color1, @@ -1831,6 +1849,56 @@ void tex_box_sample(vec3 texco, color3 = texture(ima, uv); } +void tex_box_sample_nearest(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + ivec2 pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color1 = texelFetch(ima, pix, 0); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color2 = texelFetch(ima, pix, 0); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color3 = texelFetch(ima, pix, 0); +} + +void tex_box_sample_cubic(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + tex_box_sample_linear(texco, N, ima, color1, color2, color3); +} + +void tex_box_sample_smart(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + tex_box_sample_cubic(texco, N, ima, color1, color2, color3); +} + void node_tex_image_box(vec3 texco, vec3 N, vec4 color1, diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c index 20753445aa6..9782df2638f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -55,9 +55,25 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node) static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { + static const char *names[] = { + "node_tex_image_linear", + "node_tex_image_nearest", + "node_tex_image_cubic", + "node_tex_image_smart" + }; + static const char *names_box[] = { + "tex_box_sample_linear", + "tex_box_sample_nearest", + "tex_box_sample_cubic", + "tex_box_sample_smart" + }; + Image *ima = (Image *)node->id; ImageUser *iuser = NULL; NodeTexImage *tex = node->storage; + const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) + ? names_box[tex->interpolation] + : names[tex->interpolation]; bool do_color_correction = false; GPUNodeLink *norm, *col1, *col2, *col3; @@ -84,7 +100,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat switch (tex->projection) { case SHD_PROJ_FLAT: - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_BOX: GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), @@ -93,12 +109,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat GPU_link(mat, "direction_transform_m4v3", norm, GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), &norm); - GPU_link(mat, "tex_box_sample", in[0].link, - norm, - GPU_image(ima, iuser, isdata), - &col1, - &col2, - &col3); + GPU_link(mat, gpu_node_name, in[0].link, + norm, + GPU_image(ima, iuser, isdata), + &col1, + &col2, + &col3); if (do_color_correction) { GPU_link(mat, "srgb_to_linearrgb", col1, &col1); GPU_link(mat, "srgb_to_linearrgb", col2, &col2); @@ -115,12 +131,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat case SHD_PROJ_SPHERE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_sphere", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_TUBE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_tube", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; } -- cgit v1.2.3 From 28fa79219df8d103ccc4af9433c581be50ae2bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 19:16:33 +0200 Subject: GPUMaterial: Texture Node: Add support for Cubic filtering Like in cycles it's a bit more slower than linear but it's smoother. Works for all projection type. --- .../blender/gpu/shaders/gpu_shader_material.glsl | 76 +++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 7f2475f0aab..961837f6b16 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1813,7 +1813,61 @@ void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float al void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) { - node_tex_image_linear(co, ima, color, alpha); + vec2 tex_size = vec2(textureSize(ima, 0).xy); + + co.xy *= tex_size; + /* texel center */ + vec2 tc = floor(co.xy - 0.5) + 0.5; + vec2 f = co.xy - tc; + vec2 f2 = f * f; + vec2 f3 = f2 * f; + /* Bspline coefs (optimized) */ + vec2 w3 = f3 / 6.0; + vec2 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0; + vec2 w1 = f3 * 0.5 - f2 * 1.0 + 2.0 / 3.0; + vec2 w2 = 1.0 - w0 - w1 - w3; + +#if 1 /* Optimized version using 4 filtered tap. */ + vec2 s0 = w0 + w1; + vec2 s1 = w2 + w3; + + vec2 f0 = w1 / (w0 + w1); + vec2 f1 = w3 / (w2 + w3); + + vec4 final_co; + final_co.xy = tc - 1.0 + f0; + final_co.zw = tc + 1.0 + f1; + + final_co /= tex_size.xyxy; + + color = texture(ima, final_co.xy) * s0.x * s0.y; + color += texture(ima, final_co.zy) * s1.x * s0.y; + color += texture(ima, final_co.xw) * s0.x * s1.y; + color += texture(ima, final_co.zw) * s1.x * s1.y; + +#else /* Reference bruteforce 16 tap. */ + color = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, -1.0)), 0) * w1.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, -1.0)), 0) * w2.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, -1.0)), 0) * w3.x * w0.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 0.0)), 0) * w1.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 0.0)), 0) * w2.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 0.0)), 0) * w3.x * w1.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 1.0)), 0) * w1.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 1.0)), 0) * w2.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 1.0)), 0) * w3.x * w2.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 2.0)), 0) * w1.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 2.0)), 0) * w2.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 2.0)), 0) * w3.x * w3.y; +#endif + + alpha = color.a; } void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) @@ -1886,7 +1940,25 @@ void tex_box_sample_cubic(vec3 texco, out vec4 color2, out vec4 color3) { - tex_box_sample_linear(texco, N, ima, color1, color2, color3); + float alpha; + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color1, alpha); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color2, alpha); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color3, alpha); } void tex_box_sample_smart(vec3 texco, -- cgit v1.2.3 From 4609205a3f1b02abafeba80f542c8aa21d86bf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 20:06:39 +0200 Subject: GPUMaterial: Cleanup unused headers --- source/blender/gpu/intern/gpu_material.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 92aff91da32..2264836f24a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -36,32 +36,18 @@ #include "MEM_guardedalloc.h" -#include "DNA_lamp_types.h" #include "DNA_material_types.h" -#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_world_types.h" #include "BLI_math.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_rand.h" -#include "BLI_threads.h" - -#include "BKE_anim.h" -#include "BKE_colorband.h" -#include "BKE_colortools.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_layer.h" + #include "BKE_main.h" #include "BKE_node.h" #include "BKE_scene.h" -#include "IMB_imbuf_types.h" - -#include "GPU_extensions.h" -#include "GPU_framebuffer.h" #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_texture.h" -- cgit v1.2.3 From a987daa18dc66b726cef3e502b26e13ff002d894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 20:36:14 +0200 Subject: Render Preview: Fix problem with multi size icon preview The id was free after each size. We now only free after the job has finished. --- source/blender/editors/render/render_preview.c | 39 +++++++++++++++++++------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 7270eb03c2e..7459868d835 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -173,6 +173,7 @@ typedef struct ShaderPreview { int sizex, sizey; unsigned int *pr_rect; int pr_method; + bool own_id_copy; Main *bmain; Main *pr_main; @@ -837,7 +838,7 @@ static void shader_preview_free(void *customdata) ShaderPreview *sp = customdata; Main *pr_main = sp->pr_main; - if (sp->id_copy) { + if (sp->id_copy && sp->own_id_copy) { switch (GS(sp->id_copy->name)) { case ID_MA: BKE_material_free((Material *)sp->id_copy); @@ -866,14 +867,15 @@ static void shader_preview_free(void *customdata) /* get rid of copied material */ BLI_remlink(&pr_main->mat, sp->matcopy); - BKE_material_free(sp->matcopy); - properties = IDP_GetProperties((ID *)sp->matcopy, false); if (properties) { IDP_FreeProperty(properties); MEM_freeN(properties); } - MEM_freeN(sp->matcopy); + if (sp->own_id_copy) { + BKE_material_free(sp->matcopy); + MEM_freeN(sp->matcopy); + } } if (sp->texcopy) { struct IDProperty *properties; @@ -882,14 +884,16 @@ static void shader_preview_free(void *customdata) /* get rid of copied texture */ BLI_remlink(&pr_main->tex, sp->texcopy); - BKE_texture_free(sp->texcopy); properties = IDP_GetProperties((ID *)sp->texcopy, false); if (properties) { IDP_FreeProperty(properties); MEM_freeN(properties); } - MEM_freeN(sp->texcopy); + if (sp->own_id_copy) { + BKE_texture_free(sp->texcopy); + MEM_freeN(sp->texcopy); + } } if (sp->worldcopy) { struct IDProperty *properties; @@ -898,14 +902,16 @@ static void shader_preview_free(void *customdata) /* get rid of copied world */ BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free(sp->worldcopy); properties = IDP_GetProperties((ID *)sp->worldcopy, false); if (properties) { IDP_FreeProperty(properties); MEM_freeN(properties); } - MEM_freeN(sp->worldcopy); + if (sp->own_id_copy) { + BKE_world_free(sp->worldcopy); + MEM_freeN(sp->worldcopy); + } } if (sp->lampcopy) { struct IDProperty *properties; @@ -914,14 +920,16 @@ static void shader_preview_free(void *customdata) /* get rid of copied lamp */ BLI_remlink(&pr_main->lamp, sp->lampcopy); - BKE_lamp_free(sp->lampcopy); properties = IDP_GetProperties((ID *)sp->lampcopy, false); if (properties) { IDP_FreeProperty(properties); MEM_freeN(properties); } - MEM_freeN(sp->lampcopy); + if (sp->own_id_copy) { + BKE_lamp_free(sp->lampcopy); + MEM_freeN(sp->lampcopy); + } } MEM_freeN(sp); @@ -1139,6 +1147,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short sp->id = ip->id; sp->id_copy = ip->id_copy; sp->bmain = ip->bmain; + sp->own_id_copy = false; if (is_render) { BLI_assert(ip->id); @@ -1183,6 +1192,15 @@ static void icon_preview_endjob(void *customdata) #endif } + if (ip->id_copy) { + /* Feels a bit hacky just to reuse shader_preview_free() */ + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); + sp->id_copy = ip->id_copy; + sp->own_id_copy = true; + shader_preview_free(sp); + ip->id_copy = NULL; + } + if (ip->owner) { PreviewImage *prv_img = ip->owner; prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING; @@ -1298,6 +1316,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->pr_method = method; sp->id = id; sp->id_copy = duplicate_ids(id, sp->depsgraph); + sp->own_id_copy = true; sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); -- cgit v1.2.3 From 33c4ffdf46844e90a11896c0ff160dc4e01a6fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 21:31:36 +0200 Subject: Render Preview: Fix memory leak --- source/blender/editors/render/render_preview.c | 100 +++++++------------------ 1 file changed, 27 insertions(+), 73 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 7459868d835..daff5eee4c0 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -838,7 +838,34 @@ static void shader_preview_free(void *customdata) ShaderPreview *sp = customdata; Main *pr_main = sp->pr_main; + if (sp->matcopy) { + sp->id_copy = (ID *)sp->matcopy; + BLI_remlink(&pr_main->mat, sp->matcopy); + } + if (sp->texcopy) { + sp->id_copy = (ID *)sp->texcopy; + BLI_remlink(&pr_main->tex, sp->texcopy); + } + if (sp->worldcopy) { + sp->id_copy = (ID *)sp->worldcopy; + BLI_remlink(&pr_main->world, sp->worldcopy); + } + if (sp->lampcopy) { + sp->id_copy = (ID *)sp->lampcopy; + BLI_remlink(&pr_main->lamp, sp->lampcopy); + } + if (sp->id_copy) { + /* node previews */ + shader_preview_updatejob(sp); + } if (sp->id_copy && sp->own_id_copy) { + struct IDProperty *properties; + /* get rid of copied ID */ + properties = IDP_GetProperties(sp->id_copy, false); + if (properties) { + IDP_FreeProperty(properties); + MEM_freeN(properties); + } switch (GS(sp->id_copy->name)) { case ID_MA: BKE_material_free((Material *)sp->id_copy); @@ -858,79 +885,6 @@ static void shader_preview_free(void *customdata) } MEM_freeN(sp->id_copy); } - if (sp->matcopy) { - struct IDProperty *properties; - - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied material */ - BLI_remlink(&pr_main->mat, sp->matcopy); - - properties = IDP_GetProperties((ID *)sp->matcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - if (sp->own_id_copy) { - BKE_material_free(sp->matcopy); - MEM_freeN(sp->matcopy); - } - } - if (sp->texcopy) { - struct IDProperty *properties; - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied texture */ - BLI_remlink(&pr_main->tex, sp->texcopy); - - properties = IDP_GetProperties((ID *)sp->texcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - if (sp->own_id_copy) { - BKE_texture_free(sp->texcopy); - MEM_freeN(sp->texcopy); - } - } - if (sp->worldcopy) { - struct IDProperty *properties; - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied world */ - BLI_remlink(&pr_main->world, sp->worldcopy); - - properties = IDP_GetProperties((ID *)sp->worldcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - if (sp->own_id_copy) { - BKE_world_free(sp->worldcopy); - MEM_freeN(sp->worldcopy); - } - } - if (sp->lampcopy) { - struct IDProperty *properties; - /* node previews */ - shader_preview_updatejob(sp); - - /* get rid of copied lamp */ - BLI_remlink(&pr_main->lamp, sp->lampcopy); - - properties = IDP_GetProperties((ID *)sp->lampcopy, false); - if (properties) { - IDP_FreeProperty(properties); - MEM_freeN(properties); - } - if (sp->own_id_copy) { - BKE_lamp_free(sp->lampcopy); - MEM_freeN(sp->lampcopy); - } - } MEM_freeN(sp); } -- cgit v1.2.3 From eae9228a4d6b359d082324dd2b0f39116754bf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 21:54:48 +0200 Subject: Eevee: Lamps: Fix RNA defaults and change defaults for contact shadows --- source/blender/blenkernel/intern/lamp.c | 4 ++-- source/blender/blenloader/intern/versioning_280.c | 4 ++-- source/blender/makesrna/intern/rna_lamp.c | 24 ++++++++++++++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 1d5b6de22f4..2c1b36d3496 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -84,10 +84,10 @@ void BKE_lamp_init(Lamp *la) la->cascade_count = 4; la->cascade_exponent = 0.8f; la->cascade_fade = 0.1f; - la->contact_dist = 1.0f; + la->contact_dist = 0.2f; la->contact_bias = 0.03f; la->contact_spread = 0.2f; - la->contact_thickness = 0.5f; + la->contact_thickness = 0.2f; la->spec_fac = 1.0f; curvemapping_initialize(la->curfalloff); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index d1ed166ba89..09a940436ef 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -804,10 +804,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "contact_dist")) { for (Lamp *la = bmain->lamp.first; la; la = la->id.next) { - la->contact_dist = 1.0f; + la->contact_dist = 0.2f; la->contact_bias = 0.03f; la->contact_spread = 0.2f; - la->contact_thickness = 0.5f; + la->contact_thickness = 0.2f; } } diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 573540ee641..126c5e82206 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -124,6 +124,7 @@ static void rna_def_light(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + static float default_color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; srna = RNA_def_struct(brna, "Light", "ID"); RNA_def_struct_sdna(srna, "Lamp"); @@ -146,6 +147,7 @@ static void rna_def_light(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Light_draw_update"); prop = RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 10.0f); RNA_def_property_ui_range(prop, 0, 10, 1, 3); RNA_def_property_ui_text(prop, "Energy", "Amount of light emitted"); RNA_def_property_update(prop, 0, "rna_Light_draw_update"); @@ -153,11 +155,13 @@ static void rna_def_light(BlenderRNA *brna) prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "r"); RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, default_color); RNA_def_property_ui_text(prop, "Color", "Light color"); RNA_def_property_update(prop, 0, "rna_Light_draw_update"); prop = RNA_def_property(srna, "specular_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spec_fac"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01, 2); RNA_def_property_ui_text(prop, "Specular Factor", "Specular reflection multiplier"); @@ -256,6 +260,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "shadow_buffer_clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); + RNA_def_property_float_default(prop, 0.5f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_text(prop, "Shadow Buffer Clip Start", "Shadow map clip start, below which objects will not generate shadows"); @@ -263,6 +268,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "shadow_buffer_clip_end", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipend"); + RNA_def_property_float_default(prop, 40.0f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_text(prop, "Shadow Buffer Clip End", "Shadow map clip end, beyond which objects will not generate shadows"); @@ -270,6 +276,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "shadow_buffer_bias", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bias"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.001f, 9999.0f); RNA_def_property_ui_range(prop, 0.001f, 5.0f, 1.0, 3); RNA_def_property_ui_text(prop, "Shadow Buffer Bias", "Bias for reducing self shadowing"); @@ -283,12 +290,14 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "shadow_buffer_exp", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "bleedexp"); + RNA_def_property_float_default(prop, 2.5f); RNA_def_property_range(prop, 1.0f, 9999.0f); RNA_def_property_ui_text(prop, "Shadow Buffer Exponent", "Bias for reducing light-bleed on exponential shadow maps"); RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "shadow_buffer_soft", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "soft"); + RNA_def_property_float_default(prop, 3.0f); RNA_def_property_range(prop, 0.0f, 100.0f); RNA_def_property_ui_text(prop, "Shadow Buffer Soft", "Size of shadow buffer sampling area"); RNA_def_property_update(prop, 0, "rna_Light_update"); @@ -307,6 +316,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_float_default(prop, 0.25f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Shadow Soft Size", "Light size for ray shadow sampling (Raytraced shadows)"); @@ -322,6 +332,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "contact_shadow_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "contact_dist"); + RNA_def_property_float_default(prop, 0.2f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_text(prop, "Contact Shadow Distance", "World space distance in which to search for " "screen space occluder"); @@ -329,6 +340,7 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "contact_shadow_bias", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "contact_bias"); + RNA_def_property_float_default(prop, 0.03f); RNA_def_property_range(prop, 0.001f, 9999.0f); RNA_def_property_ui_range(prop, 0.001f, 5.0f, 1.0, 3); RNA_def_property_ui_text(prop, "Contact Shadow Bias", "Bias to avoid self shadowing"); @@ -336,12 +348,14 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) prop = RNA_def_property(srna, "contact_shadow_soft_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "contact_spread"); + RNA_def_property_float_default(prop, 0.2f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_text(prop, "Contact Shadow Soft", "Control how soft the contact shadows will be"); RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "contact_shadow_thickness", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "contact_thickness"); + RNA_def_property_float_default(prop, 0.2f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Contact Shadow Thickness", "Pixel thickness used to detect occlusion"); @@ -350,24 +364,28 @@ static void rna_def_light_shadow(StructRNA *srna, int sun) if (sun) { prop = RNA_def_property(srna, "shadow_cascade_max_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "cascade_max_dist"); + RNA_def_property_float_default(prop, 1000.0f); RNA_def_property_range(prop, 0.0f, 9999.0f); RNA_def_property_ui_text(prop, "Cascade Max Distance", "End distance of the cascaded shadow map (only in perspective view)"); RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "shadow_cascade_count", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "cascade_count"); + RNA_def_property_int_default(prop, 4); RNA_def_property_range(prop, 1, 4); RNA_def_property_ui_text(prop, "Cascade Count", "Number of texture used by the cascaded shadow map"); RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "shadow_cascade_exponent", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "cascade_exponent"); + RNA_def_property_float_default(prop, 0.8f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Exponential Distribution", "Higher value increase resolution towards the viewpoint"); RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "shadow_cascade_fade", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "cascade_fade"); + RNA_def_property_float_default(prop, 0.1f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Cascade Fade", "How smooth is the transition between each cascade"); RNA_def_property_update(prop, 0, "rna_Light_update"); @@ -416,14 +434,16 @@ static void rna_def_area_light(BlenderRNA *brna) prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_float_default(prop, 0.25f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size", "Size of the area of the area light, X direction size for rectangle shapes"); RNA_def_property_update(prop, 0, "rna_Light_draw_update"); prop = RNA_def_property(srna, "size_y", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_float_sdna(prop, NULL, "area_sizey"); + RNA_def_property_float_default(prop, 0.25f); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text(prop, "Size Y", "Size of the area of the area light in the Y direction for rectangle shapes"); @@ -450,12 +470,14 @@ static void rna_def_spot_light(BlenderRNA *brna) prop = RNA_def_property(srna, "spot_blend", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spotblend"); + RNA_def_property_float_default(prop, 0.15f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Spot Blend", "The softness of the spotlight edge"); RNA_def_property_update(prop, 0, "rna_Light_draw_update"); prop = RNA_def_property(srna, "spot_size", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "spotsize"); + RNA_def_property_float_default(prop, DEG2RADF(45.0f)); RNA_def_property_range(prop, DEG2RADF(1.0f), DEG2RADF(180.0f)); RNA_def_property_ui_text(prop, "Spot Size", "Angle of the spotlight beam"); RNA_def_property_update(prop, 0, "rna_Light_draw_update"); -- cgit v1.2.3 From 3005c2e2be3d0711649e4dd10697fc43ca88f50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 22:22:30 +0200 Subject: Eevee: LightProbes: Fix RNA defaults and remove unused data_draw_size --- .../scripts/startup/bl_ui/properties_data_lightprobe.py | 7 ++----- source/blender/blenkernel/intern/lightprobe.c | 1 - source/blender/draw/modes/object_mode.c | 6 +++--- source/blender/makesdna/DNA_lightprobe_types.h | 4 +--- source/blender/makesrna/intern/rna_lightprobe.c | 17 ++++++++++++----- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_lightprobe.py b/release/scripts/startup/bl_ui/properties_data_lightprobe.py index 10b66dd0033..5924a796b65 100644 --- a/release/scripts/startup/bl_ui/properties_data_lightprobe.py +++ b/release/scripts/startup/bl_ui/properties_data_lightprobe.py @@ -155,12 +155,9 @@ class DATA_PT_lightprobe_display(DataButtonsPanel, Panel): col = layout.column() - if probe.type != 'PLANAR': - col.prop(probe, "data_draw_size", text="Size") - else: + if probe.type == 'PLANAR': col.prop(ob, "empty_draw_size", text="Arrow Size") - - col.prop(probe, "show_data") + col.prop(probe, "show_data") if probe.type in {'GRID', 'CUBEMAP'}: col.prop(probe, "show_influence") diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c index 057b6aaaf65..baf0cdbe62f 100644 --- a/source/blender/blenkernel/intern/lightprobe.c +++ b/source/blender/blenkernel/intern/lightprobe.c @@ -53,7 +53,6 @@ void BKE_lightprobe_init(LightProbe *probe) probe->vis_bias = 1.0f; probe->vis_blur = 0.2f; probe->intensity = 1.0f; - probe->data_draw_size = 1.0f; probe->flag = LIGHTPROBE_FLAG_SHOW_INFLUENCE | LIGHTPROBE_FLAG_SHOW_DATA; } diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index dc499987c8a..9e9785f5e5c 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1906,9 +1906,9 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl DRW_shgroup_call_procedural_points_add(grp, prb_data->cell_count, NULL); } else if (prb->type == LIGHTPROBE_TYPE_CUBE) { - prb_data->draw_size = prb->data_draw_size * 0.1f; - unit_m4(prb_data->probe_cube_mat); - copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); + // prb_data->draw_size = prb->data_draw_size * 0.1f; + // unit_m4(prb_data->probe_cube_mat); + // copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id); /* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose diff --git a/source/blender/makesdna/DNA_lightprobe_types.h b/source/blender/makesdna/DNA_lightprobe_types.h index 81286e5e4d0..490e2574a33 100644 --- a/source/blender/makesdna/DNA_lightprobe_types.h +++ b/source/blender/makesdna/DNA_lightprobe_types.h @@ -68,11 +68,9 @@ typedef struct LightProbe { struct Image *image; /* Image to use on as lighting data */ struct Collection *visibility_grp; /* Object visibility group, inclusive or exclusive */ - float data_draw_size; - /* Runtime display data */ float distfalloff, distgridinf; - float pad; + float pad[2]; } LightProbe; /* Probe->type */ diff --git a/source/blender/makesrna/intern/rna_lightprobe.c b/source/blender/makesrna/intern/rna_lightprobe.c index a14699691a6..f54c01fab8e 100644 --- a/source/blender/makesrna/intern/rna_lightprobe.c +++ b/source/blender/makesrna/intern/rna_lightprobe.c @@ -83,6 +83,7 @@ static void rna_def_lightprobe(BlenderRNA *brna) prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); + RNA_def_property_float_default(prop, 0.8f); RNA_def_property_range(prop, 1e-6f, FLT_MAX); RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); RNA_def_property_ui_text(prop, "Clip Start", @@ -91,6 +92,7 @@ static void rna_def_lightprobe(BlenderRNA *brna) prop = RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipend"); + RNA_def_property_float_default(prop, 40.0f); RNA_def_property_range(prop, 1e-6f, FLT_MAX); RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); RNA_def_property_ui_text(prop, "Clip End", @@ -115,11 +117,13 @@ static void rna_def_lightprobe(BlenderRNA *brna) prop = RNA_def_property(srna, "influence_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "distinf"); + RNA_def_property_float_default(prop, 2.5f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_text(prop, "Influence Distance", "Influence distance of the probe"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 0.2f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Falloff", "Control how fast the probe influence decreases"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); @@ -141,6 +145,7 @@ static void rna_def_lightprobe(BlenderRNA *brna) prop = RNA_def_property(srna, "parallax_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "distpar"); + RNA_def_property_float_default(prop, 2.5f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_text(prop, "Parallax Radius", "Lowest corner of the parallax bounding box"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); @@ -148,21 +153,25 @@ static void rna_def_lightprobe(BlenderRNA *brna) /* irradiance grid */ prop = RNA_def_property(srna, "grid_resolution_x", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, 256); + RNA_def_property_int_default(prop, 4); RNA_def_property_ui_text(prop, "Resolution X", "Number of sample along the x axis of the volume"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc"); prop = RNA_def_property(srna, "grid_resolution_y", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, 256); + RNA_def_property_int_default(prop, 4); RNA_def_property_ui_text(prop, "Resolution Y", "Number of sample along the y axis of the volume"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc"); prop = RNA_def_property(srna, "grid_resolution_z", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, 256); + RNA_def_property_int_default(prop, 4); RNA_def_property_ui_text(prop, "Resolution Z", "Number of sample along the z axis of the volume"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc"); prop = RNA_def_property(srna, "visibility_buffer_bias", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vis_bias"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.001f, 9999.0f); RNA_def_property_ui_range(prop, 0.001f, 5.0f, 1.0, 3); RNA_def_property_ui_text(prop, "Visibility Bias", "Bias for reducing self shadowing"); @@ -170,18 +179,21 @@ static void rna_def_lightprobe(BlenderRNA *brna) prop = RNA_def_property(srna, "visibility_bleed_bias", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vis_bleedbias"); + RNA_def_property_float_default(prop, 0.0f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Visibility Bleed Bias", "Bias for reducing light-bleed on variance shadow maps"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); prop = RNA_def_property(srna, "visibility_blur", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vis_blur"); + RNA_def_property_float_default(prop, 0.2f); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Visibility Blur", "Filter size of the visibilty blur"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc"); prop = RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "intensity"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0.0f, 3.0f, 1.0, 3); RNA_def_property_ui_text(prop, "Intensity", "Modify the intensity of the lighting captured by this probe"); @@ -206,11 +218,6 @@ static void rna_def_lightprobe(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Data", "Show captured lighting data into the 3D view for debuging purpose"); RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); - prop = RNA_def_property(srna, "data_draw_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.05f, 10.0f); - RNA_def_property_ui_text(prop, "Data Draw Size", "Size of the spheres to debug captured light"); - RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, NULL); - /* common */ rna_def_animdata_common(srna); } -- cgit v1.2.3 From a1689fb091a9e57336d2ac9a013a44d804cd29ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 20 Jul 2018 22:43:30 +0200 Subject: Eevee: Fix wrong SSR reprojection when switching orthographic view We just reset the temporal sampling and avoid using the previous frame for SSR at all. --- source/blender/draw/engines/eevee/eevee_private.h | 2 ++ source/blender/draw/engines/eevee/eevee_screen_raytrace.c | 8 ++++++++ source/blender/draw/engines/eevee/eevee_temporal_sampling.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 6ef24d03df8..5aa331a9b99 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -515,6 +515,7 @@ typedef struct EEVEE_EffectsInfo { int volume_current_sample; /* SSR */ bool reflection_trace_full; + bool ssr_was_persp; int ssr_neighbor_ofs; int ssr_halfres_ofs[2]; struct GPUTexture *ssr_normal_input; /* Textures from pool */ @@ -908,6 +909,7 @@ void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat void EEVEE_mist_free(void); /* eevee_temporal_sampling.c */ +void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata); int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_temporal_sampling_matrices_calc( EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2]); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 204b730f8da..b882db174b0 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -132,6 +132,14 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) }); } + const bool is_persp = DRW_viewport_is_persp_get(); + if (effects->ssr_was_persp != is_persp) { + effects->ssr_was_persp = is_persp; + DRW_viewport_request_redraw(); + EEVEE_temporal_sampling_reset(vedata); + stl->g_data->valid_double_buffer = false; + } + effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0; common_data->ssr_thickness = scene_eval->eevee.ssr_thickness; common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade; diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 7cd76669fe4..76e11e02d26 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -174,6 +174,11 @@ void EEVEE_temporal_sampling_matrices_calc( invert_m4_m4(effects->overide_wininv, effects->overide_winmat); } +void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata) +{ + vedata->stl->effects->taa_render_sample = 1; +} + int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_StorageList *stl = vedata->stl; -- cgit v1.2.3 From e361e9e99c5b6140b6284e81fa315bdcc48cee58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sat, 21 Jul 2018 14:16:29 +0200 Subject: Render Preview: Fix ID freeing in wrong function --- source/blender/editors/render/render_preview.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index daff5eee4c0..3423eedf7ca 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1146,15 +1146,6 @@ static void icon_preview_endjob(void *customdata) #endif } - if (ip->id_copy) { - /* Feels a bit hacky just to reuse shader_preview_free() */ - ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); - sp->id_copy = ip->id_copy; - sp->own_id_copy = true; - shader_preview_free(sp); - ip->id_copy = NULL; - } - if (ip->owner) { PreviewImage *prv_img = ip->owner; prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING; @@ -1169,6 +1160,15 @@ static void icon_preview_free(void *customdata) { IconPreview *ip = (IconPreview *)customdata; + if (ip->id_copy) { + /* Feels a bit hacky just to reuse shader_preview_free() */ + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); + sp->id_copy = ip->id_copy; + sp->own_id_copy = true; + shader_preview_free(sp); + ip->id_copy = NULL; + } + BLI_freelistN(&ip->sizes); MEM_freeN(ip); } -- cgit v1.2.3 From f07140940c4ef5c062fbf1c2f7d3743b3d1fd29e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sat, 21 Jul 2018 18:15:31 +0200 Subject: Eevee: Principled: Fix Subsurface input behaviour Match Cycles behaviour of scalling the SSS radius and don't interpolate between diffuse and SSS result. --- source/blender/gpu/shaders/gpu_shader_material.glsl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 961837f6b16..464851bae21 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1145,15 +1145,18 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs clearcoat *= 0.25; clearcoat *= 1.0 - transmission; + vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); + #ifdef USE_SSS - diffuse = mix(diffuse, vec3(0.0), subsurface); + diffuse = vec3(0.0); #else - diffuse = mix(diffuse, subsurface_color.rgb, subsurface); + diffuse = mixed_ss_base_color; #endif + f0 = mix(f0, vec3(1.0), transmission); - float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)); - eevee_closure_principled(N, diffuse, f0, int(ssr_id), roughness, + float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + eevee_closure_principled(N, mixed_ss_base_color, f0, int(ssr_id), roughness, CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior, out_diff, out_trans, out_spec, out_refr, ssr_spec); @@ -1177,11 +1180,11 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs #ifdef USE_SSS result.sss_data.a = sss_scalef; result.sss_data.rgb = out_diff + out_trans; -#ifdef USE_SSS_ALBEDO - result.sss_albedo.rgb = mix(vec3(0.0), subsurface_color.rgb, subsurface); -#else - result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface); -#endif +# ifdef USE_SSS_ALBEDO + result.sss_albedo.rgb = mixed_ss_base_color; +# else + result.sss_data.rgb *= mixed_ss_base_color; +# endif result.sss_data.rgb *= (1.0 - transmission); #endif } -- cgit v1.2.3 From 7232b0cbe51865653fdb3ea6b968345dd8fbc525 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Sun, 22 Jul 2018 16:02:28 -0600 Subject: make.bat : fix typo pointed out by anchpop on irc. --- build_files/windows/autodetect_msvc.cmd | 2 +- build_files/windows/check_libraries.cmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_files/windows/autodetect_msvc.cmd b/build_files/windows/autodetect_msvc.cmd index 77dc005cd18..4dbe009a890 100644 --- a/build_files/windows/autodetect_msvc.cmd +++ b/build_files/windows/autodetect_msvc.cmd @@ -10,5 +10,5 @@ echo Compiler Detection failed. Use verbose switch for more information. exit /b 1 :DetectionComplete -echo Compiler Detection successfull, detected VS%BUILD_VS_YEAR% +echo Compiler Detection successful, detected VS%BUILD_VS_YEAR% exit /b 0 \ No newline at end of file diff --git a/build_files/windows/check_libraries.cmd b/build_files/windows/check_libraries.cmd index 6ad1d1749c3..90c50293720 100644 --- a/build_files/windows/check_libraries.cmd +++ b/build_files/windows/check_libraries.cmd @@ -36,7 +36,7 @@ if NOT EXIST %BUILD_VS_LIBDIR% ( echo. echo Error: Download of external libraries failed. echo This is needed for building, please manually run 'svn cleanup' and 'svn update' in - echo %BUILD_VS_LIBDIR% , until this is resolved you CANNOT make a successfull blender build + echo %BUILD_VS_LIBDIR% , until this is resolved you CANNOT make a successful blender build echo. exit /b 1 ) -- cgit v1.2.3 From d432a239adee7e04b264303ec7e3ef6ffc8ce403 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Mon, 23 Jul 2018 11:20:31 +0200 Subject: Outliner Keymap: E key to Exclude collections from View Layer Alt+E to include. --- source/blender/editors/space_outliner/outliner_ops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 0dd492839c9..8b4ae029876 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -570,6 +570,9 @@ void outliner_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "OUTLINER_OT_collection_include_set", EKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "select", false); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); -- cgit v1.2.3 From 96abec41ccf0a58b085095640faadf36c5d9ed9a Mon Sep 17 00:00:00 2001 From: Ines Almeida Date: Sun, 27 May 2018 10:33:34 +0200 Subject: Cleanup: comments and UI descriptions for cursor snapping --- source/blender/editors/space_view3d/view3d_snap.c | 58 +++++++++++++++-------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7799854db49..6a8589f5468 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -72,6 +72,7 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r /* *********************** operators ******************** */ +/** Snaps every individual object center to its nearest point on the grid. **/ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -212,7 +213,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Grid"; - ot->description = "Snap selected item(s) to nearest grid division"; + ot->description = "Snap selected item(s) to their nearest grid division"; ot->idname = "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ @@ -225,6 +226,12 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* *************************************************** */ +/** Snaps the selection as a whole (use_offset=true) or each selected object to the given location. + * + * \param snap_target_global: a location in global space to snap to (eg. 3D cursor or active object). + * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection + * pivot point (median, active), or if every object origin should be snapped to the given location. +**/ static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -434,7 +441,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Cursor"; - ot->description = "Snap selected item(s) to cursor"; + ot->description = "Snap selected item(s) to the 3D cursor"; ot->idname = "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ @@ -445,9 +452,13 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* rna */ - RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", ""); + RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", + "If the selection should be snapped as a whole or by each object center"); } +/* *************************************************** */ + +/** Snaps each selected object to the location of the active selected object. **/ static int snap_selected_to_active_exec(bContext *C, wmOperator *op) { float snap_target_global[3]; @@ -478,6 +489,7 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot) /* *************************************************** */ +/** Snaps the 3D cursor location to its nearest point on the grid. **/ static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -502,7 +514,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Grid"; - ot->description = "Snap cursor to nearest grid division"; + ot->description = "Snap 3D cursor to the nearest grid division"; ot->idname = "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ @@ -515,7 +527,8 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* **************************************************** */ -static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float vec[3]) +/** Returns the center position of a tracking marker visible on the viewport (useful to snap to). **/ +static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_vec[3]) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); MovieTracking *tracking; @@ -563,10 +576,11 @@ static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, floa } if (ok) { - mid_v3_v3v3(vec, min, max); + mid_v3_v3v3(r_vec, min, max); } } +/** Snaps the 3D cursor location to the median point of the selection. **/ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) { Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -690,7 +704,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Selected"; - ot->description = "Snap cursor to center of selected item(s)"; + ot->description = "Snap 3D cursor to the middle of the selected item(s)"; ot->idname = "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ @@ -703,9 +717,11 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* ********************************************** */ -/* this could be exported to be a generic function - * see: calculateCenterActive */ - +/** Calculates the center position of the active object in global space. + * + * Note: this could be exported to be a generic function. + * see: calculateCenterActive +**/ static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]) { const Depsgraph *depsgraph = CTX_data_depsgraph(C); @@ -770,7 +786,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Active"; - ot->description = "Snap cursor to active item"; + ot->description = "Snap 3D cursor to the active item"; ot->idname = "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ @@ -782,7 +798,8 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) } /* **************************************************** */ -/*New Code - Snap Cursor to Center -*/ + +/** Snaps the 3D cursor location to the origin. **/ static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -802,7 +819,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Center"; - ot->description = "Snap cursor to world origin"; + ot->description = "Snap 3D cursor to the world origin"; ot->idname = "VIEW3D_OT_snap_cursor_to_center"; /* api callbacks */ @@ -815,23 +832,22 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) /* **************************************************** */ - -bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) +/** Calculates the bounding box corners (min and max) for \a obedit. The returned values are in global space. **/ +bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3]) { TransVertStore tvs = {NULL}; TransVert *tv; float centroid[3], vec[3], bmat[3][3]; - int a; - /* metaballs are an exception */ + /* Metaballs are an exception. */ if (obedit->type == OB_MBALL) { float ob_min[3], ob_max[3]; bool changed; changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT); if (changed) { - minmax_v3v3_v3(min, max, ob_min); - minmax_v3v3_v3(min, max, ob_max); + minmax_v3v3_v3(r_min, r_max, ob_min); + minmax_v3v3_v3(r_min, r_max, ob_max); } return changed; } @@ -845,12 +861,12 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) copy_m3_m4(bmat, obedit->obmat); tv = tvs.transverts; - for (a = 0; a < tvs.transverts_tot; a++, tv++) { + for (int a = 0; a < tvs.transverts_tot; a++, tv++) { copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc); mul_m3_v3(bmat, vec); add_v3_v3(vec, obedit->obmat[3]); add_v3_v3(centroid, vec); - minmax_v3v3_v3(min, max, vec); + minmax_v3v3_v3(r_min, r_max, vec); } ED_transverts_free(&tvs); -- cgit v1.2.3 From f0dd7dd4c01d2c1b2c4d9a6cbec9bfab1566b795 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Jul 2018 11:42:44 +0200 Subject: Mark view layer renderability and scene single layer render as non-animatable We can not support animation of those flags reliably in the pipeline, so just mark them as non-animatable. --- source/blender/makesrna/intern/rna_scene.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 339d3841b30..dd08be4c943 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -4255,6 +4255,7 @@ static void rna_def_scene_render_view(BlenderRNA *brna) prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "viewflag", SCE_VIEW_DISABLE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the render view"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); } @@ -5412,6 +5413,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_single_layer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_SINGLE_LAYER); RNA_def_property_ui_text(prop, "Render Single Layer", "Only render the active layer"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); /* views (stereoscopy et al) */ -- cgit v1.2.3 From d7b472c19898a04a4b90da45d2749872ef56bd88 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Jul 2018 11:47:06 +0200 Subject: Fix wrong view layer rendered from command line The issue was caused by Render Single Layer option enabled, which is very handy for artists work, so they can hit F12 and see view layer they are currently working in a final rendered state. This saves a lot of time since all the "non-interesting" objects are ignored for such iterations. However, for the render farm we need to render view layers which are explicitly set for render, and ignore active view layer. Reasonable solution seems to be to ignore the Render Single Layer option when rendering from the command line. It is really something more like UI behavior option. --- source/blender/makesrna/intern/rna_scene.c | 2 +- source/blender/render/intern/include/render_result.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index dd08be4c943..b44a53fa90b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5412,7 +5412,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "use_single_layer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_SINGLE_LAYER); - RNA_def_property_ui_text(prop, "Render Single Layer", "Only render the active layer"); + RNA_def_property_ui_text(prop, "Render Single Layer", "Only render the active layer. Only affects rendering from the interface, ignored for rendering from command line"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h index 3096949b49f..ab7eee128f0 100644 --- a/source/blender/render/intern/include/render_result.h +++ b/source/blender/render/intern/include/render_result.h @@ -123,7 +123,7 @@ bool render_result_has_views(struct RenderResult *rr); iter_ != NULL; \ iter_ = iter_->next, nr_++) \ { \ - if ((re_)->r.scemode & R_SINGLE_LAYER) { \ + if (!G.background && (re_)->r.scemode & R_SINGLE_LAYER) { \ if (nr_ != re->active_view_layer) { \ continue; \ } \ -- cgit v1.2.3 From 66fde2d0b57f2597d38545937640bad8b6f7ed30 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Jul 2018 12:53:46 +0200 Subject: Fix T55634: Particle Viewport Display affects render visibilty Changed code to follow master behavior closer: ignore draw-as checks when particles are evaluating for rendering. --- source/blender/blenkernel/intern/particle_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 35c8761f671..cee1c9147b5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2941,7 +2941,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons skip = 1; /* only hair, keyed and baked stuff can have paths */ else if (part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))) skip = 1; /* particle visualization must be set as path */ - else { + else if (DEG_get_mode(sim->depsgraph) != DAG_EVAL_RENDER) { if (part->draw_as != PART_DRAW_REND) skip = 1; /* draw visualization */ else if (psys->pointcache->flag & PTCACHE_BAKING) -- cgit v1.2.3 From 5a05aff73a922f0fdb1a2ea4edb8d139f4ff8d98 Mon Sep 17 00:00:00 2001 From: Ines Almeida Date: Mon, 23 Jul 2018 13:15:20 +0200 Subject: UI: more descriptive tooltip --- release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index a2ccfb4f1b8..55b798d103a 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -728,7 +728,7 @@ class GPENCIL_MT_snap(Menu): layout.operator("gpencil.snap_to_grid", text="Selection to Grid") layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False - layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True + layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e8c640721c8..6874055a58f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -453,7 +453,7 @@ class VIEW3D_MT_snap(Menu): layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid") layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False - layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True + layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True layout.operator("view3d.snap_selected_to_active", text="Selection to Active") layout.separator() -- cgit v1.2.3 From 01f5601fe5aee395676ecc743c1b8a48b366f404 Mon Sep 17 00:00:00 2001 From: Milan Jaros Date: Mon, 23 Jul 2018 14:20:06 +0200 Subject: Fix build for Intel compiler with C++11. --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da333286478..4de98860a61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1615,7 +1615,11 @@ if(WITH_PYTHON) endif() if(WITH_CXX11) - if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if( + CMAKE_COMPILER_IS_GNUCC OR + CMAKE_C_COMPILER_ID MATCHES "Clang" OR + CMAKE_C_COMPILER_ID MATCHES "Intel" + ) # TODO(sergey): Do we want c++11 or gnu-c++11 here? set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") elseif(MSVC) -- cgit v1.2.3 From 59286ddcf80c391094d64dcbbb94640bf73bd0d9 Mon Sep 17 00:00:00 2001 From: Germano Date: Mon, 23 Jul 2018 11:04:58 -0300 Subject: transform_snap_object: Better bvhtree creation management for editing multiple objects. - Use the object referenced in `BMEditMesh` as the `ghash` key to save the bvhtrees in cache; - Create a boundbox around edit_mesh to test the snap before creating bvhtree; - Save the `edit_mesh`s bvhtree in the mesh bvh_cache; This is a part of the D3504. --- source/blender/blenkernel/BKE_bvhutils.h | 8 +- source/blender/blenkernel/intern/bvhutils.c | 79 +++++++++-- .../editors/transform/transform_snap_object.c | 149 ++++++++++++++++++--- 3 files changed, 203 insertions(+), 33 deletions(-) diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index d79a7eae53e..a0780a5be54 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -102,7 +102,7 @@ typedef struct BVHTreeFromMesh { */ BVHTree *bvhtree_from_editmesh_verts( BVHTreeFromEditMesh *data, struct BMEditMesh *em, - float epsilon, int tree_type, int axis); + float epsilon, int tree_type, int axis, BVHCache **bvh_cache); BVHTree *bvhtree_from_editmesh_verts_ex( BVHTreeFromEditMesh *data, struct BMEditMesh *em, const BLI_bitmap *mask, int verts_num_active, @@ -115,7 +115,7 @@ BVHTree *bvhtree_from_mesh_verts_ex( BVHTree *bvhtree_from_editmesh_edges( BVHTreeFromEditMesh *data, struct BMEditMesh *em, - float epsilon, int tree_type, int axis); + float epsilon, int tree_type, int axis, BVHCache **bvh_cache); BVHTree *bvhtree_from_editmesh_edges_ex( BVHTreeFromEditMesh *data, struct BMEditMesh *em, const BLI_bitmap *edges_mask, int edges_num_active, @@ -190,7 +190,9 @@ enum { BVHTREE_FROM_LOOSEVERTS = 4, BVHTREE_FROM_LOOSEEDGES = 5, - BVHTREE_FROM_EM_LOOPTRI = 6, + BVHTREE_FROM_EM_VERTS = 6, + BVHTREE_FROM_EM_EDGES = 7, + BVHTREE_FROM_EM_LOOPTRI = 8, }; diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 1a7c4e2a4a0..19ac81b4bb7 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -495,12 +495,39 @@ BVHTree *bvhtree_from_editmesh_verts_ex( BVHTree *bvhtree_from_editmesh_verts( BVHTreeFromEditMesh *data, BMEditMesh *em, - float epsilon, int tree_type, int axis) + float epsilon, int tree_type, int axis, BVHCache **bvh_cache) { - return bvhtree_from_editmesh_verts_ex( - data, em, - NULL, -1, - epsilon, tree_type, axis); + if (bvh_cache) { + BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); + data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree); + BLI_rw_mutex_unlock(&cache_rwlock); + + if (data->cached == false) { + BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); + data->cached = bvhcache_find( + *bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree); + if (data->cached == false) { + data->tree = bvhtree_from_editmesh_verts_ex( + data, em, + NULL, -1, + epsilon, tree_type, axis); + + /* Save on cache for later use */ + /* printf("BVHTree built and saved on cache\n"); */ + bvhcache_insert( + bvh_cache, data->tree, BVHTREE_FROM_EM_VERTS); + } + BLI_rw_mutex_unlock(&cache_rwlock); + } + } + else { + data->tree = bvhtree_from_editmesh_verts_ex( + data, em, + NULL, -1, + epsilon, tree_type, axis); + } + + return data->tree; } /** @@ -649,12 +676,39 @@ BVHTree *bvhtree_from_editmesh_edges_ex( BVHTree *bvhtree_from_editmesh_edges( BVHTreeFromEditMesh *data, BMEditMesh *em, - float epsilon, int tree_type, int axis) + float epsilon, int tree_type, int axis, BVHCache **bvh_cache) { - return bvhtree_from_editmesh_edges_ex( - data, em, - NULL, -1, - epsilon, tree_type, axis); + if (bvh_cache) { + BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ); + data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree); + BLI_rw_mutex_unlock(&cache_rwlock); + + if (data->cached == false) { + BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE); + data->cached = bvhcache_find( + *bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree); + if (data->cached == false) { + data->tree = bvhtree_from_editmesh_edges_ex( + data, em, + NULL, -1, + epsilon, tree_type, axis); + + /* Save on cache for later use */ + /* printf("BVHTree built and saved on cache\n"); */ + bvhcache_insert( + bvh_cache, data->tree, BVHTREE_FROM_EM_EDGES); + } + BLI_rw_mutex_unlock(&cache_rwlock); + } + } + else { + data->tree = bvhtree_from_editmesh_edges_ex( + data, em, + NULL, -1, + epsilon, tree_type, axis); + } + + return data->tree; } /** @@ -1407,6 +1461,11 @@ BVHTree *BKE_bvhtree_from_mesh_get( BLI_rw_mutex_unlock(&cache_rwlock); } break; + case BVHTREE_FROM_EM_VERTS: + case BVHTREE_FROM_EM_EDGES: + case BVHTREE_FROM_EM_LOOPTRI: + BLI_assert(false); + break; } if (data_cp.tree != NULL) { diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index e19320fa220..b826e72acaf 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -111,6 +111,10 @@ typedef struct SnapObjectData_EditMesh { SnapObjectData sd; BVHTreeFromEditMesh *bvh_trees[3]; + /* It's like a boundbox. It is tested first to avoid + * to create a bvhtree for all the edited objects. */ + float min[3], max[3]; + } SnapObjectData_EditMesh; struct SnapObjectContext { @@ -156,6 +160,19 @@ struct SnapObjectContext { typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data); +static void min_max_from_bmesh( + BMesh *bm, float r_min[3], float r_max[3]) +{ + BMIter iter; + BMVert *eve; + + INIT_MINMAX(r_min, r_max); + BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) { + minmax_v3v3_v3(r_min, r_max, eve->co); + } +} + + /** * Walks through all objects in the scene to create the list of objets to snap. * @@ -170,8 +187,8 @@ static void iter_snap_objects( void *data) { ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph); - Object *obedit = params->use_object_edit_cage ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL; const eSnapSelect snap_select = params->snap_select; + const bool use_object_edit_cage = params->use_object_edit_cage; Base *base_act = view_layer->basact; for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) { @@ -179,20 +196,17 @@ static void iter_snap_objects( !((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) || (snap_select == SNAP_NOT_ACTIVE && base == base_act))) { - bool use_obedit; Object *obj = base->object; if (obj->transflag & OB_DUPLI) { DupliObject *dupli_ob; ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { - use_obedit = obedit && dupli_ob->ob->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data); + sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data); } free_object_duplilist(lb); } - use_obedit = obedit && obj->data == obedit->data; - sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data); + sob_callback(sctx, use_object_edit_cage, obj, obj->obmat, data); } } } @@ -378,7 +392,7 @@ static bool raycastMesh( BVHTreeFromMesh *treedata = &sod->treedata; - /* The tree is owned by the DM and may have been freed since we last used. */ + /* The tree is owned by the Mesh and may have been freed since we last used. */ if (treedata->tree) { BLI_assert(treedata->cached); if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) { @@ -502,14 +516,30 @@ static bool raycastEditMesh( SnapObjectData_EditMesh *sod = NULL; BVHTreeFromEditMesh *treedata = NULL; + Object *em_ob = em->ob; void **sod_p; - if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { + /* Use `em->ob` as the key in ghash since the editmesh is used + * to create bvhtree and is the same for each linked object. */ + if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) { sod = *sod_p; } else { sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); sod->sd.type = SNAP_EDIT_MESH; + min_max_from_bmesh(em->bm, sod->min, sod->max); + } + + { + float min[3], max[3]; + mul_v3_m4v3(min, obmat, sod->min); + mul_v3_m4v3(max, obmat, sod->max); + + if (!isect_ray_aabb_v3_simple( + ray_start, ray_dir, min, max, NULL, NULL)) + { + return retval; + } } if (sod->bvh_trees[2] == NULL) { @@ -517,7 +547,17 @@ static bool raycastEditMesh( } treedata = sod->bvh_trees[2]; + BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache; + + if (sctx->callbacks.edit_mesh.test_face_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata->tree)) { + free_bvhtree_from_editmesh(treedata); + } + } + if (treedata->tree == NULL) { + BVHCache **bvh_cache = NULL; BLI_bitmap *elem_mask = NULL; int looptri_num_active = -1; @@ -527,7 +567,15 @@ static bool raycastEditMesh( em->bm, elem_mask, sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data); } - bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL); + else { + /* Only cache if bvhtree is created without a mask. + * This helps keep a standardized bvhtree in cache. */ + bvh_cache = &em_bvh_cache; + } + + bvhtree_from_editmesh_looptri_ex( + treedata, em, elem_mask, looptri_num_active, + 0.0f, 4, 6, bvh_cache); if (elem_mask) { MEM_freeN(elem_mask); @@ -669,7 +717,7 @@ static bool raycastObj( switch (ob->type) { case OB_MESH: - if (use_obedit) { + if (use_obedit && BKE_object_is_in_editmode(ob)) { BMEditMesh *em = BKE_editmesh_from_object(ob); retval = raycastEditMesh( sctx, @@ -718,7 +766,7 @@ struct RaycastObjUserData { bool ret; }; -static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data) +static void raycast_obj_cb(SnapObjectContext *sctx, bool use_obedit, Object *ob, float obmat[4][4], void *data) { struct RaycastObjUserData *dt = data; @@ -726,7 +774,7 @@ static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, sctx, dt->ray_start, dt->ray_dir, ob, obmat, dt->ob_index++, - is_obedit, dt->use_occlusion_test, + use_obedit, dt->use_occlusion_test, dt->ray_depth, dt->r_loc, dt->r_no, dt->r_index, dt->r_ob, dt->r_obmat, @@ -1118,6 +1166,13 @@ static short snap_mesh_polygon( }; SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob); + if (sod == NULL) { + /* The object is in edit mode, and the key used + * was the object referenced in BMEditMesh */ + BMEditMesh *em = BKE_editmesh_from_object(ob); + sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob); + } + BLI_assert(sod != NULL); if (sod->type == SNAP_MESH) { @@ -1335,6 +1390,8 @@ static short snapArmature( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); + use_obedit = use_obedit && BKE_object_is_in_editmode(ob); + if (use_obedit == false) { /* Test BoundBox */ BoundBox *bb = BKE_armature_boundbox_get(ob); @@ -1469,6 +1526,8 @@ static short snapCurve( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval); + use_obedit = use_obedit && BKE_object_is_in_editmode(ob); + if (use_obedit == false) { /* Test BoundBox */ BoundBox *bb = BKE_curve_boundbox_get(ob); @@ -1792,7 +1851,7 @@ static short snapMesh( treedata = &sod->treedata; bvhtree = sod->bvhtree; - /* the tree is owned by the DM and may have been freed since we last used! */ + /* The tree is owned by the Mesh and may have been freed since we last used! */ if ((sod->has_looptris && treedata->tree && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) || (sod->has_loose_edge && bvhtree[0] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0])) || (sod->has_loose_vert && bvhtree[1] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1]))) @@ -1982,21 +2041,56 @@ static short snapEditMesh( SnapObjectData_EditMesh *sod = NULL; BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL; + Object *em_ob = em->ob; void **sod_p; - if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) { + /* Use `em->ob` as the key in ghash since the editmesh is used + * to create bvhtree and is the same for each linked object. */ + if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) { sod = *sod_p; } else { sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); sod->sd.type = SNAP_EDIT_MESH; + min_max_from_bmesh(em->bm, sod->min, sod->max); } + float dist_px_sq = SQUARE(*dist_px); + + { + float min[3], max[3]; + mul_v3_m4v3(min, obmat, sod->min); + mul_v3_m4v3(max, obmat, sod->max); + + /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */ + struct DistProjectedAABBPrecalc data_precalc; + dist_squared_to_projected_aabb_precalc( + &data_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval); + + bool dummy[3]; + float bb_dist_px_sq = dist_squared_to_projected_aabb( + &data_precalc, min, max, dummy); + + if (bb_dist_px_sq > dist_px_sq) { + return 0; + } + } + + BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache; + if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (sod->bvh_trees[0] == NULL) { sod->bvh_trees[0] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees)); } treedata_vert = sod->bvh_trees[0]; + + if (sctx->callbacks.edit_mesh.test_vert_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata_vert->tree)) { + free_bvhtree_from_editmesh(treedata_vert); + } + } + if (treedata_vert->tree == NULL) { BLI_bitmap *verts_mask = NULL; int verts_num_active = -1; @@ -2006,9 +2100,13 @@ static short snapEditMesh( BM_VERTS_OF_MESH, em->bm, verts_mask, (bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn, sctx->callbacks.edit_mesh.user_data); + + bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6); + MEM_freeN(verts_mask); + } + else { + bvhtree_from_editmesh_verts(treedata_vert, em, 0.0f, 2, 6, &em_bvh_cache); } - bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6); - MEM_SAFE_FREE(verts_mask); } } @@ -2017,6 +2115,14 @@ static short snapEditMesh( sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees)); } treedata_edge = sod->bvh_trees[1]; + + if (sctx->callbacks.edit_mesh.test_edge_fn == NULL) { + /* The tree is owned by the Mesh and may have been freed since we last used! */ + if (!bvhcache_has_tree(em_bvh_cache, treedata_edge->tree)) { + free_bvhtree_from_editmesh(treedata_edge); + } + } + if (treedata_edge->tree == NULL) { BLI_bitmap *edges_mask = NULL; int edges_num_active = -1; @@ -2027,9 +2133,12 @@ static short snapEditMesh( (bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn, sctx->callbacks.edit_mesh.user_data); + bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6); + MEM_freeN(edges_mask); + } + else { + bvhtree_from_editmesh_edges(treedata_edge, em, 0.0f, 2, 6, &em_bvh_cache); } - bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6); - MEM_SAFE_FREE(edges_mask); } } @@ -2043,7 +2152,7 @@ static short snapEditMesh( BVHTreeNearest nearest = { .index = -1, - .dist_sq = SQUARE(*dist_px), + .dist_sq = dist_px_sq, }; int last_index = nearest.index; short elem = SCE_SNAP_MODE_VERTEX; @@ -2119,7 +2228,7 @@ static short snapObject( switch (ob->type) { case OB_MESH: - if (use_obedit) { + if (use_obedit && BKE_object_is_in_editmode(ob)) { BMEditMesh *em = BKE_editmesh_from_object(ob); retval = snapEditMesh( sctx, snapdata, ob, em, obmat, -- cgit v1.2.3 From 17c3110ae5776bb4bfb11e240d4623ea9a80e073 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 23 Jul 2018 16:10:46 +0200 Subject: Fix large font drawing blurriness in a better way. GPU_LINEAR is there for shadow font blurring, the real issue was lack of rounding for the batch offset. --- source/blender/blenfont/intern/blf_font.c | 3 ++- source/blender/blenfont/intern/blf_glyph.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index ea81106e60f..f7a926275a9 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -133,7 +133,8 @@ void blf_batch_draw_begin(FontBLF *font) if (simple_shader) { /* Offset is applied to each glyph. */ - copy_v2_v2(g_batch.ofs, font->pos); + g_batch.ofs[0] = floorf(font->pos[0]); + g_batch.ofs[1] = floorf(font->pos[1]); } else { /* Offset is baked in modelview mat. */ diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 99be8539d24..f7f1e10a480 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -244,7 +244,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc) gc->textures[gc->texture_current] = tex; GPU_texture_bind(tex, 0); GPU_texture_wrap_mode(tex, false); - GPU_texture_filters(tex, GPU_NEAREST, GPU_NEAREST); + GPU_texture_filters(tex, GPU_NEAREST, GPU_LINEAR); GPU_texture_unbind(tex); } @@ -427,8 +427,8 @@ static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y) { rect->xmin = floorf(x + g->pos_x); rect->xmax = rect->xmin + (float)g->width; - rect->ymin = y + g->pos_y; - rect->ymax = y + g->pos_y - (float)g->height; + rect->ymin = floorf(y + g->pos_y); + rect->ymax = rect->ymin - (float)g->height; } void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y) -- cgit v1.2.3 From bb98e83b99e63348e0396a5ffe5bb2a20ff1607a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 23 Jul 2018 17:38:41 +0200 Subject: Fix T55668: Volume Keyframe on Cut-ted Metastrip. We actually still had cases of Meta strip duplication resulting in non-unique strip names. Quiet surprising this went unoticed for so long. :( Fixed that bug, and think it was last one (at least, no other case of SEQ_DUPE_UNIQUE_NAME usage should be broken, I think...), and raised subversion and updated doversion to run uniquename check on strips on all previous fileversions. Note: will have to do that again when merging in 2.8... --- source/blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/BKE_sequencer.h | 2 +- source/blender/blenkernel/intern/sequencer.c | 1 + source/blender/blenloader/intern/versioning_250.c | 18 ------------------ source/blender/blenloader/intern/versioning_270.c | 20 ++++++++++++++++++++ .../blender/editors/space_sequencer/sequencer_edit.c | 5 +++-- 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index a3da6d5016e..16115203294 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -28,7 +28,7 @@ * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 279 -#define BLENDER_SUBVERSION 5 +#define BLENDER_SUBVERSION 6 /* Several breakages with 270, e.g. constraint deg vs rad */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 6 diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 8574e81c4e6..c408597de32 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -392,7 +392,7 @@ typedef struct SeqLoadInfo { /* seq_dupli' flags */ -#define SEQ_DUPE_UNIQUE_NAME (1 << 0) +#define SEQ_DUPE_UNIQUE_NAME (1 << 0) /* WARNING: does NOT work when duplicating Meta strips! */ #define SEQ_DUPE_CONTEXT (1 << 1) #define SEQ_DUPE_ANIM (1 << 2) #define SEQ_DUPE_ALL (1 << 3) /* otherwise only selected are copied */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 14119998519..7e4069305f6 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -5517,6 +5517,7 @@ static Sequence *seq_dupli(const Scene *scene_src, Scene *scene_dst, Sequence *s if (scene_src == scene_dst) { if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) { + /* TODO this is broken in case of Meta strips recursive duplication... Not trivial to fix. */ BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn); } diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index e15d0f50948..28720ef5145 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -633,20 +633,6 @@ static void do_version_constraints_radians_degrees_250(ListBase *lb) } } -/* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already */ -static void do_versions_seq_unique_name_all_strips(Scene *sce, ListBase *seqbasep) -{ - Sequence * seq = seqbasep->first; - - while (seq) { - BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq); - if (seq->seqbase.first) { - do_versions_seq_unique_name_all_strips(sce, &seq->seqbase); - } - seq = seq->next; - } -} - static void do_version_bone_roll_256(Bone *bone) { Bone *child; @@ -1326,10 +1312,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (sce->r.mblur_samples == 0) sce->r.mblur_samples = sce->r.osa; - if (sce->ed && sce->ed->seqbase.first) { - do_versions_seq_unique_name_all_strips(sce, &sce->ed->seqbase); - } - sce = sce->id.next; } } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 20f2a747fb2..7b787725084 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -308,6 +308,18 @@ static char *replace_bbone_easing_rnapath(char *old_path) } } +/* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already. + * But in 2.79 another case generating non-unique names was discovered (see T55668, involving Meta strips)... */ +static void do_versions_seq_unique_name_all_strips(Scene *sce, ListBase *seqbasep) +{ + for (Sequence *seq = seqbasep->first; seq != NULL; seq = seq->next) { + BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq); + if (seq->seqbase.first != NULL) { + do_versions_seq_unique_name_all_strips(sce, &seq->seqbase); + } + } +} + static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id), FCurve *fcu, void *UNUSED(user_data)) { /* F-Curve's path (for bbone_in/out) */ @@ -1826,6 +1838,14 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + if (!MAIN_VERSION_ATLEAST(bmain, 279, 6)) { + for (Scene *sce = bmain->scene.first; sce != NULL; sce = sce->id.next) { + if (sce->ed != NULL && sce->ed->seqbase.first != NULL) { + do_versions_seq_unique_name_all_strips(sce, &sce->ed->seqbase); + } + } + } } void do_versions_after_linking_270(Main *bmain) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 679fb71f76b..5b8f2ae7067 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -737,7 +737,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM); } if (seqn) { @@ -846,7 +846,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) if (!skip_dup) { /* Duplicate AFTER the first change */ - seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM); + seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM); } if (seqn) { @@ -2112,6 +2112,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op) SEQP_BEGIN (ed, seq) { + BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); if (seq->seq1 || seq->seq2 || seq->seq3) { BKE_sequence_calc(scene, seq); } -- cgit v1.2.3 From 87090abb95263eb2eb830face64777a0eb3e7957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 23 Jul 2018 17:40:34 +0200 Subject: Eevee: Remove Colored volumetric option. This option is not necessary as it uses as much memory as the mono-chromatic transmistance. --- release/scripts/startup/bl_ui/properties_render.py | 2 -- source/blender/blenkernel/intern/scene.c | 1 - source/blender/blenloader/intern/versioning_280.c | 2 -- source/blender/makesdna/DNA_scene_types.h | 2 +- source/blender/makesrna/intern/rna_scene.c | 6 ------ 5 files changed, 1 insertion(+), 12 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index b1c5edf97e7..83d31ae6114 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -594,8 +594,6 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel): sub = col.column() sub.active = props.use_volumetric_shadows sub.prop(props, "volumetric_shadow_samples", text="Shadow Samples") - col.separator() - col.prop(props, "use_volumetric_colored_transmittance") class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel): diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 3650fa21c1c..0574eef1a0f 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -878,7 +878,6 @@ void BKE_scene_init(Scene *sce) sce->eevee.flag = SCE_EEVEE_VOLUMETRIC_LIGHTS | - SCE_EEVEE_VOLUMETRIC_COLORED | SCE_EEVEE_GTAO_BENT_NORMALS | SCE_EEVEE_GTAO_BOUNCE | SCE_EEVEE_TAA_REPROJECTION | diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 09a940436ef..6ac7c719952 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1200,7 +1200,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->eevee.flag = SCE_EEVEE_VOLUMETRIC_LIGHTS | - SCE_EEVEE_VOLUMETRIC_COLORED | SCE_EEVEE_GTAO_BENT_NORMALS | SCE_EEVEE_GTAO_BOUNCE | SCE_EEVEE_TAA_REPROJECTION | @@ -1258,7 +1257,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED); EEVEE_GET_BOOL(props, volumetric_lights, SCE_EEVEE_VOLUMETRIC_LIGHTS); EEVEE_GET_BOOL(props, volumetric_shadows, SCE_EEVEE_VOLUMETRIC_SHADOWS); - EEVEE_GET_BOOL(props, volumetric_colored_transmittance, SCE_EEVEE_VOLUMETRIC_COLORED); EEVEE_GET_BOOL(props, gtao_enable, SCE_EEVEE_GTAO_ENABLED); EEVEE_GET_BOOL(props, gtao_use_bent_normals, SCE_EEVEE_GTAO_BENT_NORMALS); EEVEE_GET_BOOL(props, gtao_bounce, SCE_EEVEE_GTAO_BOUNCE); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 16c8d8875c7..a4235a07ed5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2096,7 +2096,7 @@ enum { SCE_EEVEE_VOLUMETRIC_ENABLED = (1 << 0), SCE_EEVEE_VOLUMETRIC_LIGHTS = (1 << 1), SCE_EEVEE_VOLUMETRIC_SHADOWS = (1 << 2), - SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3), +// SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3), /* Unused */ SCE_EEVEE_GTAO_ENABLED = (1 << 4), SCE_EEVEE_GTAO_BENT_NORMALS = (1 << 5), SCE_EEVEE_GTAO_BOUNCE = (1 << 6), diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b44a53fa90b..096a2d7b8dc 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -6017,12 +6017,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Volumetric Shadow Samples", "Number of samples to compute volumetric shadowing"); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); - prop = RNA_def_property(srna, "use_volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_COLORED); - RNA_def_property_boolean_default(prop, 1); - RNA_def_property_ui_text(prop, "Colored Transmittance", "Enable wavelength dependent volumetric transmittance"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); - /* Ambient Occlusion */ prop = RNA_def_property(srna, "use_gtao", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_ENABLED); -- cgit v1.2.3 From 8876e3aae25ad0e74baf362413b0fd113aa5b638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 23 Jul 2018 17:44:16 +0200 Subject: Fix assert when loading file with multiple windows opened ... or when loading a file when having more windows opened than the file itself. --- source/blender/windowmanager/intern/wm_files.c | 4 ++++ source/blender/windowmanager/intern/wm_window.c | 4 +--- source/blender/windowmanager/wm_window.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index c191255cd21..02c24aac60e 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -279,6 +279,10 @@ static void wm_window_match_replace_by_file_wm( wm->initialized = 0; wm->winactive = NULL; + /* Clearing drawable of before deleting any context + * to avoid clearing the wrong wm. */ + wm_window_clear_drawable(oldwm); + /* only first wm in list has ghostwins */ for (wmWindow *win = wm->windows.first; win; win = win->next) { for (wmWindow *oldwin = oldwm->windows.first; oldwin; oldwin = oldwin->next) { diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index c1006db34ef..4b26532742b 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -123,7 +123,6 @@ static struct WMInitStruct { /* ******** win open & close ************ */ static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate); -static void wm_window_clear_drawable(wmWindowManager *wm); /* XXX this one should correctly check for apple top header... * done for Cocoa : returns window contents (and not frame) max size*/ @@ -202,7 +201,6 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win) GHOST_DisposeWindow(g_system, win->ghostwin); win->ghostwin = NULL; win->gpuctx = NULL; - } } @@ -1103,7 +1101,7 @@ static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool acti immActivate(); } -static void wm_window_clear_drawable(wmWindowManager *wm) +void wm_window_clear_drawable(wmWindowManager *wm) { if (wm->windrawable) { BLF_batch_reset(); diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 385d61217ad..4fd5d66fb43 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -57,6 +57,7 @@ void wm_window_ghostwindows_remove_invalid(bContext *C, wmWindowManager *wm); void wm_window_process_events (const bContext *C); void wm_window_process_events_nosleep(void); +void wm_window_clear_drawable(wmWindowManager *wm); void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win); void wm_window_reset_drawable(void); -- cgit v1.2.3 From 7d6776ba2da7dbac3d80ccef28becf311f93a745 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 23 Jul 2018 18:37:29 +0200 Subject: Fix missing header include in previous master merge. --- source/blender/blenloader/intern/versioning_280.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 79ae95e96e4..edeefe35567 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -70,6 +70,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" +#include "BKE_sequencer.h" #include "BKE_studiolight.h" #include "BKE_workspace.h" -- cgit v1.2.3 From c28a37b5d1ce9ee63e8fb744c759711ba594f434 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Mon, 23 Jul 2018 18:41:12 +0200 Subject: UI: Fix flicker in File Browser header Move running jobs to the beginning of the row. Thanks @sergey for reporting --- release/scripts/startup/bl_ui/space_filebrowser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 9d903829bbb..a85dd591b2f 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -56,6 +56,8 @@ class FILEBROWSER_HT_header(Header): layout.separator_spacer() + layout.template_running_jobs() + if params: layout.prop(params, "use_filter", text="", icon='FILTER') @@ -86,8 +88,6 @@ class FILEBROWSER_HT_header(Header): row.separator() row.prop(params, "filter_search", text="", icon='VIEWZOOM') - layout.template_running_jobs() - class FILEBROWSER_UL_dir(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): -- cgit v1.2.3 From a50e23ba791d3a3489c65321d85e567684e89b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 23 Jul 2018 18:56:24 +0200 Subject: Fix compilation issue after merge. --- source/blender/blenloader/intern/versioning_280.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index edeefe35567..3a586e49ab3 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1213,7 +1213,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->eevee.flag = SCE_EEVEE_VOLUMETRIC_LIGHTS | - SCE_EEVEE_VOLUMETRIC_COLORED | SCE_EEVEE_GTAO_BENT_NORMALS | SCE_EEVEE_GTAO_BOUNCE | SCE_EEVEE_TAA_REPROJECTION | @@ -1271,7 +1270,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED); EEVEE_GET_BOOL(props, volumetric_lights, SCE_EEVEE_VOLUMETRIC_LIGHTS); EEVEE_GET_BOOL(props, volumetric_shadows, SCE_EEVEE_VOLUMETRIC_SHADOWS); - EEVEE_GET_BOOL(props, volumetric_colored_transmittance, SCE_EEVEE_VOLUMETRIC_COLORED); EEVEE_GET_BOOL(props, gtao_enable, SCE_EEVEE_GTAO_ENABLED); EEVEE_GET_BOOL(props, gtao_use_bent_normals, SCE_EEVEE_GTAO_BENT_NORMALS); EEVEE_GET_BOOL(props, gtao_bounce, SCE_EEVEE_GTAO_BOUNCE); -- cgit v1.2.3 From f6eccd367cf7ef504ebeef332b62a86d928f5542 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Jul 2018 18:40:04 +0200 Subject: Subsurf: Subdivide polygons to the same resolution Previously it was ptex faces which were subdividing to the same resolution. This was looking like more details for non-quad faces, but was also causing discontinuity in the edge where quad touches non-quad polygon. Now ptex faces which are coming from non-quad faces are subdivided at a half of resolution, matching old behavior and solving discontinuity problem. --- source/blender/blenkernel/BKE_subdiv.h | 20 -- source/blender/blenkernel/intern/subdiv.c | 19 -- source/blender/blenkernel/intern/subdiv_mesh.c | 398 +++++++++++++++++-------- 3 files changed, 268 insertions(+), 169 deletions(-) diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index a1792866255..003dc7a37d3 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -94,26 +94,6 @@ typedef struct Subdiv { */ SubdivSettings settings; - /* Total number of ptex faces on subdivision level 0. - * - * Ptex face is what is internally used by OpenSubdiv for evaluator. It is - * a quad face, which corresponds to Blender's legacy Catmull Clark grids. - * - * Basically, here is a correspondence between polygons and ptex faces: - * - Triangle consists of 3 PTex faces. - * - Quad is a single PTex face. - * - N-gon is N PTex faces. - * - * This value is initialized in BKE_subdiv_new_from_FOO() and is read-only - * after this. - */ - int num_ptex_faces; - - /* Indexed by base face index, element indicates total number of ptex faces - * created for preceding base faces. - */ - int *face_ptex_offset; - /* Topology refiner includes all the glue logic to feed Blender side * topology to OpenSubdiv. It can be shared by both evaluator and GL mesh * drawer. diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 794da2d3477..0bf969b7de2 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -42,23 +42,6 @@ # include "opensubdiv_topology_refiner_capi.h" #endif -#ifdef WITH_OPENSUBDIV -static void update_subdiv_after_topology_change(Subdiv *subdiv) -{ - /* Count ptex faces. */ - subdiv->num_ptex_faces = subdiv->topology_refiner->getNumPtexFaces( - subdiv->topology_refiner); - /* Initialize offset of base faces in ptex indices. */ - MEM_SAFE_FREE(subdiv->face_ptex_offset); - subdiv->face_ptex_offset = MEM_malloc_arrayN(subdiv->num_ptex_faces, - sizeof(int), - "subdiv ptex offset"); - subdiv->topology_refiner->fillFacePtexIndexOffset( - subdiv->topology_refiner, - subdiv->face_ptex_offset); -} -#endif - Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, struct OpenSubdiv_Converter *converter) { @@ -79,7 +62,6 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, subdiv->settings = *settings; subdiv->topology_refiner = osd_topology_refiner; subdiv->evaluator = NULL; - update_subdiv_after_topology_change(subdiv); BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME); subdiv->stats = stats; return subdiv; @@ -113,7 +95,6 @@ void BKE_subdiv_free(Subdiv *subdiv) if (subdiv->topology_refiner != NULL) { openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner); } - MEM_SAFE_FREE(subdiv->face_ptex_offset); MEM_freeN(subdiv); #endif } diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 83f2069ea0f..eb47d9158d3 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -38,27 +38,40 @@ #include "BKE_mesh.h" -/* TODO(sergey): Somehow move this to subdiv code? */ -static int mpoly_ptex_faces_count_get(const MPoly *mp) +#include "MEM_guardedalloc.h" + +/* ============================================================================= + * General helpers. + */ + +/* Number of ptex faces for a given polygon. */ +BLI_INLINE int num_ptex_faces_per_poly_get(const MPoly *poly) { - if (mp->totloop == 4) { - return 1; - } - else { - return mp->totloop; - } + return (poly->totloop == 4) ? 1 : poly->totloop; } -static int num_edges_per_ptex_get(const int resolution) +BLI_INLINE int num_edges_per_ptex_face_get(const int resolution) { return 2 * (resolution - 1) * resolution; } -static int num_polys_per_ptex_get(const int resolution) +/* Number of subdivision polygons per ptex face. */ +BLI_INLINE int num_polys_per_ptex_get(const int resolution) { return (resolution - 1) * (resolution - 1); } +/* Subdivision resolution per given polygon's ptex faces. */ +BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution) +{ + return (poly->totloop == 4) ? (resolution) + : ((resolution >> 1) + 1); +} + +/* ============================================================================= + * Mesh subdivision context. + */ + typedef struct SubdivMeshContext { const Mesh *coarse_mesh; Subdiv *subdiv; @@ -72,8 +85,127 @@ typedef struct SubdivMeshContext { /* UV layers interpolation. */ int num_uv_layers; MLoopUV *uv_layers[MAX_MTFACE]; + + /* Indexed by coarse polygon index, indicates offset in subdivided mesh + * vertices, edges and polygons arrays, where first element of the poly + * begins. + */ + int *subdiv_vertex_offset; + int *subdiv_edge_offset; + int *subdiv_polygon_offset; + /* Indexed by base face index, element indicates total number of ptex faces + * created for preceding base faces. + */ + int *face_ptex_offset; + + /* Counters of geometry in subdivided mesh, initialized as a part of + * offsets calculation. + */ + int num_subdiv_vertices; + int num_subdiv_edges; + int num_subdiv_loops; + int num_subdiv_polygons; } SubdivMeshContext; +static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) +{ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + ctx->num_uv_layers = + CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV); + for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) { + ctx->uv_layers[layer_index] = CustomData_get_layer_n( + &subdiv_mesh->ldata, CD_MLOOPUV, layer_index); + } +} + +static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) +{ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + /* Pointers to original indices layers. */ + ctx->vert_origindex = CustomData_get_layer( + &subdiv_mesh->vdata, CD_ORIGINDEX); + ctx->edge_origindex = CustomData_get_layer( + &subdiv_mesh->edata, CD_ORIGINDEX); + ctx->loop_origindex = CustomData_get_layer( + &subdiv_mesh->ldata, CD_ORIGINDEX); + ctx->poly_origindex = CustomData_get_layer( + &subdiv_mesh->pdata, CD_ORIGINDEX); + /* UV layers interpolation. */ + subdiv_mesh_ctx_cache_uv_layers(ctx); +} + +static void subdiv_mesh_ctx_init_offsets(SubdivMeshContext *ctx) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + /* Allocate memory. */ + ctx->subdiv_vertex_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_vertex_offset), + "vertex_offset"); + ctx->subdiv_edge_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_edge_offset), + "subdiv_edge_offset"); + ctx->subdiv_polygon_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_polygon_offset), + "subdiv_polygon_offset"); + ctx->face_ptex_offset = MEM_malloc_arrayN(coarse_mesh->totpoly, + sizeof(*ctx->face_ptex_offset), + "face_ptex_offset"); + /* Fill in offsets. */ + int vertex_offset = 0; + int edge_offset = 0; + int polygon_offset = 0; + int face_ptex_offset = 0; + for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int ptex_face_resolution = ptex_face_resolution_get( + coarse_poly, ctx->settings->resolution); + const int ptex_face_resolution2 = + ptex_face_resolution * ptex_face_resolution; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + ctx->subdiv_vertex_offset[poly_index] = vertex_offset; + ctx->subdiv_edge_offset[poly_index] = edge_offset; + ctx->subdiv_polygon_offset[poly_index] = polygon_offset; + ctx->face_ptex_offset[poly_index] = face_ptex_offset; + vertex_offset += num_ptex_faces_per_poly * ptex_face_resolution2; + edge_offset += num_ptex_faces_per_poly * + num_edges_per_ptex_face_get(ptex_face_resolution); + polygon_offset += + num_ptex_faces_per_poly * + num_polys_per_ptex_get(ptex_face_resolution); + face_ptex_offset += num_ptex_faces_per_poly; + } + ctx->num_subdiv_vertices = vertex_offset; + ctx->num_subdiv_edges = edge_offset; + ctx->num_subdiv_polygons = polygon_offset; + ctx->num_subdiv_loops = 4 * ctx->num_subdiv_polygons; +} + +static void subdiv_mesh_ctx_init(SubdivMeshContext *ctx) +{ + subdiv_mesh_ctx_init_offsets(ctx); +} + +static void subdiv_mesh_ctx_init_result(SubdivMeshContext *ctx) +{ + subdiv_mesh_ctx_cache_custom_data_layers(ctx); +} + +static void subdiv_mesh_ctx_free(SubdivMeshContext *ctx) +{ + MEM_freeN(ctx->subdiv_vertex_offset); + MEM_freeN(ctx->subdiv_edge_offset); + MEM_freeN(ctx->face_ptex_offset); +} + +/* ============================================================================= + * Loop custom data copy helpers. + */ + typedef struct LoopsOfPtex { /* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */ const MLoop *first_loop; @@ -112,6 +244,10 @@ static void loops_of_ptex_get( } } +/* ============================================================================= + * Edge custom data copy helpers. + */ + typedef struct EdgesOfPtex { /* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */ const MEdge *first_edge; @@ -145,6 +281,10 @@ static void edges_of_ptex_get( } } +/* ============================================================================= + * Vertex custom data interpolation helpers. + */ + /* TODO(sergey): Somehow de-duplicate with loops storage, without too much * exception cases all over the code. */ @@ -285,6 +425,10 @@ static void vertex_interpolation_end( } } +/* ============================================================================= + * Loop custom data interpolation helpers. + */ + typedef struct LoopsForInterpolation { /* This field points to a loop data which is to be used for interpolation. * The idea is to avoid unnecessary allocations for regular faces, where @@ -413,6 +557,10 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) } } +/* ============================================================================= + * Vertex subdivision process. + */ + static void subdiv_copy_vertex_data( const SubdivMeshContext *ctx, MVert *subdiv_vertex, @@ -468,23 +616,26 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, { Subdiv *subdiv = ctx->subdiv; const int resolution = ctx->settings->resolution; - const int resolution2 = resolution * resolution; - const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_polyoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_polyoly[poly_index]; - const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + const int ptex_resolution = + ptex_face_resolution_get(coarse_poly, resolution); + const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1); /* Hi-poly subdivided mesh. */ Mesh *subdiv_mesh = ctx->subdiv_mesh; MVert *subdiv_vertex = subdiv_mesh->mvert; - const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; + MVert *subdiv_vert = &subdiv_vertex[start_vertex_index]; /* Actual evaluation. */ VerticesForInterpolation vertex_interpolation; vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly); - MVert *subdiv_vert = &subdiv_vertex[ptex_face_index * resolution2]; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index < num_ptex_faces_per_poly; ptex_of_poly_index++) { vertex_interpolation_from_ptex(ctx, @@ -496,13 +647,13 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal( subdiv, current_ptex_face_index, - resolution, + ptex_resolution, subdiv_vert, offsetof(MVert, co), sizeof(MVert), subdiv_vert, offsetof(MVert, no), sizeof(MVert)); - for (int y = 0; y < resolution; y++) { - const float v = y * inv_resolution_1; - for (int x = 0; x < resolution; x++, subdiv_vert++) { - const float u = x * inv_resolution_1; + for (int y = 0; y < ptex_resolution; y++) { + const float v = y * inv_ptex_resolution_1; + for (int x = 0; x < ptex_resolution; x++, subdiv_vert++) { + const float u = x * inv_ptex_resolution_1; subdiv_copy_vertex_data(ctx, subdiv_vert, coarse_mesh, @@ -516,6 +667,10 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, vertex_interpolation_end(&vertex_interpolation); } +/* ============================================================================= + * Edge subdivision process. + */ + static void subdiv_copy_edge_data( SubdivMeshContext *ctx, MEdge *subdiv_edge, @@ -590,22 +745,22 @@ static MEdge *subdiv_create_edges_column(SubdivMeshContext *ctx, static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) { - Subdiv *subdiv = ctx->subdiv; - const int resolution = ctx->settings->resolution; - const int resolution2 = resolution * resolution; - const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; - const int num_edges_per_ptex = num_edges_per_ptex_get(resolution); - const int start_edge_index = ptex_face_index * num_edges_per_ptex; + const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; + const int start_edge_index = ctx->subdiv_edge_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_polyoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_polyoly[poly_index]; - const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + const int ptex_face_resolution = ptex_face_resolution_get( + coarse_poly, ctx->settings->resolution); + const int ptex_face_resolution2 = + ptex_face_resolution * ptex_face_resolution; /* Hi-poly subdivided mesh. */ Mesh *subdiv_mesh = ctx->subdiv_mesh; MEdge *subdiv_medge = subdiv_mesh->medge; MEdge *subdiv_edge = &subdiv_medge[start_edge_index]; - const int start_poly_vertex_index = ptex_face_index * resolution2; /* Consider a subdivision of base face at level 1: * * y @@ -619,22 +774,25 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) * * This is illustrate which parts of geometry is created by code below. */ - for (int i = 0; i < num_poly_ptex_faces; i++) { + for (int ptex_of_poly_index = 0; + ptex_of_poly_index < num_ptex_faces_per_poly; + ptex_of_poly_index++) + { const int start_ptex_face_vertex_index = - start_poly_vertex_index + i * resolution2; + start_vertex_index + ptex_of_poly_index * ptex_face_resolution2; EdgesOfPtex edges_of_ptex; - edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, i); + edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, ptex_of_poly_index); /* Create bottom row of edges (0-1, 1-2). */ subdiv_edge = subdiv_create_edges_row( ctx, subdiv_edge, edges_of_ptex.first_edge, start_ptex_face_vertex_index, - resolution); + ptex_face_resolution); /* Create remaining edges. */ - for (int row = 0; row < resolution - 1; row++) { + for (int row = 0; row < ptex_face_resolution - 1; row++) { const int start_row_vertex_index = - start_ptex_face_vertex_index + row * resolution; + start_ptex_face_vertex_index + row * ptex_face_resolution; /* Create vertical columns. * * At first iteration it will be edges (0-3. 1-4, 2-5), then it @@ -646,7 +804,7 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) edges_of_ptex.last_edge, edges_of_ptex.second_edge, start_row_vertex_index, - resolution); + ptex_face_resolution); /* Create horizontal edge row. * * At first iteration it will be edges (3-4, 4-5), then it will be @@ -655,14 +813,18 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) subdiv_edge = subdiv_create_edges_row( ctx, subdiv_edge, - (row == resolution - 2) ? edges_of_ptex.third_edge - : NULL, - start_row_vertex_index + resolution, - resolution); + (row == ptex_face_resolution - 2) ? edges_of_ptex.third_edge + : NULL, + start_row_vertex_index + ptex_face_resolution, + ptex_face_resolution); } } } +/* ============================================================================= + * Loops creation/interpolation. + */ + static void subdiv_copy_loop_data( const SubdivMeshContext *ctx, MLoop *subdiv_loop, @@ -723,24 +885,25 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) { - Subdiv *subdiv = ctx->subdiv; const int resolution = ctx->settings->resolution; - const int resolution2 = resolution * resolution; - const float inv_resolution_1 = 1.0f / (float)(resolution - 1); - const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; - const int num_edges_per_ptex = num_edges_per_ptex_get(resolution); - const int start_edge_index = ptex_face_index * num_edges_per_ptex; - const int num_polys_per_ptex = num_polys_per_ptex_get(resolution); - const int start_poly_index = ptex_face_index * num_polys_per_ptex; - const int start_loop_index = 4 * start_poly_index; - const int start_vert_index = ptex_face_index * resolution2; - const float du = inv_resolution_1; - const float dv = inv_resolution_1; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; + const int start_edge_index = ctx->subdiv_edge_offset[poly_index]; + const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_polyoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_polyoly[poly_index]; - const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + const int ptex_resolution = + ptex_face_resolution_get(coarse_poly, resolution); + const int ptex_resolution2 = ptex_resolution * ptex_resolution; + const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1); + const int num_edges_per_ptex = num_edges_per_ptex_face_get(ptex_resolution); + const int start_loop_index = 4 * start_poly_index; + const float du = inv_ptex_resolution_1; + const float dv = inv_ptex_resolution_1; /* Hi-poly subdivided mesh. */ Mesh *subdiv_mesh = ctx->subdiv_mesh; MLoop *subdiv_loopoop = subdiv_mesh->mloop; @@ -748,7 +911,7 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) LoopsForInterpolation loop_interpolation; loop_interpolation_init(ctx, &loop_interpolation, coarse_poly); for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index < num_ptex_faces_per_poly; ptex_of_poly_index++) { loop_interpolation_from_ptex(ctx, @@ -757,24 +920,24 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) ptex_of_poly_index); const int current_ptex_face_index = ptex_face_index + ptex_of_poly_index; - for (int y = 0; y < resolution - 1; y++) { - const float v = y * inv_resolution_1; - for (int x = 0; x < resolution - 1; x++, subdiv_loop += 4) { - const float u = x * inv_resolution_1; + for (int y = 0; y < ptex_resolution - 1; y++) { + const float v = y * inv_ptex_resolution_1; + for (int x = 0; x < ptex_resolution - 1; x++, subdiv_loop += 4) { + const float u = x * inv_ptex_resolution_1; /* Vertex indicies ordered counter-clockwise. */ - const int v0 = start_vert_index + - (ptex_of_poly_index * resolution2) + - (y * resolution + x); + const int v0 = start_vertex_index + + (ptex_of_poly_index * ptex_resolution2) + + (y * ptex_resolution + x); const int v1 = v0 + 1; - const int v2 = v0 + resolution + 1; - const int v3 = v0 + resolution; + const int v2 = v0 + ptex_resolution + 1; + const int v3 = v0 + ptex_resolution; /* Edge indicies ordered counter-clockwise. */ const int e0 = start_edge_index + (ptex_of_poly_index * num_edges_per_ptex) + - (y * (2 * resolution - 1) + x); - const int e1 = e0 + resolution; - const int e2 = e0 + (2 * resolution - 1); - const int e3 = e0 + resolution - 1; + (y * (2 * ptex_resolution - 1) + x); + const int e1 = e0 + ptex_resolution; + const int e2 = e0 + (2 * ptex_resolution - 1); + const int e3 = e0 + ptex_resolution - 1; /* Initialize 4 loops of corresponding hi-poly poly. */ /* TODO(sergey): For ptex boundaries we should use loops from * coarse mesh. @@ -808,13 +971,17 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) subdiv_loop, current_ptex_face_index, u, v, - inv_resolution_1); + inv_ptex_resolution_1); } } } loop_interpolation_end(&loop_interpolation); } +/* ============================================================================= + * Polygons subdivision process. + */ + static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, MPoly *subdiv_poly, const MPoly *coarse_poly) @@ -833,24 +1000,25 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) { - Subdiv *subdiv = ctx->subdiv; const int resolution = ctx->settings->resolution; - const int ptex_face_index = subdiv->face_ptex_offset[poly_index]; - const int num_polys_per_ptex = num_polys_per_ptex_get(resolution); - const int num_loops_per_ptex = 4 * num_polys_per_ptex; - const int start_poly_index = ptex_face_index * num_polys_per_ptex; - const int start_loop_index = 4 * start_poly_index; + const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_polyoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_polyoly[poly_index]; - const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly); + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + const int ptex_resolution = + ptex_face_resolution_get(coarse_poly, resolution); + const int num_polys_per_ptex = num_polys_per_ptex_get(ptex_resolution); + const int num_loops_per_ptex = 4 * num_polys_per_ptex; + const int start_loop_index = 4 * start_poly_index; /* Hi-poly subdivided mesh. */ Mesh *subdiv_mesh = ctx->subdiv_mesh; MPoly *subdiv_mpoly = subdiv_mesh->mpoly; MPoly *subdiv_mp = &subdiv_mpoly[start_poly_index]; for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_poly_ptex_faces; + ptex_of_poly_index < num_ptex_faces_per_poly; ptex_of_poly_index++) { for (int subdiv_poly_index = 0; @@ -866,6 +1034,10 @@ static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) } } +/* ============================================================================= + * Subdivision process entry points. + */ + static void subdiv_eval_task( void *__restrict userdata, const int poly_index, @@ -880,33 +1052,6 @@ static void subdiv_eval_task( subdiv_create_polys(data, poly_index); } -static void cache_uv_layers(SubdivMeshContext *ctx) -{ - Mesh *subdiv_mesh = ctx->subdiv_mesh; - ctx->num_uv_layers = - CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV); - for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) { - ctx->uv_layers[layer_index] = CustomData_get_layer_n( - &subdiv_mesh->ldata, CD_MLOOPUV, layer_index); - } -} - -static void cache_custom_data_layers(SubdivMeshContext *ctx) -{ - Mesh *subdiv_mesh = ctx->subdiv_mesh; - /* Pointers to original indices layers. */ - ctx->vert_origindex = CustomData_get_layer( - &subdiv_mesh->vdata, CD_ORIGINDEX); - ctx->edge_origindex = CustomData_get_layer( - &subdiv_mesh->edata, CD_ORIGINDEX); - ctx->loop_origindex = CustomData_get_layer( - &subdiv_mesh->ldata, CD_ORIGINDEX); - ctx->poly_origindex = CustomData_get_layer( - &subdiv_mesh->pdata, CD_ORIGINDEX); - /* UV layers interpolation. */ - cache_uv_layers(ctx); -} - Mesh *BKE_subdiv_to_mesh( Subdiv *subdiv, const SubdivToMeshSettings *settings, @@ -917,29 +1062,20 @@ Mesh *BKE_subdiv_to_mesh( * is is refined for the new positions of coarse vertices. */ BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh); - const int resolution = settings->resolution; - const int resolution2 = resolution * resolution; - const int num_result_verts = subdiv->num_ptex_faces * resolution2; - const int num_result_edges = - subdiv->num_ptex_faces * num_edges_per_ptex_get(resolution); - const int num_result_polys = - subdiv->num_ptex_faces * num_polys_per_ptex_get(resolution); - const int num_result_loops = 4 * num_result_polys; - /* Create mesh and its arrays. */ + SubdivMeshContext ctx = {0}; + ctx.coarse_mesh = coarse_mesh; + ctx.subdiv = subdiv; + ctx.settings = settings; + subdiv_mesh_ctx_init(&ctx); Mesh *result = BKE_mesh_new_nomain_from_template( coarse_mesh, - num_result_verts, - num_result_edges, + ctx.num_subdiv_vertices, + ctx.num_subdiv_edges, 0, - num_result_loops, - num_result_polys); - /* Evaluate subdivisions of base faces in threads. */ - SubdivMeshContext ctx; - ctx.coarse_mesh = coarse_mesh; - ctx.subdiv = subdiv; + ctx.num_subdiv_loops, + ctx.num_subdiv_polygons); ctx.subdiv_mesh = result; - ctx.settings = settings; - cache_custom_data_layers(&ctx); + subdiv_mesh_ctx_init_result(&ctx); /* Multi-threaded evaluation. */ ParallelRangeSettings parallel_range_settings; BLI_parallel_range_settings_defaults(¶llel_range_settings); @@ -947,6 +1083,8 @@ Mesh *BKE_subdiv_to_mesh( &ctx, subdiv_eval_task, ¶llel_range_settings); + subdiv_mesh_ctx_free(&ctx); + // BKE_mesh_validate(result, true, true); BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); return result; } -- cgit v1.2.3 From b466c09c305dfafbe3d15d6564c34f9f874ac0ad Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 23 Jul 2018 19:09:16 +0200 Subject: Subsurf: Fix wrong vertices index in vertex data interpolation --- source/blender/blenkernel/intern/subdiv_mesh.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index eb47d9158d3..ad2e094fa48 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -355,7 +355,7 @@ static void vertex_interpolation_init( int *indices = BLI_array_alloca(indices, coarse_poly->totloop); for (int i = 0; i < coarse_poly->totloop; ++i) { weights[i] = weight; - indices[i] = coarse_poly->loopstart + i; + indices[i] = coarse_mloop[coarse_poly->loopstart + i].v; } CustomData_interp(&coarse_mesh->vdata, &vertex_interpolation->vertex_data_storage, @@ -395,13 +395,15 @@ static void vertex_interpolation_from_ptex( * iteration. */ const float weights[2] = {0.5f, 0.5f}; + const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop; + const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop; const int first_indices[2] = { - coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v, - coarse_mloop[(loops_of_ptex.first_loop + 1 - coarse_mloop) % - coarse_poly->totloop].v}; - const int last_indices[2] = { - coarse_mloop[loops_of_ptex.last_loop - coarse_mloop].v, - coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v}; + coarse_mloop[first_loop_index].v, + coarse_mloop[coarse_poly->loopstart + + (first_loop_index - coarse_poly->loopstart + 1) % + coarse_poly->totloop].v}; + const int last_indices[2] = {coarse_mloop[first_loop_index].v, + coarse_mloop[last_loop_index].v}; CustomData_interp(vertex_data, &vertex_interpolation->vertex_data_storage, first_indices, -- cgit v1.2.3 From 4d978cc2e496eb0287b3b828ac105bb767da4bb4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 24 Jul 2018 13:54:25 +1000 Subject: Cleanup: changes from 2.8 --- source/blender/blenlib/intern/hash_mm3.c | 18 +++---- .../compositor/nodes/COM_CryptomatteNode.cpp | 6 +-- .../operations/COM_CryptomatteOperation.cpp | 2 +- .../composite/nodes/node_composite_cryptomatte.c | 58 +++++++++++----------- .../nodes/node_shader_bsdf_hair_principled.c | 2 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c index 5ead9ceca63..105c1f46832 100644 --- a/source/blender/blenlib/intern/hash_mm3.c +++ b/source/blender/blenlib/intern/hash_mm3.c @@ -92,7 +92,7 @@ BLI_INLINE uint64_t fmix64(uint64_t k) uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) { - const uint8_t *data = (const uint8_t*)in; + const uint8_t *data = (const uint8_t *)in; const int nblocks = len / 4; uint32_t h1 = seed; @@ -102,23 +102,23 @@ uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) /* body */ - const uint32_t *blocks = (const uint32_t *)(data + nblocks*4); + const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4); for (int i = -nblocks; i; i++) { - uint32_t k1 = getblock32(blocks,i); + uint32_t k1 = getblock32(blocks, i); k1 *= c1; - k1 = ROTL32(k1,15); + k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - h1 = ROTL32(h1,13); - h1 = h1*5+0xe6546b64; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; } /* tail */ - const uint8_t *tail = (const uint8_t*)(data + nblocks*4); + const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); uint32_t k1 = 0; @@ -132,10 +132,10 @@ uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed) case 1: k1 ^= tail[0]; k1 *= c1; - k1 = ROTL32(k1,15); + k1 = ROTL32(k1, 15); k1 *= c2; h1 ^= k1; - }; + } /* finalization */ diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp index bc115e66c20..5ed66fe45e7 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp @@ -62,7 +62,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos bNode *node = this->getbNode(); NodeCryptomatte *cryptoMatteSettings = (NodeCryptomatte *)node->storage; - CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets()-1); + CryptomatteOperation *operation = new CryptomatteOperation(getNumberOfInputSockets() - 1); if (cryptoMatteSettings) { if (cryptoMatteSettings->matte_id) { /* Split the string by commas, ignoring white space. */ @@ -83,7 +83,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos operation->addObjectIndex(atof(token.substr(1, token.length() - 2).c_str())); } else { - uint32_t hash = BLI_hash_mm3((const unsigned char*)token.c_str(), token.length(), 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)token.c_str(), token.length(), 0); operation->addObjectIndex(hash_to_float(hash)); } } @@ -93,7 +93,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos converter.addOperation(operation); - for (int i = 0; i < getNumberOfInputSockets()-1; ++i) { + for (int i = 0; i < getNumberOfInputSockets() - 1; ++i) { converter.mapInputSocket(this->getInputSocket(i + 1), operation->getInputSocket(i)); } diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp index 9dd36863d37..f3fa81075c6 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp @@ -63,7 +63,7 @@ void CryptomatteOperation::executePixel(float output[4], output[1] = ((float) ((m3hash << 8)) / (float) UINT32_MAX); output[2] = ((float) ((m3hash << 16)) / (float) UINT32_MAX); } - for(size_t i = 0; i < m_objectIndex.size(); i++) { + for (size_t i = 0; i < m_objectIndex.size(); i++) { if (m_objectIndex[i] == input[0]) { output[3] += input[1]; } diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c index 0231e4717b2..bf9ab4a5064 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -39,10 +39,10 @@ static inline float hash_to_float(uint32_t hash) { - uint32_t mantissa = hash & (( 1 << 23) - 1); + uint32_t mantissa = hash & ((1 << 23) - 1); uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); - exponent = MAX2(exponent, (uint32_t) 1); - exponent = MIN2(exponent, (uint32_t) 254); + exponent = MAX2(exponent, (uint32_t)1); + exponent = MIN2(exponent, (uint32_t)254); exponent = exponent << 23; uint32_t sign = (hash >> 31); sign = sign << 31; @@ -54,7 +54,7 @@ static inline float hash_to_float(uint32_t hash) return f; } -static void cryptomatte_add(NodeCryptomatte* n, float f) +static void cryptomatte_add(NodeCryptomatte *n, float f) { /* Turn the number into a string. */ char number[32]; @@ -72,16 +72,16 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) } /* Find the next seprator. */ - char* token_end = strchr(n->matte_id+start, ','); - if (token_end == NULL || token_end == n->matte_id+start) { - token_end = n->matte_id+end; + char *token_end = strchr(n->matte_id + start, ','); + if (token_end == NULL || token_end == n->matte_id + start) { + token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ token_len = token_end - (n->matte_id + start); /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ if (n->matte_id[start] == '<') { - if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + if (strncmp(n->matte_id + start, number, strlen(number)) == 0) { /* This number is already there, so continue. */ return; } @@ -89,16 +89,16 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) else { /* Remove trailing white space */ size_t name_len = token_len; - while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + while (n->matte_id[start + name_len] == ' ' && name_len > 0) { name_len--; } /* Calculate the hash of the token and compare. */ - uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0); if (f == hash_to_float(hash)) { return; } } - start += token_len+1; + start += token_len + 1; } } @@ -107,12 +107,12 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) return; } - if(n->matte_id) { + if (n->matte_id) { BLI_dynstr_append(new_matte, n->matte_id); MEM_freeN(n->matte_id); } - if(BLI_dynstr_get_len(new_matte) > 0) { + if (BLI_dynstr_get_len(new_matte) > 0) { BLI_dynstr_append(new_matte, ","); } BLI_dynstr_append(new_matte, number); @@ -120,7 +120,7 @@ static void cryptomatte_add(NodeCryptomatte* n, float f) BLI_dynstr_free(new_matte); } -static void cryptomatte_remove(NodeCryptomatte*n, float f) +static void cryptomatte_remove(NodeCryptomatte *n, float f) { if (n->matte_id == NULL || strlen(n->matte_id) == 0) { /* Empty string, nothing to remove. */ @@ -150,9 +150,9 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) } /* Find the next seprator. */ - char* token_end = strchr(n->matte_id+start+1, ','); - if (token_end == NULL || token_end == n->matte_id+start) { - token_end = n->matte_id+end; + char *token_end = strchr(n->matte_id + start + 1, ','); + if (token_end == NULL || token_end == n->matte_id + start) { + token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ token_len = token_end - (n->matte_id + start); @@ -162,7 +162,7 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) } /* If this has a leading bracket, assume a raw floating point number and look for the closing bracket. */ else if (n->matte_id[start] == '<') { - if (strncmp(n->matte_id+start, number, strlen(number)) == 0) { + if (strncmp(n->matte_id + start, number, strlen(number)) == 0) { /* This number is already there, so skip it. */ skip = true; } @@ -170,11 +170,11 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) else { /* Remove trailing white space */ size_t name_len = token_len; - while (n->matte_id[start+name_len] == ' ' && name_len > 0) { + while (n->matte_id[start + name_len] == ' ' && name_len > 0) { name_len--; } /* Calculate the hash of the token and compare. */ - uint32_t hash = BLI_hash_mm3((const unsigned char*)(n->matte_id+start), name_len, 0); + uint32_t hash = BLI_hash_mm3((const unsigned char *)(n->matte_id + start), name_len, 0); if (f == hash_to_float(hash)) { skip = true; } @@ -186,26 +186,26 @@ static void cryptomatte_remove(NodeCryptomatte*n, float f) else { BLI_dynstr_append(new_matte, ", "); } - BLI_dynstr_nappend(new_matte, n->matte_id+start, token_len); + BLI_dynstr_nappend(new_matte, n->matte_id + start, token_len); } - start += token_len+1; + start += token_len + 1; } - if(n->matte_id) { + if (n->matte_id) { MEM_freeN(n->matte_id); n->matte_id = NULL; } - if(BLI_dynstr_get_len(new_matte) > 0) { + if (BLI_dynstr_get_len(new_matte) > 0) { n->matte_id = BLI_dynstr_get_cstring(new_matte); } BLI_dynstr_free(new_matte); } static bNodeSocketTemplate outputs[] = { - { SOCK_RGBA, 0, N_("Image")}, - { SOCK_FLOAT, 0, N_("Matte")}, - { SOCK_RGBA, 0, N_("Pick")}, - { -1, 0, "" } + { SOCK_RGBA, 0, N_("Image")}, + { SOCK_FLOAT, 0, N_("Matte")}, + { SOCK_RGBA, 0, N_("Pick")}, + { -1, 0, "" } }; void ntreeCompositCryptomatteSyncFromAdd(bNodeTree *UNUSED(ntree), bNode *node) @@ -235,7 +235,7 @@ bNodeSocket *ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node) NodeCryptomatte *n = node->storage; char sockname[32]; n->num_inputs++; - BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs-1); + BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs - 1); bNodeSocket *sock = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, NULL, sockname); return sock; } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c index c5029852033..aeeb262a5a6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c @@ -40,7 +40,7 @@ static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = { { SOCK_FLOAT, 1, N_("Radial Roughness"), 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, - { SOCK_FLOAT, 1, N_("Offset"), 2.f*((float)M_PI)/180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, + { SOCK_FLOAT, 1, N_("Offset"), 2.0f * ((float)M_PI) / 180.f, 0.0f, 0.0f, 0.0f, -M_PI_2, M_PI_2, PROP_ANGLE}, { SOCK_FLOAT, 1, N_("Random Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Random Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Random"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, -- cgit v1.2.3 From ec640510a8c8ef5de8daea907da2351ef1988915 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 14 Jul 2018 17:01:02 +0300 Subject: Fix T55958: allow the user to select between spring and spring2. The old springs with damping 1.0 operate in a special way that is more similar to plastic deformation than a spring. Some users rely on that, so let the user choose which implementation to use. This also restores full backward compatibility with 2.79. Reviewers: sergof Differential Revision: https://developer.blender.org/D3544 --- intern/rigidbody/RBI_api.h | 9 +- intern/rigidbody/rb_bullet_api.cpp | 55 ++++++++++- .../properties_physics_rigidbody_constraint.py | 5 + source/blender/blenkernel/intern/rigidbody.c | 66 ++++++++----- source/blender/makesdna/DNA_rigidbody_types.h | 11 ++- source/blender/makesrna/intern/rna_rigidbody.c | 102 +++++++++++++-------- 6 files changed, 181 insertions(+), 67 deletions(-) diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h index 556ca959e64..eec94bcea50 100644 --- a/intern/rigidbody/RBI_api.h +++ b/intern/rigidbody/RBI_api.h @@ -268,6 +268,7 @@ rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2); rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2); rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2); +rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2); rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2); /* ............ */ @@ -299,12 +300,18 @@ void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float l void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper); /* 6dof spring specific */ -void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper); void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness); void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping); void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable); void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con); +/* 6dof spring 2 specific */ +void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper); +void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness); +void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping); +void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable); +void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con); + /* motors */ void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang); void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang); diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp index a9fbcb28529..6a50c5c93ee 100644 --- a/intern/rigidbody/rb_bullet_api.cpp +++ b/intern/rigidbody/rb_bullet_api.cpp @@ -954,11 +954,25 @@ rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigi make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn); - btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2); + btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true); return (rbConstraint *)con; } +rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2) +{ + btRigidBody *body1 = rb1->body; + btRigidBody *body2 = rb2->body; + btTransform transform1; + btTransform transform2; + + make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn); + + btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2); + + return (rbConstraint *)con; +} + rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2) { btRigidBody *body1 = rb1->body; @@ -1034,7 +1048,7 @@ void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, flo constraint->setLimit(axis, lower, upper); } -void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper) +void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper) { btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); @@ -1043,26 +1057,57 @@ void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float low void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness) { - btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + btGeneric6DofSpringConstraint *constraint = reinterpret_cast(con); constraint->setStiffness(axis, stiffness); } void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping) { - btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + btGeneric6DofSpringConstraint *constraint = reinterpret_cast(con); + + // invert damping range so that 0 = no damping + damping = (damping > 1.0f) ? 0.0f : 1.0f - damping; constraint->setDamping(axis, damping); } void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable) { - btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + btGeneric6DofSpringConstraint *constraint = reinterpret_cast(con); constraint->enableSpring(axis, enable); } void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con) +{ + btGeneric6DofSpringConstraint *constraint = reinterpret_cast(con); + + constraint->setEquilibriumPoint(); +} + +void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness) +{ + btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + + constraint->setStiffness(axis, stiffness); +} + +void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping) +{ + btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + + constraint->setDamping(axis, damping); +} + +void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable) +{ + btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); + + constraint->enableSpring(axis, enable); +} + +void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con) { btGeneric6DofSpring2Constraint *constraint = reinterpret_cast(con); diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 84a4cbb4b68..8f6b5b5d8b2 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -140,6 +140,11 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse") elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}: + if rbc.type == 'GENERIC_SPRING': + row = layout.row() + row.label("Spring Type:") + row.prop(rbc, "spring_type", text="") + col = layout.column(align=True) col.label("Limits:") diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 502b6a81c76..5d6695e6598 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -700,6 +700,35 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool /* --------------------- */ +static void rigidbody_constraint_init_spring( + RigidBodyCon *rbc, void (*set_spring)(rbConstraint*,int,int), + void (*set_stiffness)(rbConstraint*,int,float), void (*set_damping)(rbConstraint*,int,float) +) { + set_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X); + set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x); + set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x); + + set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y); + set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y); + set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y); + + set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z); + set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z); + set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z); + + set_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X); + set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x); + set_damping(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x); + + set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y); + set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y); + set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y); + + set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z); + set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z); + set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z); +} + static void rigidbody_constraint_set_limits(RigidBodyCon *rbc, void (*set_limits)(rbConstraint*,int,float,float)) { if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) @@ -824,35 +853,24 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper); break; case RBC_TYPE_6DOF_SPRING: - rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2); - - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x); - - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y); + if (rbc->spring_type == RBC_SPRING_TYPE2) { + rbc->physics_constraint = RB_constraint_new_6dof_spring2(loc, rot, rb1, rb2); - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z); + rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring2, RB_constraint_set_stiffness_6dof_spring2, RB_constraint_set_damping_6dof_spring2); - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x); + RB_constraint_set_equilibrium_6dof_spring2(rbc->physics_constraint); - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y); + rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring2); + } + else { + rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2); - RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z); - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z); - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z); + rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring, RB_constraint_set_stiffness_6dof_spring, RB_constraint_set_damping_6dof_spring); - RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint); + RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint); - rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring); + rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof); + } break; case RBC_TYPE_6DOF: rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2); @@ -1071,6 +1089,8 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty rbc->flag |= RBC_FLAG_ENABLED; rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS; + rbc->spring_type = RBC_SPRING_TYPE2; + rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */ rbc->num_solver_iterations = 10; /* 10 is Bullet default */ diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 1cd3a22fbe0..19e49644816 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -203,7 +203,8 @@ typedef struct RigidBodyCon { int flag; /* (eRigidBodyCon_Flag) */ float breaking_threshold; /* breaking impulse threshold */ - float pad; + char spring_type; /* spring implementation to use */ + char pad[3]; /* limits */ /* translation limits */ @@ -273,9 +274,15 @@ typedef enum eRigidBodyCon_Type { /* Simplified spring constraint with only once axis that's automatically placed between the connected bodies */ RBC_TYPE_SPRING, /* dirves bodies by applying linear and angular forces */ - RBC_TYPE_MOTOR + RBC_TYPE_MOTOR, } eRigidBodyCon_Type; +/* Spring implementation type for RigidBodyOb */ +typedef enum eRigidBodyCon_SpringType { + RBC_SPRING_TYPE1 = 0, /* btGeneric6DofSpringConstraint */ + RBC_SPRING_TYPE2, /* btGeneric6DofSpring2Constraint */ +} eRigidBodyCon_SpringType; + /* Flags for RigidBodyCon */ typedef enum eRigidBodyCon_Flag { /* constraint influences rigid body motion */ diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index e1e9bb30335..853b1d9978c 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -76,6 +76,12 @@ const EnumPropertyItem rna_enum_rigidbody_constraint_type_items[] = { {RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"}, {0, NULL, 0, NULL, NULL}}; +/* bullet spring type */ +const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = { + {RBC_SPRING_TYPE1, "SPRING1", ICON_NONE, "Blender 2.7", "Spring implementation used in blender 2.7. Damping is capped at 1.0"}, + {RBC_SPRING_TYPE2, "SPRING2", ICON_NONE, "Blender 2.8", "New implementation available since 2.8"}, + {0, NULL, 0, NULL, NULL}}; + #ifndef RNA_RUNTIME /* mesh source for collision shape creation */ static const EnumPropertyItem rigidbody_mesh_source_items[] = { @@ -376,6 +382,14 @@ static void rna_RigidBodyCon_type_set(PointerRNA *ptr, int value) rbc->flag |= RBC_FLAG_NEEDS_VALIDATE; } +static void rna_RigidBodyCon_spring_type_set(PointerRNA *ptr, int value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_type = value; + rbc->flag |= RBC_FLAG_NEEDS_VALIDATE; +} + static void rna_RigidBodyCon_enabled_set(PointerRNA *ptr, bool value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -468,6 +482,22 @@ static void rna_RigidBodyCon_num_solver_iterations_set(PointerRNA *ptr, int valu #endif } +#ifdef WITH_BULLET +static void rna_RigidBodyCon_do_set_spring_stiffness(RigidBodyCon *rbc, float value, int flag, int axis) +{ + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) { + switch (rbc->spring_type) { + case RBC_SPRING_TYPE1: + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, axis, value); + break; + case RBC_SPRING_TYPE2: + RB_constraint_set_stiffness_6dof_spring2(rbc->physics_constraint, axis, value); + break; + } + } +} +#endif + static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -475,9 +505,7 @@ static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value rbc->spring_stiffness_x = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X); #endif } @@ -488,9 +516,7 @@ static void rna_RigidBodyCon_spring_stiffness_y_set(PointerRNA *ptr, float value rbc->spring_stiffness_y = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y); #endif } @@ -501,9 +527,7 @@ static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value rbc->spring_stiffness_z = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z); #endif } @@ -514,9 +538,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_x_set(PointerRNA *ptr, float v rbc->spring_stiffness_ang_x = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X); #endif } @@ -527,9 +549,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_y_set(PointerRNA *ptr, float v rbc->spring_stiffness_ang_y = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y); #endif } @@ -540,12 +560,26 @@ static void rna_RigidBodyCon_spring_stiffness_ang_z_set(PointerRNA *ptr, float v rbc->spring_stiffness_ang_z = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { - RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); - } + rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z); #endif } +#ifdef WITH_BULLET +static void rna_RigidBodyCon_do_set_spring_damping(RigidBodyCon *rbc, float value, int flag, int axis) +{ + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) { + switch (rbc->spring_type) { + case RBC_SPRING_TYPE1: + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, axis, value); + break; + case RBC_SPRING_TYPE2: + RB_constraint_set_damping_6dof_spring2(rbc->physics_constraint, axis, value); + break; + } + } +} +#endif + static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -553,9 +587,7 @@ static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value) rbc->spring_damping_x = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X); #endif } @@ -565,9 +597,7 @@ static void rna_RigidBodyCon_spring_damping_y_set(PointerRNA *ptr, float value) rbc->spring_damping_y = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y); #endif } @@ -577,9 +607,7 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value) rbc->spring_damping_z = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z); #endif } @@ -590,9 +618,7 @@ static void rna_RigidBodyCon_spring_damping_ang_x_set(PointerRNA *ptr, float val rbc->spring_damping_ang_x = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X); #endif } @@ -602,9 +628,7 @@ static void rna_RigidBodyCon_spring_damping_ang_y_set(PointerRNA *ptr, float val rbc->spring_damping_ang_y = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y); #endif } @@ -614,9 +638,7 @@ static void rna_RigidBodyCon_spring_damping_ang_z_set(PointerRNA *ptr, float val rbc->spring_damping_ang_z = value; #ifdef WITH_BULLET - if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { - RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); - } + rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z); #endif } @@ -1025,6 +1047,14 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "spring_type"); + RNA_def_property_enum_items(prop, rna_enum_rigidbody_constraint_spring_type_items); + RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyCon_spring_type_set", NULL); + RNA_def_property_ui_text(prop, "Spring Type", "Which implementation of spring to use"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_ENABLED); RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_enabled_set"); -- cgit v1.2.3 From 1b415e4456ff4f6666c92efabeb88ead84227648 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 23 Jul 2018 16:38:25 +0200 Subject: Motion paths: default to bone head instead of tail location. This puts the motion path in the same location as the transform gizmo, which is less confusing especially if you have a custom bone shape where the tail is not visible. --- source/blender/blenkernel/intern/anim.c | 2 ++ source/blender/editors/armature/pose_edit.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index eed8943cd5b..a867accfe44 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -99,6 +99,8 @@ void animviz_settings_init(bAnimVizSettings *avs) avs->path_viewflag = (MOTIONPATH_VIEW_KFRAS | MOTIONPATH_VIEW_KFNOS); avs->path_step = 1; + + avs->path_bakeflag |= MOTIONPATH_BAKE_HEADS; } /* ------------------- */ diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index a9ba8c405ba..3ae578279ca 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -287,7 +287,8 @@ void POSE_OT_paths_calculate(wmOperatorType *ot) RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", "Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0); - RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0, + RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, + MOTIONPATH_BAKE_HEADS, "Bake Location", "Which point on the bones is used when calculating paths"); } -- cgit v1.2.3 From 9284c051d62833960ff836f2f48bf5a3b18b369c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 11:08:58 +0200 Subject: Fix incorrect object visibility test in baking. --- source/blender/editors/object/object_bake_api.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 5210182510f..e8fabdabf17 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -49,6 +49,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" @@ -357,17 +358,24 @@ static bool is_noncolor_pass(eScenePassType pass_type) } /* if all is good tag image and return true */ -static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports) +static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports) { Image *image; + Base *base = BKE_view_layer_base_find(view_layer, ob); void *lock; int i; - if ((ob->lay & scene->lay) == 0) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not on a scene layer", ob->id.name + 2); + if (base == NULL) { + BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2); return false; } + if (!(base->flag & BASE_ENABLED_RENDER)) { + BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2); + return false; + } + + if (ob->type != OB_MESH) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2); return false; @@ -497,7 +505,7 @@ static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filt } /* before even getting in the bake function we check for some basic errors */ -static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *selected_objects, +static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects, ReportList *reports, const bool is_selected_to_active) { CollectionPointerLink *link; @@ -508,7 +516,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase * if (is_selected_to_active) { int tot_objects = 0; - if (!bake_object_check(scene, ob, reports)) + if (!bake_object_check(view_layer, ob, reports)) return false; for (link = selected_objects->first; link; link = link->next) { @@ -536,7 +544,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase * } for (link = selected_objects->first; link; link = link->next) { - if (!bake_object_check(scene, link->ptr.data, reports)) + if (!bake_object_check(view_layer, link->ptr.data, reports)) return false; } } @@ -1204,7 +1212,7 @@ static int bake_exec(bContext *C, wmOperator *op) goto finally; } - if (!bake_objects_check(bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { + if (!bake_objects_check(bkr.main, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { goto finally; } @@ -1263,7 +1271,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa return; } - if (!bake_objects_check(bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { + if (!bake_objects_check(bkr->main, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { bkr->result = OPERATOR_CANCELLED; return; } -- cgit v1.2.3 From 31c49493d14a68d4f7bf35162c6b16765d1433a0 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 11:18:45 +0200 Subject: Fix incorrect active object setting in scripts. --- release/scripts/modules/bpy_extras/object_utils.py | 2 +- release/scripts/startup/bl_operators/clip.py | 4 ++-- release/scripts/startup/bl_operators/rigidbody.py | 12 ++++++------ release/scripts/startup/bl_operators/uvcalc_lightmap.py | 2 +- release/scripts/templates_py/batch_export.py | 8 ++++---- .../scripts/templates_py/operator_modal_view3d_raycast.py | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 7719e2f6e30..fff73a4285a 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -166,7 +166,7 @@ def object_data_add(context, obdata, operator=None, name=None): obj_act.select_set(action='SELECT') scene.update() # apply location - # scene.objects.active = obj_new + # layer.objects.active = obj_new # Match up UV layers, this is needed so adding an object with UV's # doesn't create new layers when there happens to be a naming mis-match. diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 2717a4f62a3..a94076ab61b 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -238,7 +238,7 @@ class CLIP_OT_track_to_empty(Operator): ob = bpy.data.objects.new(name=track.name, object_data=None) ob.select_set(action='SELECT') context.scene.objects.link(ob) - context.scene.objects.active = ob + context.view_layer.objects.active = ob for con in ob.constraints: if con.type == 'FOLLOW_TRACK': @@ -314,7 +314,7 @@ class CLIP_OT_bundles_to_mesh(Operator): ob.matrix_world = matrix context.scene.objects.link(ob) ob.select = True - context.scene.objects.active = ob + context.view_layer.objects.active = ob else: self.report({'WARNING'}, "No usable tracks selected") diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index 36150a63895..6b76fb96b62 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -60,7 +60,7 @@ class CopyRigidbodySettings(Operator): def execute(self, context): obj_act = context.object - scene = context.scene + view_layer = context.view_layer # deselect all but mesh objects for o in context.selected_objects: @@ -68,9 +68,9 @@ class CopyRigidbodySettings(Operator): o.select_set(action='DESELECT') elif o.rigid_body is None: # Add rigidbody to object! - scene.objects.active = o + view_layer.objects.active = o bpy.ops.rigidbody.object_add() - scene.objects.active = obj_act + view_layer.objects.active = obj_act objects = context.selected_objects if objects: @@ -265,7 +265,7 @@ class ConnectRigidBodies(Operator): ob = bpy.data.objects.new("Constraint", object_data=None) ob.location = loc context.scene.objects.link(ob) - context.scene.objects.active = ob + context.view_layer.objects.active = ob ob.select_set(action='SELECT') bpy.ops.rigidbody.constraint_add() @@ -278,7 +278,7 @@ class ConnectRigidBodies(Operator): con.object2 = object2 def execute(self, context): - scene = context.scene + view_layer = context.view_layer objects = context.selected_objects obj_act = context.active_object change = False @@ -312,7 +312,7 @@ class ConnectRigidBodies(Operator): bpy.ops.object.select_all(action='DESELECT') for obj in objects: obj.select_set(action='SELECT') - scene.objects.active = obj_act + view_layer.objects.active = obj_act return {'FINISHED'} else: self.report({'WARNING'}, "No other objects selected") diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 95a3d18304b..b866fb1ce40 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -579,7 +579,7 @@ def unwrap(operator, context, **kwargs): # define list of meshes meshes = [] if PREF_ACT_ONLY: - obj = context.scene.objects.active + obj = context.view_layer.objects.active if obj and obj.type == 'MESH': meshes = [obj.data] else: diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py index 1463915886a..a07491742ec 100644 --- a/release/scripts/templates_py/batch_export.py +++ b/release/scripts/templates_py/batch_export.py @@ -9,9 +9,9 @@ basedir = os.path.dirname(bpy.data.filepath) if not basedir: raise Exception("Blend file is not saved") -scene = bpy.context.scene +view_layer = bpy.context.view_layer -obj_active = scene.objects.active +obj_active = view_layer.objects.active selection = bpy.context.selected_objects bpy.ops.object.select_all(action='DESELECT') @@ -21,7 +21,7 @@ for obj in selection: obj.select_set(action='SELECT') # some exporters only use the active object - scene.objects.active = obj + view_layer.objects.active = obj name = bpy.path.clean_name(obj.name) fn = os.path.join(basedir, name) @@ -36,7 +36,7 @@ for obj in selection: print("written:", fn) -scene.objects.active = obj_active +view_layer.objects.active = obj_active for obj in selection: obj.select_set(action='SELECT') diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py index e3b63813fc4..613501143f7 100644 --- a/release/scripts/templates_py/operator_modal_view3d_raycast.py +++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py @@ -68,7 +68,7 @@ def main(context, event): # we could do lots of stuff but for the example just select. if best_obj is not None: best_obj.select_set(action='SELECT') - context.scene.objects.active = best_obj + context.view_layer.objects.active = best_obj class ViewOperatorRayCast(bpy.types.Operator): -- cgit v1.2.3 From c4803759a260853ca516dbdc9028bd0077056114 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 11:21:32 +0200 Subject: Fix T55245: undo with multiple windows and view layers not working correct. --- source/blender/blenloader/intern/writefile.c | 14 +++++++------- source/blender/windowmanager/intern/wm_window.c | 7 ++++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 552f5420e8d..503f8b44ec3 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1147,7 +1147,7 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree) */ static void current_screen_compat( Main *mainvar, bool use_active_win, - bScreen **r_screen, Scene **r_scene, ViewLayer **r_render_layer) + bScreen **r_screen, Scene **r_scene, ViewLayer **r_view_layer) { wmWindowManager *wm; wmWindow *window = NULL; @@ -1177,7 +1177,7 @@ static void current_screen_compat( *r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL; *r_scene = (window) ? window->scene : NULL; - *r_render_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) : NULL; + *r_view_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) : NULL; } typedef struct RenderInfo { @@ -1193,11 +1193,11 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) { bScreen *curscreen; Scene *sce, *curscene = NULL; - ViewLayer *render_layer; + ViewLayer *view_layer; RenderInfo data; /* XXX in future, handle multiple windows with multiple screens? */ - current_screen_compat(mainvar, false, &curscreen, &curscene, &render_layer); + current_screen_compat(mainvar, false, &curscreen, &curscene, &view_layer); for (sce = mainvar->scene.first; sce; sce = sce->id.next) { if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) { @@ -3686,7 +3686,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) FileGlobal fg; bScreen *screen; Scene *scene; - ViewLayer *render_layer; + ViewLayer *view_layer; char subvstr[8]; /* prevent mem checkers from complaining */ @@ -3695,12 +3695,12 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) memset(fg.build_hash, 0, sizeof(fg.build_hash)); fg.pad1 = NULL; - current_screen_compat(mainvar, is_undo, &screen, &scene, &render_layer); + current_screen_compat(mainvar, is_undo, &screen, &scene, &view_layer); /* XXX still remap G */ fg.curscreen = screen; fg.curscene = scene; - fg.cur_view_layer = render_layer; + fg.cur_view_layer = view_layer; /* prevent to save this, is not good convention, and feature with concerns... */ fg.fileflags = (fileflags & ~G_FILE_FLAGS_RUNTIME); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 4b26532742b..dd4013efdf2 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -2167,7 +2167,12 @@ ViewLayer *WM_window_get_active_view_layer(const wmWindow *win) return view_layer; } - return BKE_view_layer_default_view(scene); + view_layer = BKE_view_layer_default_view(scene); + if (view_layer) { + WM_window_set_active_view_layer((wmWindow*)win, view_layer); + } + + return view_layer; } void WM_window_set_active_view_layer(wmWindow *win, ViewLayer *view_layer) -- cgit v1.2.3 From 882ccd924ba9febaec2db53831d95bc4a6c45ef3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 11:37:27 +0200 Subject: Fix T55721: crashes with collections panel in object properties. --- source/blender/editors/object/object_group.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 53cabe3759e..72c5fde2955 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -411,6 +411,9 @@ static int collection_add_exec(bContext *C, wmOperator *UNUSED(op)) id_fake_user_set(&collection->id); BKE_collection_object_add(bmain, collection, ob); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -460,6 +463,9 @@ static int collection_link_exec(bContext *C, wmOperator *op) BKE_collection_object_add(bmain, collection, ob); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -500,6 +506,9 @@ static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op)) BKE_collection_object_remove(bmain, collection, ob, false); + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; @@ -531,6 +540,8 @@ static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op)) BKE_libblock_delete(bmain, collection); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); return OPERATOR_FINISHED; -- cgit v1.2.3 From 293c15ec0cc3878bced1b52e274c078810ba2d8a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 12:02:24 +0200 Subject: Fix T56081: crash with make static override and linked collection. --- source/blender/editors/object/object_relations.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 2c3ff8b6afe..52d9c43ea65 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2329,6 +2329,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op) if (new_ob != NULL && new_ob->id.override_static != NULL) { if ((base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) { BKE_collection_object_add_from(bmain, scene, obcollection, new_ob); + base = BKE_view_layer_base_find(view_layer, new_ob); DEG_id_tag_update_ex(bmain, &new_ob->id, DEG_TAG_TRANSFORM | DEG_TAG_BASE_FLAGS_UPDATE); } /* parent to 'collection' empty */ -- cgit v1.2.3 From 7f7e51161f65c371d0f0c6c39bd32cbea45694cd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 12:43:21 +0200 Subject: Fix T56079: crash with startup.blend saved in sculpt/paint modes. This reverts commit 81a93df6d22c2f148667b9a6e8308e083a4cec39, it is not safe to handle initialization for startup.blend differently. Instead fix the root issue of the preview icon data structures not being initialized in time. --- source/blender/editors/include/UI_interface_icons.h | 2 +- source/blender/editors/interface/interface_icons.c | 3 +-- source/blender/editors/interface/resources.c | 2 +- source/blender/windowmanager/intern/wm_files.c | 8 +------- source/blender/windowmanager/intern/wm_init_exit.c | 13 ++++++------- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 651081c46bb..a34c4938b86 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -59,7 +59,7 @@ typedef struct IconFile { /* * Resizable Icons for Blender */ -void UI_icons_init(int first_dyn_id); +void UI_icons_init(void); int UI_icon_get_width(int icon_id); int UI_icon_get_height(int icon_id); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 22b82898288..7255640bedc 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -934,9 +934,8 @@ int UI_icon_get_height(int icon_id) return 0; } -void UI_icons_init(int first_dyn_id) +void UI_icons_init() { - BKE_icons_init(first_dyn_id); #ifndef WITH_HEADLESS init_iconfile_list(&iconfilelist); init_internal_icons(); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 47d664eaeb2..3cb8a277e9a 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -83,7 +83,7 @@ static struct bThemeState g_theme_state = { void ui_resources_init(void) { - UI_icons_init(BIFICONID_LAST); + UI_icons_init(); } void ui_resources_free(void) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 02c24aac60e..042bd8823c4 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -492,13 +492,7 @@ static void wm_file_read_post(bContext *C, const bool is_startup_file, const boo Main *bmain = CTX_data_main(C); DEG_on_visible_update(bmain, true); - - if (!is_startup_file) { - /* When starting up, the UI hasn't been fully initialised yet, and - * this call can trigger icon updates, causing a segfault due to a - * not-yet-initialised ghash for the icons. */ - wm_event_do_depsgraph(C); - } + wm_event_do_depsgraph(C); ED_editors_init(C); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c51d4c5534a..4b0d751a7ce 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -115,6 +115,7 @@ #include "ED_undo.h" #include "UI_interface.h" +#include "UI_resources.h" #include "BLF_api.h" #include "BLT_lang.h" @@ -237,6 +238,11 @@ void WM_init(bContext *C, int argc, const char **argv) BLF_init(); BLT_lang_init(); + /* Init icons before reading .blend files for preview icons, which can + * get triggered by the depsgraph. This is also done in background mode + * for scripts that do background processing with preview icons. */ + BKE_icons_init(BIFICONID_LAST); + /* reports cant be initialized before the wm, * but keep before file reading, since that may report errors */ wm_init_reports(C); @@ -259,13 +265,6 @@ void WM_init(bContext *C, int argc, const char **argv) UI_init(); BKE_studiolight_init(); } - else { - /* Note: Currently only inits icons, which we now want in background mode too - * (scripts could use those in background processing...). - * In case we do more later, we may need to pass a 'background' flag. - * Called from 'UI_init' above */ - BKE_icons_init(1); - } ED_spacemacros_init(); -- cgit v1.2.3 From c924f6f53f13fb55f76b878dbf5d69d60f9d64c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 24 Jul 2018 16:50:31 +0200 Subject: Workbench: Fix missing geometry on Iris 640/630 GPUs For some reason 32c5972653041a3423122b5a5ae791ef536b87ed broke display of solid meshes in workbench. After some investigation, it seems that the vertex coordinate output is degenerated even if the input is correct and the matrix too. Removing dead code seems to fix the problem. So maybe the GLSL preprocessor is not doing what it should? --- source/blender/draw/engines/workbench/workbench_deferred.c | 7 +++++-- source/blender/draw/engines/workbench/workbench_forward.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 4e90a08a543..23fbbe56c16 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -142,9 +142,12 @@ static char *workbench_build_prepass_frag(void) return str; } -static char *workbench_build_prepass_vert(void) +static char *workbench_build_prepass_vert(bool is_hair) { char *str = NULL; + if (!is_hair) { + return BLI_strdup(datatoc_workbench_prepass_vert_glsl); + } DynStr *ds = BLI_dynstr_new(); @@ -176,7 +179,7 @@ static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, bool if (e_data.prepass_sh_cache[index] == NULL) { char *defines = workbench_material_build_defines(wpd, use_textures, is_hair); char *composite_frag = workbench_build_composite_frag(wpd); - char *prepass_vert = workbench_build_prepass_vert(); + char *prepass_vert = workbench_build_prepass_vert(is_hair); char *prepass_frag = workbench_build_prepass_frag(); e_data.prepass_sh_cache[index] = DRW_shader_create( prepass_vert, NULL, diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 825b80ace52..c81ecc492db 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -80,9 +80,12 @@ extern char datatoc_workbench_common_lib_glsl[]; extern char datatoc_workbench_world_light_lib_glsl[]; /* static functions */ -static char *workbench_build_forward_vert(void) +static char *workbench_build_forward_vert(bool is_hair) { char *str = NULL; + if (!is_hair) { + return BLI_strdup(datatoc_workbench_prepass_vert_glsl); + } DynStr *ds = BLI_dynstr_new(); @@ -206,7 +209,7 @@ static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, bool u if (e_data.transparent_accum_sh_cache[index] == NULL) { char *defines = workbench_material_build_defines(wpd, use_textures, is_hair); - char *transparent_accum_vert = workbench_build_forward_vert(); + char *transparent_accum_vert = workbench_build_forward_vert(is_hair); char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag(); e_data.transparent_accum_sh_cache[index] = DRW_shader_create( transparent_accum_vert, NULL, @@ -267,7 +270,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) char *defines = workbench_material_build_defines(wpd, false, false); char *defines_texture = workbench_material_build_defines(wpd, true, false); char *defines_hair = workbench_material_build_defines(wpd, false, true); - char *forward_vert = workbench_build_forward_vert(); + char *forward_vert = workbench_build_forward_vert(false); + char *forward_hair_vert = workbench_build_forward_vert(true); e_data.object_outline_sh = DRW_shader_create( forward_vert, NULL, datatoc_workbench_forward_depth_frag_glsl, defines); @@ -275,12 +279,13 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) forward_vert, NULL, datatoc_workbench_forward_depth_frag_glsl, defines_texture); e_data.object_outline_hair_sh = DRW_shader_create( - forward_vert, NULL, + forward_hair_vert, NULL, datatoc_workbench_forward_depth_frag_glsl, defines_hair); e_data.checker_depth_sh = DRW_shader_create_fullscreen( datatoc_workbench_checkerboard_depth_frag_glsl, NULL); + MEM_freeN(forward_hair_vert); MEM_freeN(forward_vert); MEM_freeN(defines); MEM_freeN(defines_texture); -- cgit v1.2.3 From 45addee39e5510d7fd2c1f69ffa77cd96996045d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 24 Jul 2018 17:29:53 +0200 Subject: Fix presets not working after Python refactoring. --- release/scripts/startup/bl_operators/presets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 530194e5bb7..fe09fada297 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -257,7 +257,7 @@ class PresetMenu(Panel): bl_space_type = 'PROPERTIES' bl_region_type = 'HEADER' bl_label = "Presets" - path_menu: Menu.path_menu + path_menu = Menu.path_menu @classmethod def draw_panel_header(cls, layout): -- cgit v1.2.3 From cfaea24117f2ef3f1e2ce9bc0ebd620c27bfeba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 24 Jul 2018 17:57:24 +0200 Subject: Fix T55754: DOF with new Camera is not working Was due to non initialized gpu_dof.ratio --- source/blender/blenkernel/intern/camera.c | 3 +++ source/blender/makesrna/intern/rna_scene.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 4203e0455f8..87b65601534 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -76,6 +76,9 @@ void BKE_camera_init(Camera *cam) cam->flag |= CAM_SHOWPASSEPARTOUT; cam->passepartalpha = 0.5f; + cam->gpu_dof.fstop = 128.0f; + cam->gpu_dof.ratio = 1.0f; + /* stereoscopy 3d */ cam->stereo.interocular_distance = 0.065f; cam->stereo.convergence_distance = 30.f * 0.065f; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 096a2d7b8dc..b666b15015a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -4092,6 +4092,7 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna) prop = RNA_def_property(srna, "fstop", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "F-stop", "F-stop for dof effect"); + RNA_def_property_float_default(prop, 128.0f); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0.1f, 128.0f, 10, 1); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUDOFSettings_update"); @@ -4110,6 +4111,7 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna) prop = RNA_def_property(srna, "ratio", PROP_FLOAT, PROP_NONE); RNA_def_property_ui_text(prop, "Ratio", "Distortion to simulate anamorphic lens bokeh"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.0000001f, FLT_MAX); RNA_def_property_ui_range(prop, 1.0f, 2.0f, 0.1, 3); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); -- cgit v1.2.3 From a76198cb238bef5c08e83b7777c977daa7316c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 24 Jul 2018 17:59:46 +0200 Subject: RNA: Remove Unused dof.is_hq_supported and dof.use_high_quality It's not necessary anymore since we assume it's always high quality. --- intern/cycles/blender/addon/ui.py | 7 +------ release/scripts/startup/bl_ui/properties_data_camera.py | 7 +------ source/blender/makesrna/intern/rna_scene.c | 17 ----------------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 3d5ed6b9b44..a1941ce6176 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -883,14 +883,9 @@ class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel): cam = context.camera dof_options = cam.gpu_dof - hq_support = dof_options.is_hq_supported sub = flow.column(align=True) - subhq = sub.column() - subhq.active = hq_support - subhq.prop(dof_options, "use_high_quality") sub.prop(dof_options, "fstop") - if dof_options.use_high_quality and hq_support: - sub.prop(dof_options, "blades") + sub.prop(dof_options, "blades") class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index f66419a7f8e..8ede329ea45 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -250,15 +250,10 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): col.prop(dof_options, "rotation") col.prop(dof_options, "ratio") else: - hq_support = dof_options.is_hq_supported col = flow.column() col.label("Viewport") - sub = col.column() - sub.active = hq_support - sub.prop(dof_options, "use_high_quality") col.prop(dof_options, "fstop") - if dof_options.use_high_quality and hq_support: - col.prop(dof_options, "blades") + col.prop(dof_options, "blades") class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b666b15015a..764e55e9e30 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2024,11 +2024,6 @@ static void rna_Stereo3dFormat_update(Main *bmain, Scene *UNUSED(scene), Pointer } } -static bool rna_gpu_is_hq_supported_get(PointerRNA *UNUSED(ptr)) -{ - return true; -} - static ViewLayer *rna_ViewLayer_new( ID *id, Scene *UNUSED(sce), Main *bmain, const char *name) { @@ -4115,18 +4110,6 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna) RNA_def_property_range(prop, 0.0000001f, FLT_MAX); RNA_def_property_ui_range(prop, 1.0f, 2.0f, 0.1, 3); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - - prop = RNA_def_property(srna, "use_high_quality", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "high_quality", 1); - RNA_def_property_ui_text(prop, "High Quality", "Use high quality depth of field"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUDOFSettings_update"); - - /* NOTE: high quality is always supported */ - prop = RNA_def_property(srna, "is_hq_supported", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_gpu_is_hq_supported_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "High Quality", "Use high quality depth of field"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); } static void rna_def_gpu_ssao_fx(BlenderRNA *brna) -- cgit v1.2.3 From decb724572c4700d2ed2b9fb9447a17c2b5b1626 Mon Sep 17 00:00:00 2001 From: Germano Date: Tue, 24 Jul 2018 19:13:28 -0300 Subject: Fix T55798: Crash when snapping objects with data recalculated by modifiers. Although the default behavior is for these objects to be ignored during the snap operation, this should not crash. --- .../editors/transform/transform_snap_object.c | 38 ++++++++++++++-------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index b826e72acaf..dd4fc5025d9 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -172,6 +172,26 @@ static void min_max_from_bmesh( } } +static SnapObjectData_Mesh *snap_object_data_mesh_create(SnapObjectContext *sctx) +{ + SnapObjectData_Mesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod->sd.type = SNAP_MESH; + /* start assuming that it has each of these element types */ + sod->has_looptris = true; + sod->has_loose_edge = true; + sod->has_loose_vert = true; + + return sod; +} + +static SnapObjectData_EditMesh *snap_object_data_editmesh_create(SnapObjectContext *sctx, BMesh *bm) +{ + SnapObjectData_EditMesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); + sod->sd.type = SNAP_EDIT_MESH; + min_max_from_bmesh(bm, sod->min, sod->max); + + return sod; +} /** * Walks through all objects in the scene to create the list of objets to snap. @@ -386,8 +406,7 @@ static bool raycastMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_MESH; + sod = *sod_p = snap_object_data_mesh_create(sctx); } BVHTreeFromMesh *treedata = &sod->treedata; @@ -525,9 +544,7 @@ static bool raycastEditMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_EDIT_MESH; - min_max_from_bmesh(em->bm, sod->min, sod->max); + sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm); } { @@ -1838,12 +1855,7 @@ static short snapMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_MESH; - /* start assuming that it has each of these element types */ - sod->has_looptris = true; - sod->has_loose_edge = true; - sod->has_loose_vert = true; + sod = *sod_p = snap_object_data_mesh_create(sctx); } BVHTreeFromMesh *treedata, dummy_treedata; @@ -2050,9 +2062,7 @@ static short snapEditMesh( sod = *sod_p; } else { - sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod)); - sod->sd.type = SNAP_EDIT_MESH; - min_max_from_bmesh(em->bm, sod->min, sod->max); + sod = *sod_p = snap_object_data_mesh_create(sctx, em->bm); } float dist_px_sq = SQUARE(*dist_px); -- cgit v1.2.3 From 4f85982c6f6621c7d64a573e1d4558de4e824a00 Mon Sep 17 00:00:00 2001 From: Germano Date: Tue, 24 Jul 2018 19:34:49 -0300 Subject: Fix base->flag and base->flag_legacy: The flags of the Transform operator are being added to the bases of the not evaluated view_layer. But I'm not sure if the flags `BA_WAS_SEL`,` BASE_SELECTED` and `BA_SNAP_FIX_DEPS_FIASCO`(lol XD) should be added to the bases of the not evaluated `view_layer`. This needs to be discussed. --- source/blender/editors/transform/transform_snap_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index dd4fc5025d9..95ce26beed1 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -206,7 +206,7 @@ static void iter_snap_objects( IterSnapObjsCallback sob_callback, void *data) { - ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph); + ViewLayer *view_layer = DEG_get_input_view_layer(sctx->depsgraph); const eSnapSelect snap_select = params->snap_select; const bool use_object_edit_cage = params->use_object_edit_cage; -- cgit v1.2.3 From fdd4b03f33da4f046faa72b77dc0e77289afda0b Mon Sep 17 00:00:00 2001 From: Germano Date: Tue, 24 Jul 2018 19:45:03 -0300 Subject: Correction on the last commit. --- source/blender/editors/transform/transform_snap_object.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 95ce26beed1..7116923e678 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -216,17 +216,17 @@ static void iter_snap_objects( !((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) || (snap_select == SNAP_NOT_ACTIVE && base == base_act))) { - Object *obj = base->object; - if (obj->transflag & OB_DUPLI) { + Object *obj_eval = DEG_get_evaluated_object(sctx->depsgraph, base->object); + if (obj_eval->transflag & OB_DUPLI) { DupliObject *dupli_ob; - ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj); + ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj_eval); for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data); } free_object_duplilist(lb); } - sob_callback(sctx, use_object_edit_cage, obj, obj->obmat, data); + sob_callback(sctx, use_object_edit_cage, obj_eval, obj_eval->obmat, data); } } } -- cgit v1.2.3 From bd608d9aff84804d8912f4e652f7d7bf9dccb5d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jul 2018 09:23:07 +1000 Subject: Fix mistake in fix for T55798 --- source/blender/editors/transform/transform_snap_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 7116923e678..4ac4bdfb34d 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2062,7 +2062,7 @@ static short snapEditMesh( sod = *sod_p; } else { - sod = *sod_p = snap_object_data_mesh_create(sctx, em->bm); + sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm); } float dist_px_sq = SQUARE(*dist_px); -- cgit v1.2.3 From d8514482fe6b750070270ac886d49d06d28a9a9b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jul 2018 11:00:03 +1000 Subject: WM: keymap utility to set enum from a key range --- source/blender/windowmanager/WM_keymap.h | 4 ++++ source/blender/windowmanager/intern/wm_keymap.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 547028c88f9..2e84140707d 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -70,6 +70,10 @@ wmKeyMapItem *WM_keymap_add_panel(struct wmKeyMap *keymap, const char *idname, i wmKeyMapItem *WM_keymap_add_tool(struct wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier); +void WM_keymap_add_context_enum_set_items( + wmKeyMap *keymap, const struct EnumPropertyItem *items, const char *data_path, + int type_start, int val, int modifier, int keymodifier); + bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); int WM_keymap_item_to_string(wmKeyMapItem *kmi, const bool compact, char *result, const int result_len); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index a95ccf36fdb..6815ff4413a 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -526,6 +526,25 @@ wmKeyMapItem *WM_keymap_add_tool(wmKeyMap *keymap, const char *idname, int type, return kmi; } +/** Useful for mapping numbers to an enum. */ +void WM_keymap_add_context_enum_set_items( + wmKeyMap *keymap, const EnumPropertyItem *items, const char *data_path, + int type_start, int val, int modifier, int keymodifier) +{ + for (int i = 0, type_offset = 0; items[i].identifier; i++) { + if (items[i].identifier[0] == '\0') { + continue; + } + wmKeyMapItem *kmi = WM_keymap_add_item( + keymap, "WM_OT_context_set_enum", + type_start + type_offset, val, modifier, keymodifier); + RNA_string_set(kmi->ptr, "data_path", data_path); + RNA_string_set(kmi->ptr, "value", items[i].identifier); + type_offset += 1; + } +} + + bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) { if (BLI_findindex(&keymap->items, kmi) != -1) { -- cgit v1.2.3 From 2e112f591413eb8b49595c209298d61fec612476 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jul 2018 11:02:12 +1000 Subject: Keymap: Use 1..4 to change UV select modes Support for sync selection switching which keys apply. --- source/blender/editors/include/ED_object.h | 1 + source/blender/editors/mesh/editmesh_select.c | 12 ++++++++++++ source/blender/editors/mesh/mesh_ops.c | 18 ++---------------- source/blender/editors/object/object_ops.c | 24 ++++++++++++++++++++++++ source/blender/editors/uvedit/uvedit_ops.c | 10 ++++++++++ source/blender/makesrna/RNA_enum_types.h | 1 + source/blender/makesrna/intern/rna_scene.c | 18 +++++++++--------- 7 files changed, 59 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 38545137740..9fd5cc99073 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -112,6 +112,7 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, const bool do_connected); +void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode); void ED_object_base_activate(struct bContext *C, struct Base *base); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 2e7cf1fc76f..cdb8981801a 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1462,6 +1462,18 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op) static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + /* Bypass when in UV non sync-select mode, fall through to keymap that edits. */ + if (CTX_wm_space_image(C)) { + ToolSettings *ts = CTX_data_tool_settings(C); + if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) { + return OPERATOR_PASS_THROUGH; + } + /* Bypass when no action is needed. */ + if (!RNA_struct_property_is_set(op->ptr, "type")) { + return OPERATOR_CANCELLED; + } + } + /* detecting these options based on shift/ctrl here is weak, but it's done * to make this work when clicking buttons or menus */ if (!RNA_struct_property_is_set(op->ptr, "use_extend")) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 0fcc5ada854..79c8f5c0b09 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -335,22 +335,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "vertex_only", true); - /* selecting */ - for (int i = 0; i < 4; i++) { - const bool is_extend = (i & 1); - const bool is_expand = (i & 2); - const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0); - for (int j = 0; j < 3; j++) { - kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0); - RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j); - if (is_extend) { - RNA_boolean_set(kmi->ptr, "use_extend", true); - } - if (is_expand) { - RNA_boolean_set(kmi->ptr, "use_expand", true); - } - } - } + /* Selec Vert/Edge/Face. */ + ED_keymap_editmesh_elem_mode(keyconf, keymap); /* standard mouse selection goes via space_view3d */ kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 5a83d085aee..7b6c1156874 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -40,6 +40,7 @@ #include "BKE_context.h" #include "RNA_access.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -490,3 +491,26 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct RNA_string_set(kmi->ptr, "value_2", "CONNECTED"); } } + +/** + * Map 1..3 to Vert/Edge/Face. + */ +void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) +{ + for (int i = 0; i < 4; i++) { + const bool is_extend = (i & 1); + const bool is_expand = (i & 2); + const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0); + for (int j = 0; j < 3; j++) { + wmKeyMapItem *kmi = WM_keymap_add_item( + keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0); + RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j); + if (is_extend) { + RNA_boolean_set(kmi->ptr, "use_extend", true); + } + if (is_expand) { + RNA_boolean_set(kmi->ptr, "use_expand", true); + } + } + } +} diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 51e2c1b6334..32bf32b03ab 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -80,6 +80,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -4404,6 +4405,15 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf) RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt"); #endif + /* Select Element (Sync Select: on) */ + ED_keymap_editmesh_elem_mode(keyconf, keymap); + /* Hack to prevent fall-through, when the button isn't visible. */ + WM_keymap_add_item(keymap, "MESH_OT_select_mode", FOURKEY, KM_PRESS, 0, 0); + /* Select Element (Sync Select: off) */ + WM_keymap_add_context_enum_set_items( + keymap, rna_enum_mesh_select_mode_uv_items, "tool_settings.uv_select_mode", + ONEKEY, KM_PRESS, 0, 0); + /* Mark edge seam */ WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index bafb2bf5753..043375a066a 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -54,6 +54,7 @@ extern const EnumPropertyItem rna_enum_snap_element_items[]; extern const EnumPropertyItem rna_enum_snap_node_element_items[]; extern const EnumPropertyItem rna_enum_curve_fit_method_items[]; extern const EnumPropertyItem rna_enum_mesh_select_mode_items[]; +extern const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[]; extern const EnumPropertyItem rna_enum_mesh_delimit_mode_items[]; extern const EnumPropertyItem rna_enum_space_graph_mode_items[]; extern const EnumPropertyItem rna_enum_space_type_items[]; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 764e55e9e30..5637783aa04 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -165,6 +165,14 @@ const EnumPropertyItem rna_enum_mesh_select_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[] = { + {UV_SELECT_VERTEX, "VERTEX", ICON_UV_VERTEXSEL, "Vertex", "Vertex selection mode"}, + {UV_SELECT_EDGE, "EDGE", ICON_UV_EDGESEL, "Edge", "Edge selection mode"}, + {UV_SELECT_FACE, "FACE", ICON_UV_FACESEL, "Face", "Face selection mode"}, + {UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode"}, + {0, NULL, 0, NULL, NULL} +}; + const EnumPropertyItem rna_enum_snap_element_items[] = { {SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"}, {SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"}, @@ -2404,14 +2412,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem uv_select_mode_items[] = { - {UV_SELECT_VERTEX, "VERTEX", ICON_UV_VERTEXSEL, "Vertex", "Vertex selection mode"}, - {UV_SELECT_EDGE, "EDGE", ICON_UV_EDGESEL, "Edge", "Edge selection mode"}, - {UV_SELECT_FACE, "FACE", ICON_UV_FACESEL, "Face", "Face selection mode"}, - {UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode"}, - {0, NULL, 0, NULL, NULL} - }; - /* the construction of this enum is quite special - everything is stored as bitflags, * with 1st position only for for on/off (and exposed as boolean), while others are mutually * exclusive options but which will only have any effect when autokey is enabled @@ -2806,7 +2806,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) /* UV */ prop = RNA_def_property(srna, "uv_select_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "uv_selectmode"); - RNA_def_property_enum_items(prop, uv_select_mode_items); + RNA_def_property_enum_items(prop, rna_enum_mesh_select_mode_uv_items); RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); -- cgit v1.2.3 From 509d87230a1c744d555b8b25a3a6069f68d21c5b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 11:39:32 +0200 Subject: Fix missing particle use count object names with disabled particles. --- source/blender/makesrna/intern/rna_particle.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 4b8299b9245..979e5d433e7 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1132,6 +1132,9 @@ static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str) { + ParticleSettings *part = (ParticleSettings *)ptr->id.data; + psys_find_group_weights(part); + ParticleDupliWeight *dw = ptr->data; if (dw->ob) -- cgit v1.2.3 From ee9d3750450cbf290565ee5048e52acdf027d222 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Wed, 25 Jul 2018 11:56:37 +0200 Subject: UI: Add "New" and "Open..." to the File Context Menu Puts both operators at easy reach with the left hand since the shortcuts for these are somewhat cumbersome (Ctrl+O/Ctrl+N) --- release/scripts/startup/bl_ui/space_topbar.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 96ef2e51e60..77cc0f7c34e 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -265,8 +265,8 @@ class INFO_MT_file(Menu): layout.separator() layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link", text="Link", icon='LINK_BLEND') - layout.operator("wm.append", text="Append", icon='APPEND_BLEND') + layout.operator("wm.link", text="Link...", icon='LINK_BLEND') + layout.operator("wm.append", text="Append...", icon='APPEND_BLEND') layout.menu("INFO_MT_file_previews") layout.separator() @@ -539,8 +539,13 @@ class TOPBAR_MT_file_specials(Menu): layout = self.layout layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.link", text="Link", icon='LINK_BLEND') - layout.operator("wm.append", text="Append", icon='APPEND_BLEND') + layout.operator("wm.read_homefile", text="New", icon='NEW') + layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') + + layout.separator() + + layout.operator("wm.link", text="Link...", icon='LINK_BLEND') + layout.operator("wm.append", text="Append...", icon='APPEND_BLEND') layout.separator() -- cgit v1.2.3 From f3524fe759e8ad42ab305cf2e1636959914cc97e Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Wed, 25 Jul 2018 12:53:15 +0200 Subject: UI: Minor tweaks to nodes Match roundness with widget defaults and collapse triangle size with panel's. Interaction is the same, just an aesthetic tweak. --- source/blender/editors/interface/interface_panel.c | 6 +++--- source/blender/editors/space_node/node_draw.c | 8 ++++---- source/blender/editors/space_node/node_intern.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 59fdf7e672d..aa67d58fd57 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -454,9 +454,9 @@ static void ui_offset_panel_block(uiBlock *block) /* triangle 'icon' for panel header */ void UI_draw_icon_tri(float x, float y, char dir, const float color[4]) { - float f3 = 0.15 * U.widget_unit; - float f5 = 0.25 * U.widget_unit; - float f7 = 0.35 * U.widget_unit; + float f3 = 0.05 * U.widget_unit; + float f5 = 0.15 * U.widget_unit; + float f7 = 0.25 * U.widget_unit; if (dir == 'h') { UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 4b3a3abc642..bba46771674 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -951,18 +951,18 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* open/close entirely? */ { uiBut *but; - int but_size = UI_UNIT_X * 0.6f; + int but_size = UI_UNIT_X * 1.2f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ UI_block_emboss_set(node->block, UI_EMBOSS_NONE); but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", - rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, + rct->xmin + 0.6f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.2f - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); UI_block_emboss_set(node->block, UI_EMBOSS); UI_GetThemeColor4fv(TH_TEXT, color); /* custom draw function for this button */ - UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color); + UI_draw_icon_tri(rct->xmin + 0.6f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color); } nodeLabel(ntree, node, showname, sizeof(showname)); @@ -1071,7 +1071,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b /* open entirely icon */ { uiBut *but; - int but_size = UI_UNIT_X * 0.6f; + int but_size = UI_UNIT_X * 1.2f; /* XXX button uses a custom triangle draw below, so make it invisible without icon */ UI_block_emboss_set(node->block, UI_EMBOSS_NONE); but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "", diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index ed7379acca9..3644c8d09e6 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -238,7 +238,7 @@ extern const char *node_context_dir[]; // nodes draw without dpi - the view zoom is flexible #define HIDDEN_RAD (0.75f * U.widget_unit) -#define BASIS_RAD (0.4f * U.widget_unit) +#define BASIS_RAD (0.2f * U.widget_unit) #define NODE_DYS (U.widget_unit / 2) #define NODE_DY U.widget_unit #define NODE_SOCKDY (0.08f * U.widget_unit) -- cgit v1.2.3 From 4183e62d1b4c39fe6f4ef75951b066249147e01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuk=20Garda=C5=A1evi=C4=87?= Date: Wed, 25 Jul 2018 14:01:01 +0200 Subject: UI: Texture Properties Layout and Cleanup Initial work on single column layout, flow and organization of the texture properties. More work needs to be done in the C templates for image textures. See D3557 --- .../scripts/startup/bl_ui/properties_texture.py | 560 +++++++++++++-------- 1 file changed, 351 insertions(+), 209 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index d937f2470b8..a4f6f753669 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -17,19 +17,21 @@ # ##### END GPL LICENSE BLOCK ##### # -import bpy -from bpy.types import Menu, Panel, UIList +import bpy +from bpy.types import ( + Menu, + Panel, + UIList, +) from bpy.types import ( Brush, FreestyleLineStyle, - Object, ParticleSettings, Texture, ) from rna_prop_ui import PropertyPanel - from .properties_paint_common import brush_texture_settings @@ -47,9 +49,9 @@ class TEXTURE_MT_specials(Menu): class TEXTURE_UL_texslots(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - ma = data slot = item tex = slot.texture if slot else None + if self.layout_type in {'DEFAULT', 'COMPACT'}: if tex: layout.prop(tex, "name", text="", emboss=False, icon_value=icon) @@ -131,18 +133,18 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): if not pin_id: col.template_texture_user() - col.separator() - if user or pin_id: + col.separator() + if pin_id: col.template_ID(space, "pin_id") else: propname = context.texture_user_property.identifier col.template_ID(user, propname, new="texture.new") - col.separator() - if tex: + col.separator() + split = col.split(percentage=0.2) split.label(text="Type") split.prop(tex, "type", text="") @@ -179,25 +181,35 @@ class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) node = context.texture_node mapping = node.texture_mapping - layout.prop(mapping, "vector_type", expand=True) + col = flow.column() + col.prop(mapping, "vector_type") + + col.separator() + + col = col.column(align=True) + col.prop(mapping, "mapping_x", text="Projection X") + col.prop(mapping, "mapping_y", text="Y") + col.prop(mapping, "mapping_z", text="Z") - row = layout.row() + col.separator() - row.column().prop(mapping, "translation") - row.column().prop(mapping, "rotation") - row.column().prop(mapping, "scale") + col = flow.column() + col.column().prop(mapping, "translation") - layout.label(text="Projection:") + col = flow.column() + col.column().prop(mapping, "rotation") - row = layout.row() - row.prop(mapping, "mapping_x", text="") - row.prop(mapping, "mapping_y", text="") - row.prop(mapping, "mapping_z", text="") + col = flow.column() + col.column().prop(mapping, "scale") class TextureTypePanel(TextureButtonsPanel): @@ -216,21 +228,29 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.row().prop(tex, "cloud_type", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "noise_type", text="Type") + + col.separator() - split = layout.split() + col = flow.column() + col.prop(tex, "cloud_type") - col = split.column() + col.separator() + + col = flow.column() col.prop(tex, "noise_scale", text="Size") col.prop(tex, "noise_depth", text="Depth") - - split.prop(tex, "nabla", text="Nabla") + col.prop(tex, "nabla", text="Nabla") class TEXTURE_PT_wood(TextureTypePanel, Panel): @@ -240,26 +260,34 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False) tex = context.texture - layout.row().prop(tex, "noise_basis_2", expand=True) - layout.row().prop(tex, "wood_type", expand=True) + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") - col = layout.column() - col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} - col.label(text="Noise:") - col.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col.separator() - split = layout.split() - split.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + col.prop(tex, "wood_type") - col = split.column() - col.prop(tex, "noise_scale", text="Size") - col.prop(tex, "turbulence") + col.separator() - split.prop(tex, "nabla") + col = flow.column() + col.prop(tex, "noise_basis_2", text="Second Basis") + + col = col.column() + col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + col.prop(tex, "noise_type", text="Type") + + col.separator() + + sub = flow.column() + sub.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'} + sub.prop(tex, "noise_scale", text="Size") + sub.prop(tex, "turbulence") + sub.prop(tex, "nabla") class TEXTURE_PT_marble(TextureTypePanel, Panel): @@ -269,22 +297,29 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.row().prop(tex, "marble_type", expand=True) - layout.row().prop(tex, "noise_basis_2", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "marble_type") - split = layout.split() + col.separator() - col = split.column() + col = flow.column() + col.prop(tex, "noise_basis_2", text="Second Basis") + col.prop(tex, "noise_type", text="Type") + + col.separator() + + col = flow.column() col.prop(tex, "noise_scale", text="Size") col.prop(tex, "noise_depth", text="Depth") - - col = split.column() col.prop(tex, "turbulence") col.prop(tex, "nabla") @@ -296,12 +331,16 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - row = layout.row() - row.prop(tex, "noise_depth", text="Depth") - row.prop(tex, "turbulence") + col = flow.column() + col.prop(tex, "noise_depth", text="Depth") + + col = flow.column() + col.prop(tex, "turbulence") class TEXTURE_PT_blend(TextureTypePanel, Panel): @@ -311,15 +350,19 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "progression") + col = flow.column() + col.prop(tex, "progression") - sub = layout.row() + col.separator() - sub.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'}) - sub.prop(tex, "use_flip_axis", expand=True) + col = flow.column() + col.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'}) + col.prop(tex, "use_flip_axis", text="Orientation") class TEXTURE_PT_stucci(TextureTypePanel, Panel): @@ -329,17 +372,28 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - layout.row().prop(tex, "stucci_type", expand=True) - layout.label(text="Noise:") - layout.row().prop(tex, "noise_type", text="Type", expand=True) - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "turbulence") + col.row().prop(tex, "stucci_type") + + col.separator() + + col = flow.column() + col.prop(tex, "noise_type", text="Type") + + col.separator() + + col = flow.column() + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "turbulence") class TEXTURE_PT_image(TextureTypePanel, Panel): @@ -347,6 +401,18 @@ class TEXTURE_PT_image(TextureTypePanel, Panel): tex_type = 'IMAGE' COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + def draw(self, context): + # TODO: maybe expose the template_ID from the template image here. + layout = self.layout + del layout + + +class TEXTURE_PT_image_settings(TextureTypePanel, Panel): + bl_label = "Settings" + bl_parent_id = 'TEXTURE_PT_image' + tex_type = 'IMAGE' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + def draw(self, context): layout = self.layout @@ -356,11 +422,13 @@ class TEXTURE_PT_image(TextureTypePanel, Panel): def texture_filter_common(tex, layout): layout.prop(tex, "filter_type", text="Filter Type") + if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}: + col = layout.column() if tex.filter_type == 'FELINE': - layout.prop(tex, "filter_lightprobes", text="Light Probes") + col.prop(tex, "filter_lightprobes", text="Light Probes") else: - layout.prop(tex, "filter_eccentricity", text="Eccentricity") + col.prop(tex, "filter_eccentricity", text="Eccentricity") layout.prop(tex, "filter_size", text="Size") layout.prop(tex, "use_filter_size_min", text="Minimum Size") @@ -376,14 +444,11 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - idblock = context_tex_datablock(context) tex = context.texture - slot = getattr(context, "texture_slot", None) col = flow.column() - col.prop(tex, "use_flip_axis", text="Flip X/Y Axis") col.prop(tex, "use_interpolation") col.separator() @@ -396,8 +461,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel): col.separator() - col = flow.column() - texture_filter_common(tex, col) + texture_filter_common(tex, flow) class TEXTURE_PT_image_alpha(TextureTypePanel, Panel): @@ -433,43 +497,70 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel): def draw(self, context): layout = self.layout layout.use_property_split = True - flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - col = flow.column() - col.prop(tex, "extension") + col = layout.column() + col.prop(tex, "use_flip_axis", text="Flip Axes") + + col.separator() + + subcol = layout.column() + subcol.prop(tex, "extension") # use layout, to keep the same location in case of button cycling. + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) if tex.extension == 'REPEAT': + + col = flow.column() sub = col.column(align=True) sub.prop(tex, "repeat_x", text="Repeat X") sub.prop(tex, "repeat_y", text="Y") + col = flow.column() sub = col.column() - sub.prop(tex, "use_mirror_x", text="Mirror X") sub.active = (tex.repeat_x > 1) + sub.prop(tex, "use_mirror_x", text="Mirror X") sub = col.column() - sub.prop(tex, "use_mirror_y", text="Y") sub.active = (tex.repeat_y > 1) + sub.prop(tex, "use_mirror_y", text="Y") elif tex.extension == 'CHECKER': - col = layout.column(align=True) - col.prop(tex, "use_checker_even", text="Even") - col.prop(tex, "use_checker_odd", text="Odd") + subcol.separator() - col = layout.column() + col = flow.column() col.prop(tex, "checker_distance", text="Distance") - col = flow.column() - sub = col.column(align=True) + col = flow.column() + col.prop(tex, "use_checker_even", text="Tiles Even") + col.prop(tex, "use_checker_odd", text="Odd") + else: + del flow + + +class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel): + bl_label = "Crop" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'TEXTURE_PT_image_mapping' + tex_type = 'IMAGE' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) + + tex = context.texture + + col = flow.column(align=True) # col.prop(tex, "crop_rectangle") - sub.prop(tex, "crop_min_x", text="Crop Minimum X") - sub.prop(tex, "crop_min_y", text="Y") + col.prop(tex, "crop_min_x", text="Minimum X") + col.prop(tex, "crop_min_y", text="Y") - sub = col.column(align=True) - sub.prop(tex, "crop_max_x", text="Crop Maximum X") - sub.prop(tex, "crop_max_y", text="Y") + col = flow.column(align=True) + col.prop(tex, "crop_max_x", text="Maximum X") + col.prop(tex, "crop_max_y", text="Y") class TEXTURE_PT_musgrave(TextureTypePanel, Panel): @@ -479,34 +570,43 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "musgrave_type") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") + + col.separator() + + col.prop(tex, "musgrave_type") + + col.separator() + + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") - split = layout.split() + col.separator() - col = split.column() + col = flow.column() col.prop(tex, "dimension_max", text="Dimension") col.prop(tex, "lacunarity") col.prop(tex, "octaves") + col.separator() + musgrave_type = tex.musgrave_type - col = split.column() + + col = flow.column() + if musgrave_type in {'HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "offset") col.prop(tex, "noise_intensity", text="Intensity") + if musgrave_type in {'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}: col.prop(tex, "gain") - layout.label(text="Noise:") - - layout.prop(tex, "noise_basis", text="Basis") - - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "nabla") - class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" @@ -515,33 +615,51 @@ class TEXTURE_PT_voronoi(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) tex = context.texture - split = layout.split() + col = flow.column() + col.prop(tex, "distance_metric") - col = split.column() - col.label(text="Distance Metric:") - col.prop(tex, "distance_metric", text="") sub = col.column() sub.active = tex.distance_metric == 'MINKOVSKY' sub.prop(tex, "minkovsky_exponent", text="Exponent") - col.label(text="Coloring:") - col.prop(tex, "color_mode", text="") + + sub.separator() + + col = flow.column() + col.prop(tex, "color_mode") col.prop(tex, "noise_intensity", text="Intensity") - col = split.column() - sub = col.column(align=True) - sub.label(text="Feature Weights:") - sub.prop(tex, "weight_1", text="1", slider=True) - sub.prop(tex, "weight_2", text="2", slider=True) - sub.prop(tex, "weight_3", text="3", slider=True) - sub.prop(tex, "weight_4", text="4", slider=True) + col.separator() + + col = flow.column() + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") + + +class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): + bl_label = "Feature Weights" + bl_parent_id = "TEXTURE_PT_voronoi" + tex_type = 'VORONOI' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + tex = context.texture - layout.label(text="Noise:") - row = layout.row() - row.prop(tex, "noise_scale", text="Size") - row.prop(tex, "nabla") + col = flow.column(align=True) + col.prop(tex, "weight_1", text="First", slider=True) + col.prop(tex, "weight_2", text="Second", slider=True) + + sub = flow.column(align=True) + sub.prop(tex, "weight_3", text="Third", slider=True) + sub.prop(tex, "weight_4", text="Fourth", slider=True) class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): @@ -551,19 +669,24 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) tex = context.texture - layout.prop(tex, "noise_distortion") - layout.prop(tex, "noise_basis", text="Basis") + col = flow.column() + col.prop(tex, "noise_basis", text="Noise Basis") - split = layout.split() + col.separator() - col = split.column() - col.prop(tex, "distortion", text="Distortion") - col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "noise_distortion", text="Distortion") - split.prop(tex, "nabla") + col.separator() + + col = flow.column() + col.prop(tex, "distortion", text="Amount") + col.prop(tex, "noise_scale", text="Size") + col.prop(tex, "nabla") class TextureSlotPanel(TextureButtonsPanel): @@ -595,68 +718,64 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) idblock = context_tex_datablock(context) tex = context.texture_slot - if not isinstance(idblock, Brush): - split = layout.split(percentage=0.3) - col = split.column() - col.label(text="Coordinates:") - col = split.column() - col.prop(tex, "texture_coords", text="") + if isinstance(idblock, Brush): + if context.sculpt_object or context.image_paint_object: + brush_texture_settings(layout, idblock, context.sculpt_object) + else: + col = flow.column() - if tex.texture_coords == 'ORCO': - """ - ob = context.object - if ob and ob.type == 'MESH': - split = layout.split(percentage=0.3) - split.label(text="Mesh:") - split.prop(ob.data, "texco_mesh", text="") - """ - elif tex.texture_coords == 'UV': - split = layout.split(percentage=0.3) - split.label(text="Map:") + col.prop(tex, "texture_coords", text="Coordinates") + + # Note: the ORCO case used to call ob.data, "texco_mesh" prop. + if tex.texture_coords == 'UV': ob = context.object + if ob and ob.type == 'MESH': - split.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="") + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="Map") + row.label(text="", icon='BLANK1') else: - split.prop(tex, "uv_layer", text="") + col.prop(tex, "uv_layer", text="Map") elif tex.texture_coords == 'OBJECT': - split = layout.split(percentage=0.3) - split.label(text="Object:") - split.prop(tex, "object", text="") + col.prop(tex, "object", text="Object") elif tex.texture_coords == 'ALONG_STROKE': - split = layout.split(percentage=0.3) - split.label(text="Use Tips:") - split.prop(tex, "use_tips", text="") + col.prop(tex, "use_tips", text="Use Tips") + + col.separator() - if isinstance(idblock, Brush): - if context.sculpt_object or context.image_paint_object: - brush_texture_settings(layout, idblock, context.sculpt_object) - else: if isinstance(idblock, FreestyleLineStyle): - split = layout.split(percentage=0.3) - split.label(text="Projection:") - split.prop(tex, "mapping", text="") + col = flow.column() + col.prop(tex, "mapping", text="Projection") + + col.separator() + + col = flow.column() + col.prop(tex, "mapping_x", text="Mapping X") + col.prop(tex, "mapping_y", text="Y") + col.prop(tex, "mapping_z", text="Z") - split = layout.split(percentage=0.3) - split.separator() - row = split.row() - row.prop(tex, "mapping_x", text="") - row.prop(tex, "mapping_y", text="") - row.prop(tex, "mapping_z", text="") + col.separator() - row = layout.row() - row.column().prop(tex, "offset") - row.column().prop(tex, "scale") + col = flow.column(align=True) + col.column().prop(tex, "offset") + + col = flow.column(align=True) + col.column().prop(tex, "scale") class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" + bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod @@ -672,107 +791,126 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel): return (engine in cls.COMPAT_ENGINES) def draw(self, context): - layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) idblock = context_tex_datablock(context) - tex = context.texture_slot def factor_but(layout, toggle, factor, name): row = layout.row(align=True) - row.prop(tex, toggle, text="") + row.active = getattr(tex, toggle) + + row.prop(tex, factor, text=name, slider=True) sub = row.row(align=True) - sub.active = getattr(tex, toggle) - sub.prop(tex, factor, text=name, slider=True) + sub.prop(tex, toggle, text="") return sub # XXX, temp. use_map_normal needs to override. if isinstance(idblock, ParticleSettings): - split = layout.split() - - col = split.column() - col.label(text="General:") - factor_but(col, "use_map_time", "time_factor", "Time") + col = flow.column() + factor_but(col, "use_map_time", "time_factor", "General Time") factor_but(col, "use_map_life", "life_factor", "Lifetime") factor_but(col, "use_map_density", "density_factor", "Density") factor_but(col, "use_map_size", "size_factor", "Size") - col = split.column() - col.label(text="Physics:") - factor_but(col, "use_map_velocity", "velocity_factor", "Velocity") + col.separator() + + col = flow.column() + factor_but(col, "use_map_velocity", "velocity_factor", "Physics Velocity") factor_but(col, "use_map_damp", "damp_factor", "Damp") factor_but(col, "use_map_gravity", "gravity_factor", "Gravity") factor_but(col, "use_map_field", "field_factor", "Force Fields") - layout.label(text="Hair:") - - split = layout.split() + col.separator() - col = split.column() - factor_but(col, "use_map_length", "length_factor", "Length") + col = flow.column() + factor_but(col, "use_map_length", "length_factor", "Hair Length") factor_but(col, "use_map_clump", "clump_factor", "Clump") factor_but(col, "use_map_twist", "twist_factor", "Twist") - col = split.column() + col = flow.column() factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude") factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency") factor_but(col, "use_map_rough", "rough_factor", "Rough") elif isinstance(idblock, FreestyleLineStyle): - split = layout.split() - - col = split.column() + col = flow.column() factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color") - col = split.column() factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") - layout.separator() - if not isinstance(idblock, ParticleSettings): - split = layout.split() + col = flow.column() - col = split.column() col.prop(tex, "blend_type", text="Blend") col.prop(tex, "use_rgb_to_intensity") + # color is used on gray-scale textures even when use_rgb_to_intensity is disabled. col.prop(tex, "color", text="") - col = split.column() + col = flow.column() col.prop(tex, "invert", text="Negative") col.prop(tex, "use_stencil") -class TEXTURE_PT_colors(TextureButtonsPanel, Panel): - bl_label = "Colors" - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - +class TextureColorsPoll: @classmethod def poll(cls, context): tex = context.texture return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES) + +class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel): + bl_label = "Colors" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + def draw(self, context): layout = self.layout layout.use_property_split = True + flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False) tex = context.texture - col = layout.column() - sub = col.column(align=True) - sub.prop(tex, "factor_red", text="Multiply R") - sub.prop(tex, "factor_green", text="G") - sub.prop(tex, "factor_blue", text="B") + col = flow.column() + col.prop(tex, "use_clamp", text="Clamp") + + col = flow.column(align=True) + col.prop(tex, "factor_red", text="Multiply R") + col.prop(tex, "factor_green", text="G") + col.prop(tex, "factor_blue", text="B") + col.separator() + + col = flow.column() col.prop(tex, "intensity") col.prop(tex, "contrast") col.prop(tex, "saturation") - col.prop(tex, "use_clamp", text="Clamp") - col.prop(tex, "use_color_ramp", text="Ramp") - if tex.use_color_ramp: - layout.use_property_split = False + +class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): + bl_label = "Color Ramp" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'TEXTURE_PT_colors' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + tex = context.texture + self.layout.prop(tex, "use_color_ramp", text="") + + def draw(self, context): + layout = self.layout + + tex = context.texture + + # Note: TODO after creation of a new texture, the template_color_ramp will be blank. + # Possibly needs to be fixed in the template itself. + is_active = bool(tex and tex.use_color_ramp) + if is_active: layout.template_color_ramp(tex, "color_ramp", expand=True) + else: + layout.alignment = 'RIGHT' + layout.label("Please enable the Color Ramp first") class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): @@ -792,8 +930,6 @@ classes = ( TEXTURE_PT_context, TEXTURE_PT_node, TEXTURE_PT_node_mapping, - TEXTURE_PT_mapping, - TEXTURE_PT_influence, TEXTURE_PT_clouds, TEXTURE_PT_wood, TEXTURE_PT_marble, @@ -801,13 +937,19 @@ classes = ( TEXTURE_PT_blend, TEXTURE_PT_stucci, TEXTURE_PT_image, + TEXTURE_PT_image_settings, TEXTURE_PT_image_alpha, - TEXTURE_PT_image_sampling, TEXTURE_PT_image_mapping, + TEXTURE_PT_image_mapping_crop, + TEXTURE_PT_image_sampling, TEXTURE_PT_musgrave, TEXTURE_PT_voronoi, + TEXTURE_PT_voronoi_feature_weights, TEXTURE_PT_distortednoise, + TEXTURE_PT_influence, + TEXTURE_PT_mapping, TEXTURE_PT_colors, + TEXTURE_PT_colors_ramp, TEXTURE_PT_custom_props, ) -- cgit v1.2.3 From 5f1ead63953527abd9ddca16986990d59f123aff Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 25 Jul 2018 14:52:29 +0200 Subject: Fix T55895: VSE crash while moving a strip Glitch from multi-edit project. ;) --- source/blender/editors/transform/transform_snap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index b67fd22dbff..54253e36351 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1462,7 +1462,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2]) float xmouse, ymouse; int frame; int mframe; - TransSeq *ts = t->custom.type.data; + TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data; /* reuse increment, strictly speaking could be another snap mode, but leave as is */ if (!(t->modifiers & MOD_SNAP_INVERT)) return; -- cgit v1.2.3 From 421017d24a05f7c83c3933d158b9cf7b8f28c00c Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Wed, 25 Jul 2018 15:04:19 +0200 Subject: UI: Node Editor Properties single column Color and Properties panels as sub-panels of Node. Collapse Node properties by default, since they are already in the node itself and in material properties. --- release/scripts/startup/bl_ui/space_node.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 9d8c14ba9c3..45343c09b27 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -364,7 +364,6 @@ class NODE_PT_active_node_generic(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_label = "Node" -# bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): @@ -383,6 +382,7 @@ class NODE_PT_active_node_color(Panel): bl_region_type = 'UI' bl_label = "Color" bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'NODE_PT_active_node_generic' @classmethod def poll(cls, context): @@ -410,6 +410,8 @@ class NODE_PT_active_node_properties(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_label = "Properties" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = 'NODE_PT_active_node_generic' @classmethod def poll(cls, context): @@ -453,18 +455,22 @@ class NODE_PT_backdrop(Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True snode = context.space_data layout.active = snode.show_backdrop - layout.prop(snode, "backdrop_channels", text="") - layout.prop(snode, "backdrop_zoom", text="Zoom") - col = layout.column(align=True) - col.label(text="Offset:") - col.prop(snode, "backdrop_offset", text="") - col.operator("node.backimage_move", text="Move") + col = layout.column() + + col.prop(snode, "backdrop_channels", text="Channels") + col.prop(snode, "backdrop_zoom", text="Zoom") - layout.operator("node.backimage_fit", text="Fit") + col.prop(snode, "backdrop_offset", text="Offset") + + col.separator() + + col.operator("node.backimage_move", text="Move") + col.operator("node.backimage_fit", text="Fit") class NODE_PT_quality(bpy.types.Panel): @@ -479,6 +485,7 @@ class NODE_PT_quality(bpy.types.Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True snode = context.space_data tree = snode.node_tree @@ -522,6 +529,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList): class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} # NOTE: this is just a wrapper around the generic GP Panel -- cgit v1.2.3 From 5d0a3d3c9ce326ba0f90d43d8215b755418aa081 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 25 Jul 2018 15:57:30 +0200 Subject: UI: Dynamic Paint single column and sub panels --- .../bl_ui/properties_physics_dynamicpaint.py | 328 ++++++++++++++------- 1 file changed, 223 insertions(+), 105 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 611f477a31b..44d07ff53e6 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -87,24 +87,22 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="") col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="") + layout.use_property_split = True + if surface: layout.prop(surface, "surface_format") col = layout.column() if surface.surface_format != 'VERTEX': - col.label(text="Quality:") col.prop(surface, "image_resolution") col.prop(surface, "use_antialiasing") - col = layout.column() - col.label(text="Frames:") - split = col.split() - col = split.column(align=True) - col.prop(surface, "frame_start", text="Start") - col.prop(surface, "frame_end", text="End") + sub = col.column(align=True) + sub.prop(surface, "frame_start", text="Frame Start") + sub.prop(surface, "frame_end", text="End") - split.prop(surface, "frame_substeps") + col.prop(surface, "frame_substeps") elif md.ui_type == 'BRUSH': brush = md.brush_settings @@ -114,16 +112,14 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): else: layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH' - split = layout.split() + layout.use_property_split = True - col = split.column() + col = layout.column() + col.prop(brush, "paint_color") + col.prop(brush, "paint_alpha", text="Alpha", slider=True) + col.prop(brush, "paint_wetness", text="Wetness", slider=True) col.prop(brush, "use_absolute_alpha") col.prop(brush, "use_paint_erase") - col.prop(brush, "paint_wetness", text="Wetness") - - col = split.column() - col.prop(brush, "paint_color", text="") - col.prop(brush, "paint_alpha", text="Alpha") class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): @@ -141,65 +137,113 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel): canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active - surface_type = surface.surface_type + layout.use_property_split = True + layout.prop(surface, "surface_type") + layout.separator() - # dissolve - if surface_type == 'PAINT': - split = layout.split(percentage=0.35) - split.prop(surface, "use_drying", text="Dry:") - - col = split.column() - col.active = surface.use_drying - split = col.split(percentage=0.7) - col = split.column(align=True) - col.prop(surface, "dry_speed", text="Time") - col.prop(surface, "color_dry_threshold") - split.prop(surface, "use_dry_log", text="Slow") - - if surface_type != 'WAVE': - split = layout.split(percentage=0.35) - col = split.column() - if surface_type == 'WEIGHT': - col.prop(surface, "use_dissolve", text="Fade:") - else: - col.prop(surface, "use_dissolve", text="Dissolve:") - col = split.column() - col.active = surface.use_dissolve - split = col.split(percentage=0.7) - split.prop(surface, "dissolve_speed", text="Time") - split.prop(surface, "use_dissolve_log", text="Slow") + col = layout.column() # per type settings if surface_type == 'DISPLACE': - layout.prop(surface, "use_incremental_displace") + col.prop(surface, "use_incremental_displace") if surface.surface_format == 'VERTEX': - row = layout.row() - row.prop(surface, "depth_clamp") - row.prop(surface, "displace_factor") - - elif surface_type == 'WAVE': - layout.prop(surface, "use_wave_open_border") + col.prop(surface, "depth_clamp") + col.prop(surface, "displace_factor") - split = layout.split() + col.separator() - col = split.column(align=True) + elif surface_type == 'WAVE': + col.prop(surface, "use_wave_open_border") col.prop(surface, "wave_timescale") col.prop(surface, "wave_speed") - - col = split.column(align=True) col.prop(surface, "wave_damping") col.prop(surface, "wave_spring") col.prop(surface, "wave_smoothness") - layout.separator() - layout.prop(surface, "brush_group") - row = layout.row() - row.prop(surface, "brush_influence_scale") - row.prop(surface, "brush_radius_scale") + col.separator() + + col.prop(surface, "brush_group") + col.prop(surface, "brush_influence_scale") + col.prop(surface, "brush_radius_scale") + + +class PHYSICS_PT_dp_advanced_canvas_paint_dry(PhysicButtonsPanel, Panel): + bl_label = "Dry" + bl_parent_id = "PHYSICS_PT_dp_advanced_canvas" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type == 'PAINT' and context.engine in cls.COMPAT_ENGINES + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + self.layout.prop(surface, "use_drying", text="") + + def draw(self, context): + layout = self.layout + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + layout.use_property_split = True + + layout.active = surface.use_drying + + col = layout.column() + col.prop(surface, "dry_speed", text="Time") + col.prop(surface, "color_dry_threshold") + col.prop(surface, "use_dry_log", text="Slow") + + +class PHYSICS_PT_dp_advanced_canvas_paint_dissolve(PhysicButtonsPanel, Panel): + bl_label = "Dissolve" + bl_parent_id = "PHYSICS_PT_dp_advanced_canvas" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type != 'WAVE' and context.engine in cls.COMPAT_ENGINES + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + self.layout.prop(surface, "use_dissolve", text="") + + + def draw(self, context): + layout = self.layout + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + surface_type = surface.surface_type + + layout.use_property_split = True + + layout.active = surface.use_dissolve + + col = layout.column() + + col.prop(surface, "dissolve_speed", text="Time") + col.prop(surface, "use_dissolve_log", text="Slow") class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): @@ -220,6 +264,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active @@ -317,6 +362,8 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): surface = canvas.canvas_surfaces.active ob = context.object + layout.use_property_split = True + layout.prop(surface, "init_color_type", expand=False) if surface.init_color_type != 'NONE': layout.separator() @@ -350,37 +397,86 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + + +class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel): + bl_label = "Spread" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): canvas = context.dynamic_paint.canvas_settings surface = canvas.canvas_surfaces.active - layout.row().prop(surface, "effect_ui", expand=True) + self.layout.prop(surface, "use_spread", text="") - if surface.effect_ui == 'SPREAD': - layout.prop(surface, "use_spread") + def draw(self, context): + layout = self.layout - row = layout.row() - row.active = surface.use_spread - row.prop(surface, "spread_speed") - row.prop(surface, "color_spread_speed") + layout.use_property_split = True - elif surface.effect_ui == 'DRIP': - layout.prop(surface, "use_drip") + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + layout.active = surface.use_spread - col = layout.column() - col.active = surface.use_drip - effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') + col = layout.column() - layout.label(text="Surface Movement:") - row = layout.row() - row.prop(surface, "drip_velocity", slider=True) - row.prop(surface, "drip_acceleration", slider=True) + col.prop(surface, "spread_speed") + col.prop(surface, "color_spread_speed") - elif surface.effect_ui == 'SHRINK': - layout.prop(surface, "use_shrink") - row = layout.row() - row.active = surface.use_shrink - row.prop(surface, "shrink_speed") +class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel): + bl_label = "Drip" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + self.layout.prop(surface, "use_drip", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + layout.active = surface.use_drip + + col = layout.column() + col.prop(surface, "drip_velocity", slider=True) + col.prop(surface, "drip_acceleration", slider=True) + + col.separator() + + effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') + +class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel): + bl_label = "Shrink" + bl_parent_id = "PHYSICS_PT_dp_effects" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + + self.layout.prop(surface, "use_shrink", text="") + + def draw(self, context): + layout = self.layout + + layout.use_property_split = True + + canvas = context.dynamic_paint.canvas_settings + surface = canvas.canvas_surfaces.active + layout.active = surface.use_shrink + + layout.prop(surface, "shrink_speed") class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): @@ -418,6 +514,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings ob = context.object @@ -427,7 +524,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): col.prop(brush, "paint_source") if brush.paint_source == 'PARTICLE_SYSTEM': - col.prop_search(brush, "particle_system", ob, "particle_systems", text="") + col.prop_search(brush, "particle_system", ob, "particle_systems") if brush.particle_system: col.label(text="Particle Effect:") sub = col.column() @@ -438,22 +535,19 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}: col.prop(brush, "paint_distance", text="Paint Distance") - split = layout.row().split(percentage=0.4) - sub = split.column() + if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: - sub.prop(brush, "use_proximity_project") + col.prop(brush, "use_proximity_project") if brush.paint_source == 'VOLUME_DISTANCE': - sub.prop(brush, "invert_proximity") - sub.prop(brush, "use_negative_volume") - - sub = split.column() + col.prop(brush, "invert_proximity") + col.prop(brush, "use_negative_volume") if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}: - column = sub.column() - column.active = brush.use_proximity_project - column.prop(brush, "ray_direction") - sub.prop(brush, "proximity_falloff") + sub = col.column() + sub.active = brush.use_proximity_project + sub.prop(brush, "ray_direction") + col.prop(brush, "proximity_falloff") if brush.proximity_falloff == 'RAMP': - col = layout.row().column() + col.separator() col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha") col.template_color_ramp(brush, "paint_ramp", expand=True) @@ -472,28 +566,45 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings - split = layout.split() - - col = split.column() + col = layout.column() col.prop(brush, "use_velocity_alpha") col.prop(brush, "use_velocity_color") - - split.prop(brush, "use_velocity_depth") + col.prop(brush, "use_velocity_depth") col = layout.column() col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth) col.prop(brush, "velocity_max") col.template_color_ramp(brush, "velocity_ramp", expand=True) - layout.separator() - row = layout.row() - row.prop(brush, "use_smudge") - sub = row.row() - sub.active = brush.use_smudge - sub.prop(brush, "smudge_strength") + +class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel): + bl_label = "Smudge" + bl_parent_id = "PHYSICS_PT_dp_brush_velocity" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + md = context.dynamic_paint + return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES) + + def draw_header(self, context): + brush = context.dynamic_paint.brush_settings + + self.layout.prop(brush, "use_smudge", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + brush = context.dynamic_paint.brush_settings + + layout.active = brush.use_smudge + layout.prop(brush, "smudge_strength", slider=True) class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): @@ -509,26 +620,33 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True brush = context.dynamic_paint.brush_settings layout.prop(brush, "wave_type") if brush.wave_type != 'REFLECT': - row = layout.row() - row.prop(brush, "wave_factor") - row.prop(brush, "wave_clamp") + col = layout.column() + col.prop(brush, "wave_factor") + col.prop(brush, "wave_clamp") classes = ( PHYSICS_UL_dynapaint_surfaces, PHYSICS_PT_dynamic_paint, PHYSICS_PT_dp_advanced_canvas, + PHYSICS_PT_dp_advanced_canvas_paint_dry, + PHYSICS_PT_dp_advanced_canvas_paint_dissolve, PHYSICS_PT_dp_canvas_output, PHYSICS_PT_dp_canvas_initial_color, PHYSICS_PT_dp_effects, + PHYSICS_PT_dp_effects_spread, + PHYSICS_PT_dp_effects_drip, + PHYSICS_PT_dp_effects_shrink, PHYSICS_PT_dp_cache, PHYSICS_PT_dp_brush_source, PHYSICS_PT_dp_brush_velocity, + PHYSICS_PT_dp_brush_velocity_smudge, PHYSICS_PT_dp_brush_wave, ) -- cgit v1.2.3 From 41130ecf16b661391915e0ace14ee941045b4a52 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:35:27 +0200 Subject: Cleanup: mark missing Cycles view layer override features with TODO. --- intern/cycles/blender/blender_mesh.cpp | 15 +++------------ intern/cycles/blender/blender_object.cpp | 24 ++++++++++++++---------- intern/cycles/blender/blender_session.cpp | 10 ++++------ intern/cycles/blender/blender_sync.cpp | 17 ----------------- intern/cycles/blender/blender_sync.h | 15 ++------------- 5 files changed, 23 insertions(+), 58 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 08206dd5521..8a6480a9a42 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -1080,27 +1080,18 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph, /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data; - BL::Material material_override = view_layer.material_override; /* find shader indices */ vector used_shaders; BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { - if(material_override) { - find_shader(material_override, used_shaders, scene->default_surface); - } - else { - BL::ID b_material(slot->material()); - find_shader(b_material, used_shaders, scene->default_surface); - } + BL::ID b_material(slot->material()); + find_shader(b_material, used_shaders, scene->default_surface); } if(used_shaders.size() == 0) { - if(material_override) - find_shader(material_override, used_shaders, scene->default_surface); - else - used_shaders.push_back(scene->default_surface); + used_shaders.push_back(scene->default_surface); } /* test if we need to sync */ diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index ed01d728931..56365d12bab 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -292,7 +292,6 @@ void BlenderSync::sync_background_light(bool use_portal) Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, BL::DepsgraphObjectInstance& b_instance, - uint layer_flag, float motion_time, bool hide_tris, BlenderObjectCulling& culling, @@ -314,10 +313,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, } /* light is handled separately */ - if(object_is_light(b_ob)) { - /* don't use lights for excluded layers used as mask layer */ - if(!motion && !((layer_flag & view_layer.holdout_layer) && - (layer_flag & view_layer.exclude_layer))) + if(!motion && object_is_light(b_ob)) { + /* TODO: don't use lights for excluded layers used as mask layer, + * when dynamic overrides are back. */ +#if 0 + if(!((layer_flag & view_layer.holdout_layer) && + (layer_flag & view_layer.exclude_layer))) +#endif { sync_light(b_parent, persistent_id, @@ -343,23 +345,26 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); - bool use_holdout = (layer_flag & view_layer.holdout_layer) != 0 || - get_boolean(cobject, "is_holdout"); + bool use_holdout = get_boolean(cobject, "is_holdout"); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { visibility &= object_ray_visibility(b_parent); } - /* Make holdout objects on excluded layer invisible for non-camera rays. */ + /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */ +#if 0 if(use_holdout && (layer_flag & view_layer.exclude_layer)) { visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA); } +#endif - /* Hide objects not on render layer from camera rays. */ + /* TODO: hide objects not on render layer from camera rays. */ +#if 0 if(!(layer_flag & view_layer.layer)) { visibility &= ~PATH_RAY_CAMERA; } +#endif /* Don't export completely invisible objects. */ if(visibility == 0) { @@ -605,7 +610,6 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) /* object itself */ sync_object(b_depsgraph, b_instance, - ~(0), /* until we get rid of layers */ motion_time, hide_tris, culling, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index cd55155e33b..1a4b26128e3 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -461,15 +461,13 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_) scene->integrator->tag_update(scene); } - /* Update number of samples per layer. */ - int samples = sync->get_layer_samples(); - bool bound_samples = sync->get_layer_bound_samples(); - int effective_layer_samples; + int effective_layer_samples = session_params.samples; + /* TODO: Update number of samples per layer. */ +#if 0 if(samples != 0 && (!bound_samples || (samples < session_params.samples))) effective_layer_samples = samples; - else - effective_layer_samples = session_params.samples; +#endif /* Update tile manager if we're doing resumable render. */ update_resumable_tile_manager(effective_layer_samples); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3204e0cd3f2..93232fbf98f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -365,28 +365,11 @@ void BlenderSync::sync_film() void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer) { /* render layer */ - uint layer_override = get_layer(b_engine.layer_override()); - uint view_layers = layer_override ? layer_override : get_layer(b_scene.layers()); - view_layer.name = b_view_layer.name(); - - view_layer.holdout_layer = 0; - view_layer.exclude_layer = 0; - - view_layer.view_layer = view_layers & ~view_layer.exclude_layer; - view_layer.view_layer |= view_layer.exclude_layer & view_layer.holdout_layer; - - view_layer.layer = (1 << 20) - 1; - view_layer.layer |= view_layer.holdout_layer; - - view_layer.material_override = PointerRNA_NULL; view_layer.use_background_shader = b_view_layer.use_sky(); view_layer.use_background_ao = b_view_layer.use_ao(); view_layer.use_surfaces = b_view_layer.use_solid(); view_layer.use_hair = b_view_layer.use_strand(); - - view_layer.bound_samples = false; - view_layer.samples = 0; } /* Images */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 0465f703c51..ba3f5e6428f 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -127,7 +127,6 @@ private: int motion_step = 0); Object *sync_object(BL::Depsgraph& b_depsgraph, BL::DepsgraphObjectInstance& b_instance, - uint layer_flag, float motion_time, bool hide_tris, BlenderObjectCulling& culling, @@ -191,28 +190,18 @@ private: struct RenderLayerInfo { RenderLayerInfo() - : view_layer(0), layer(0), - holdout_layer(0), exclude_layer(0), - material_override(PointerRNA_NULL), - use_background_shader(true), + : use_background_shader(true), use_background_ao(true), use_surfaces(true), - use_hair(true), - samples(0), bound_samples(false) + use_hair(true) {} string name; uint view_layer; - uint layer; /* This can be safely removed from Cycles. */ - uint holdout_layer; /* This can be safely removed from Cycles. */ - uint exclude_layer; /* This can be safely removed from Cycles. */ - BL::Material material_override; /* This can be safely removed from Cycles. */ bool use_background_shader; bool use_background_ao; bool use_surfaces; bool use_hair; - int samples; /* This can be safely removed from Cycles. */ - bool bound_samples; /* This can be safely removed from Cycles. */ } view_layer; Progress &progress; -- cgit v1.2.3 From b0077992d2759b29b536187a226e8382b72261b6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:26:09 +0200 Subject: Cycles: add per layer collection mask/holdout support. In the outliner, right click > view layer > set holdout. This is temporary until we have more general dynamic overrides, but helps Spring production for now. --- intern/cycles/blender/blender_object.cpp | 6 +- intern/cycles/blender/blender_sync.h | 3 +- release/scripts/startup/bl_ui/space_outliner.py | 8 +- source/blender/blenkernel/intern/layer.c | 12 ++- source/blender/blenloader/intern/versioning_280.c | 1 + .../editors/space_outliner/outliner_collections.c | 87 ++++++++++++++++------ .../editors/space_outliner/outliner_intern.h | 4 +- .../blender/editors/space_outliner/outliner_ops.c | 6 +- source/blender/makesdna/DNA_layer_types.h | 2 + source/blender/makesrna/intern/rna_layer.c | 6 ++ source/blender/makesrna/intern/rna_object_api.c | 32 ++++++-- 11 files changed, 129 insertions(+), 38 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 56365d12bab..fd8790c0c79 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -291,6 +291,7 @@ void BlenderSync::sync_background_light(bool use_portal) /* Object */ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, + BL::ViewLayer& b_view_layer, BL::DepsgraphObjectInstance& b_instance, float motion_time, bool hide_tris, @@ -345,7 +346,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); - bool use_holdout = get_boolean(cobject, "is_holdout"); + bool use_holdout = get_boolean(cobject, "is_holdout") || + b_ob.holdout_get(b_view_layer); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { @@ -588,6 +590,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) bool cancel = false; bool use_portal = false; + BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode(); BL::Depsgraph::object_instances_iterator b_instance_iter; @@ -609,6 +612,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) { /* object itself */ sync_object(b_depsgraph, + b_view_layer, b_instance, motion_time, hide_tris, diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index ba3f5e6428f..e63ef9e5e47 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -78,8 +78,6 @@ public: void sync_view(BL::SpaceView3D& b_v3d, BL::RegionView3D& b_rv3d, int width, int height); - inline int get_layer_samples() { return view_layer.samples; } - inline int get_layer_bound_samples() { return view_layer.bound_samples; } /* get parameters */ static SceneParams get_scene_params(BL::Scene& b_scene, @@ -126,6 +124,7 @@ private: bool motion, int motion_step = 0); Object *sync_object(BL::Depsgraph& b_depsgraph, + BL::ViewLayer& b_view_layer, BL::DepsgraphObjectInstance& b_instance, float motion_time, bool hide_tris, diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 8f722c4d3ce..284a49c8789 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -142,8 +142,12 @@ class OUTLINER_MT_collection_view_layer(Menu): space = context.space_data - layout.operator("outliner.collection_exclude_set", text="Exclude") - layout.operator("outliner.collection_include_set", text="Include") + layout.operator("outliner.collection_exclude_set") + layout.operator("outliner.collection_exclude_clear") + + if context.engine == 'CYCLES': + layout.operator("outliner.collection_holdout_set") + layout.operator("outliner.collection_holdout_clear") class OUTLINER_MT_collection(Menu): diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 2f5c8e7817e..73a217b8865 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -715,6 +715,11 @@ static int layer_collection_sync( lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS; } + /* Holdout */ + if (lc->flag & LAYER_COLLECTION_HOLDOUT) { + base->flag |= BASE_HOLDOUT; + } + lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS; } @@ -750,7 +755,12 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer) /* Clear visible and selectable flags to be reset. */ for (Base *base = view_layer->object_bases.first; base; base = base->next) { - base->flag &= ~(BASE_VISIBLE | BASE_ENABLED | BASE_SELECTABLE | BASE_ENABLED_VIEWPORT | BASE_ENABLED_RENDER); + base->flag &= ~(BASE_VISIBLE | + BASE_ENABLED | + BASE_SELECTABLE | + BASE_ENABLED_VIEWPORT | + BASE_ENABLED_RENDER | + BASE_HOLDOUT); } view_layer->runtime_flag = 0; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 3a586e49ab3..94afc410000 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -492,6 +492,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) { if (srl->lay_zmask & (1 << layer)) { have_override = true; + lc->flag |= LAYER_COLLECTION_HOLDOUT; BKE_override_layer_collection_boolean_add( lc, diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index ad94615a0d2..eec1d654944 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -574,7 +574,7 @@ static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, v return TRAVERSE_CONTINUE; } -static bool collections_view_layer_poll(bContext *C, bool include) +static bool collections_view_layer_poll(bContext *C, bool clear, int flag) { /* Poll function so the right click menu show current state of selected collections. */ SpaceOops *soops = CTX_wm_space_outliner(C); @@ -593,10 +593,10 @@ static bool collections_view_layer_poll(bContext *C, bool include) GSET_ITER(collections_to_edit_iter, data.collections_to_edit) { LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); - if (include && (lc->flag & LAYER_COLLECTION_EXCLUDE)) { + if (clear && (lc->flag & flag)) { result = true; } - else if (!include && !(lc->flag & LAYER_COLLECTION_EXCLUDE)) { + else if (!clear && !(lc->flag & flag)) { result = true; } } @@ -605,27 +605,37 @@ static bool collections_view_layer_poll(bContext *C, bool include) return result; } -static bool collections_exclude_poll(bContext *C) +static bool collections_exclude_set_poll(bContext *C) { - return collections_view_layer_poll(C, false); + return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE); } -static bool collections_include_poll(bContext *C) +static bool collections_exclude_clear_poll(bContext *C) { - return collections_view_layer_poll(C, true); + return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE); } -static void layer_collection_exclude_recursive_set(LayerCollection *lc) +static bool collections_holdout_set_poll(bContext *C) +{ + return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT); +} + +static bool collections_holdout_clear_poll(bContext *C) +{ + return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT); +} + +static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag) { for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { - if (lc->flag & LAYER_COLLECTION_EXCLUDE) { - nlc->flag |= LAYER_COLLECTION_EXCLUDE; + if (lc->flag & flag) { + nlc->flag |= flag; } else { - nlc->flag &= ~LAYER_COLLECTION_EXCLUDE; + nlc->flag &= ~flag; } - layer_collection_exclude_recursive_set(nlc); + layer_collection_flag_recursive_set(nlc, flag); } } @@ -636,7 +646,8 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); SpaceOops *soops = CTX_wm_space_outliner(C); struct CollectionEditData data = {.scene = scene, .soops = soops}; - bool include = STREQ(op->idname, "OUTLINER_OT_collection_include_set"); + bool clear = strstr(op->idname, "clear") != NULL; + int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT : LAYER_COLLECTION_EXCLUDE; data.collections_to_edit = BLI_gset_ptr_new(__func__); @@ -647,14 +658,14 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter); if (!(lc->collection->flag & COLLECTION_IS_MASTER)) { - if (include) { - lc->flag &= ~LAYER_COLLECTION_EXCLUDE; + if (clear) { + lc->flag &= ~flag; } else { - lc->flag |= LAYER_COLLECTION_EXCLUDE; + lc->flag |= flag; } - layer_collection_exclude_recursive_set(lc); + layer_collection_flag_recursive_set(lc, flag); } } @@ -671,28 +682,58 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot) { /* identifiers */ - ot->name = "Exclude from View Layer"; + ot->name = "Set Exclude"; ot->idname = "OUTLINER_OT_collection_exclude_set"; ot->description = "Exclude collection from the active view layer"; /* api callbacks */ ot->exec = collection_view_layer_exec; - ot->poll = collections_exclude_poll; + ot->poll = collections_exclude_set_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -void OUTLINER_OT_collection_include_set(wmOperatorType *ot) +void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot) { /* identifiers */ - ot->name = "Include in View Layer"; - ot->idname = "OUTLINER_OT_collection_include_set"; + ot->name = "Clear Exclude"; + ot->idname = "OUTLINER_OT_collection_exclude_clear"; ot->description = "Include collection in the active view layer"; /* api callbacks */ ot->exec = collection_view_layer_exec; - ot->poll = collections_include_poll; + ot->poll = collections_exclude_clear_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Holdout"; + ot->idname = "OUTLINER_OT_collection_holdout_set"; + ot->description = "Mask collection in the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_holdout_set_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Holdout"; + ot->idname = "OUTLINER_OT_collection_holdout_clear"; + ot->description = "Clear masking of collection in the active view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_holdout_clear_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 093ad9361c2..9262cf8578c 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -358,7 +358,9 @@ void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot); void OUTLINER_OT_collection_link(struct wmOperatorType *ot); void OUTLINER_OT_collection_instance(struct wmOperatorType *ot); void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot); -void OUTLINER_OT_collection_include_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_exclude_clear(struct wmOperatorType *ot); +void OUTLINER_OT_collection_holdout_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_holdout_clear(struct wmOperatorType *ot); /* outliner_utils.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 8b4ae029876..4bd5a0c3792 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -457,7 +457,9 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_link); WM_operatortype_append(OUTLINER_OT_collection_instance); WM_operatortype_append(OUTLINER_OT_collection_exclude_set); - WM_operatortype_append(OUTLINER_OT_collection_include_set); + WM_operatortype_append(OUTLINER_OT_collection_exclude_clear); + WM_operatortype_append(OUTLINER_OT_collection_holdout_set); + WM_operatortype_append(OUTLINER_OT_collection_holdout_clear); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) @@ -571,7 +573,7 @@ void outliner_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "OUTLINER_OT_collection_include_set", EKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_clear", EKEY, KM_PRESS, KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "select", false); diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index bfdd21807b8..2bfe4c4e13b 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -104,6 +104,7 @@ enum { BASE_ENABLED_VIEWPORT = (1 << 6), /* Object is enabled in viewport. */ BASE_ENABLED_RENDER = (1 << 7), /* Object is enabled in final render */ BASE_ENABLED = (1 << 9), /* Object is enabled. */ + BASE_HOLDOUT = (1 << 10), /* Object masked out from render */ }; /* LayerCollection->flag */ @@ -113,6 +114,7 @@ enum { /* LAYER_COLLECTION_DEPRECATED2 = (1 << 2), */ /* LAYER_COLLECTION_DEPRECATED3 = (1 << 3), */ LAYER_COLLECTION_EXCLUDE = (1 << 4), + LAYER_COLLECTION_HOLDOUT = (1 << 5), }; /* Layer Collection->runtime_flag */ diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 7d770a99c0c..1ab69d78f03 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -230,6 +230,12 @@ static void rna_def_layer_collection(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update"); + + prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Holdout", "Mask out collection from view layer"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update"); } static void rna_def_layer_collections(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 1a2b3854668..dc799928e5a 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -148,6 +148,18 @@ static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports) return ((base->flag & BASE_VISIBLE) != 0) ? 1 : 0; } +static bool rna_Object_holdout_get(Object *ob, ReportList *reports, ViewLayer *view_layer) +{ + Base *base = BKE_view_layer_base_find(view_layer, ob); + + if (!base) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name); + return -1; + } + + return ((base->flag & BASE_HOLDOUT) != 0) ? 1 : 0; +} + /* Convert a given matrix from a space to another (using the object and/or a bone as reference). */ static void rna_Object_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan, float *mat, float *mat_ret, int from, int to) @@ -470,31 +482,39 @@ void RNA_api_object(StructRNA *srna) #endif static EnumPropertyItem object_select_items[] = { - {0, "SELECT", 0, "Select", "Select object from the active render layer"}, - {1, "DESELECT", 0, "Deselect", "Deselect object from the active render layer"}, - {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active render layer"}, + {0, "SELECT", 0, "Select", "Select object from the active view layer"}, + {1, "DESELECT", 0, "Deselect", "Deselect object from the active view layer"}, + {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active view layer"}, {0, NULL, 0, NULL, NULL} }; /* Special wrapper to access the base selection value */ func = RNA_def_function(srna, "select_set", "rna_Object_select_set"); - RNA_def_function_ui_description(func, "Select the object (for the active render layer)"); + RNA_def_function_ui_description(func, "Select the object (for the active view layer)"); RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); parm = RNA_def_enum(func, "action", object_select_items, 0, "Action", "Select mode"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "select_get", "rna_Object_select_get"); - RNA_def_function_ui_description(func, "Get the object selection for the active render layer"); + RNA_def_function_ui_description(func, "Get the object selection for the active view layer"); RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); parm = RNA_def_boolean(func, "result", 0, "", "Object selected"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "visible_get", "rna_Object_visible_get"); - RNA_def_function_ui_description(func, "Get the object visibility for the active render layer"); + RNA_def_function_ui_description(func, "Get the object visibility for the active view layer"); RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); parm = RNA_def_boolean(func, "result", 0, "", "Object visible"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "holdout_get", "rna_Object_holdout_get"); + RNA_def_function_ui_description(func, "Test if object is masked in the view layer"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_boolean(func, "result", 0, "", "Object holdout"); + RNA_def_function_return(func, parm); + /* Matrix space conversion */ func = RNA_def_function(srna, "convert_space", "rna_Object_mat_convert_space"); RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another"); -- cgit v1.2.3 From e6e8ee2922c023971c11a566cba8085c3dd70e76 Mon Sep 17 00:00:00 2001 From: William Reynish Date: Wed, 25 Jul 2018 16:12:04 +0200 Subject: UI: Single column and subpanels for Particles Physics Fluids and Boids --- .../scripts/startup/bl_ui/properties_particle.py | 449 +++++++++++++++------ 1 file changed, 316 insertions(+), 133 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 9d891a07989..75b2d76d9c4 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -662,164 +662,336 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): if part.physics_type == 'FLUID': fluid = part.fluid - col.label(text="Fluid") + col.separator() col.prop(fluid, "solver") col.prop(fluid, "stiffness", text="Stiffness") col.prop(fluid, "linear_viscosity", text="Viscosity") col.prop(fluid, "buoyancy", text="Buoyancy", slider=True) - col.label(text="Advanced") + elif part.physics_type == 'KEYED': + + sub = col.column() + sub.active = not psys.use_keyed_timing + sub.prop(part, "keyed_loops", text="Loops") + if psys: + col.prop(psys, "use_keyed_timing", text="Use Timing") + + col.label(text="Keys") + + +class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel): + bl_label = "Advanced" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - if fluid.solver == 'DDR': - sub = col.column() - sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) - sub.prop(fluid, "factor_repulsion") + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID': + return True + else: + return False - sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) - sub.prop(fluid, "factor_stiff_viscosity") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + col = layout.column() + + if fluid.solver == 'DDR': sub = col.column() - sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius) - sub.prop(fluid, "factor_radius") + sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion) + sub.prop(fluid, "factor_repulsion") - sub.prop(fluid, "rest_density", slider=fluid.use_factor_density) - sub.prop(fluid, "use_factor_density") + sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity) + sub.prop(fluid, "factor_stiff_viscosity") - if fluid.solver == 'CLASSICAL': - # With the classical solver, it is possible to calculate the - # spacing between particles when the fluid is at rest. This - # makes it easier to set stable initial conditions. - particle_volume = part.mass / fluid.rest_density - spacing = pow(particle_volume, 1.0 / 3.0) + sub = col.column() + sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius) + sub.prop(fluid, "factor_radius") - sub.label(text="Spacing: %g" % spacing) + sub.prop(fluid, "rest_density", slider=fluid.use_factor_density) + sub.prop(fluid, "use_factor_density") - elif fluid.solver == 'DDR': + if fluid.solver == 'CLASSICAL': + # With the classical solver, it is possible to calculate the + # spacing between particles when the fluid is at rest. This + # makes it easier to set stable initial conditions. + particle_volume = part.mass / fluid.rest_density + spacing = pow(particle_volume, 1.0 / 3.0) - col.label(text="Springs") - col.prop(fluid, "spring_force", text="Force") - col.prop(fluid, "use_viscoelastic_springs") + sub.label(text="Spacing: %g" % spacing) - sub = col.column() - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "yield_ratio", slider=True) - sub.prop(fluid, "plasticity", slider=True) - col.label(text="Advanced") - sub = col.column() - sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) - sub.prop(fluid, "factor_rest_length", text="") +class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel): + bl_label = "Springs" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - sub = col.column() - sub.active = fluid.use_viscoelastic_springs - sub.prop(fluid, "use_initial_rest_length") - sub.prop(fluid, "spring_frames", text="Frames") + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False - elif part.physics_type == 'KEYED': + def draw(self, context): + layout = self.layout + layout.use_property_split = True - sub = col.column() - sub.active = not psys.use_keyed_timing - sub.prop(part, "keyed_loops", text="Loops") - if psys: - col.prop(psys, "use_keyed_timing", text="Use Timing") + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid - col.label(text="Keys") + col = layout.column() - elif part.physics_type == 'BOIDS': - boids = part.boids + col.prop(fluid, "spring_force", text="Force") - row = layout.row() - row.prop(boids, "use_flight") - row.prop(boids, "use_land") - row.prop(boids, "use_climb") - - split = layout.split() - - col = split.column(align=True) - col.active = boids.use_flight - col.prop(boids, "air_speed_max") - col.prop(boids, "air_speed_min", slider=True) - col.prop(boids, "air_acc_max", slider=True) - col.prop(boids, "air_ave_max", slider=True) - col.prop(boids, "air_personal_space") - row = col.row(align=True) - row.active = (boids.use_land or boids.use_climb) and boids.use_flight - row.prop(boids, "land_smooth") - - col = split.column(align=True) - col.active = boids.use_land or boids.use_climb - col.prop(boids, "land_speed_max") - col.prop(boids, "land_jump_speed") - col.prop(boids, "land_acc_max", slider=True) - col.prop(boids, "land_ave_max", slider=True) - col.prop(boids, "land_personal_space") - col.prop(boids, "land_stick_force") - - layout.prop(part, "collision_group") - - split = layout.split() - - col = split.column(align=True) - col.label(text="Battle:") - col.prop(boids, "health") - col.prop(boids, "strength") - col.prop(boids, "aggression") - col.prop(boids, "accuracy") - col.prop(boids, "range") - col = split.column() - col.label(text="Misc:") - col.prop(boids, "bank", slider=True) - col.prop(boids, "pitch", slider=True) - col.prop(boids, "height", slider=True) - - if psys and part.physics_type in {'KEYED', 'BOIDS', 'FLUID'}: - if part.physics_type == 'BOIDS': - layout.label(text="Relations:") +class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel): + bl_label = "Viscoelastic Springs" + bl_parent_id = "PARTICLE_PT_physics_fluid_springs" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False + + def draw_header(self, context): + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + self.layout.prop(fluid, "use_viscoelastic_springs", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + col = layout.column() + col.active = fluid.use_viscoelastic_springs + col.prop(fluid, "yield_ratio", slider=True) + col.prop(fluid, "plasticity", slider=True) + + col.separator() + + col.prop(fluid, "use_initial_rest_length") + col.prop(fluid, "spring_frames", text="Frames") + + +class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel): + bl_label = "Advanced" + bl_parent_id = "PARTICLE_PT_physics_fluid_springs" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + fluid = part.fluid + if part.physics_type == 'FLUID' and fluid.solver == 'DDR': + return True + else: + return False + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + fluid = part.fluid + + sub = layout.column() + sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length) + sub.prop(fluid, "factor_rest_length") + + +class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): + bl_label = "Movement" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col=layout.column() + + col.prop(boids, "use_flight") + col.prop(boids, "use_land") + col.prop(boids, "use_climb") + + col=layout.column() + + col.active = boids.use_flight + sub = col.column() + sub.prop(boids, "air_speed_max") + sub.prop(boids, "air_speed_min", slider=True) + col.prop(boids, "air_acc_max", slider=True) + col.prop(boids, "air_ave_max", slider=True) + col.prop(boids, "air_personal_space") + row = col.row(align=True) + row.active = (boids.use_land or boids.use_climb) and boids.use_flight + row.prop(boids, "land_smooth") + + layout.separator() + + col=layout.column() + col.active = boids.use_land or boids.use_climb + col.prop(boids, "land_speed_max") + col.prop(boids, "land_jump_speed") + col.prop(boids, "land_acc_max", slider=True) + col.prop(boids, "land_ave_max", slider=True) + col.prop(boids, "land_personal_space") + col.prop(boids, "land_stick_force") + + layout.separator() + + layout.prop(part, "collision_group") + +class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): + bl_label = "Battle" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col=layout.column() + + col.prop(boids, "health") + col.prop(boids, "strength") + col.prop(boids, "aggression") + col.prop(boids, "accuracy") + col.prop(boids, "range") + +class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): + bl_label = "Misc" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'BOIDS'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + boids = part.boids + + col=layout.column() + + col.prop(boids, "bank", slider=True) + col.prop(boids, "pitch", slider=True) + col.prop(boids, "height", slider=True) + + +class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): + bl_label = "Relations" + bl_parent_id = "PARTICLE_PT_physics" + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + part = particle_get_settings(context) + return part.physics_type in {'KEYED', 'BOIDS', 'FLUID'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + psys = context.particle_system + part = particle_get_settings(context) + + + row = layout.row() + row.template_list("UI_UL_list", "particle_targets", psys, "targets", + psys, "active_particle_target_index", rows=4) + + col = row.column() + sub = col.row() + subsub = sub.column(align=True) + subsub.operator("particle.new_target", icon='ZOOMIN', text="") + subsub.operator("particle.target_remove", icon='ZOOMOUT', text="") + sub = col.row() + subsub = sub.column(align=True) + subsub.operator("particle.target_move_up", icon='TRIA_UP', text="") + subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="") + + key = psys.active_particle_target + + if key: + if part.physics_type == 'KEYED': + col = layout.column() + # doesn't work yet + #col.alert = key.valid + col.prop(key, "object") + col.prop(key, "system", text="System") + + col.active = psys.use_keyed_timing + col.prop(key, "time") + col.prop(key, "duration") + elif part.physics_type == 'BOIDS': + sub = layout.column() + # doesn't work yet + #sub.alert = key.valid + sub.prop(key, "object") + sub.prop(key, "system", text="System") + layout.prop(key, "alliance") elif part.physics_type == 'FLUID': - layout.label(text="Fluid Interaction:") + sub = layout.column() + # doesn't work yet + #sub.alert = key.valid + sub.prop(key, "object") + sub.prop(key, "system", text="System") - row = layout.row() - row.template_list("UI_UL_list", "particle_targets", psys, "targets", - psys, "active_particle_target_index", rows=4) - - col = row.column() - sub = col.row() - subsub = sub.column(align=True) - subsub.operator("particle.new_target", icon='ZOOMIN', text="") - subsub.operator("particle.target_remove", icon='ZOOMOUT', text="") - sub = col.row() - subsub = sub.column(align=True) - subsub.operator("particle.target_move_up", icon='TRIA_UP', text="") - subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="") - - key = psys.active_particle_target - if key: - row = layout.row() - if part.physics_type == 'KEYED': - col = row.column() - # doesn't work yet - #col.alert = key.valid - col.prop(key, "object", text="") - col.prop(key, "system", text="System") - col = row.column() - col.active = psys.use_keyed_timing - col.prop(key, "time") - col.prop(key, "duration") - elif part.physics_type == 'BOIDS': - sub = row.row() - # doesn't work yet - #sub.alert = key.valid - sub.prop(key, "object", text="") - sub.prop(key, "system", text="System") - - layout.row().prop(key, "alliance", expand=True) - elif part.physics_type == 'FLUID': - sub = row.row() - # doesn't work yet - #sub.alert = key.valid - sub.prop(key, "object", text="") - sub.prop(key, "system", text="System") class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): @@ -911,6 +1083,9 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_label = "Boid Brain" + bl_options = {'DEFAULT_CLOSED'} + bl_parent_id = "PARTICLE_PT_physics" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod @@ -1941,9 +2116,17 @@ classes = ( PARTICLE_PT_rotation, PARTICLE_PT_rotation_angular_velocity, PARTICLE_PT_physics, + PARTICLE_PT_physics_fluid_springs, + PARTICLE_PT_physics_fluid_springs_viscoelastic, + PARTICLE_PT_physics_fluid_springs_advanced, + PARTICLE_PT_physics_fluid_advanced, + PARTICLE_PT_physics_boids_movement, + PARTICLE_PT_physics_boids_battle, + PARTICLE_PT_physics_boids_misc, PARTICLE_PT_physics_forces, PARTICLE_PT_physics_deflection, PARTICLE_PT_physics_integration, + PARTICLE_PT_physics_relations, PARTICLE_PT_boidbrain, PARTICLE_PT_render, PARTICLE_PT_render_line, -- cgit v1.2.3 From 885cda65c90b3f85dc4e72e2e9759aa926a8f07c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:26:09 +0200 Subject: Cycles: add per layer collection indirectly on setting. In the outliner, right click > view layer > set indirect only. This is like clearing camera ray visibility on objects in the collection, and is temporary until we have more general dynamic overrides. --- intern/cycles/blender/blender_object.cpp | 7 ++-- release/scripts/startup/bl_ui/space_outliner.py | 3 ++ source/blender/blenkernel/intern/layer.c | 8 +++- source/blender/blenloader/intern/versioning_280.c | 17 +-------- .../editors/space_outliner/outliner_collections.c | 44 +++++++++++++++++++++- .../editors/space_outliner/outliner_intern.h | 2 + .../blender/editors/space_outliner/outliner_ops.c | 2 + source/blender/makesdna/DNA_layer_types.h | 2 + source/blender/makesrna/intern/rna_layer.c | 8 +++- source/blender/makesrna/intern/rna_object_api.c | 26 +++++++++++-- 10 files changed, 93 insertions(+), 26 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index fd8790c0c79..42e2198779e 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -361,12 +361,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, } #endif - /* TODO: hide objects not on render layer from camera rays. */ -#if 0 - if(!(layer_flag & view_layer.layer)) { + /* Clear camera visibility for indirect only objects. */ + bool use_indirect_only = b_ob.indirect_only_get(b_view_layer); + if(use_indirect_only) { visibility &= ~PATH_RAY_CAMERA; } -#endif /* Don't export completely invisible objects. */ if(visibility == 0) { diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py index 284a49c8789..20ef5ae0c53 100644 --- a/release/scripts/startup/bl_ui/space_outliner.py +++ b/release/scripts/startup/bl_ui/space_outliner.py @@ -146,6 +146,9 @@ class OUTLINER_MT_collection_view_layer(Menu): layout.operator("outliner.collection_exclude_clear") if context.engine == 'CYCLES': + layout.operator("outliner.collection_indirect_only_set") + layout.operator("outliner.collection_indirect_only_clear") + layout.operator("outliner.collection_holdout_set") layout.operator("outliner.collection_holdout_clear") diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 73a217b8865..1396ad1f97c 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -715,10 +715,13 @@ static int layer_collection_sync( lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS; } - /* Holdout */ + /* Holdout and indirect only */ if (lc->flag & LAYER_COLLECTION_HOLDOUT) { base->flag |= BASE_HOLDOUT; } + if (lc->flag & LAYER_COLLECTION_INDIRECT_ONLY) { + base->flag |= BASE_INDIRECT_ONLY; + } lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS; } @@ -760,7 +763,8 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer) BASE_SELECTABLE | BASE_ENABLED_VIEWPORT | BASE_ENABLED_RENDER | - BASE_HOLDOUT); + BASE_HOLDOUT | + BASE_INDIRECT_ONLY); } view_layer->runtime_flag = 0; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 94afc410000..068c12daa94 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -487,28 +487,15 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene) nlc->flag |= LAYER_COLLECTION_EXCLUDE; } } - else if ((scene->lay & srl->lay & ~(srl->lay_exclude) & (1 << layer)) || - (srl->lay_zmask & (scene->lay | srl->lay_exclude) & (1 << layer))) - { + else { if (srl->lay_zmask & (1 << layer)) { have_override = true; lc->flag |= LAYER_COLLECTION_HOLDOUT; - - BKE_override_layer_collection_boolean_add( - lc, - ID_OB, - "cycles.is_holdout", - true); } if ((srl->lay & (1 << layer)) == 0) { have_override = true; - - BKE_override_layer_collection_boolean_add( - lc, - ID_OB, - "cycles_visibility.camera", - false); + lc->flag |= LAYER_COLLECTION_INDIRECT_ONLY; } } } diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index eec1d654944..e480cac2dcc 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -625,6 +625,16 @@ static bool collections_holdout_clear_poll(bContext *C) return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT); } +static bool collections_indirect_only_set_poll(bContext *C) +{ + return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY); +} + +static bool collections_indirect_only_clear_poll(bContext *C) +{ + return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY); +} + static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag) { for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) { @@ -647,7 +657,9 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) SpaceOops *soops = CTX_wm_space_outliner(C); struct CollectionEditData data = {.scene = scene, .soops = soops}; bool clear = strstr(op->idname, "clear") != NULL; - int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT : LAYER_COLLECTION_EXCLUDE; + int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT : + strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY : + LAYER_COLLECTION_EXCLUDE; data.collections_to_edit = BLI_gset_ptr_new(__func__); @@ -739,6 +751,36 @@ void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Indirect Only"; + ot->idname = "OUTLINER_OT_collection_indirect_only_set"; + ot->description = "Set collection to only contribute indirectly (through shadows and reflections) in the view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_indirect_only_set_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Indirect Only"; + ot->idname = "OUTLINER_OT_collection_indirect_only_clear"; + ot->description = "Clear collection contributing only indirectly in the view layer"; + + /* api callbacks */ + ot->exec = collection_view_layer_exec; + ot->poll = collections_indirect_only_clear_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /** * Populates the \param objects ListBase with all the outliner selected objects * We store it as (Object *)LinkData->data diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 9262cf8578c..461d4bd7c56 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -361,6 +361,8 @@ void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot); void OUTLINER_OT_collection_exclude_clear(struct wmOperatorType *ot); void OUTLINER_OT_collection_holdout_set(struct wmOperatorType *ot); void OUTLINER_OT_collection_holdout_clear(struct wmOperatorType *ot); +void OUTLINER_OT_collection_indirect_only_set(struct wmOperatorType *ot); +void OUTLINER_OT_collection_indirect_only_clear(struct wmOperatorType *ot); /* outliner_utils.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 4bd5a0c3792..576038979d3 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -460,6 +460,8 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_exclude_clear); WM_operatortype_append(OUTLINER_OT_collection_holdout_set); WM_operatortype_append(OUTLINER_OT_collection_holdout_clear); + WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set); + WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h index 2bfe4c4e13b..e6b1bda7cf5 100644 --- a/source/blender/makesdna/DNA_layer_types.h +++ b/source/blender/makesdna/DNA_layer_types.h @@ -105,6 +105,7 @@ enum { BASE_ENABLED_RENDER = (1 << 7), /* Object is enabled in final render */ BASE_ENABLED = (1 << 9), /* Object is enabled. */ BASE_HOLDOUT = (1 << 10), /* Object masked out from render */ + BASE_INDIRECT_ONLY = (1 << 11), /* Object only contributes indirectly to render */ }; /* LayerCollection->flag */ @@ -115,6 +116,7 @@ enum { /* LAYER_COLLECTION_DEPRECATED3 = (1 << 3), */ LAYER_COLLECTION_EXCLUDE = (1 << 4), LAYER_COLLECTION_HOLDOUT = (1 << 5), + LAYER_COLLECTION_INDIRECT_ONLY = (1 << 6), }; /* Layer Collection->runtime_flag */ diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 1ab69d78f03..d425534fe53 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -234,7 +234,13 @@ static void rna_def_layer_collection(BlenderRNA *brna) prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Holdout", "Mask out collection from view layer"); + RNA_def_property_ui_text(prop, "Holdout", "Mask out objects in collection from view layer"); + RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update"); + + prop = RNA_def_property(srna, "indirect_only", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_INDIRECT_ONLY); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Indirect Only", "Objects in collection only contribute indirectly (through shadows and reflections) in the view layer"); RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update"); } diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index dc799928e5a..44709db9d94 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -128,7 +128,7 @@ static bool rna_Object_select_get(Object *ob, bContext *C, ReportList *reports) Base *base = BKE_view_layer_base_find(view_layer, ob); if (!base) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); return -1; } @@ -141,7 +141,7 @@ static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports) Base *base = BKE_view_layer_base_find(view_layer, ob); if (!base) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); return -1; } @@ -153,13 +153,25 @@ static bool rna_Object_holdout_get(Object *ob, ReportList *reports, ViewLayer *v Base *base = BKE_view_layer_base_find(view_layer, ob); if (!base) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); return -1; } return ((base->flag & BASE_HOLDOUT) != 0) ? 1 : 0; } +static bool rna_Object_indirect_only_get(Object *ob, ReportList *reports, ViewLayer *view_layer) +{ + Base *base = BKE_view_layer_base_find(view_layer, ob); + + if (!base) { + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); + return -1; + } + + return ((base->flag & BASE_INDIRECT_ONLY) != 0) ? 1 : 0; +} + /* Convert a given matrix from a space to another (using the object and/or a bone as reference). */ static void rna_Object_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan, float *mat, float *mat_ret, int from, int to) @@ -515,6 +527,14 @@ void RNA_api_object(StructRNA *srna) parm = RNA_def_boolean(func, "result", 0, "", "Object holdout"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "indirect_only_get", "rna_Object_indirect_only_get"); + RNA_def_function_ui_description(func, "Test if object is set to contribute only indirectly (through shadows and reflections) in the view layer"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_boolean(func, "result", 0, "", "Object indirect only"); + RNA_def_function_return(func, parm); + /* Matrix space conversion */ func = RNA_def_function(srna, "convert_space", "rna_Object_mat_convert_space"); RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another"); -- cgit v1.2.3 From bd326d0d1fedf2bcedbb72fb8f14847991e6cce6 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Wed, 25 Jul 2018 16:48:04 +0200 Subject: UI: Sort panels in mesh context Also collapse by default the less frequented Face Maps and Normals --- release/scripts/startup/bl_ui/properties_data_mesh.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 214852cc826..f096ff83957 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -152,6 +152,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" + bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} def draw(self, context): @@ -239,6 +240,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" + bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod @@ -450,13 +452,13 @@ classes = ( MESH_UL_shape_keys, MESH_UL_uvmaps_vcols, DATA_PT_context_mesh, - DATA_PT_normals, - DATA_PT_texture_space, DATA_PT_vertex_groups, - DATA_PT_face_maps, DATA_PT_shape_keys, DATA_PT_uv_texture, DATA_PT_vertex_colors, + DATA_PT_face_maps, + DATA_PT_normals, + DATA_PT_texture_space, DATA_PT_customdata, DATA_PT_custom_props_mesh, ) -- cgit v1.2.3 From 9a40690242dff4153a48c1da0f0f87a71a020e64 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 18:30:26 +0200 Subject: Fix for holdout / indirect only with collection instances. --- intern/cycles/blender/blender_object.cpp | 4 ++-- source/blender/makesrna/intern/rna_object_api.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 42e2198779e..a1f39d0848f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -347,7 +347,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); bool use_holdout = get_boolean(cobject, "is_holdout") || - b_ob.holdout_get(b_view_layer); + b_parent.holdout_get(b_view_layer); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { @@ -362,7 +362,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, #endif /* Clear camera visibility for indirect only objects. */ - bool use_indirect_only = b_ob.indirect_only_get(b_view_layer); + bool use_indirect_only = b_parent.indirect_only_get(b_view_layer); if(use_indirect_only) { visibility &= ~PATH_RAY_CAMERA; } diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 44709db9d94..8f8f3176096 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -129,10 +129,10 @@ static bool rna_Object_select_get(Object *ob, bContext *C, ReportList *reports) if (!base) { BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); - return -1; + return false; } - return ((base->flag & BASE_SELECTED) != 0) ? 1 : 0; + return ((base->flag & BASE_SELECTED) != 0); } static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports) @@ -142,10 +142,10 @@ static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports) if (!base) { BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); - return -1; + return false; } - return ((base->flag & BASE_VISIBLE) != 0) ? 1 : 0; + return ((base->flag & BASE_VISIBLE) != 0); } static bool rna_Object_holdout_get(Object *ob, ReportList *reports, ViewLayer *view_layer) @@ -154,10 +154,10 @@ static bool rna_Object_holdout_get(Object *ob, ReportList *reports, ViewLayer *v if (!base) { BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); - return -1; + return false; } - return ((base->flag & BASE_HOLDOUT) != 0) ? 1 : 0; + return ((base->flag & BASE_HOLDOUT) != 0); } static bool rna_Object_indirect_only_get(Object *ob, ReportList *reports, ViewLayer *view_layer) @@ -166,10 +166,10 @@ static bool rna_Object_indirect_only_get(Object *ob, ReportList *reports, ViewLa if (!base) { BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name); - return -1; + return false; } - return ((base->flag & BASE_INDIRECT_ONLY) != 0) ? 1 : 0; + return ((base->flag & BASE_INDIRECT_ONLY) != 0); } /* Convert a given matrix from a space to another (using the object and/or a bone as reference). */ -- cgit v1.2.3 From 8c9e6c59863077512e7abfa4fdedbbedfd954a87 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 19:15:20 +0200 Subject: Fix crash Cycles rendering with --debug-value 256. --- intern/cycles/blender/addon/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 5c52a8bcce9..60057818e37 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -168,7 +168,7 @@ def reset(engine, data, depsgraph): import bpy if bpy.app.debug_value == 256: - _cycles.debug_flags_update(depsgraph.scene) + _cycles.debug_flags_update(depsgraph.scene.as_pointer()) else: _cycles.debug_flags_reset() -- cgit v1.2.3 From 5ba4d059c014a038202b6981a040ba247ff42758 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 25 Jul 2018 21:04:28 +0200 Subject: Fix (unreported) potential div-by-zero in ray/bbox intersection BLI code. Also added note that direction parameter should be normalized vector in case one intend to use returned distance values. --- source/blender/blenlib/intern/math_geom.c | 32 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index a48d985faed..61b8f6819cc 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2475,9 +2475,11 @@ bool isect_ray_aabb_v3( return true; } -/* - * Test a bounding box (AABB) for ray intersection - * assumes the ray is already local to the boundbox space +/** + * Test a bounding box (AABB) for ray intersection. + * Assumes the ray is already local to the boundbox space. + * + * \note: \a direction should be normalized if you intend to use the \a tmin or \a tmax distance results! */ bool isect_ray_aabb_v3_simple( const float orig[3], const float dir[3], @@ -2486,19 +2488,25 @@ bool isect_ray_aabb_v3_simple( { double t[7]; float hit_dist[2]; - t[1] = (double)(bb_min[0] - orig[0]) / dir[0]; - t[2] = (double)(bb_max[0] - orig[0]) / dir[0]; - t[3] = (double)(bb_min[1] - orig[1]) / dir[1]; - t[4] = (double)(bb_max[1] - orig[1]) / dir[1]; - t[5] = (double)(bb_min[2] - orig[2]) / dir[2]; - t[6] = (double)(bb_max[2] - orig[2]) / dir[2]; + const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX; + const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX; + const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX; + t[1] = (double)(bb_min[0] - orig[0]) * invdirx; + t[2] = (double)(bb_max[0] - orig[0]) * invdirx; + t[3] = (double)(bb_min[1] - orig[1]) * invdiry; + t[4] = (double)(bb_max[1] - orig[1]) * invdiry; + t[5] = (double)(bb_min[2] - orig[2]) * invdirz; + t[6] = (double)(bb_max[2] - orig[2]) * invdirz; hit_dist[0] = (float)fmax(fmax(fmin(t[1], t[2]), fmin(t[3], t[4])), fmin(t[5], t[6])); hit_dist[1] = (float)fmin(fmin(fmax(t[1], t[2]), fmax(t[3], t[4])), fmax(t[5], t[6])); - if ((hit_dist[1] < 0 || hit_dist[0] > hit_dist[1])) + if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) { return false; + } else { - if (tmin) *tmin = hit_dist[0]; - if (tmax) *tmax = hit_dist[1]; + if (tmin) + *tmin = hit_dist[0]; + if (tmax) + *tmax = hit_dist[1]; return true; } } -- cgit v1.2.3 From 29d1db9ed6253f68c5452be1f0125ed364d4a954 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 25 Jul 2018 21:05:44 +0200 Subject: Fix T55964: Direction not normalized in isect_ray_aabb_v3_simple()? RNA API Object.ray_cast would not normalize direction vector before doing first quick bbox intersection test, while using its returned distance value. This could lead to wrong exclusion of object. Thanks to @codemanx for finding that issue. --- source/blender/makesrna/intern/rna_object_api.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 2acda5985e1..376a89c65d1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -332,8 +332,10 @@ static void rna_Object_ray_cast( /* Test BoundBox first (efficiency) */ BoundBox *bb = BKE_object_boundbox_get(ob); float distmin; - if (!bb || (isect_ray_aabb_v3_simple(origin, direction, bb->vec[0], bb->vec[6], &distmin, NULL) && distmin <= distance)) { - + normalize_v3(direction); /* Needed for valid distance check from isect_ray_aabb_v3_simple() call. */ + if (!bb || + (isect_ray_aabb_v3_simple(origin, direction, bb->vec[0], bb->vec[6], &distmin, NULL) && distmin <= distance)) + { BVHTreeFromMesh treeData = {NULL}; /* no need to managing allocation or freeing of the BVH data. this is generated and freed as needed */ @@ -346,9 +348,6 @@ static void rna_Object_ray_cast( hit.index = -1; hit.dist = distance; - normalize_v3(direction); - - if (BLI_bvhtree_ray_cast(treeData.tree, origin, direction, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { -- cgit v1.2.3 From 1882dfc47c18c9b715c36eb7a76d01a306a10580 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Thu, 26 Jul 2018 02:42:20 +0200 Subject: UI: More opaque type icons in the Outliner Also always draw the counter of elements-per-type with a dark background regardless of the active status. It being white when active affects readability since the icon background itself is already highlighted. Thanks devtalk forum for feedback. --- source/blender/editors/space_outliner/outliner_draw.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 783a03f3993..e1049d02e37 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1341,16 +1341,9 @@ static void tselem_draw_icon( static void outliner_draw_iconrow_number( const uiFontStyle *fstyle, int offsx, int ys, - const eOLDrawState active, const int num_elements) { - float color[4] = {0.4f, 0.4f, 0.4f, 0.9f}; - copy_v3_fl(color, 0.2f); - if (active != OL_DRAWSEL_NONE) { - copy_v3_fl(color, 0.65f); - color[3] = 1.0f; - } - + float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float ufac = 0.25f * UI_UNIT_X; float offset_x = (float) offsx + UI_UNIT_X * 0.35f; @@ -1414,13 +1407,13 @@ static void outliner_draw_iconrow_doit( } /* No inlined icon should be clickable. */ - tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac, false); + tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false); te->xs = *offsx; te->ys = ys; te->xend = (short)*offsx + UI_UNIT_X; if (num_elements > 1) { - outliner_draw_iconrow_number(fstyle, *offsx, ys, active, num_elements); + outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements); } (*offsx) += UI_UNIT_X; } -- cgit v1.2.3 From 2df27fa6cf85a6b4534302a41d9588b550029b01 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 11:07:56 +1000 Subject: Cleanup: Use const argument --- source/blender/makesrna/RNA_access.h | 2 +- source/blender/makesrna/intern/rna_access.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index ffada6efd02..a026d8e875e 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -800,7 +800,7 @@ bool RNA_struct_bl_idname_ok_or_report(struct ReportList *reports, const char *i /* Property Information */ -const char *RNA_property_identifier(PropertyRNA *prop); +const char *RNA_property_identifier(const PropertyRNA *prop); const char *RNA_property_description(PropertyRNA *prop); PropertyType RNA_property_type(PropertyRNA *prop); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 2a74aedd60a..d805d6138a7 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -952,7 +952,7 @@ bool RNA_struct_bl_idname_ok_or_report(ReportList *reports, const char *identifi /* Property Information */ -const char *RNA_property_identifier(PropertyRNA *prop) +const char *RNA_property_identifier(const PropertyRNA *prop) { return rna_ensure_property_identifier(prop); } -- cgit v1.2.3 From dbd79c097c14d486fe79b91b916a9f854587b27e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 09:59:56 +1000 Subject: WM: Add operator property poll callback This allows operators to filter out properties from the auto-generated draw functions. Some custom draw functions can move to using this. --- source/blender/editors/gpencil/gpencil_convert.c | 4 ++-- source/blender/editors/include/UI_interface.h | 7 ++++-- .../editors/interface/interface_templates.c | 20 +++++++++++++++-- source/blender/editors/interface/interface_utils.c | 5 +++-- source/blender/editors/mesh/editmesh_tools.c | 4 ++-- .../blender/editors/object/object_data_transfer.c | 4 ++-- source/blender/editors/object/object_relations.c | 4 ++-- source/blender/editors/screen/screendump.c | 4 ++-- source/blender/editors/space_clip/clip_toolbar.c | 2 +- source/blender/editors/space_file/file_panels.c | 25 ++++++++++++---------- source/blender/editors/space_image/image_ops.c | 8 +++---- .../editors/space_sequencer/sequencer_add.c | 4 ++-- .../blender/editors/space_view3d/view3d_toolbar.c | 2 +- source/blender/windowmanager/WM_types.h | 6 ++++++ source/blender/windowmanager/intern/wm_operators.c | 8 +++---- 15 files changed, 68 insertions(+), 39 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 0c148710e3e..d6cb36d7fcd 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1371,7 +1371,7 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes"); @@ -1444,7 +1444,7 @@ static void gp_convert_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, NULL, '\0'); } void GPENCIL_OT_convert(wmOperatorType *ot) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index eefbeee6336..f2aad249df3 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -703,7 +703,11 @@ uiBut *uiDefSearchButO_ptr( short width, short height, float a1, float a2, const char *tip); uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2); -int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align); + +int uiDefAutoButsRNA( + uiLayout *layout, struct PointerRNA *ptr, + bool (*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data, + const char label_align); /* Links * @@ -988,7 +992,6 @@ void UI_but_func_operator_search(uiBut *but); void uiTemplateOperatorSearch(uiLayout *layout); void uiTemplateOperatorPropertyButs( const struct bContext *C, uiLayout *layout, struct wmOperator *op, - bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag); void uiTemplateHeader3D(uiLayout *layout, struct bContext *C); void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index daee0d3af3f..9d05819dd6a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3549,13 +3549,24 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, } #endif +struct uiTemplateOperatorPropertyPollParam { + const bContext *C; + wmOperator *op; +}; + +static bool ui_layout_operator_buts_poll_property( + struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data) +{ + struct uiTemplateOperatorPropertyPollParam *params = user_data; + return params->op->type->poll_property(params->C, params->op, prop); +} + /** * Draw Operator property buttons for redoing execution with different settings. * This function does not initialize the layout, functions can be called on the layout before and after. */ void uiTemplateOperatorPropertyButs( const bContext *C, uiLayout *layout, wmOperator *op, - bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *), const char label_align, const short flag) { if (!op->properties) { @@ -3611,11 +3622,16 @@ void uiTemplateOperatorPropertyButs( wmWindowManager *wm = CTX_wm_manager(C); PointerRNA ptr; int empty; + struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op}; RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* main draw call */ - empty = uiDefAutoButsRNA(layout, &ptr, check_prop, label_align) == 0; + empty = uiDefAutoButsRNA( + layout, &ptr, + op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL, + op->type->poll_property ? &user_data : NULL, + label_align) == 0; if (empty && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) { uiItemL(layout, IFACE_("No Properties"), ICON_NONE); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 1aa6f045266..2059fc1c849 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -159,7 +159,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind */ int uiDefAutoButsRNA( uiLayout *layout, PointerRNA *ptr, - bool (*check_prop)(PointerRNA *, PropertyRNA *), + bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data, const char label_align) { uiLayout *split, *col; @@ -172,8 +172,9 @@ int uiDefAutoButsRNA( RNA_STRUCT_BEGIN (ptr, prop) { flag = RNA_property_flag(prop); - if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop) == 0)) + if (flag & PROP_HIDDEN || (check_prop && check_prop(ptr, prop, user_data) == 0)) { continue; + } if (label_align != '\0') { PropertyType type = RNA_property_type(prop); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index a478fee1f82..c5c670b77ea 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5373,7 +5373,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); const int action = RNA_enum_get(ptr, "type"); @@ -5406,7 +5406,7 @@ static void edbm_sort_elements_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, NULL, '\0'); } void MESH_OT_sort_elements(wmOperatorType *ot) diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 384bea3701f..44cca58fc5c 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -453,7 +453,7 @@ static bool data_transfer_poll(bContext *C) } /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */ -static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { PropertyRNA *prop_other; @@ -525,7 +525,7 @@ static void data_transfer_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, NULL, '\0'); } /* transfers weight from active to selected */ diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 286a7e09581..77b5d35db03 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -938,7 +938,7 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent return OPERATOR_INTERFACE; } -static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); const int type = RNA_enum_get(ptr, "type"); @@ -963,7 +963,7 @@ static void parent_set_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, NULL, '\0'); } void OBJECT_OT_parent_set(wmOperatorType *ot) diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index dda75877f50..3ec2078a4d1 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -247,7 +247,7 @@ static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op) screenshot_data_free(op); } -static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -266,7 +266,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, '\0'); } static bool screenshot_poll(bContext *C) diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c index fbd73ee4315..7d4aa0083f1 100644 --- a/source/blender/editors/space_clip/clip_toolbar.c +++ b/source/blender/editors/space_clip/clip_toolbar.c @@ -193,7 +193,7 @@ void CLIP_OT_tools(wmOperatorType *ot) static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op) { - uiTemplateOperatorPropertyButs(C, pa->layout, op, NULL, 'V', 0); + uiTemplateOperatorPropertyButs(C, pa->layout, op, 'V', 0); } static void clip_panel_operator_redo_header(const bContext *C, Panel *pa) diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index c02320de89e..c5350750af4 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -43,6 +43,7 @@ #include "MEM_guardedalloc.h" #include "RNA_access.h" +#include "RNA_define.h" #include "ED_fileselect.h" @@ -71,24 +72,26 @@ static void file_panel_operator_header(const bContext *C, Panel *pa) BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname)); } -static bool file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) -{ - const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath") || - STREQ(prop_id, "directory") || - STREQ(prop_id, "filename") - ); -} - static void file_panel_operator(const bContext *C, Panel *pa) { SpaceFile *sfile = CTX_wm_space_file(C); wmOperator *op = sfile->op; - // int empty = 1, flag; UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); - uiTemplateOperatorPropertyButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); + /* Hack: temporary hide.*/ + const char *hide[3] = {"filepath", "directory", "filename"}; + for (int i = 0; i < ARRAY_SIZE(hide); i++) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); + RNA_def_property_flag(prop, PROP_HIDDEN); + } + + uiTemplateOperatorPropertyButs(C, pa->layout, op, '\0', UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); + + for (int i = 0; i < ARRAY_SIZE(hide); i++) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); + RNA_def_property_clear_flag(prop, PROP_HIDDEN); + } UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index d9f66ef175a..2a015177dac 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1406,7 +1406,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED( return OPERATOR_RUNNING_MODAL; } -static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -1425,7 +1425,7 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, NULL, '\0'); /* image template */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr); @@ -2120,7 +2120,7 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op) image_save_as_free(op); } -static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -2145,7 +2145,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, NULL, '\0'); /* multiview template */ if (is_multiview) diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 5c332925011..b3e1d3be42a 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -627,7 +627,7 @@ static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op) op->customdata = NULL; } -static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -693,7 +693,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op) /* main draw call */ RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, NULL, '\0'); /* image template */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 02634d1b0d1..02136af958b 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -67,7 +67,7 @@ static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op) { - uiTemplateOperatorPropertyButs(C, pa->layout, op, NULL, 'V', 0); + uiTemplateOperatorPropertyButs(C, pa->layout, op, 'V', 0); } static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa) diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 3d4080eb600..918188117eb 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -571,6 +571,12 @@ typedef struct wmOperatorType { * that the operator might still fail to execute even if this return true */ bool (*poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT; + /* Use to check of properties should be displayed in auto-generated UI. + * Use 'check' callback to enforce refreshing. */ + bool (*poll_property)( + const struct bContext *C, struct wmOperator *op, + const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT; + /* optional panel for redo and repeat, autogenerated if not set */ void (*ui)(struct bContext *, struct wmOperator *); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index ffa6b0fc371..454d7dc57f0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -996,13 +996,13 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) if (op->type->flag & OPTYPE_MACRO) { for (op = op->macro.first; op; op = op->next) { - uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); + uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); if (op->next) uiItemS(layout); } } else { - uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); + uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); } UI_block_bounds_set_popup(block, 4, 0, 0); @@ -1071,7 +1071,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData) layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); - uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); + uiTemplateOperatorPropertyButs(C, layout, op, 'H', UI_TEMPLATE_OP_PROPS_SHOW_TITLE); /* clear so the OK button is left alone */ UI_block_func_set(block, NULL, NULL, NULL); @@ -1110,7 +1110,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData) layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style); /* since ui is defined the auto-layout args are not used */ - uiTemplateOperatorPropertyButs(C, layout, op, NULL, 'V', 0); + uiTemplateOperatorPropertyButs(C, layout, op, 'V', 0); UI_block_func_set(block, NULL, NULL, NULL); -- cgit v1.2.3 From e6c5490323068aad1ab9823f8974dea9ed567df9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 11:13:38 +1000 Subject: UI: hide proportional transform options Adds property poll function to transform. --- source/blender/editors/transform/transform_ops.c | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 7505a0ba7fe..f8e23c9744d 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -495,6 +495,25 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event) } } +static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + + /* Proportional Editing. */ + { + PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional"); + if (prop_pet && (prop_pet != prop) && + (RNA_property_enum_get(op->ptr, prop_pet) == PROP_EDIT_OFF)) + { + if (STRPREFIX(prop_id, "proportional")) { + return false; + } + } + } + + return true; +} + void Transform_Properties(struct wmOperatorType *ot, int flags) { PropertyRNA *prop; @@ -596,6 +615,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -616,6 +636,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -647,6 +668,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = skin_resize_poll; + ot->poll_property = transform_poll_property; RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); @@ -667,6 +689,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; /* Maybe we could use float_vector_xyz here too? */ RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX); @@ -688,6 +711,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -712,6 +736,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -732,6 +757,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_region_view3d_active; + ot->poll_property = transform_poll_property; RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); @@ -752,6 +778,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); @@ -773,6 +800,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX); @@ -793,6 +821,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh; + ot->poll_property = transform_poll_property; RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX); @@ -816,6 +845,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1); @@ -836,6 +866,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT | P_CENTER); } @@ -856,6 +887,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh_region_view3d; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); @@ -885,6 +917,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh_region_view3d; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f); RNA_def_boolean(ot->srna, "use_even", false, "Even", @@ -911,6 +944,7 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_editmesh; + ot->poll_property = transform_poll_property; RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f); @@ -994,6 +1028,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot) ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; + ot->poll_property = transform_poll_property; prop = RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", ""); RNA_def_property_flag(prop, PROP_HIDDEN); -- cgit v1.2.3 From 629403fb511089e4545eb6d2248418bf71e0d669 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 14:46:33 +1000 Subject: WM: remove duplicate ui-list functions Missed when moving into own file. Caused issues on MSVC, not GCC. --- source/blender/windowmanager/intern/wm.c | 59 -------------------------------- 1 file changed, 59 deletions(-) diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index f92cc511449..7247529d02d 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -223,65 +223,6 @@ void WM_operator_handlers_clear(wmWindowManager *wm, wmOperatorType *ot) } } -/* ************ uiListType handling ************** */ - -static GHash *uilisttypes_hash = NULL; - -uiListType *WM_uilisttype_find(const char *idname, bool quiet) -{ - uiListType *ult; - - if (idname[0]) { - ult = BLI_ghash_lookup(uilisttypes_hash, idname); - if (ult) { - return ult; - } - } - - if (!quiet) { - printf("search for unknown uilisttype %s\n", idname); - } - - return NULL; -} - -bool WM_uilisttype_add(uiListType *ult) -{ - BLI_ghash_insert(uilisttypes_hash, ult->idname, ult); - return 1; -} - -void WM_uilisttype_freelink(uiListType *ult) -{ - bool ok; - - ok = BLI_ghash_remove(uilisttypes_hash, ult->idname, NULL, MEM_freeN); - - BLI_assert(ok); - (void)ok; -} - -/* called on initialize WM_init() */ -void WM_uilisttype_init(void) -{ - uilisttypes_hash = BLI_ghash_str_new_ex("uilisttypes_hash gh", 16); -} - -void WM_uilisttype_free(void) -{ - GHashIterator gh_iter; - - GHASH_ITER (gh_iter, uilisttypes_hash) { - uiListType *ult = BLI_ghashIterator_getValue(&gh_iter); - if (ult->ext.free) { - ult->ext.free(ult->ext.data); - } - } - - BLI_ghash_free(uilisttypes_hash, NULL, MEM_freeN); - uilisttypes_hash = NULL; -} - /* ****************************************** */ void WM_keymap_init(bContext *C) -- cgit v1.2.3 From 0dd3b200b06883796ad18bddd53cb97f12c94ee9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 14:58:36 +1000 Subject: Cleanup: remove redundant flag Caller can pass this flag if necessary. --- source/blender/editors/interface/interface_templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e60c64a971f..131ffbca377 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1557,7 +1557,7 @@ static void template_operator_redo_property_buts_draw( eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs( C, layout, op, UI_BUT_LABEL_ALIGN_NONE, - layout_flags | (r_has_advanced ? UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED : 0)); + layout_flags); if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) { if (r_has_advanced) { *r_has_advanced = true; -- cgit v1.2.3 From 44370a307cc77435880793a6420be143004b34f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 15:44:27 +1000 Subject: UI: hide transform constraints when not used --- source/blender/editors/transform/transform.c | 6 +++++- source/blender/editors/transform/transform_ops.c | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d9e36d0963a..79d06de8b41 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1999,7 +1999,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) } } - RNA_property_boolean_set_array(op->ptr, prop, constraint_axis); + /* Only set if needed, so we can hide in the UI when nothing is set. + * See 'transform_poll_property'. */ + if (ELEM(true, UNPACK3(constraint_axis))) { + RNA_property_boolean_set_array(op->ptr, prop, constraint_axis); + } } { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index f8e23c9744d..df118d7a272 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -499,6 +499,17 @@ static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, c { const char *prop_id = RNA_property_identifier(prop); + /* Orientation/Constraints. */ + { + /* Hide orientation axis if no constraints are set, since it wont be used. */ + PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "constraint_axis"); + if (prop_con && !RNA_property_is_set(op->ptr, prop_con)) { + if (STRPREFIX(prop_id, "constraint")) { + return false; + } + } + } + /* Proportional Editing. */ { PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional"); -- cgit v1.2.3 From ab67c6e46b689a703c22c6e04f6d098603e3b49c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 17:35:33 +1000 Subject: WM: replace UI draw callbacks w/ property poll Custom drawing functions were used just to control property display. Move to poll function. --- source/blender/editors/gpencil/gpencil_convert.c | 17 +++-------------- source/blender/editors/mesh/editmesh_tools.c | 18 +++--------------- source/blender/editors/object/object_data_transfer.c | 20 ++++---------------- source/blender/editors/object/object_relations.c | 18 +++--------------- 4 files changed, 13 insertions(+), 60 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index d6cb36d7fcd..e0c2e116b8a 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1371,8 +1371,9 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) +static bool gp_convert_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { + PointerRNA *ptr = op->ptr; const char *prop_id = RNA_property_identifier(prop); const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes"); int timing_mode = RNA_enum_get(ptr, "timing_mode"); @@ -1435,18 +1436,6 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void return false; } -static void gp_convert_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, NULL, '\0'); -} - void GPENCIL_OT_convert(wmOperatorType *ot) { PropertyRNA *prop; @@ -1460,7 +1449,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot) ot->invoke = WM_menu_invoke; ot->exec = gp_convert_layer_exec; ot->poll = gp_convert_poll; - ot->ui = gp_convert_ui; + ot->poll_property = gp_convert_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index c5c670b77ea..3e4f8232e62 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5373,10 +5373,10 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) +static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { const char *prop_id = RNA_property_identifier(prop); - const int action = RNA_enum_get(ptr, "type"); + const int action = RNA_enum_get(op->ptr, "type"); /* Only show seed for randomize action! */ if (STREQ(prop_id, "seed")) { @@ -5397,18 +5397,6 @@ static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *pro return true; } -static void edbm_sort_elements_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, NULL, '\0'); -} - void MESH_OT_sort_elements(wmOperatorType *ot) { static const EnumPropertyItem type_items[] = { @@ -5444,7 +5432,7 @@ void MESH_OT_sort_elements(wmOperatorType *ot) ot->invoke = WM_menu_invoke; ot->exec = edbm_sort_elements_exec; ot->poll = ED_operator_editmesh; - ot->ui = edbm_sort_elements_ui; + ot->poll_property = edbm_sort_elements_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 44cca58fc5c..91081345069 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -453,8 +453,9 @@ static bool data_transfer_poll(bContext *C) } /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */ -static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) +static bool data_transfer_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { + PointerRNA *ptr = op->ptr; PropertyRNA *prop_other; const char *prop_id = RNA_property_identifier(prop); @@ -515,19 +516,6 @@ static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, vo return true; } -/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */ -static void data_transfer_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, NULL, '\0'); -} - /* transfers weight from active to selected */ void OBJECT_OT_data_transfer(wmOperatorType *ot) { @@ -540,10 +528,10 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot) /* API callbacks.*/ ot->poll = data_transfer_poll; + ot->poll_property = data_transfer_poll_property; ot->invoke = WM_menu_invoke; ot->exec = data_transfer_exec; ot->check = data_transfer_check; - ot->ui = data_transfer_ui; /* Flags.*/ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -702,10 +690,10 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot) ot->idname = "OBJECT_OT_datalayout_transfer"; ot->poll = datalayout_transfer_poll; + ot->poll_property = data_transfer_poll_property; ot->invoke = datalayout_transfer_invoke; ot->exec = datalayout_transfer_exec; ot->check = data_transfer_check; - ot->ui = data_transfer_ui; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 77b5d35db03..34f64023441 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -938,13 +938,13 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent return OPERATOR_INTERFACE; } -static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) +static bool parent_set_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop) { const char *prop_id = RNA_property_identifier(prop); - const int type = RNA_enum_get(ptr, "type"); /* Only show XMirror for PAR_ARMATURE_ENVELOPE and PAR_ARMATURE_AUTO! */ if (STREQ(prop_id, "xmirror")) { + const int type = RNA_enum_get(op->ptr, "type"); if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO)) return true; else @@ -954,18 +954,6 @@ static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void return true; } -static void parent_set_ui(bContext *C, wmOperator *op) -{ - uiLayout *layout = op->layout; - wmWindowManager *wm = CTX_wm_manager(C); - PointerRNA ptr; - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - - /* Main auto-draw call. */ - uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, NULL, '\0'); -} - void OBJECT_OT_parent_set(wmOperatorType *ot) { /* identifiers */ @@ -977,7 +965,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot) ot->invoke = parent_set_invoke; ot->exec = parent_set_exec; ot->poll = ED_operator_object_active; - ot->ui = parent_set_ui; + ot->poll_property = parent_set_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -- cgit v1.2.3 From 2499ee64a18ca8db468b0b5d1664db7a7baecc9b Mon Sep 17 00:00:00 2001 From: William Reynish Date: Thu, 26 Jul 2018 11:39:29 +0200 Subject: UI: Single column layout and sub-panels for Rigid Body Physics panels --- .../startup/bl_ui/properties_physics_rigidbody.py | 136 +++++++++++++++++---- 1 file changed, 110 insertions(+), 26 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 013822793de..00733e2fb12 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -39,20 +39,23 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object rbo = ob.rigid_body if rbo is not None: layout.prop(rbo, "type", text="Type") - row = layout.row() - if rbo.type == 'ACTIVE': - row.prop(rbo, "enabled", text="Dynamic") - row.prop(rbo, "kinematic", text="Animated") if rbo.type == 'ACTIVE': layout.prop(rbo, "mass") + col = layout.column() + if rbo.type == 'ACTIVE': + col.prop(rbo, "enabled", text="Dynamic") + col.prop(rbo, "kinematic", text="Animated") + + class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" @@ -70,6 +73,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): ob = context.object rbo = ob.rigid_body + layout.use_property_split = True layout.prop(rbo, "collision_shape", text="Shape") @@ -79,15 +83,51 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): if rbo.collision_shape == 'MESH' and rbo.mesh_source == 'DEFORM': layout.prop(rbo, "use_deform", text="Deforming") - split = layout.split() - col = split.column() - col.label(text="Surface Response:") +class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Surface Response" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() col.prop(rbo, "friction") col.prop(rbo, "restitution", text="Bounciness") - col = split.column() - col.label(text="Sensitivity:") +class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Sensitivity" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() + if rbo.collision_shape in {'MESH', 'CONE'}: col.prop(rbo, "collision_margin", text="Margin") else: @@ -96,7 +136,25 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): sub.active = rbo.use_margin sub.prop(rbo, "collision_margin", text="Margin") - layout.prop(rbo, "collision_groups") +class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Collision Collections" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + + layout.prop(rbo, "collision_groups", text="") class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): @@ -114,6 +172,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True ob = context.object rbo = ob.rigid_body @@ -122,28 +181,53 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): # col.label(text="Activation:") # XXX: settings such as activate on collison/etc. - split = layout.split() - - col = split.column() - col.label(text="Deactivation:") - col.prop(rbo, "use_deactivation") - sub = col.column() - sub.active = rbo.use_deactivation - sub.prop(rbo, "use_start_deactivated") - sub.prop(rbo, "deactivate_linear_velocity", text="Linear Vel") - sub.prop(rbo, "deactivate_angular_velocity", text="Angular Vel") - # TODO: other params such as time? - - col = split.column() - col.label(text="Damping:") - col.prop(rbo, "linear_damping", text="Translation") - col.prop(rbo, "angular_damping", text="Rotation") + col = layout.column() + col.prop(rbo, "linear_damping", text="Translation Damping") + col.prop(rbo, "angular_damping", text="Rotation Damping") + + +class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Deactivation" + bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + obj.rigid_body.type == 'ACTIVE' and + (context.engine in cls.COMPAT_ENGINES)) + + def draw_header(self, context): + ob = context.object + rbo = ob.rigid_body + self.layout.prop(rbo, "use_deactivation", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + rbo = ob.rigid_body + + layout.active = rbo.use_deactivation + + col = layout.column() + col.prop(rbo, "use_start_deactivated") + col.prop(rbo, "deactivate_linear_velocity", text="Linear Velocity") + col.prop(rbo, "deactivate_angular_velocity", text="Angular Velocity") + # TODO: other params such as time? classes = ( PHYSICS_PT_rigid_body, PHYSICS_PT_rigid_body_collisions, + PHYSICS_PT_rigid_body_collisions_surface, + PHYSICS_PT_rigid_body_collisions_sensitivity, + PHYSICS_PT_rigid_body_collisions_collections, PHYSICS_PT_rigid_body_dynamics, + PHYSICS_PT_rigid_body_dynamics_deactivation, ) if __name__ == "__main__": # only for live edit. -- cgit v1.2.3 From 4d83759f6aad69ccc579bbf302ed2a76d43a3ed1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jul 2018 19:51:56 +1000 Subject: Cleanup: unused args --- source/blender/blenkernel/intern/subdiv.c | 2 ++ source/blender/editors/transform/transform_snap_object.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index 0bf969b7de2..d8e0c517d91 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -96,5 +96,7 @@ void BKE_subdiv_free(Subdiv *subdiv) openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner); } MEM_freeN(subdiv); +#else + UNUSED_VARS(subdiv); #endif } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 4ac4bdfb34d..8b2b80a4239 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2055,6 +2055,9 @@ static short snapEditMesh( BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL; Object *em_ob = em->ob; + BLI_assert(em_ob->data == ob->data); + UNUSED_VARS_NDEBUG(ob); + void **sod_p; /* Use `em->ob` as the key in ghash since the editmesh is used * to create bvhtree and is the same for each linked object. */ -- cgit v1.2.3 From bc6e6a758fa25dcee55842b17f8da254fa507531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuk=20Garda=C5=A1evi=C4=87?= Date: Thu, 26 Jul 2018 12:33:31 +0200 Subject: UI: Use Single Column and Grid Flow layout for Physics Cloth See D3559 --- .../startup/bl_ui/properties_physics_cloth.py | 200 ++++++++++++++------- 1 file changed, 134 insertions(+), 66 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 7775722784b..0a7318864a3 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -17,8 +17,11 @@ # ##### END GPL LICENSE BLOCK ##### # + import bpy -from bpy.types import Menu, Panel +from bpy.types import ( + Panel, +) from bl_operators.presets import PresetMenu from .properties_physics_common import ( @@ -58,6 +61,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object @@ -65,64 +69,82 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): layout.active = cloth_panel_enabled(md) - split = layout.split(percentage=0.25) - - split.label(text="Quality:") - split.prop(cloth, "quality", text="Steps") - - split = layout.split(percentage=0.25) + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) - split.label(text="Speed:") - split.prop(cloth, "time_scale", text="Multiplier") + col = flow.column() + col.prop(cloth, "quality", text="Quality Steps") + col.prop(cloth, "time_scale", text="Speed Multiplier") - split = layout.split() + col.separator() - col = split.column() - - col.label(text="Material:") - col.prop(cloth, "mass") + col = flow.column() + col.prop(cloth, "mass", text="Material Mass") col.prop(cloth, "structural_stiffness", text="Structural") col.prop(cloth, "bending_stiffness", text="Bending") - col = split.column() + col.separator() - col.label(text="Damping:") - col.prop(cloth, "spring_damping", text="Spring") + col = flow.column() + col.prop(cloth, "spring_damping", text="Damping Spring") col.prop(cloth, "air_damping", text="Air") col.prop(cloth, "vel_damping", text="Velocity") - split = layout.split() + col = flow.column() + col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh") - col = split.column() + key = ob.data.shape_keys - col.prop(cloth, "use_pin_cloth", text="Pinning:") - sub = col.column() - sub.active = cloth.use_pin_cloth - sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="") - sub.prop(cloth, "pin_stiffness", text="Stiffness") + if key: + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.active = not cloth.use_dynamic_mesh + row.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="Rest Shape Key") + row.label(text="", icon='BLANK1') - # Disabled for now - """ - if cloth.vertex_group_mass: - layout.label(text="Goal:") - col = layout.column_flow() - col.prop(cloth, "goal_default", text="Default") - col.prop(cloth, "goal_spring", text="Stiffness") - col.prop(cloth, "goal_friction", text="Friction") - """ +class PHYSICS_PT_cloth_pinning(PhysicButtonsPanel, Panel): + bl_label = "Pinning" + bl_parent_id = 'PHYSICS_PT_cloth' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - col = split.column() + def draw_header(self, context): + md = context.cloth + cloth = md.settings - col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh") + self.layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth + self.layout.prop(cloth, "use_pin_cloth", text="") - key = ob.data.shape_keys + def draw(self, context): + layout = self.layout + layout.use_property_split = True - if key: - sub = col.column() - sub.active = not cloth.use_dynamic_mesh - sub.label(text="Rest Shape Key:") - sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="") + md = context.cloth + ob = context.object + cloth = md.settings + + layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() + + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="Mass Group") + row.label(text="", icon='BLANK1') + + col = flow.column() + col.prop(cloth, "pin_stiffness", text="Stiffness") + + # Disabled for now. + """ + if cloth.vertex_group_mass: + col = flow.column() + col.prop(cloth, "goal_default", text="Goal Default") + col.prop(cloth, "goal_spring", text="Stiffness") + col.prop(cloth, "goal_friction", text="Friction") + """ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): @@ -150,31 +172,59 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True cloth = context.cloth.collision_settings md = context.cloth - ob = context.object layout.active = cloth.use_collision and cloth_panel_enabled(md) - split = layout.split() + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) - col = split.column() + col = flow.column() col.prop(cloth, "collision_quality", text="Quality") col.prop(cloth, "distance_min", slider=True, text="Distance") col.prop(cloth, "repel_force", slider=True, text="Repel") + + col = flow.column() col.prop(cloth, "distance_repel", slider=True, text="Repel Distance") col.prop(cloth, "friction") + col.prop(cloth, "group") - col = split.column() - col.prop(cloth, "use_self_collision", text="Self Collision") - sub = col.column() - sub.active = cloth.use_self_collision - sub.prop(cloth, "self_collision_quality", text="Quality") - sub.prop(cloth, "self_distance_min", slider=True, text="Distance") - sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="") - layout.prop(cloth, "group") +class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel): + bl_label = "Self Collision" + bl_parent_id = 'PHYSICS_PT_cloth_collision' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + def draw_header(self, context): + cloth = context.cloth.collision_settings + + self.layout.active = cloth_panel_enabled(context.cloth) and cloth.use_self_collision + self.layout.prop(cloth, "use_self_collision", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + cloth = context.cloth.collision_settings + md = context.cloth + ob = context.object + + layout.active = cloth.use_collision and cloth_panel_enabled(md) and cloth.use_self_collision + + flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() + col.prop(cloth, "self_collision_quality", text="Quality") + col.prop(cloth, "self_distance_min", slider=True, text="Distance") + + col = flow.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="Vertex Group") + row.label(text="", icon='BLANK1') class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): @@ -191,6 +241,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object @@ -198,16 +249,27 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md)) - split = layout.split() + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - col = split.column() - col.label(text="Structural Stiffness:") - col.prop_search(cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", text="") + col = flow.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search( + cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", + text="Structural Group" + ) + row.label(text="", icon='BLANK1') col.prop(cloth, "structural_stiffness_max", text="Max") - col = split.column() - col.label(text="Bending Stiffness:") - col.prop_search(cloth, "vertex_group_bending", ob, "vertex_groups", text="") + col.separator() + + col = flow.column() + row = col.row(align=True) + row.prop_search( + cloth, "vertex_group_bending", ob, "vertex_groups", + text="Bending Group" + ) + row.label(text="", icon='BLANK1') col.prop(cloth, "bending_stiffness_max", text="Max") @@ -225,23 +287,27 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True md = context.cloth ob = context.object cloth = context.cloth.settings layout.active = (cloth.use_sewing_springs and cloth_panel_enabled(md)) + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - layout.prop(cloth, "sewing_force_max", text="Sewing Force") + col = flow.column() + col.prop(cloth, "sewing_force_max", text="Sewing Force") - split = layout.split() + col.separator() - col = split.column(align=True) - col.label(text="Shrinking:") - col.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="") + col = col.column() + # Note: TODO prop_search doesn't align on the right. + row = col.row(align=True) + row.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="Shrinking Group") + row.label(text="", icon='BLANK1') - col = split.column(align=True) - col.label() + col = flow.column(align=True) col.prop(cloth, "shrink_min", text="Min") col.prop(cloth, "shrink_max", text="Max") @@ -262,6 +328,8 @@ classes = ( PHYSICS_PT_cloth, PHYSICS_PT_cloth_cache, PHYSICS_PT_cloth_collision, + PHYSICS_PT_cloth_self_collision, + PHYSICS_PT_cloth_pinning, PHYSICS_PT_cloth_stiffness, PHYSICS_PT_cloth_sewing, PHYSICS_PT_cloth_field_weights, -- cgit v1.2.3 From 1c41dbb079e391a1d684a7dedf40728025ef8839 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Thu, 26 Jul 2018 14:21:15 +0200 Subject: Fix compiling after ui cleanups --- source/blender/editors/sound/sound_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 356a5f8074b..c3ed2a7b9c2 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -634,7 +634,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* main draw call */ - uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, NULL, '\0'); } #endif // WITH_AUDASPACE -- cgit v1.2.3 From d6e769d32e7939e3bbd1986cdc4abd2b13135eab Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Thu, 26 Jul 2018 16:48:15 +0200 Subject: Cycles: Add reflection fix to Bump and Normal Map nodes While changing the shading normal is a great way to add additional detail to a model, there are some problems with it. One of them is that at grazing angles and/or strong changes to the normal, the reflected ray can end up pointing into the actual geometry, which results in a black spot. This patch helps avoid this by automatically reducing the strength of the bump/normal map if the reflected direction would end up too shallow or inside the geometry. Differential Revision: https://developer.blender.org/D2574 --- intern/cycles/kernel/kernel_montecarlo.h | 29 +++++++++++++++++++++++ intern/cycles/kernel/shaders/node_bump.osl | 2 ++ intern/cycles/kernel/shaders/node_normal_map.osl | 2 ++ intern/cycles/kernel/shaders/stdosl.h | 30 ++++++++++++++++++++++++ intern/cycles/kernel/svm/svm_displace.h | 2 ++ intern/cycles/kernel/svm/svm_tex_coord.h | 2 ++ 6 files changed, 67 insertions(+) diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index 49dc1f08cc1..09a3fe8f23d 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -184,6 +184,35 @@ ccl_device float2 regular_polygon_sample(float corners, float rotation, float u, return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y); } +ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N) +{ + float3 R = 2*dot(N, I)*N - I; + if(dot(Ng, R) >= 0.05f) { + return N; + } + + /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane. + * The X axis is found by normalizing the component of N that's orthogonal to Ng. + * The Y axis isn't actually needed. + */ + float3 X = normalize(N - dot(N, Ng)*Ng); + + /* Calculate N.z and N.x in the local coordinate system. */ + float Iz = dot(I, Ng); + float Ix2 = sqr(dot(I, X)), Iz2 = sqr(Iz); + float Ix2Iz2 = Ix2 + Iz2; + + float a = sqrtf(Ix2*(Ix2Iz2 - sqr(0.05f))); + float b = Iz*0.05f + Ix2Iz2; + float c = (a + b > 0.0f)? (a + b) : (-a + b); + + float Nz = sqrtf(0.5f * c * (1.0f / Ix2Iz2)); + float Nx = sqrtf(1.0f - sqr(Nz)); + + /* Transform back into global coordinates. */ + return Nx*X + Nz*Ng; +} + CCL_NAMESPACE_END #endif /* __KERNEL_MONTECARLO_CL__ */ diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl index 7f01cf2ca91..a2a4468d5f3 100644 --- a/intern/cycles/kernel/shaders/node_bump.osl +++ b/intern/cycles/kernel/shaders/node_bump.osl @@ -64,5 +64,7 @@ surface node_bump( if (use_object_space) { NormalOut = normalize(transform("object", "world", NormalOut)); } + + NormalOut = ensure_valid_reflection(Ng, I, NormalOut); } diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl index 41bcac4fb10..fda6f12a5da 100644 --- a/intern/cycles/kernel/shaders/node_normal_map.osl +++ b/intern/cycles/kernel/shaders/node_normal_map.osl @@ -88,5 +88,7 @@ shader node_normal_map( if (Strength != 1.0) Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0)); + + Normal = ensure_valid_reflection(Ng, I, Normal); } diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index df9c2010872..4a8378796ba 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -282,6 +282,36 @@ point rotate (point p, float angle, point a, point b) return transform (M, p-a) + a; } +normal ensure_valid_reflection(normal Ng, vector I, normal N) +{ + float sqr(float x) { return x*x; } + + vector R = 2*dot(N, I)*N - I; + if (dot(Ng, R) >= 0.05) { + return N; + } + + /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane. + * The X axis is found by normalizing the component of N that's orthogonal to Ng. + * The Y axis isn't actually needed. + */ + vector X = normalize(N - dot(N, Ng)*Ng); + + /* Calculate N.z and N.x in the local coordinate system. */ + float Ix = dot(I, X), Iz = dot(I, Ng); + float Ix2 = sqr(dot(I, X)), Iz2 = sqr(dot(I, Ng)); + float Ix2Iz2 = Ix2 + Iz2; + + float a = sqrt(Ix2*(Ix2Iz2 - sqr(0.05))); + float b = Iz*0.05 + Ix2Iz2; + float c = (a + b > 0.0)? (a + b) : (-a + b); + + float Nz = sqrt(0.5 * c * (1.0 / Ix2Iz2)); + float Nx = sqrt(1.0 - sqr(Nz)); + + /* Transform back into global coordinates. */ + return Nx*X + Nz*Ng; +} // Color functions diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index b85eb9c0458..0f5b3abef87 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -75,6 +75,8 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac object_normal_transform(kg, sd, &normal_out); } + normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); + stack_store_float3(stack, node.w, normal_out); #endif } diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 7c207083929..45c38d64763 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -345,6 +345,8 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st N = safe_normalize(sd->N + (N - sd->N)*strength); } + N = ensure_valid_reflection(sd->Ng, sd->I, N); + if(is_zero(N)) { N = sd->N; } -- cgit v1.2.3 From cb42850ef25ab023a7d4a346a438148c42cb89c9 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Thu, 26 Jul 2018 13:48:26 -0300 Subject: Fix assert in snapEditMesh. --- source/blender/editors/transform/transform_snap_object.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 8b2b80a4239..a6e857c4a60 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -537,6 +537,8 @@ static bool raycastEditMesh( BVHTreeFromEditMesh *treedata = NULL; Object *em_ob = em->ob; + BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob)); + void **sod_p; /* Use `em->ob` as the key in ghash since the editmesh is used * to create bvhtree and is the same for each linked object. */ @@ -2055,7 +2057,7 @@ static short snapEditMesh( BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL; Object *em_ob = em->ob; - BLI_assert(em_ob->data == ob->data); + BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob)); UNUSED_VARS_NDEBUG(ob); void **sod_p; -- cgit v1.2.3 From 7d768fc8554e26ba5295604532a9f5790891d3cc Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Fri, 27 Jul 2018 02:02:11 +0200 Subject: UI: Help menu minor tweaks Show "Operators Cheatsheet" and Python API link only when developers extra is enabled. Fix URL for User Communities, Developer Community and Release Notes (which 404s now just like the wiki anyway since the page for 2.80 is being made). --- release/scripts/startup/bl_ui/space_topbar.py | 44 +++++++++++++++++---------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 77cc0f7c34e..55129aa0ce1 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -495,12 +495,26 @@ class INFO_MT_help(Menu): def draw(self, context): layout = self.layout + show_developer = context.user_preferences.view.show_developer_ui + layout.operator( "wm.url_open", text="Manual", icon='HELP', ).url = "https://docs.blender.org/manual/en/dev/" + + + layout.operator( + "wm.url_open", text="Report a Bug", icon='URL', + ).url = "https://developer.blender.org/maniphest/task/edit/form/1" + + layout.separator() + layout.operator( - "wm.url_open", text="Release Log", icon='URL', - ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2] + "wm.url_open", text="User Communities", icon='URL', + ).url = "https://www.blender.org/community/" + layout.operator( + "wm.url_open", text="Developer Community", icon='URL', + ).url = "https://www.blender.org/get-involved/developers/" + layout.separator() layout.operator( @@ -509,24 +523,22 @@ class INFO_MT_help(Menu): layout.operator( "wm.url_open", text="Blender Store", icon='URL', ).url = "https://store.blender.org" + layout.operator( - "wm.url_open", text="Developer Community", icon='URL', - ).url = "https://www.blender.org/get-involved/" - layout.operator( - "wm.url_open", text="User Community", icon='URL', - ).url = "https://www.blender.org/support/user-community" - layout.separator() - layout.operator( - "wm.url_open", text="Report a Bug", icon='URL', - ).url = "https://developer.blender.org/maniphest/task/edit/form/1" + "wm.url_open", text="Release Notes", icon='URL', + ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] + layout.separator() - layout.operator( - "wm.url_open", text="Python API Reference", icon='URL', - ).url = bpy.types.WM_OT_doc_view._prefix + if show_developer: + layout.operator( + "wm.url_open", text="Python API Reference", icon='URL', + ).url = bpy.types.WM_OT_doc_view._prefix + + layout.operator("wm.operator_cheat_sheet", icon='TEXT') + + layout.operator("wm.sysinfo") - layout.operator("wm.operator_cheat_sheet", icon='TEXT') - layout.operator("wm.sysinfo", icon='TEXT') layout.separator() layout.operator("wm.splash", icon='BLENDER') -- cgit v1.2.3 From cf080657a1a5ad62121079f93e130ac10fcce18f Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Fri, 27 Jul 2018 02:13:52 +0200 Subject: UI: Tooltip tweaks for Display Mode Keep UI -> Keep User Interface, and don't use the word UI again in the tooltip. --- source/blender/makesrna/intern/rna_scene.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 5637783aa04..915018612a1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -4779,10 +4779,10 @@ static void rna_def_scene_render_data(BlenderRNA *brna) }; static const EnumPropertyItem display_mode_items[] = { - {R_OUTPUT_SCREEN, "SCREEN", 0, "Full Screen", "Images are rendered in full Screen"}, - {R_OUTPUT_AREA, "AREA", 0, "Image Editor", "Images are rendered in Image Editor"}, - {R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in new Window"}, - {R_OUTPUT_NONE, "NONE", 0, "Keep UI", "Images are rendered without forcing UI changes"}, + {R_OUTPUT_SCREEN, "SCREEN", 0, "Full Screen", "Images are rendered in a maximized Image Editor"}, + {R_OUTPUT_AREA, "AREA", 0, "Image Editor", "Images are rendered in an Image Editor"}, + {R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in a new window"}, + {R_OUTPUT_NONE, "NONE", 0, "Keep User Interface", "Images are rendered without changing the user interface"}, {0, NULL, 0, NULL, NULL} }; @@ -4795,7 +4795,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) }; static const EnumPropertyItem pixel_size_items[] = { - {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"}, + {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the user interface scale"}, {1, "1", 0, "1x", "Render at full resolution"}, {2, "2", 0, "2x", "Render at 50% resolution"}, {4, "4", 0, "4x", "Render at 25% resolution"}, -- cgit v1.2.3 From 71564debf919d9ac99387359e9a07195bf0d94ff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 27 Jul 2018 10:51:42 +1000 Subject: Fix T56074: Remove doubles creates holes Own regression when moving remove-doubles to kd-tree (seems to happen only in rare cases). --- source/blender/blenlib/intern/BLI_kdtree.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 700000b7717..80a2957d907 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -774,7 +774,12 @@ int BLI_kdtree_calc_duplicates_fast( if (ELEM(duplicates[index], -1, index)) { p.search = index; copy_v3_v3(p.search_co, tree->nodes[node_index].co); + int found_prev = found; deduplicate_recursive(&p, tree->root); + if (found != found_prev) { + /* Prevent chains of doubles. */ + duplicates[index] = index; + } } } MEM_freeN(order); @@ -786,7 +791,12 @@ int BLI_kdtree_calc_duplicates_fast( if (ELEM(duplicates[index], -1, index)) { p.search = index; copy_v3_v3(p.search_co, tree->nodes[node_index].co); + int found_prev = found; deduplicate_recursive(&p, tree->root); + if (found != found_prev) { + /* Prevent chains of doubles. */ + duplicates[index] = index; + } } } } -- cgit v1.2.3 From 98c8094e3a52edaec87bb9f61809e9ae573df430 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 27 Jul 2018 16:41:18 +1000 Subject: Correct arguments for callback --- source/blender/editors/sound/sound_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index c3ed2a7b9c2..b605bd6e1a7 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -481,7 +481,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *even #ifdef WITH_AUDASPACE -static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop) +static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); return !(STREQ(prop_id, "filepath") || -- cgit v1.2.3 From 3e2dfc6db8e01ffa5e12a8e9b300ef6509a06552 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 27 Jul 2018 16:49:41 +1000 Subject: Fix T55991: Python ignores scene switch argument --- source/creator/creator_args.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index b78e76f6ba3..22301bd62f5 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -60,6 +60,8 @@ #include "BKE_sound.h" #include "BKE_image.h" +#include "DNA_screen_types.h" + #include "DEG_depsgraph.h" #ifdef WITH_FFMPEG @@ -1588,6 +1590,16 @@ static int arg_handle_scene_set(int argc, const char **argv, void *data) Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]); if (scene) { CTX_data_scene_set(C, scene); + + /* Set the scene of the first window, see: T55991, + * otherwise scrips that run later won't get this scene back from the context. */ + wmWindow *win = CTX_wm_window(C); + if (win == NULL) { + win = CTX_wm_manager(C)->windows.first; + } + if (win != NULL) { + win->screen->scene = scene; + } } return 1; } -- cgit v1.2.3 From fe8d8aa27e26f1f8e4d5e1e3fcb6fc6288ebf226 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 27 Jul 2018 17:40:01 +1000 Subject: Fix Vector.project crash w/ >4 length vectors --- source/blender/python/mathutils/mathutils_Vector.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index a06a63c8067..6a40f22d9df 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -1127,23 +1127,17 @@ PyDoc_STRVAR(Vector_project_doc, static PyObject *Vector_project(VectorObject *self, PyObject *value) { const int size = self->size; - float tvec[MAX_DIMENSIONS]; - float vec[MAX_DIMENSIONS]; + float *tvec; double dot = 0.0f, dot2 = 0.0f; int x; - if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1) + if (BaseMath_ReadCallback(self) == -1) return NULL; - if (self->size > 4) { - PyErr_SetString(PyExc_ValueError, - "Vector must be 2D, 3D or 4D"); + if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) { return NULL; } - if (BaseMath_ReadCallback(self) == -1) - return NULL; - /* get dot products */ for (x = 0; x < size; x++) { dot += (double)(self->vec[x] * tvec[x]); @@ -1152,9 +1146,9 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value) /* projection */ dot /= dot2; for (x = 0; x < size; x++) { - vec[x] = (float)dot * tvec[x]; + tvec[x] *= (float)dot; } - return Vector_CreatePyObject(vec, size, Py_TYPE(self)); + return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self)); } PyDoc_STRVAR(Vector_lerp_doc, -- cgit v1.2.3 From e977fe985f019b7b28c022ffb0ca8fb37f6418ee Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:16:30 +0200 Subject: Cycles: Cleanup in image manager, switch statement instead of if-else Allows to catch enumerator values which are missing from being handled. Also use `const char*`, no need to construct string just to throw it away. --- intern/cycles/render/image.cpp | 36 ++++++++++++++++++------------------ intern/cycles/render/image.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 27d6ae78289..854eddac716 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -253,24 +253,23 @@ int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *typ return flat_slot >> IMAGE_DATA_TYPE_SHIFT; } -string ImageManager::name_from_type(int type) +const char* ImageManager::name_from_type(ImageDataType type) { - if(type == IMAGE_DATA_TYPE_FLOAT4) - return "float4"; - else if(type == IMAGE_DATA_TYPE_FLOAT) - return "float"; - else if(type == IMAGE_DATA_TYPE_BYTE) - return "byte"; - else if(type == IMAGE_DATA_TYPE_HALF4) - return "half4"; - else if(type == IMAGE_DATA_TYPE_HALF) - return "half"; - else if(type == IMAGE_DATA_TYPE_USHORT) - return "ushort"; - else if(type == IMAGE_DATA_TYPE_USHORT4) - return "ushort4"; - else - return "byte4"; + switch(type) { + case IMAGE_DATA_TYPE_FLOAT4: return "float4"; + case IMAGE_DATA_TYPE_BYTE4: return "byte4"; + case IMAGE_DATA_TYPE_HALF4: return "half4"; + case IMAGE_DATA_TYPE_FLOAT: return "float"; + case IMAGE_DATA_TYPE_BYTE: return "byte"; + case IMAGE_DATA_TYPE_HALF: return "half"; + case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; + case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_NUM_TYPES: + assert(!"System enumerator type, should never be used"); + return ""; + } + assert(!"Unhandled image data type"); + return ""; } static bool image_equals(ImageManager::Image *image, @@ -732,7 +731,8 @@ void ImageManager::device_load_image(Device *device, /* Slot assignment */ int flat_slot = type_index_to_flattened_slot(slot, type); - img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot); + img->mem_name = string_printf("__tex_image_%s_%03d", + name_from_type(type), flat_slot); /* Free previous texture in slot. */ if(img->mem) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 5932c24cb74..627ad3ce6aa 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -152,7 +152,7 @@ private: int max_flattened_slot(ImageDataType type); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); - string name_from_type(int type); + const char* name_from_type(ImageDataType type); void device_load_image(Device *device, Scene *scene, -- cgit v1.2.3 From de80b928a33bb753bec360e0d4cfeafd0bf23b0c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:22:45 +0200 Subject: Cycles: Cleanup, remove unused function --- intern/cycles/render/image.cpp | 9 --------- intern/cycles/render/image.h | 1 - 2 files changed, 10 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 854eddac716..b8892a5329d 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -229,15 +229,6 @@ bool ImageManager::get_image_metadata(const string& filename, return true; } -int ImageManager::max_flattened_slot(ImageDataType type) -{ - if(tex_num_images[type] == 0) { - /* No textures for the type, no slots needs allocation. */ - return 0; - } - return type_index_to_flattened_slot(tex_num_images[type], type); -} - /* The lower three bits of a device texture slot number indicate its type. * These functions convert the slot ids from ImageManager "images" ones * to device ones and vice verse. diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 627ad3ce6aa..40b8629d549 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -149,7 +149,6 @@ private: int texture_limit, device_vector& tex_img); - int max_flattened_slot(ImageDataType type); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); const char* name_from_type(ImageDataType type); -- cgit v1.2.3 From ca359461a803808a832ff603e2d01468a252c90f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:24:03 +0200 Subject: Cycles: Cleanup, move functions outside of class methods There is no reason or justification to have helper functions as class methods: they do not depend on anything in the class itself. There are probably more cases like that. --- intern/cycles/render/image.cpp | 78 ++++++++++++++++++++++-------------------- intern/cycles/render/image.h | 4 --- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index b8892a5329d..78451658764 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -30,20 +30,58 @@ CCL_NAMESPACE_BEGIN +namespace { + /* Some helpers to silence warning in templated function. */ -static bool isfinite(uchar /*value*/) +bool isfinite(uchar /*value*/) { return true; } -static bool isfinite(half /*value*/) +bool isfinite(half /*value*/) { return true; } -static bool isfinite(uint16_t /*value*/) +bool isfinite(uint16_t /*value*/) { return true; } +/* The lower three bits of a device texture slot number indicate its type. + * These functions convert the slot ids from ImageManager "images" ones + * to device ones and vice verse. + */ +int type_index_to_flattened_slot(int slot, ImageDataType type) +{ + return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); +} + +int flattened_slot_to_type_index(int flat_slot, ImageDataType *type) +{ + *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); + return flat_slot >> IMAGE_DATA_TYPE_SHIFT; +} + +const char* name_from_type(ImageDataType type) +{ + switch(type) { + case IMAGE_DATA_TYPE_FLOAT4: return "float4"; + case IMAGE_DATA_TYPE_BYTE4: return "byte4"; + case IMAGE_DATA_TYPE_HALF4: return "half4"; + case IMAGE_DATA_TYPE_FLOAT: return "float"; + case IMAGE_DATA_TYPE_BYTE: return "byte"; + case IMAGE_DATA_TYPE_HALF: return "half"; + case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; + case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_NUM_TYPES: + assert(!"System enumerator type, should never be used"); + return ""; + } + assert(!"Unhandled image data type"); + return ""; +} + +} // namespace + ImageManager::ImageManager(const DeviceInfo& info) { need_update = true; @@ -229,40 +267,6 @@ bool ImageManager::get_image_metadata(const string& filename, return true; } -/* The lower three bits of a device texture slot number indicate its type. - * These functions convert the slot ids from ImageManager "images" ones - * to device ones and vice verse. - */ -int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type) -{ - return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); -} - -int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type) -{ - *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); - return flat_slot >> IMAGE_DATA_TYPE_SHIFT; -} - -const char* ImageManager::name_from_type(ImageDataType type) -{ - switch(type) { - case IMAGE_DATA_TYPE_FLOAT4: return "float4"; - case IMAGE_DATA_TYPE_BYTE4: return "byte4"; - case IMAGE_DATA_TYPE_HALF4: return "half4"; - case IMAGE_DATA_TYPE_FLOAT: return "float"; - case IMAGE_DATA_TYPE_BYTE: return "byte"; - case IMAGE_DATA_TYPE_HALF: return "half"; - case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; - case IMAGE_DATA_TYPE_USHORT: return "ushort"; - case IMAGE_DATA_NUM_TYPES: - assert(!"System enumerator type, should never be used"); - return ""; - } - assert(!"Unhandled image data type"); - return ""; -} - static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 40b8629d549..67af4ba886c 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -149,10 +149,6 @@ private: int texture_limit, device_vector& tex_img); - int type_index_to_flattened_slot(int slot, ImageDataType type); - int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); - const char* name_from_type(ImageDataType type); - void device_load_image(Device *device, Scene *scene, ImageDataType type, -- cgit v1.2.3 From 46b85d195cd539d61673a6cf1ffa3704788912ce Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:28:06 +0200 Subject: Cycles: Cleanup, line length --- intern/cycles/render/image.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 78451658764..7f090b7a752 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -171,10 +171,12 @@ bool ImageManager::get_image_metadata(const string& filename, if(metadata.is_float) { metadata.is_linear = true; - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } return true; @@ -186,7 +188,8 @@ bool ImageManager::get_image_metadata(const string& filename, return false; } if(path_is_directory(filename)) { - VLOG(1) << "File '" << filename << "' is a directory, can't use as image."; + VLOG(1) << "File '" << filename + << "' is a directory, can't use as image."; return false; } @@ -249,16 +252,20 @@ bool ImageManager::get_image_metadata(const string& filename, metadata.channels = spec.nchannels; if(metadata.is_half) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 + : IMAGE_DATA_TYPE_HALF; } else if(metadata.is_float) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else if(spec.format == TypeDesc::USHORT) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 + : IMAGE_DATA_TYPE_USHORT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } in->close(); @@ -338,14 +345,16 @@ int ImageManager::add_image(const string& filename, } /* Count if we're over the limit. - * Very unlikely, since max_num_images is insanely big. But better safe than sorry. */ + * Very unlikely, since max_num_images is insanely big. But better safe + * than sorry. + */ int tex_count = 0; for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { tex_count += tex_num_images[type]; } if(tex_count > max_num_images) { - printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n", - max_num_images, filename.c_str()); + printf("ImageManager::add_image: Reached image limit (%d), " + "skipping '%s'\n", max_num_images, filename.c_str()); return -1; } -- cgit v1.2.3 From fcea94489cb181504435868472a74d4887bba947 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:28:28 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/render/image.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7f090b7a752..741dfb0717a 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -128,12 +128,12 @@ bool ImageManager::set_animation_frame_update(int frame) device_memory *ImageManager::image_memory(int flat_slot) { - ImageDataType type; - int slot = flattened_slot_to_type_index(flat_slot, &type); + ImageDataType type; + int slot = flattened_slot_to_type_index(flat_slot, &type); - Image *img = images[type][slot]; + Image *img = images[type][slot]; - return img->mem; + return img->mem; } bool ImageManager::get_image_metadata(int flat_slot, -- cgit v1.2.3 From b517b310853cc752ca1bb92b4219b257f5a94e30 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:30:10 +0200 Subject: Cycles: Cleanup, spelling --- intern/cycles/render/image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 67af4ba886c..9a2b373d016 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -153,7 +153,7 @@ private: Scene *scene, ImageDataType type, int slot, - Progress *progess); + Progress *progress); void device_free_image(Device *device, ImageDataType type, int slot); -- cgit v1.2.3 From 75c47542d787c91293572b007bbf6787f903522a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:09:10 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/render/mesh.cpp | 14 +++++++------- intern/cycles/render/mesh.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 7a9d604244d..df408b478b2 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -2015,8 +2015,8 @@ void MeshManager::device_update_displacement_images(Device *device, } void MeshManager::device_update_volume_images(Device *device, - Scene *scene, - Progress& progress) + Scene *scene, + Progress& progress) { progress.set_status("Updating Volume Images"); TaskPool pool; @@ -2043,11 +2043,11 @@ void MeshManager::device_update_volume_images(Device *device, foreach(int slot, volume_images) { pool.push(function_bind(&ImageManager::device_update_slot, - image_manager, - device, - scene, - slot, - &progress)); + image_manager, + device, + scene, + slot, + &progress)); } pool.wait_work(); } diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index e7dc1c8e5cf..fc7d0b40273 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -381,8 +381,8 @@ protected: Progress& progress); void device_update_volume_images(Device *device, - Scene *scene, - Progress& progress); + Scene *scene, + Progress& progress); }; CCL_NAMESPACE_END -- cgit v1.2.3 From 67e690f5fcc084fbd949240f2c7733854079efc5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:19:29 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/graph/node_type.cpp | 2 +- intern/cycles/graph/node_type.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp index 671ae2d815a..e045777e969 100644 --- a/intern/cycles/graph/node_type.cpp +++ b/intern/cycles/graph/node_type.cpp @@ -134,7 +134,7 @@ NodeType::~NodeType() void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset, const void *default_value, const NodeEnum *enum_values, - const NodeType **node_type, int flags, int extra_flags) + const NodeType **node_type, int flags, int extra_flags) { SocketType socket; socket.name = name; diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index d4e2dbceff6..1d565794b27 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -114,9 +114,9 @@ struct NodeType void register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset, const void *default_value, - const NodeEnum *enum_values = NULL, - const NodeType **node_type = NULL, - int flags = 0, int extra_flags = 0); + const NodeEnum *enum_values = NULL, + const NodeType **node_type = NULL, + int flags = 0, int extra_flags = 0); void register_output(ustring name, ustring ui_name, SocketType::Type type); const SocketType *find_input(ustring name) const; -- cgit v1.2.3 From 9a080d2ea6065b3686089c156cfa72d29744c953 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 27 Jul 2018 11:34:52 +0200 Subject: Fix T56092: command line arguments after -- beginning with -h don't work. --- intern/cycles/blender/addon/engine.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 08c6a65e5ad..7e06b15afdd 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -52,7 +52,9 @@ def _workaround_buggy_drivers(): def _configure_argument_parser(): import argparse - parser = argparse.ArgumentParser(description="Cycles Addon argument parser") + # No help because it conflicts with general Python scripts argument parsing + parser = argparse.ArgumentParser(description="Cycles Addon argument parser", + add_help=False) parser.add_argument("--cycles-resumable-num-chunks", help="Number of chunks to split sample range into", default=None) -- cgit v1.2.3 From 5f5fd4c14333cab84d67446f2f9b2fbbf2c49462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 26 Jul 2018 12:28:12 +0200 Subject: UI: Fix error in camera property panel --- release/scripts/startup/bl_ui/properties_data_camera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 8ede329ea45..cc0bde46189 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -88,7 +88,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': - row.prop(cam, "angle") + col.prop(cam, "angle") col.prop(cam, "lens_unit") elif cam.type == 'ORTHO': -- cgit v1.2.3 From c6a4b469e3ac8844dfd66ad03cee38a746e0e01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 26 Jul 2018 12:29:16 +0200 Subject: RNA: Set default for Camera properties Change the default clipend value to match the viewport (1000.0f) --- source/blender/blenkernel/intern/camera.c | 2 +- source/blender/makesrna/intern/rna_camera.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 87b65601534..1b5995de4f0 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -70,7 +70,7 @@ void BKE_camera_init(Camera *cam) cam->sensor_x = DEFAULT_SENSOR_WIDTH; cam->sensor_y = DEFAULT_SENSOR_HEIGHT; cam->clipsta = 0.1f; - cam->clipend = 100.0f; + cam->clipend = 1000.0f; cam->drawsize = 0.5f; cam->ortho_scale = 6.0; cam->flag |= CAM_SHOWPASSEPARTOUT; diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 146a8e2738d..8ca45e6dd2d 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -428,6 +428,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "passepartalpha"); + RNA_def_property_float_default(prop, 0.5f); RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view"); RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL); @@ -454,6 +455,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); + RNA_def_property_float_default(prop, 0.1f); RNA_def_property_range(prop, 1e-6f, FLT_MAX); RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); RNA_def_property_ui_text(prop, "Clip Start", "Camera near clipping distance"); @@ -461,6 +463,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipend"); + RNA_def_property_float_default(prop, 1000.0f); RNA_def_property_range(prop, 1e-6f, FLT_MAX); RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3); RNA_def_property_ui_text(prop, "Clip End", "Camera far clipping distance"); @@ -468,6 +471,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_DISTANCE_CAMERA); RNA_def_property_float_sdna(prop, NULL, "lens"); + RNA_def_property_float_default(prop, 50.0f); RNA_def_property_range(prop, 1.0f, FLT_MAX); RNA_def_property_ui_range(prop, 1.0f, 5000.0f, 1, 2); RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters"); @@ -475,6 +479,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_DISTANCE_CAMERA); RNA_def_property_float_sdna(prop, NULL, "sensor_x"); + RNA_def_property_float_default(prop, 36.0f); RNA_def_property_range(prop, 1.0f, FLT_MAX); RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2); RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters"); @@ -482,6 +487,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_DISTANCE_CAMERA); RNA_def_property_float_sdna(prop, NULL, "sensor_y"); + RNA_def_property_float_default(prop, 34.0f); RNA_def_property_range(prop, 1.0f, FLT_MAX); RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2); RNA_def_property_ui_text(prop, "Sensor Height", "Vertical size of the image sensor area in millimeters"); @@ -489,6 +495,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ortho_scale"); + RNA_def_property_float_default(prop, 6.0f); RNA_def_property_range(prop, FLT_MIN, FLT_MAX); RNA_def_property_ui_range(prop, 0.001f, 10000.0f, 10, 3); RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)"); @@ -496,6 +503,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "drawsize"); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_range(prop, 0.01f, 1000.0f); RNA_def_property_ui_range(prop, 0.01, 100, 1, 2); RNA_def_property_ui_text(prop, "Draw Size", "Apparent size of the Camera object in the 3D View"); @@ -542,6 +550,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "show_passepartout", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWPASSEPARTOUT); + RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text(prop, "Show Passepartout", "Show a darkened overlay outside the image area in Camera view"); RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL); -- cgit v1.2.3 From bd6d0b94bc17bd0e1a2a89210732a207a0e2b7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 12:15:39 +0200 Subject: Fix T55744: Assertion failure using the Knife angle constraint option --- source/blender/editors/mesh/editmesh_knife.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 99756269c1f..61f55451b17 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1048,14 +1048,15 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void GPU_matrix_push(); GPU_matrix_mul(kcd->ob->obmat); + if (kcd->mode == MODE_DRAGGING && kcd->is_angle_snapping) { + knifetool_draw_angle_snapping(kcd); + } + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); if (kcd->mode == MODE_DRAGGING) { - if (kcd->is_angle_snapping) - knifetool_draw_angle_snapping(kcd); - immUniformColor3ubv(kcd->colors.line); GPU_line_width(2.0); -- cgit v1.2.3 From 141e94f87ff29452ed8df82b4c25d8d134a34dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 13:56:07 +0200 Subject: Fix T55888: Eevee: crash when shadow cube size is > 512px Note that this was only reported to happen on AMD GPU + windows. --- source/blender/gpu/intern/gpu_extensions.c | 7 +++++++ source/blender/gpu/intern/gpu_texture.c | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index dff6cfb74a8..43081154e89 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -66,6 +66,7 @@ static struct GPUGlobal { GLint maxtexsize; + GLint maxtexlayers; GLint maxcubemapsize; GLint maxtextures; GLint maxubosize; @@ -96,6 +97,11 @@ int GPU_max_texture_size(void) return GG.maxtexsize; } +int GPU_max_texture_layers(void) +{ + return GG.maxtexlayers; +} + int GPU_max_textures(void) { return GG.maxtextures; @@ -142,6 +148,7 @@ void gpu_extensions_init(void) glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtextures); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize); + glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GG.maxtexlayers); glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GG.maxcubemapsize); if (GLEW_EXT_texture_filter_anisotropic) diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 5ac746ec9c1..f5b52db1c85 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -432,6 +432,11 @@ static bool gpu_texture_try_alloc( glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL); break; case GL_PROXY_TEXTURE_2D_ARRAY: + /* HACK: Some driver wrongly check GL_PROXY_TEXTURE_2D_ARRAY as a GL_PROXY_TEXTURE_3D + * checking all dimensions against GPU_max_texture_layers (see T55888). */ + return (tex->w < GPU_max_texture_size()) && + (tex->h < GPU_max_texture_size()) && + (tex->d < GPU_max_texture_layers()); case GL_PROXY_TEXTURE_3D: glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); break; -- cgit v1.2.3 From 6a05c14a8a24219e43ea82012762e63bd3b2a93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 13:57:46 +0200 Subject: DRW: Fix Race condition in defered compilation --- source/blender/draw/intern/draw_manager_shader.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index b0aec4a7600..b85e6267687 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -72,6 +72,7 @@ typedef struct DRWShaderCompiler { ThreadMutex compilation_lock; void *gl_context; + bool own_context; int shaders_done; /* To compute progress. */ } DRWShaderCompiler; @@ -146,7 +147,7 @@ static void drw_deferred_shader_compilation_free(void *custom_data) BLI_spin_end(&comp->list_lock); BLI_mutex_end(&comp->compilation_lock); - if (comp->gl_context) { + if (comp->own_context) { /* Only destroy if the job owns the context. */ WM_opengl_context_dispose(comp->gl_context); } @@ -189,8 +190,11 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) BLI_movelisttolist(&comp->queue, &old_comp->queue); BLI_spin_unlock(&old_comp->list_lock); /* Do not recreate context, just pass ownership. */ - comp->gl_context = old_comp->gl_context; - old_comp->gl_context = NULL; + if (old_comp->gl_context) { + comp->gl_context = old_comp->gl_context; + old_comp->own_context = false; + comp->own_context = true; + } } BLI_addtail(&comp->queue, dsh); @@ -199,6 +203,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) if (comp->gl_context == NULL) { comp->gl_context = WM_opengl_context_create(); WM_opengl_context_activate(DST.gl_context); + comp->own_context = true; } WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free); -- cgit v1.2.3 From 0d20207771e76649fcce3766bcfa1634c087caae Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 27 Jul 2018 14:15:45 +0200 Subject: Fix GPU build error after recent commit. --- source/blender/gpu/GPU_extensions.h | 1 + source/blender/gpu/intern/gpu_texture.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index d36b0ea15be..f435be7fb34 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -42,6 +42,7 @@ bool GPU_full_non_power_of_two_support(void); bool GPU_bicubic_bump_support(void); int GPU_max_texture_size(void); +int GPU_max_texture_layers(void); int GPU_max_textures(void); float GPU_max_texture_anisotropy(void); int GPU_max_color_texture_samples(void); diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index f5b52db1c85..e5073196a52 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -160,6 +160,8 @@ static int gpu_get_component_count(GPUTextureFormat format) /* Definitely not complete, edit according to the gl specification. */ static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format) { + (void)data_format; + if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, GPU_DEPTH_COMPONENT16, -- cgit v1.2.3 From d6ff77878039a5c3848482c6a82ff626d4b3872c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 27 Jul 2018 14:13:47 +0200 Subject: Fix crash enabling disabled collection containing curves. Fixes T55948, T56016, T55926, T55947. Differential Revision: https://developer.blender.org/D3564 --- source/blender/depsgraph/intern/builder/deg_builder.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 4cbc7700947..8f5925a5ce3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -67,6 +67,12 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) } if (!deg_copy_on_write_is_expanded(id_node->id_cow)) { flag |= DEG_TAG_COPY_ON_WRITE; + /* This means ID is being added to the dependency graph first + * time, which is similar to "ob-visible-change" + */ + if (GS(id->name) == ID_OB) { + flag |= OB_RECALC_OB | OB_RECALC_DATA; + } } if (flag != 0) { DEG_graph_id_tag_update(bmain, -- cgit v1.2.3 From 70966af5134b0cf53273e3c6da19ad7d5857b0f2 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jul 2018 15:05:46 +0200 Subject: Workbench: option to change background Replaced the draw world option with a shading.background_type enum. Where the user can select Theme, World or a Custom color. World and theme colors do not always work in workbench. We needed to have an option what the user could control locally (per viewport). Especially when using linked data. I removed the world background drawing from the draw_manager. It was never used as EEVEE and Workbench both override the logic. Not 100% sure about the naming of Theme, World, Viewport. In other parts of blender's codebase World is sometimes called Scene. Will stick to the names that describes its location best. {F3990139} Reviewers: fclem, campbellbarton Reviewed By: fclem Subscribers: venomgfx Tags: #bf_blender_2.8 Differential Revision: https://developer.blender.org/D3551 --- release/scripts/startup/bl_ui/space_view3d.py | 14 ++++++------ source/blender/blenkernel/intern/screen.c | 1 + source/blender/blenloader/intern/versioning_280.c | 14 ++++++++++++ .../draw/engines/workbench/workbench_data.c | 8 ++++++- source/blender/draw/intern/draw_view.c | 11 +-------- source/blender/editors/space_view3d/space_view3d.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 2 +- source/blender/makesdna/DNA_view3d_types.h | 17 ++++++++++++-- source/blender/makesrna/intern/rna_space.c | 26 +++++++++++++++++----- source/blender/makesrna/intern/rna_world.c | 3 +++ 10 files changed, 71 insertions(+), 27 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 6874055a58f..e6d8b1ec2a7 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3839,10 +3839,14 @@ class VIEW3D_PT_shading_color(Panel): shading = VIEW3D_PT_shading.get_shading(context) - layout.row().prop(shading, "color_type", expand=True) - + layout.row().prop(shading, 'color_type', expand=True) if shading.color_type == 'SINGLE': - layout.row().prop(shading, "single_color", text="") + layout.row().prop(shading, 'single_color', text="") + + layout.row().label("Background") + layout.row().prop(shading, 'background_type', expand=True) + if shading.background_type == 'VIEWPORT': + layout.row().prop(shading, "background_color", text="") class VIEW3D_PT_shading_options(Panel): @@ -3912,10 +3916,6 @@ class VIEW3D_PT_shading_options(Panel): if not shading.light == 'MATCAP': col.prop(shading, "show_specular_highlight") - view = context.space_data - if view.type == 'VIEW_3D': - col.prop(view, "show_world") - class VIEW3D_PT_shading_options_shadow(Panel): bl_label = "Shadow Settings" diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index f8d926a13ed..c107bb04e6e 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -869,6 +869,7 @@ void BKE_screen_view3d_shading_init(View3DShading *shading) shading->cavity_valley_factor = 1.0f; shading->cavity_ridge_factor = 1.0f; copy_v3_fl(shading->single_color, 0.8f); + copy_v3_fl(shading->background_color, 0.05f); } /* magic zoom calculation, no idea what diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 068c12daa94..39ceb527209 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1546,6 +1546,20 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!DNA_struct_elem_find(fd->filesdna, "View3DShadeing", "short", "background_type")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->shading.background_type = (v3d->flag3 & V3D_SHOW_WORLD)? V3D_SHADING_BACKGROUND_WORLD: V3D_SHADING_BACKGROUND_THEME; + copy_v3_fl(v3d->shading.background_color, 0.05f); + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "gi_cubemap_draw_size")) { for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { scene->eevee.gi_irradiance_draw_size = 0.1f; diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 5c3ab5f6688..24eb0f38a46 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -45,10 +45,16 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0; wd->background_alpha = (v3d || scene->r.alphamode == R_ADDSKY) ? 1.0f : 0.0f; - if (!v3d || ((v3d->flag3 & V3D_SHOW_WORLD) && (scene->world != NULL))) { + if (!v3d || ((v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD) && + (scene->world != NULL))) + { copy_v3_v3(wd->background_color_low, &scene->world->horr); copy_v3_v3(wd->background_color_high, &scene->world->horr); } + else if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_VIEWPORT) { + copy_v3_v3(wd->background_color_low, v3d->shading.background_color); + copy_v3_v3(wd->background_color_high, v3d->shading.background_color); + } else if (v3d) { UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low); UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 05aecea1d7a..95835a691a3 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -561,21 +561,12 @@ void DRW_draw_grid(void) void DRW_draw_background(void) { - const DRWContextState *draw_ctx = DRW_context_state_get(); - /* Just to make sure */ glDepthMask(GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilMask(0xFF); - if ((draw_ctx->v3d->flag3 & V3D_SHOW_WORLD) && - (draw_ctx->scene->world != NULL)) - { - const World *world = draw_ctx->scene->world; - glClearColor(world->horr, world->horg, world->horb, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - } - else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { float m[4][4]; unit_m4(m); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 71bdd2e20c2..2577077002e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1406,7 +1406,7 @@ static void space_view3d_listener( switch (wmn->data) { case ND_WORLD_DRAW: case ND_WORLD: - if (v3d->flag3 & V3D_SHOW_WORLD) + if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD) ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 552d84ebb39..941f9262694 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1599,7 +1599,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( v3d.flag2 |= V3D_SOLID_TEX; } - v3d.flag3 |= V3D_SHOW_WORLD; + v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD; if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) { if (camera->type == OB_CAMERA) { diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index fedc604f120..bbbaf8bb957 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -142,7 +142,9 @@ typedef struct View3DShading { short color_type; short light; - short pad[3]; + short background_type; + short pad2[2]; + char studio_light[256]; /* FILE_MAXFILE */ char matcap[256]; /* FILE_MAXFILE */ @@ -157,6 +159,10 @@ typedef struct View3DShading { float cavity_valley_factor; float cavity_ridge_factor; + + float background_color[3]; + int pad; + } View3DShading; /* 3D Viewport Overlay setings */ @@ -349,7 +355,7 @@ typedef struct View3D { /* View3d->flag3 (short) */ -#define V3D_SHOW_WORLD (1 << 0) +#define V3D_SHOW_WORLD (1 << 0) /* LEGACY replaced by V3D_SHADING_BACKGROUND_WORLD */ /* View3DShading->light */ enum { @@ -378,6 +384,13 @@ enum { V3D_SHADING_TEXTURE_COLOR = 3, }; +/* View3DShading->background_type */ +enum { + V3D_SHADING_BACKGROUND_THEME = 0, + V3D_SHADING_BACKGROUND_WORLD = 1, + V3D_SHADING_BACKGROUND_VIEWPORT = 2, +}; + /* View3DOverlay->flag */ enum { V3D_OVERLAY_FACE_ORIENTATION = (1 << 0), diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index e670d3c31a5..2f009238851 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2427,6 +2427,15 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem background_type_items[] = { + {V3D_SHADING_BACKGROUND_THEME, "THEME", 0, "Theme", "Use the theme for background color"}, + {V3D_SHADING_BACKGROUND_WORLD, "WORLD", 0, "World", "Use the world for background color"}, + {V3D_SHADING_BACKGROUND_VIEWPORT, "VIEWPORT", 0, "Viewport", "Use a custom color limited to this viewport only"}, + {0, NULL, 0, NULL, NULL} + }; + static const float default_background_color[] = {0.05f, 0.05f, 0.05f}; + + /* Note these settings are used for both 3D viewport and the OpenGL render * engine in the scene, so can't assume to always be part of a screen. */ srna = RNA_def_struct(brna, "View3DShading", NULL); @@ -2514,6 +2523,18 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "background_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, background_type_items); + RNA_def_property_ui_text(prop, "Background", "Way to draw the background"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "background_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, default_background_color); + RNA_def_property_ui_text(prop, "Background Color", "Color for custom background color"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_shadows", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SHADOW); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -2957,11 +2978,6 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Lock Camera to View", "Enable view navigation within the camera view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD); - RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - prop = RNA_def_property(srna, "use_occlude_geometry", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ZBUF_SELECT); RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)"); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index f4dc07cf6c3..fe561cdef1c 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -199,6 +199,8 @@ void RNA_def_world(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static float default_world_color[] = {0.05f, 0.05f, 0.05f}; + srna = RNA_def_struct(brna, "World", "ID"); RNA_def_struct_ui_text(srna, "World", "World data-block describing the environment and ambient lighting of a scene"); @@ -210,6 +212,7 @@ void RNA_def_world(BlenderRNA *brna) prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "horr"); RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, default_world_color); RNA_def_property_ui_text(prop, "Color", "Color of the background"); /* RNA_def_property_update(prop, 0, "rna_World_update"); */ /* render-only uses this */ -- cgit v1.2.3 From 60499ff25da4be074324694589bb014b1c9466d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 16:28:44 +0200 Subject: GHOST: Fix SDL backend. We use a hidden window for each offscreen context we need. On X11 (linux) it does not show any other windows in the OS task bar but it might be the case on other operating systems (untested). --- intern/ghost/intern/GHOST_ContextSDL.cpp | 20 ++++++++++++++++++-- intern/ghost/intern/GHOST_ContextSDL.h | 1 + intern/ghost/intern/GHOST_System.cpp | 4 +++- intern/ghost/intern/GHOST_SystemSDL.cpp | 29 +++++++++++++++++++++++++++++ intern/ghost/intern/GHOST_SystemSDL.h | 6 ++++++ intern/ghost/intern/GHOST_WindowSDL.cpp | 2 +- 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp index 1ba591bd0b2..3b3cf7a2962 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.cpp +++ b/intern/ghost/intern/GHOST_ContextSDL.cpp @@ -55,6 +55,7 @@ GHOST_ContextSDL::GHOST_ContextSDL( int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_window(window), + m_hidden_window(NULL), m_contextProfileMask(contextProfileMask), m_contextMajorVersion(contextMajorVersion), m_contextMinorVersion(contextMinorVersion), @@ -62,7 +63,7 @@ GHOST_ContextSDL::GHOST_ContextSDL( m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_context(NULL) { - assert(m_window != NULL); + // assert(m_window != NULL); } @@ -70,7 +71,7 @@ GHOST_ContextSDL::~GHOST_ContextSDL() { if (m_context != NULL) { if (m_window != NULL && m_context == SDL_GL_GetCurrentContext()) - SDL_GL_MakeCurrent(m_window, m_context); + SDL_GL_MakeCurrent(m_window, NULL); if (m_context != s_sharedContext || s_sharedCount == 1) { assert(s_sharedCount > 0); @@ -82,6 +83,9 @@ GHOST_ContextSDL::~GHOST_ContextSDL() SDL_GL_DeleteContext(m_context); } + + if (m_hidden_window != NULL) + SDL_DestroyWindow(m_hidden_window); } } @@ -160,6 +164,18 @@ GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext() SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples); } + if (m_window == NULL) { + m_hidden_window = SDL_CreateWindow( + "Offscreen Context Windows", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 1, 1, + SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN + ); + + m_window = m_hidden_window; + } + m_context = SDL_GL_CreateContext(m_window); GHOST_TSuccess success; diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h index 681d24bb7c6..1829819300c 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.h +++ b/intern/ghost/intern/GHOST_ContextSDL.h @@ -120,6 +120,7 @@ public: private: SDL_Window *m_window; + SDL_Window *m_hidden_window; const int m_contextProfileMask; const int m_contextMajorVersion; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 0629eacc3ff..c3fd87c65af 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -297,7 +297,9 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown #ifdef WITH_INPUT_NDOF void GHOST_System::setNDOFDeadZone(float deadzone) { - this->m_ndofManager->setDeadZone(deadzone); + if (this->m_ndofManager) { + this->m_ndofManager->setDeadZone(deadzone); + } } #endif diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index d7860577338..094cbe76cb2 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -26,6 +26,7 @@ #include +#include "GHOST_ContextSDL.h" #include "GHOST_SystemSDL.h" #include "GHOST_WindowSDL.h" @@ -149,6 +150,34 @@ GHOST_SystemSDL::getNumDisplays() const return SDL_GetNumVideoDisplays(); } +GHOST_IContext * +GHOST_SystemSDL::createOffscreenContext() +{ + GHOST_Context *context = new GHOST_ContextSDL( + 0, + 0, + NULL, + 0, // profile bit + 3, 3, + GHOST_OPENGL_SDL_CONTEXT_FLAGS, + GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) + return context; + else + delete context; + + return NULL; +} + +GHOST_TSuccess +GHOST_SystemSDL::disposeContext(GHOST_IContext *context) +{ + delete context; + + return GHOST_kSuccess; +} + GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const { diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h index 41f110ed15d..0610a80ea5f 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.h +++ b/intern/ghost/intern/GHOST_SystemSDL.h @@ -95,6 +95,12 @@ public: getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const; + GHOST_IContext * + createOffscreenContext(); + + GHOST_TSuccess + disposeContext(GHOST_IContext *context); + /** * Informs if the system provides native dialogs (eg. confirm quit) */ diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp index aeb6188daef..9c41087bd59 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.cpp +++ b/intern/ghost/intern/GHOST_WindowSDL.cpp @@ -93,7 +93,7 @@ GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type) m_wantNumOfAASamples, m_sdl_win, 0, // profile bit - 0, 0, + 3, 3, GHOST_OPENGL_SDL_CONTEXT_FLAGS, GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY); -- cgit v1.2.3 From 709b36e43b94678b18fec20a92d7d34f9b5aa78b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:40:44 +0200 Subject: Cycles: Add utility function to query graph node size in bytes --- intern/cycles/graph/node.cpp | 85 +++++++++++++++++++++++++++++++++++++++++--- intern/cycles/graph/node.h | 3 ++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index 45ffc8d7d6b..5960d9aa7d5 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -425,20 +425,22 @@ bool Node::equals(const Node& other) const /* Hash */ +namespace { + template -static void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { md5.append(((uint8_t*)node) + socket.struct_offset, socket.size()); } -static void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ md5.append(((uint8_t*)node) + socket.struct_offset, sizeof(float) * 3); } template -static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { const array& a = *(const array*)(((char*)node) + socket.struct_offset); for (size_t i = 0; i < a.size(); i++) { @@ -446,7 +448,7 @@ static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) } } -static void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ const array& a = *(const array*)(((char*)node) + socket.struct_offset); @@ -455,6 +457,8 @@ static void float3_array_hash(const Node *node, const SocketType& socket, MD5Has } } +} // namespace + void Node::hash(MD5Hash& md5) { md5.append(type->name.string()); @@ -495,4 +499,77 @@ void Node::hash(MD5Hash& md5) } } +namespace { + +template +size_t array_size_in_bytes(const Node *node, const SocketType& socket) +{ + const array& a = *(const array*)(((char*)node) + socket.struct_offset); + return a.size() * sizeof(T); +} + +} // namespace + +size_t Node::get_total_size_in_bytes() const +{ + size_t total_size = 0; + foreach(const SocketType& socket, type->inputs) { + switch(socket.type) { + case SocketType::BOOLEAN: + case SocketType::FLOAT: + case SocketType::INT: + case SocketType::UINT: + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + case SocketType::POINT2: + case SocketType::CLOSURE: + case SocketType::STRING: + case SocketType::ENUM: + case SocketType::TRANSFORM: + case SocketType::NODE: + total_size += socket.size(); + break; + + case SocketType::BOOLEAN_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::FLOAT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::INT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::COLOR_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::VECTOR_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::POINT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::NORMAL_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::POINT2_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::STRING_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::TRANSFORM_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::NODE_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + + case SocketType::UNDEFINED: break; + } + } + return total_size; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index a738bfe197e..11695a8631d 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -92,6 +92,9 @@ struct Node /* compute hash of node and its socket values */ void hash(MD5Hash& md5); + /* Get total size of this node. */ + size_t get_total_size_in_bytes() const; + ustring name; const NodeType *type; }; -- cgit v1.2.3 From 84d47e3685c7ccfeaf2dd41ab64d1b642f157add Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 15:46:13 +0200 Subject: Cycles: Initial implementation of detailed statistics Gathers information about object geometry and textures. Very basic at this moment, but need to start somewhere. Things which needs to be included still: - "Runtime" information, like BVH. While it is not directly controllable by artists, it's still important to know. - Device array sizes. Again, not under artists control, but is added to the overall size. - Memory peak at different synchronization stages. At this point it simply prints info to the stdout after F12 is done, need better control over that too. Reviewers: brecht Differential Revision: https://developer.blender.org/D3566 --- intern/cycles/blender/addon/engine.py | 6 ++ intern/cycles/blender/blender_python.cpp | 9 +++ intern/cycles/blender/blender_session.cpp | 8 ++ intern/cycles/blender/blender_session.h | 2 + intern/cycles/render/CMakeLists.txt | 2 + intern/cycles/render/image.cpp | 12 +++ intern/cycles/render/image.h | 3 + intern/cycles/render/mesh.cpp | 10 +++ intern/cycles/render/mesh.h | 3 + intern/cycles/render/scene.cpp | 6 ++ intern/cycles/render/scene.h | 3 + intern/cycles/render/stats.cpp | 119 ++++++++++++++++++++++++++++++ intern/cycles/render/stats.h | 104 ++++++++++++++++++++++++++ 13 files changed, 287 insertions(+) create mode 100644 intern/cycles/render/stats.cpp create mode 100644 intern/cycles/render/stats.h diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 7e06b15afdd..c30d199ede8 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -67,6 +67,9 @@ def _configure_argument_parser(): parser.add_argument("--cycles-resumable-end-chunk", help="End chunk to render", default=None) + parser.add_argument("--cycles-print-stats", + help="Print rendering statistics to stderr", + action='store_true') return parser @@ -95,6 +98,9 @@ def _parse_command_line(): int(args.cycles_resumable_start_chunk), int(args.cycles_resumable_end_chunk), ) + if args.cycles_print_stats: + import _cycles + _cycles.enable_print_stats() def init(): diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 3eccecb8850..4b01eb5f2d4 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -734,6 +734,12 @@ static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *a Py_RETURN_NONE; } +static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/) +{ + BlenderSession::print_render_stats = true; + Py_RETURN_NONE; +} + static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/) { vector& devices = Device::available_devices(); @@ -772,6 +778,9 @@ static PyMethodDef methods[] = { {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""}, {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""}, + /* Statistics. */ + {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""}, + /* Resumable render */ {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""}, {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""}, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 00d23b9095e..e11b8e0c70d 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -28,6 +28,7 @@ #include "render/scene.h" #include "render/session.h" #include "render/shader.h" +#include "render/stats.h" #include "util/util_color.h" #include "util/util_foreach.h" @@ -48,6 +49,7 @@ int BlenderSession::num_resumable_chunks = 0; int BlenderSession::current_resumable_chunk = 0; int BlenderSession::start_resumable_chunk = 0; int BlenderSession::end_resumable_chunk = 0; +bool BlenderSession::print_render_stats = false; BlenderSession::BlenderSession(BL::RenderEngine& b_engine, BL::UserPreferences& b_userpref, @@ -492,6 +494,12 @@ void BlenderSession::render() /* free result without merging */ end_render_result(b_engine, b_rr, true, true, false); + if(!b_engine.is_preview() && background && print_render_stats) { + RenderStats stats; + session->scene->collect_statistics(&stats); + printf("Render statistics:\n%s\n", stats.full_report().c_str()); + } + if(session->progress.get_cancel()) break; } diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 3804e07cffc..08f5c873bef 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -143,6 +143,8 @@ public: static int start_resumable_chunk; static int end_resumable_chunk; + static bool print_render_stats; + protected: void do_write_update_render_result(BL::RenderResult& b_rr, BL::RenderLayer& b_rlay, diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index b7248354abd..7d2220f37f9 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRC session.cpp shader.cpp sobol.cpp + stats.cpp svm.cpp tables.cpp tile.cpp @@ -60,6 +61,7 @@ set(SRC_HEADERS session.h shader.h sobol.h + stats.h svm.h tables.h tile.h diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 741dfb0717a..e6ef19cc3be 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -17,6 +17,7 @@ #include "device/device.h" #include "render/image.h" #include "render/scene.h" +#include "render/stats.h" #include "util/util_foreach.h" #include "util/util_logging.h" @@ -1042,4 +1043,15 @@ void ImageManager::device_free(Device *device) } } +void ImageManager::collect_statistics(RenderStats *stats) +{ + for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { + foreach(const Image *image, images[type]) { + stats->image.textures.add_entry( + NamedSizeEntry(path_filename(image->filename), + image->mem->memory_size())); + } + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 9a2b373d016..d94ebe564e3 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN class Device; class Progress; +class RenderStats; class Scene; class ImageMetaData { @@ -89,6 +90,8 @@ public: device_memory *image_memory(int flat_slot); + void collect_statistics(RenderStats *stats); + bool need_update; /* NOTE: Here pixels_size is a size of storage, which equals to diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index df408b478b2..ade575a52d6 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -27,6 +27,7 @@ #include "render/nodes.h" #include "render/object.h" #include "render/scene.h" +#include "render/stats.h" #include "kernel/osl/osl_globals.h" @@ -2276,6 +2277,15 @@ void MeshManager::tag_update(Scene *scene) scene->object_manager->need_update = true; } +void MeshManager::collect_statistics(const Scene *scene, RenderStats *stats) +{ + foreach(Mesh *mesh, scene->meshes) { + stats->mesh.geometry.add_entry( + NamedSizeEntry(string(mesh->name.c_str()), + mesh->get_total_size_in_bytes())); + } +} + bool Mesh::need_attribute(Scene *scene, AttributeStandard std) { if(std == ATTR_STD_NONE) diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index fc7d0b40273..444f03a3664 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -38,6 +38,7 @@ class Device; class DeviceScene; class Mesh; class Progress; +class RenderStats; class Scene; class SceneParams; class AttributeRequest; @@ -351,6 +352,8 @@ public: void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress); + void collect_statistics(const Scene *scene, RenderStats *stats); + protected: /* Calculate verts/triangles/curves offsets in global arrays. */ void mesh_calc_offset(Scene *scene); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 1d65ef65980..9f93fed139c 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -379,4 +379,10 @@ void Scene::device_free() free_memory(false); } +void Scene::collect_statistics(RenderStats *stats) +{ + mesh_manager->collect_statistics(this, stats); + image_manager->collect_statistics(stats); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 713eba623b1..dd8069537eb 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -56,6 +56,7 @@ class ShaderManager; class Progress; class BakeManager; class BakeData; +class RenderStats; /* Scene Device Data */ @@ -255,6 +256,8 @@ public: void reset(); void device_free(); + void collect_statistics(RenderStats *stats); + protected: /* Check if some heavy data worth logging was updated. * Mainly used to suppress extra annoying logging. diff --git a/intern/cycles/render/stats.cpp b/intern/cycles/render/stats.cpp new file mode 100644 index 00000000000..101d33fcf65 --- /dev/null +++ b/intern/cycles/render/stats.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "render/stats.h" +#include "util/util_algorithm.h" +#include "util/util_foreach.h" +#include "util/util_string.h" + +CCL_NAMESPACE_BEGIN + +static int kIndentNumSpaces = 2; + +/* Named size entry. */ + +namespace { + +bool namedSizeEntryComparator(const NamedSizeEntry& a, const NamedSizeEntry& b) +{ + /* We sort in descending order. */ + return a.size > b.size; +} + +} // namespace + +NamedSizeEntry::NamedSizeEntry() + : name(""), + size(0) { +} + +NamedSizeEntry::NamedSizeEntry(const string& name, size_t size) + : name(name), + size(size) { +} + +/* Named size statistics. */ + +NamedSizeStats::NamedSizeStats() + : total_size(0) { +} + +void NamedSizeStats::add_entry(const NamedSizeEntry& entry) { + total_size += entry.size; + entries.push_back(entry); +} + +string NamedSizeStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + const string double_indent = indent + indent; + string result = ""; + result += string_printf("%sTotal memory: %s (%s)\n", + indent.c_str(), + string_human_readable_size(total_size).c_str(), + string_human_readable_number(total_size).c_str()); + sort(entries.begin(), entries.end(), namedSizeEntryComparator); + foreach(const NamedSizeEntry& entry, entries) { + result += string_printf( + "%s%-32s %s (%s)\n", + double_indent.c_str(), + entry.name.c_str(), + string_human_readable_size(entry.size).c_str(), + string_human_readable_number(entry.size).c_str()); + } + return result; +} + +/* Mesh statistics. */ + +MeshStats::MeshStats() { +} + +string MeshStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + string result = ""; + result += indent + "Geometry:\n" + geometry.full_report(indent_level + 1); + return result; +} + +/* Image statistics. */ + +ImageStats::ImageStats() { +} + +string ImageStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + string result = ""; + result += indent + "Textures:\n" + textures.full_report(indent_level + 1); + return result; +} + +/* Overall statistics. */ + +RenderStats::RenderStats() { +} + +string RenderStats::full_report() +{ + string result = ""; + result += "Mesh statistics:\n" + mesh.full_report(1); + result += "Image statistics:\n" + image.full_report(1); + return result; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/stats.h b/intern/cycles/render/stats.h new file mode 100644 index 00000000000..72d5f1dd93d --- /dev/null +++ b/intern/cycles/render/stats.h @@ -0,0 +1,104 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RENDER_STATS_H__ +#define __RENDER_STATS_H__ + +#include "util/util_string.h" +#include "util/util_vector.h" + +CCL_NAMESPACE_BEGIN + +/* Named statistics entry, which corresponds to a size. There is no real + * semantic around the units of size, it just should be the same for all + * entries. + * + * This is a generic entry foi all size-related statistics, which helps + * avoiding duplicating code for things like sorting. + */ +class NamedSizeEntry { +public: + NamedSizeEntry(); + NamedSizeEntry(const string& name, size_t size); + + string name; + size_t size; +}; + +/* Container of named size entries. Used, for example, to store per-mesh memory + * usage statistics. But also keeps track of overall memory usage of the + * container. + */ +class NamedSizeStats { +public: + NamedSizeStats(); + + /* Add entry to the statistics. */ + void add_entry(const NamedSizeEntry& entry); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + /* Total size of all entries. */ + size_t total_size; + + /* NOTE: Is fine to read directly, but for adding use add_entry(), which + * makes sure all accumulating values are properly updated. + */ + vector entries; +}; + +/* Statistics about mesh in the render database. */ +class MeshStats { +public: + MeshStats(); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + /* Input geometry statistics, this is what is coming as an input to render + * from. say, Blender. This does not include runtime or engine specific + * memory like BVH. + */ + NamedSizeStats geometry; +}; + +/* Statistics about images held in memory. */ +class ImageStats { +public: + ImageStats(); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + NamedSizeStats textures; +}; + +/* Render process statistics. */ +class RenderStats { +public: + RenderStats(); + + /* Return full report as string. */ + string full_report(); + + MeshStats mesh; + ImageStats image; +}; + +CCL_NAMESPACE_END + +#endif /* __RENDER_STATS_H__ */ -- cgit v1.2.3 From af2a801731441d132b81bd109c999bde3db58a88 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 25 Jul 2018 10:30:11 +0200 Subject: Subsurf: Correction to origindex Only enforce origindex to NONE for a generated geometry. For the rest of geometry rely on CustomData_copy() to set it to the proper value. This will ensure origindex is set correct for cases when there is an array modifier prior to subsurf. --- source/blender/blenkernel/intern/subdiv_mesh.c | 36 +++++++++++++++----------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index ad2e094fa48..76f41d512bc 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -566,10 +566,10 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) static void subdiv_copy_vertex_data( const SubdivMeshContext *ctx, MVert *subdiv_vertex, - const Mesh *coarse_mesh, + const Mesh *UNUSED(coarse_mesh), const MPoly *coarse_poly, const VerticesForInterpolation *vertex_interpolation, - const int ptex_of_poly_index, + const int UNUSED(ptex_of_poly_index), const float u, const float v) { const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert; @@ -587,27 +587,33 @@ static void subdiv_copy_vertex_data( ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; if (coarse_poly->totloop == 4) { if (u == 0.0f && v == 0.0f) { - ctx->vert_origindex[subdiv_vertex_index] = - vertex_interpolation->vertex_indices[0]; + // ctx->vert_origindex[subdiv_vertex_index] = + // vertex_interpolation->vertex_indices[0]; } else if (u == 1.0f && v == 0.0f) { - ctx->vert_origindex[subdiv_vertex_index] = - vertex_interpolation->vertex_indices[1]; + // ctx->vert_origindex[subdiv_vertex_index] = + // vertex_interpolation->vertex_indices[1]; } else if (u == 1.0f && v == 1.0f) { - ctx->vert_origindex[subdiv_vertex_index] = - vertex_interpolation->vertex_indices[2]; + // ctx->vert_origindex[subdiv_vertex_index] = + // vertex_interpolation->vertex_indices[2]; } else if (u == 0.0f && v == 1.0f) { - ctx->vert_origindex[subdiv_vertex_index] = - vertex_interpolation->vertex_indices[3]; + // ctx->vert_origindex[subdiv_vertex_index] = + // vertex_interpolation->vertex_indices[3]; + } + else { + ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; } } else { if (u == 0.0f && v == 0.0f) { - const MLoop *coarse_mloop = coarse_mesh->mloop; - ctx->vert_origindex[subdiv_vertex_index] = - coarse_mloop[coarse_poly->loopstart + - ptex_of_poly_index].v; + // const MLoop *coarse_mloop = coarse_mesh->mloop; + // ctx->vert_origindex[subdiv_vertex_index] = + // coarse_mloop[coarse_poly->loopstart + + // ptex_of_poly_index].v; + } + else { + ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; } } } @@ -996,7 +1002,7 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, subdiv_poly_index, 1); if (ctx->poly_origindex != NULL) { - ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index; + // ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index; } } -- cgit v1.2.3 From 5c9754c3aa3f2cb9922d76cb73611cd01192895f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 17:33:53 +0200 Subject: Eevee: Fix assert when baking lightprobes. The GPU context was freed before all framebuffer attached to it were deleted. Fix T56117 --- source/blender/draw/engines/eevee/eevee_data.c | 6 +++--- source/blender/draw/engines/eevee/eevee_lightcache.c | 9 +++++++++ source/blender/draw/engines/eevee/eevee_private.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index 96e784b524c..636e532555f 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -30,7 +30,7 @@ #include "eevee_private.h" #include "eevee_lightcache.h" -static void eevee_view_layer_data_free(void *storage) +void EEVEE_view_layer_data_free(void *storage) { EEVEE_ViewLayerData *sldata = (EEVEE_ViewLayerData *)storage; @@ -77,7 +77,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void) EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer) { EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex( - view_layer, &draw_engine_eevee_type, &eevee_view_layer_data_free); + view_layer, &draw_engine_eevee_type, &EEVEE_view_layer_data_free); if (*sldata == NULL) { *sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData"); @@ -89,7 +89,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_laye EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void) { EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure( - &draw_engine_eevee_type, &eevee_view_layer_data_free); + &draw_engine_eevee_type, &EEVEE_view_layer_data_free); if (*sldata == NULL) { *sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData"); diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 4f5ad5159cf..b0b66ee50dc 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -93,6 +93,7 @@ typedef struct EEVEE_LightBake { LightCache *lcache; Scene *scene; struct Main *bmain; + EEVEE_ViewLayerData *sldata; LightProbe **probe; /* Current probe being rendered. */ GPUTexture *rt_color; /* Target cube color texture. */ @@ -597,6 +598,12 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake) lbake->lcache = NULL; } + /* XXX Free the resources contained in the viewlayer data + * to be able to free the context before deleting the depsgraph. */ + if (lbake->sldata) { + EEVEE_view_layer_data_free(lbake->sldata); + } + DRW_TEXTURE_FREE_SAFE(lbake->rt_depth); DRW_TEXTURE_FREE_SAFE(lbake->rt_color); DRW_TEXTURE_FREE_SAFE(lbake->grid_prev); @@ -633,6 +640,8 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph); + lbake->sldata = sldata; + /* Disable all effects BUT high bitdepth shadows. */ scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH; scene_eval->eevee.taa_samples = 1; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 5aa331a9b99..349a27a1765 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -777,6 +777,7 @@ typedef struct EEVEE_PrivateData { } EEVEE_PrivateData; /* Transient data */ /* eevee_data.c */ +void EEVEE_view_layer_data_free(void *sldata); EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void); EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer); EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void); -- cgit v1.2.3 From bdbc6fafc038afdffdb4d040ea692f15f31a0048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 17:50:14 +0200 Subject: GPUTexture: Fix wrong texture size check --- source/blender/gpu/intern/gpu_texture.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index e5073196a52..a5dfb6a6b73 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -436,9 +436,9 @@ static bool gpu_texture_try_alloc( case GL_PROXY_TEXTURE_2D_ARRAY: /* HACK: Some driver wrongly check GL_PROXY_TEXTURE_2D_ARRAY as a GL_PROXY_TEXTURE_3D * checking all dimensions against GPU_max_texture_layers (see T55888). */ - return (tex->w < GPU_max_texture_size()) && - (tex->h < GPU_max_texture_size()) && - (tex->d < GPU_max_texture_layers()); + return (tex->w > 0) && (tex->w <= GPU_max_texture_size()) && + (tex->h > 0) && (tex->h <= GPU_max_texture_size()) && + (tex->d > 0) && (tex->d <= GPU_max_texture_layers()); case GL_PROXY_TEXTURE_3D: glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL); break; -- cgit v1.2.3 From 48759580839aa4e2ad2541ff4c19baaaf751721d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 27 Jul 2018 18:12:02 +0200 Subject: Cleanup: Remove occurances of GPULamp --- source/blender/blenkernel/intern/object.c | 1 - source/blender/blenloader/intern/readfile.c | 1 - source/blender/gpu/GPU_material.h | 1 - source/blender/makesdna/DNA_object_types.h | 1 - 4 files changed, 4 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 33ea13c9a38..1d6b23ce7f7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1204,7 +1204,6 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con ob_dst->derivedDeform = NULL; ob_dst->derivedFinal = NULL; - BLI_listbase_clear(&ob_dst->gpulamp); BLI_listbase_clear((ListBase *)&ob_dst->drawdata); BLI_listbase_clear(&ob_dst->pc_ids); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d76a2fc2cd0..f226693b989 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5545,7 +5545,6 @@ static void direct_link_object(FileData *fd, Object *ob) ob->derivedDeform = NULL; ob->derivedFinal = NULL; BKE_object_runtime_reset(ob); - BLI_listbase_clear(&ob->gpulamp); link_list(fd, &ob->pc_ids); /* Runtime curve data */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f2c029f643e..9fea9eaf4e1 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -55,7 +55,6 @@ struct GPUNodeStack; struct GPUMaterial; struct GPUTexture; struct GPUUniformBuffer; -struct GPULamp; struct PreviewImage; struct World; struct bNode; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 999ebe0ccc3..edc87c492a6 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -283,7 +283,6 @@ typedef struct Object { /* Runtime valuated curve-specific data, not stored in the file */ struct CurveCache *curve_cache; - ListBase gpulamp; /* runtime, for glsl lamp display only */ ListBase pc_ids; struct RigidBodyOb *rigidbody_object; /* settings for Bullet rigid body */ -- cgit v1.2.3 From bcefb202a2278188c0c780a6e4a3603d4d727c91 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Fri, 27 Jul 2018 23:30:20 +0200 Subject: Cycles: Save a few instructions in area light sampling Just basic algebra - because all vectors have the same z coordinate, a lot of terms end up cancelling out. Not exactly a massive improvement, but it's measurable with Branched PT and a high sample count on the lamp. Reviewers: brecht, sergey Reviewed By: brecht Subscribers: swerner Differential Revision: https://developer.blender.org/D3540 --- intern/cycles/kernel/kernel_light.h | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index a25a7e3842b..b5a777efa78 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -72,24 +72,17 @@ ccl_device_inline float area_light_sample(float3 P, float y0 = dot(dir, y); float x1 = x0 + axisu_len; float y1 = y0 + axisv_len; - /* Create vectors to four vertices. */ - float3 v00 = make_float3(x0, y0, z0); - float3 v01 = make_float3(x0, y1, z0); - float3 v10 = make_float3(x1, y0, z0); - float3 v11 = make_float3(x1, y1, z0); - /* Compute normals to edges. */ - float3 n0 = normalize(cross(v00, v10)); - float3 n1 = normalize(cross(v10, v11)); - float3 n2 = normalize(cross(v11, v01)); - float3 n3 = normalize(cross(v01, v00)); /* Compute internal angles (gamma_i). */ - float g0 = safe_acosf(-dot(n0, n1)); - float g1 = safe_acosf(-dot(n1, n2)); - float g2 = safe_acosf(-dot(n2, n3)); - float g3 = safe_acosf(-dot(n3, n0)); + float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1); + float4 nz = make_float4(y0, x1, y1, x0) * diff; + nz = nz / sqrt(sqr(z0 * diff) + sqr(nz)); + float g0 = safe_acosf(-nz.x * nz.y); + float g1 = safe_acosf(-nz.y * nz.z); + float g2 = safe_acosf(-nz.z * nz.w); + float g3 = safe_acosf(-nz.w * nz.x); /* Compute predefined constants. */ - float b0 = n0.z; - float b1 = n2.z; + float b0 = nz.x; + float b1 = nz.z; float b0sq = b0 * b0; float k = M_2PI_F - g2 - g3; /* Compute solid angle from internal angles. */ -- cgit v1.2.3 From decd924116d778a524aae49f271f3020e8696ca4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 26 Jul 2018 17:35:14 +0200 Subject: Fix outliner icon row with counters not correct for nested collections. --- .../blender/editors/space_outliner/outliner_draw.c | 67 +++++++++++----------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index e1049d02e37..435e0018ac0 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1441,23 +1441,19 @@ static int tree_element_id_type_to_index(TreeElement *te) } } +typedef struct MergedIconRow { + eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX]; + int num_elements[INDEX_ID_MAX + OB_TYPE_MAX]; + TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX]; +} MergedIconRow; + static void outliner_draw_iconrow( bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, SpaceOops *soops, - ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac) + ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac, MergedIconRow *merged) { eOLDrawState active; const Object *obact = OBACT(view_layer); - struct { - eOLDrawState active[INDEX_ID_MAX + OB_TYPE_MAX]; - int num_elements[INDEX_ID_MAX + OB_TYPE_MAX]; - TreeElement *tree_element[INDEX_ID_MAX + OB_TYPE_MAX]; - } data = { - .active = {0}, - .num_elements = {0}, - .tree_element = {NULL}, - }; - for (TreeElement *te = lb->first; te; te = te->next) { /* exit drawing early */ if ((*offsx) - UI_UNIT_X > xmax) @@ -1488,13 +1484,13 @@ static void outliner_draw_iconrow( } else { const int index = tree_element_id_type_to_index(te); - data.num_elements[index]++; - if ((data.tree_element[index] == NULL) || - (active > data.active[index])) + merged->num_elements[index]++; + if ((merged->tree_element[index] == NULL) || + (active > merged->active[index])) { - data.tree_element[index] = te; + merged->tree_element[index] = te; } - data.active[index] = MAX2(active, data.active[index]); + merged->active[index] = MAX2(active, merged->active[index]); } } @@ -1502,26 +1498,28 @@ static void outliner_draw_iconrow( if (tselem->type != TSE_R_LAYER) { outliner_draw_iconrow( C, block, fstyle, scene, view_layer, soops, - &te->subtree, level + 1, xmax, offsx, ys, alpha_fac); + &te->subtree, level + 1, xmax, offsx, ys, alpha_fac, merged); } } - for (int i = 0; i < INDEX_ID_MAX; i++) { - const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1; - /* See tree_element_id_type_to_index for the index logic. */ - int index_base = i; - if (i > INDEX_ID_OB) { - index_base += OB_TYPE_MAX; - } - for (int j = 0; j < num_subtypes; j++) { - const int index = index_base + j; - if (data.num_elements[index] != 0) { - outliner_draw_iconrow_doit(block, - data.tree_element[index], - fstyle, - xmax, offsx, ys, alpha_fac, - data.active[index], - data.num_elements[index]); + if (level == 0) { + for (int i = 0; i < INDEX_ID_MAX; i++) { + const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1; + /* See tree_element_id_type_to_index for the index logic. */ + int index_base = i; + if (i > INDEX_ID_OB) { + index_base += OB_TYPE_MAX; + } + for (int j = 0; j < num_subtypes; j++) { + const int index = index_base + j; + if (merged->num_elements[index] != 0) { + outliner_draw_iconrow_doit(block, + merged->tree_element[index], + fstyle, + xmax, offsx, ys, alpha_fac, + merged->active[index], + merged->num_elements[index]); + } } } } @@ -1748,9 +1746,10 @@ static void outliner_draw_tree_element( immUnbindProgram(); } + MergedIconRow merged = {{0}}; outliner_draw_iconrow( C, block, fstyle, scene, view_layer, soops, &te->subtree, 0, xmax, &tempx, - *starty, alpha_fac); + *starty, alpha_fac, &merged); GPU_blend(false); } -- cgit v1.2.3 From b747524144c54c2c71d550de6331d96afc4cb711 Mon Sep 17 00:00:00 2001 From: Stefan Werner Date: Sat, 28 Jul 2018 18:14:05 +0200 Subject: Cycles: speed up mesh volume bounds construction. Patch by Stefan, with minor tweaks by Brecht. --- intern/cycles/render/mesh_volume.cpp | 91 +++++++++++------------------------- 1 file changed, 26 insertions(+), 65 deletions(-) diff --git a/intern/cycles/render/mesh_volume.cpp b/intern/cycles/render/mesh_volume.cpp index d1c49b456ff..3ee4124ba0f 100644 --- a/intern/cycles/render/mesh_volume.cpp +++ b/intern/cycles/render/mesh_volume.cpp @@ -87,23 +87,31 @@ const float3 quads_normals[6] = { make_float3(0.0f, 0.0f, 1.0f), }; -static void create_quad(int3 corners[8], vector &vertices, vector &quads, int face_index) +static int add_vertex(int3 v, vector &vertices, int3 res, unordered_map &used_verts) { - size_t vertex_offset = vertices.size(); + size_t vert_key = v.x + v.y * (res.x+1) + v.z * (res.x+1)*(res.y+1); + unordered_map::iterator it = used_verts.find(vert_key); + if(it != used_verts.end()) { + return it->second; + } + + int vertex_offset = vertices.size(); + used_verts[vert_key] = vertex_offset; + vertices.push_back(v); + return vertex_offset; +} + +static void create_quad(int3 corners[8], vector &vertices, vector &quads, int3 res, unordered_map &used_verts, int face_index) +{ QuadData quad; - quad.v0 = vertex_offset + 0; - quad.v1 = vertex_offset + 1; - quad.v2 = vertex_offset + 2; - quad.v3 = vertex_offset + 3; + quad.v0 = add_vertex(corners[quads_indices[face_index][0]], vertices, res, used_verts); + quad.v1 = add_vertex(corners[quads_indices[face_index][1]], vertices, res, used_verts); + quad.v2 = add_vertex(corners[quads_indices[face_index][2]], vertices, res, used_verts); + quad.v3 = add_vertex(corners[quads_indices[face_index][3]], vertices, res, used_verts); quad.normal = quads_normals[face_index]; quads.push_back(quad); - - vertices.push_back(corners[quads_indices[face_index][0]]); - vertices.push_back(corners[quads_indices[face_index][1]]); - vertices.push_back(corners[quads_indices[face_index][2]]); - vertices.push_back(corners[quads_indices[face_index][3]]); } struct VolumeParams { @@ -159,9 +167,6 @@ private: void generate_vertices_and_quads(vector &vertices_is, vector &quads); - void deduplicate_vertices(vector &vertices, - vector &quads); - void convert_object_space(const vector &vertices, vector &out_vertices); @@ -234,8 +239,6 @@ void VolumeMeshBuilder::create_mesh(vector &vertices, generate_vertices_and_quads(vertices_is, quads); - deduplicate_vertices(vertices_is, quads); - convert_object_space(vertices_is, vertices); convert_quads_to_tris(quads, indices, face_normals); @@ -245,10 +248,7 @@ void VolumeMeshBuilder::generate_vertices_and_quads( vector &vertices_is, vector &quads) { - /* Overallocation, we could count the number of quads and vertices to create - * in a pre-pass if memory becomes an issue. */ - vertices_is.reserve(number_of_nodes*8); - quads.reserve(number_of_nodes*6); + unordered_map used_verts; for(int z = 0; z < res.z; ++z) { for(int y = 0; y < res.y; ++y) { @@ -283,77 +283,38 @@ void VolumeMeshBuilder::generate_vertices_and_quads( voxel_index = compute_voxel_index(res, x - 1, y, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_X_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MIN); } voxel_index = compute_voxel_index(res, x + 1, y, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_X_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_X_MAX); } voxel_index = compute_voxel_index(res, x, y - 1, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Y_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MIN); } voxel_index = compute_voxel_index(res, x, y + 1, z); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Y_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Y_MAX); } voxel_index = compute_voxel_index(res, x, y, z - 1); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Z_MIN); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MIN); } voxel_index = compute_voxel_index(res, x, y, z + 1); if(voxel_index == -1 || grid[voxel_index] == 0) { - create_quad(corners, vertices_is, quads, QUAD_Z_MAX); + create_quad(corners, vertices_is, quads, res, used_verts, QUAD_Z_MAX); } } } } } -void VolumeMeshBuilder::deduplicate_vertices(vector &vertices, - vector &quads) -{ - vector sorted_vertices = vertices; - std::sort(sorted_vertices.begin(), sorted_vertices.end()); - vector::iterator it = std::unique(sorted_vertices.begin(), sorted_vertices.end()); - sorted_vertices.resize(std::distance(sorted_vertices.begin(), it)); - - vector new_quads = quads; - - for(size_t i = 0; i < vertices.size(); ++i) { - for(size_t j = 0; j < sorted_vertices.size(); ++j) { - if(vertices[i] != sorted_vertices[j]) { - continue; - } - - for(int k = 0; k < quads.size(); ++k) { - if(quads[k].v0 == i) { - new_quads[k].v0 = j; - } - else if(quads[k].v1 == i) { - new_quads[k].v1 = j; - } - else if(quads[k].v2 == i) { - new_quads[k].v2 = j; - } - else if(quads[k].v3 == i) { - new_quads[k].v3 = j; - } - } - - break; - } - } - - vertices = sorted_vertices; - quads = new_quads; -} - void VolumeMeshBuilder::convert_object_space(const vector &vertices, vector &out_vertices) { -- cgit v1.2.3 From f50fa4c5d69a50fca880d1abb0b49d06d4745be8 Mon Sep 17 00:00:00 2001 From: Ines Almeida Date: Sat, 28 Jul 2018 22:58:33 +0200 Subject: Fix T56120: Crash on "Install Matcap, World or Camera HDRI" Code was trying to hide properties by name that may not exist. Check if it was actually found and add 'files' to the filter, since it is what WM_OT_studio_lights_install uses. --- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/blender/editors/space_file/file_panels.c | 15 ++++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index ebd058d7a64..c87ee4d46f1 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit ebd058d7a6438d137522063bb3286c8acc325ca6 +Subproject commit c87ee4d46f16d60a2e1db7514c8d5ab42c5d93df diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 47470215783..15b25a42783 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 474702157831f1a58bb50f5240ab8b1b02b6ba37 +Subproject commit 15b25a42783d1e516b5298d70b582fae2559ae17 diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index abe9f173b09..cf8a5b9e1f2 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -80,19 +80,24 @@ static void file_panel_operator(const bContext *C, Panel *pa) UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); /* Hack: temporary hide.*/ - const char *hide[3] = {"filepath", "directory", "filename"}; + const char *hide[4] = {"filepath", "files", "directory", "filename"}; for (int i = 0; i < ARRAY_SIZE(hide); i++) { - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); - RNA_def_property_flag(prop, PROP_HIDDEN); + PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]); + if (prop) { + RNA_def_property_flag(prop, PROP_HIDDEN); + } } uiTemplateOperatorPropertyButs( C, pa->layout, op, UI_BUT_LABEL_ALIGN_NONE, UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); + /* Hack: temporary hide.*/ for (int i = 0; i < ARRAY_SIZE(hide); i++) { - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); - RNA_def_property_clear_flag(prop, PROP_HIDDEN); + PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]); + if (prop) { + RNA_def_property_clear_flag(prop, PROP_HIDDEN); + } } UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); -- cgit v1.2.3 From 8f01623ef314f72ac7628d7fd54c1855cd0cb731 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 29 Jul 2018 11:54:12 +1000 Subject: UI: correct RNA property --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index eeb47595213..3101ffc8336 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -182,7 +182,7 @@ class _defs_transform: def transform(): def draw_settings(context, layout, tool): tool_settings = context.tool_settings - layout.prop(tool_settings, "use_gizmo") + layout.prop(tool_settings, "use_gizmo_mode") return dict( text="Transform", -- cgit v1.2.3 From 018c9af446de10f038a6e641ca3a61ce451a7c92 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 29 Jul 2018 12:09:00 +1000 Subject: Fix T56120: bad property access (from 2.8) Thanks to @brita_ for the fix. --- source/blender/editors/space_file/file_panels.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index c5350750af4..a40334098d7 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -80,17 +80,21 @@ static void file_panel_operator(const bContext *C, Panel *pa) UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); /* Hack: temporary hide.*/ - const char *hide[3] = {"filepath", "directory", "filename"}; + const char *hide[] = {"filepath", "directory", "filename", "files"}; for (int i = 0; i < ARRAY_SIZE(hide); i++) { - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); - RNA_def_property_flag(prop, PROP_HIDDEN); + PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]); + if (prop) { + RNA_def_property_flag(prop, PROP_HIDDEN); + } } uiTemplateOperatorPropertyButs(C, pa->layout, op, '\0', UI_TEMPLATE_OP_PROPS_SHOW_EMPTY); for (int i = 0; i < ARRAY_SIZE(hide); i++) { - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); - RNA_def_property_clear_flag(prop, PROP_HIDDEN); + PropertyRNA *prop = RNA_struct_find_property(op->ptr, hide[i]); + if (prop) { + RNA_def_property_clear_flag(prop, PROP_HIDDEN); + } } UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL); -- cgit v1.2.3 From 83227de828c9cb8f7807e1d15308bda0bc261fab Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Sun, 29 Jul 2018 11:24:49 -0600 Subject: make.bat : fix msvc 2017 detection. when 2017 was not found, it did not properly bail out of the rest of the detection process unless verbose mode was used. --- build_files/windows/detect_msvc2017.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/windows/detect_msvc2017.cmd b/build_files/windows/detect_msvc2017.cmd index 7695dc8d5a2..029f98cbe1e 100644 --- a/build_files/windows/detect_msvc2017.cmd +++ b/build_files/windows/detect_msvc2017.cmd @@ -10,8 +10,8 @@ set vs_where=%ProgramFilesX86%\Microsoft Visual Studio\Installer\vswhere.exe if not exist "%vs_where%" ( if NOT "%verbose%" == "" ( echo Visual Studio 2017 ^(15.2 or newer^) is not detected - goto FAIL ) + goto FAIL ) if NOT "%verbose%" == "" ( -- cgit v1.2.3 From 40ad0de0027dd15934bec4fa79349c4580f83945 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Sun, 29 Jul 2018 22:49:49 +0200 Subject: UI: Custom FPS not showing properly if editor is narrow --- release/scripts/startup/bl_ui/properties_render.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 83d31ae6114..1c26d172e4c 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -120,7 +120,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): return args @staticmethod - def draw_framerate(sub, rd): + def draw_framerate(layout, sub, rd): if RENDER_PT_dimensions._preset_class is None: RENDER_PT_dimensions._preset_class = bpy.types.RENDER_MT_framerate_presets @@ -130,8 +130,9 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): sub.menu("RENDER_MT_framerate_presets", text=fps_label_text) if show_framerate: - sub.prop(rd, "fps") - sub.prop(rd, "fps_base", text="/") + col = layout.column(align=True) + col.prop(rd, "fps") + col.prop(rd, "fps_base", text="Base") def draw(self, context): layout = self.layout @@ -161,10 +162,10 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): col.prop(scene, "frame_end", text="End") col.prop(scene, "frame_step", text="Step") - col = layout.split(percentage=0.5) + col = layout.split() col.alignment = 'RIGHT' col.label(text="Frame Rate") - self.draw_framerate(col, rd) + self.draw_framerate(layout, col, rd) class RENDER_PT_frame_remapping(RenderButtonsPanel, Panel): -- cgit v1.2.3 From 6f1514d22d1908c1c4418d2ef33b03c499687a51 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 15:20:34 +1000 Subject: CMake: omit superfluous Up-to-date messages Causes a lot of noise when building the install target. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4de98860a61..7b018905e4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,11 @@ if(NOT DEFINED CMAKE_BUILD_TYPE_INIT) set(CMAKE_BUILD_TYPE_INIT "Release") endif() +# Omit superfluous "Up-to-date" messages. +if(NOT DEFINED CMAKE_INSTALL_MESSAGE) + set(CMAKE_INSTALL_MESSAGE "LAZY") +endif() + # quiet output for Makefiles, 'make -s' helps too # set_property(GLOBAL PROPERTY RULE_MESSAGES OFF) -- cgit v1.2.3 From 9c960557a7d2734b3be8cf5f512ef0d8bba54e98 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 15:38:39 +1000 Subject: Cleanup: trailing space --- source/blender/compositor/nodes/COM_CryptomatteNode.cpp | 4 ++-- source/blender/compositor/nodes/COM_CryptomatteNode.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp index 5ed66fe45e7..648ea4556ad 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cpp +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cpp @@ -100,7 +100,7 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos SeparateChannelOperation *separateOperation = new SeparateChannelOperation; separateOperation->setChannel(3); converter.addOperation(separateOperation); - + SetAlphaOperation *operationAlpha = new SetAlphaOperation(); converter.addOperation(operationAlpha); @@ -117,5 +117,5 @@ void CryptomatteNode::convertToOperations(NodeConverter &converter, const Compos converter.mapOutputSocket(outputSocketMatte, separateOperation->getOutputSocket(0)); converter.mapOutputSocket(outputSocketImage, operationAlpha->getOutputSocket(0)); converter.mapOutputSocket(outputSocketPick, clearAlphaOperation->getOutputSocket(0)); - + } diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h index 5251b57d8af..0ee3c1740b3 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.h +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.h @@ -35,4 +35,3 @@ public: }; #endif - -- cgit v1.2.3 From f8f4feefb8083e7f5875ae81b678a4c7c3c81660 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 15:40:09 +1000 Subject: Cleanup: trailing space --- source/blender/blenkernel/intern/world.c | 1 - source/blender/draw/engines/eevee/eevee_lightcache.h | 2 +- .../blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl | 2 +- source/blender/editors/space_view3d/view3d_snap.c | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 3e1a9a4f57b..a5a38a6dc12 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -168,4 +168,3 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local) { BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local); } - diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.h b/source/blender/draw/engines/eevee/eevee_lightcache.h index b58a0544c59..3c6fc73a849 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.h +++ b/source/blender/draw/engines/eevee/eevee_lightcache.h @@ -56,4 +56,4 @@ void EEVEE_lightcache_free(struct LightCache *lcache); void EEVEE_lightcache_load(struct LightCache *lcache); void EEVEE_lightcache_info_update(struct SceneEEVEE *eevee); -#endif /* __EEVEE_LIGHTCACHE_H__ */ \ No newline at end of file +#endif /* __EEVEE_LIGHTCACHE_H__ */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index ba5b78f4ecf..1f14e506dcf 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -178,4 +178,4 @@ void main() length(ls_vol_isect) / length(ls_ray_dir), length(vs_ray_dir) * stepLength); #endif -} \ No newline at end of file +} diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 6a8589f5468..6cb0db94099 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -229,7 +229,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /** Snaps the selection as a whole (use_offset=true) or each selected object to the given location. * * \param snap_target_global: a location in global space to snap to (eg. 3D cursor or active object). - * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection + * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection * pivot point (median, active), or if every object origin should be snapped to the given location. **/ static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset) -- cgit v1.2.3 From f4379f8b914eaf7aa1f17323f927836a3d9288fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 16:16:44 +1000 Subject: Use Ctrl Snap to seconds w/ play-head drag D3056 by @alourenco --- source/blender/blenkernel/BKE_scene.h | 2 ++ source/blender/blenkernel/intern/scene.c | 10 ++++++++++ source/blender/editors/animation/anim_ops.c | 10 ++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index ae809641480..e85867fcbe7 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -114,6 +114,8 @@ int BKE_scene_camera_switch_update(struct Scene *scene); char *BKE_scene_find_marker_name(struct Scene *scene, int frame); char *BKE_scene_find_last_marker_name(struct Scene *scene, int frame); +int BKE_scene_frame_snap_by_seconds(struct Scene *scene, double interval_in_seconds, int cfra); + /* checks for cycle, returns 1 if it's all OK */ bool BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a1003910ca3..1eb65519596 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1204,6 +1204,16 @@ char *BKE_scene_find_last_marker_name(Scene *scene, int frame) return best_marker ? best_marker->name : NULL; } +int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int cfra) +{ + const int fps = round_db_to_int(FPS * interval_in_seconds); + const int second_prev = cfra - mod_i(cfra, fps); + const int second_next = second_prev + fps; + const int delta_prev = cfra - second_prev; + const int delta_next = second_next - cfra; + return (delta_prev < delta_next) ? second_prev : second_next; +} + Base *BKE_scene_base_add(Scene *sce, Object *ob) { diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 8612f5944bb..939d547dc94 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -45,6 +45,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_sound.h" +#include "BKE_scene.h" #include "UI_view2d.h" @@ -98,8 +99,13 @@ static void change_frame_apply(bContext *C, wmOperator *op) float frame = RNA_float_get(op->ptr, "frame"); bool do_snap = RNA_boolean_get(op->ptr, "snap"); - if (do_snap && CTX_wm_space_seq(C)) { - frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + if (do_snap) { + if (CTX_wm_space_seq(C)) { + frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false); + } + else { + frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame); + } } /* set the new frame number */ -- cgit v1.2.3 From ff6c6f18c1591a213d6dffb266b9f2136ef09c3b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 16:36:07 +1000 Subject: Cleanup: id-property creation D3473 by @JacquesLucke --- source/blender/python/generic/idprop_py_api.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 4b56d4412e6..4d4d5232800 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -596,15 +596,15 @@ static IDProperty *idp_from_PyMapping(const char *name, PyObject *ob) return prop; } -static IDProperty *idp_from_DatablockPointer(const char *name, PyObject *ob, IDPropertyTemplate *val) +static IDProperty *idp_from_DatablockPointer(const char *name, PyObject *ob) { - pyrna_id_FromPyObject(ob, &val->id); - return IDP_New(IDP_ID, val, name); + IDPropertyTemplate val = {0}; + pyrna_id_FromPyObject(ob, &val.id); + return IDP_New(IDP_ID, &val, name); } static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob) { - IDPropertyTemplate val = {0}; const char *name = idp_try_read_name(name_obj); if (name == NULL) { return NULL; @@ -626,7 +626,7 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob) return idp_from_PySequence(name, ob); } else if (ob == Py_None || pyrna_id_CheckPyObject(ob)) { - return idp_from_DatablockPointer(name, ob, &val); + return idp_from_DatablockPointer(name, ob); } else if (PyMapping_Check(ob)) { return idp_from_PyMapping(name, ob); -- cgit v1.2.3 From c8b6e3d77717a6efdc0dc68c18aa07a291385e3a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 16:46:55 +1000 Subject: Sequencer: move text & color into own category Add 'Generate' menu, these aren't effects from a user perspective. D3546 by @rudolf.ortner --- release/scripts/startup/bl_ui/space_sequencer.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index d156f822606..c3ca26efcb7 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -338,9 +338,21 @@ class SEQUENCER_MT_add(Menu): layout.operator("sequencer.image_strip_add", text="Image") layout.operator("sequencer.sound_strip_add", text="Sound") + layout.menu("SEQUENCER_MT_add_generate") layout.menu("SEQUENCER_MT_add_effect") +class SEQUENCER_MT_add_generate(Menu): + bl_label = "Generate" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR' + layout.operator("sequencer.effect_strip_add", text="Text").type = 'TEXT' + + class SEQUENCER_MT_add_effect(Menu): bl_label = "Effect Strip" @@ -360,10 +372,8 @@ class SEQUENCER_MT_add_effect(Menu): layout.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP' layout.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE' layout.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW' - layout.operator("sequencer.effect_strip_add", text="Text").type = 'TEXT' layout.operator("sequencer.effect_strip_add", text="Color Mix").type = 'COLORMIX' layout.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM' - layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR' layout.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED' layout.operator("sequencer.effect_strip_add", text="Multicam Selector").type = 'MULTICAM' layout.operator("sequencer.effect_strip_add", text="Adjustment Layer").type = 'ADJUSTMENT' @@ -1303,6 +1313,7 @@ classes = ( SEQUENCER_MT_marker, SEQUENCER_MT_frame, SEQUENCER_MT_add, + SEQUENCER_MT_add_generate, SEQUENCER_MT_add_effect, SEQUENCER_MT_strip, SEQUENCER_MT_strip_transform, -- cgit v1.2.3 From 914e4d121263ae02dd33f27827417316726778d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Jul 2018 20:53:34 +1000 Subject: Fix T56152: Rotate crash w/ individual origins --- source/blender/editors/transform/transform_constraints.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index c8f74cbcd4f..b24ef4e0ba2 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -560,7 +560,9 @@ static void applyObjectConstraintRot( /* on setup call, use first object */ if (td == NULL) { - td = TRANS_DATA_CONTAINER_FIRST_OK(t)->data; + BLI_assert(tc == NULL); + tc = TRANS_DATA_CONTAINER_FIRST_OK(t); + td = tc->data; } if (t->flag & T_EDIT) { -- cgit v1.2.3 From bd49a765689a8abfb6662c0b748268d24b1b3d2a Mon Sep 17 00:00:00 2001 From: mano-wii Date: Mon, 30 Jul 2018 08:49:27 -0300 Subject: Fix T56121 and maybe others: DST.gpu_context was being created in the wrong DST.gl_context. In addition to the crash in the selection of bones, this was responsible for other problems such as wrong hair and disappearing objects. --- source/blender/draw/intern/draw_manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index cc4f8ec7947..0a15fb3a114 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2351,6 +2351,7 @@ void DRW_opengl_context_create(void) } /* This changes the active context. */ DST.gl_context = WM_opengl_context_create(); + WM_opengl_context_activate(DST.gl_context); /* Be sure to create gawain.context too. */ DST.gpu_context = GPU_context_create(); if (!G.background) { -- cgit v1.2.3 From d01319df76496d2ded7643d5b38be394e5e29a0b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Jul 2018 12:22:18 +0200 Subject: Shape keys: change default interpolation for absolute shape keys to linear. --- source/blender/blenkernel/intern/key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 13f7716cd80..0d8e281fa06 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1457,7 +1457,7 @@ KeyBlock *BKE_keyblock_add(Key *key, const char *name) kb = MEM_callocN(sizeof(KeyBlock), "Keyblock"); BLI_addtail(&key->block, kb); - kb->type = KEY_CARDINAL; + kb->type = KEY_LINEAR; tot = BLI_listbase_count(&key->block); if (name) { -- cgit v1.2.3 From 6a493e44302588c35a269ed34a3e679c7912074b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Jul 2018 13:43:06 +0200 Subject: Viewport: add new default set of matcaps. These were made by the community and curated by Pablo and William. Thanks to everyone who contributed! https://devtalk.blender.org/t/call-for-content-matcaps/737 Command used for compression: oiiotool %s --ch R,G,B -d half --compression dwab -o output/%s --- release/datafiles/studiolights/matcap/basic_1.exr | Bin 0 -> 44539 bytes release/datafiles/studiolights/matcap/basic_2.exr | Bin 0 -> 61142 bytes release/datafiles/studiolights/matcap/basic_dark.exr | Bin 0 -> 38734 bytes release/datafiles/studiolights/matcap/basic_side.exr | Bin 0 -> 41554 bytes release/datafiles/studiolights/matcap/ceramic_dark.exr | Bin 0 -> 63518 bytes .../studiolights/matcap/ceramic_lightbulb.exr | Bin 0 -> 102212 bytes .../datafiles/studiolights/matcap/check_normal+y.exr | Bin 0 -> 87477 bytes .../datafiles/studiolights/matcap/check_reflection.exr | Bin 0 -> 151596 bytes .../datafiles/studiolights/matcap/check_rim_dark.exr | Bin 0 -> 50807 bytes .../datafiles/studiolights/matcap/check_rim_light.exr | Bin 0 -> 56757 bytes release/datafiles/studiolights/matcap/clay_brown.exr | Bin 0 -> 65156 bytes release/datafiles/studiolights/matcap/clay_muddy.exr | Bin 0 -> 53778 bytes release/datafiles/studiolights/matcap/clay_studio.exr | Bin 0 -> 51624 bytes release/datafiles/studiolights/matcap/jade.exr | Bin 0 -> 63103 bytes release/datafiles/studiolights/matcap/license.txt | 4 ++-- release/datafiles/studiolights/matcap/mc01.jpg | Bin 20830 -> 0 bytes release/datafiles/studiolights/matcap/mc02.jpg | Bin 23428 -> 0 bytes release/datafiles/studiolights/matcap/mc03.jpg | Bin 17550 -> 0 bytes release/datafiles/studiolights/matcap/mc04.jpg | Bin 29197 -> 0 bytes release/datafiles/studiolights/matcap/mc05.jpg | Bin 25454 -> 0 bytes release/datafiles/studiolights/matcap/mc06.jpg | Bin 19864 -> 0 bytes release/datafiles/studiolights/matcap/mc07.jpg | Bin 59262 -> 0 bytes release/datafiles/studiolights/matcap/mc08.jpg | Bin 24133 -> 0 bytes release/datafiles/studiolights/matcap/mc09.jpg | Bin 31101 -> 0 bytes release/datafiles/studiolights/matcap/mc10.jpg | Bin 28973 -> 0 bytes release/datafiles/studiolights/matcap/mc11.jpg | Bin 21395 -> 0 bytes release/datafiles/studiolights/matcap/mc12.jpg | Bin 23797 -> 0 bytes release/datafiles/studiolights/matcap/mc13.jpg | Bin 45661 -> 0 bytes release/datafiles/studiolights/matcap/mc14.jpg | Bin 44762 -> 0 bytes release/datafiles/studiolights/matcap/mc15.jpg | Bin 27456 -> 0 bytes release/datafiles/studiolights/matcap/mc16.jpg | Bin 33401 -> 0 bytes release/datafiles/studiolights/matcap/mc17.jpg | Bin 49292 -> 0 bytes release/datafiles/studiolights/matcap/mc18.jpg | Bin 40254 -> 0 bytes release/datafiles/studiolights/matcap/mc19.jpg | Bin 46330 -> 0 bytes release/datafiles/studiolights/matcap/mc20.jpg | Bin 52893 -> 0 bytes release/datafiles/studiolights/matcap/mc21.jpg | Bin 28717 -> 0 bytes release/datafiles/studiolights/matcap/mc22.jpg | Bin 33801 -> 0 bytes release/datafiles/studiolights/matcap/mc23.jpg | Bin 26688 -> 0 bytes release/datafiles/studiolights/matcap/mc24.jpg | Bin 14149 -> 0 bytes .../studiolights/matcap/metal_anisotropic.exr | Bin 0 -> 118909 bytes .../datafiles/studiolights/matcap/metal_carpaint.exr | Bin 0 -> 91775 bytes release/datafiles/studiolights/matcap/metal_lead.exr | Bin 0 -> 41455 bytes release/datafiles/studiolights/matcap/metal_shiny.exr | Bin 0 -> 126238 bytes release/datafiles/studiolights/matcap/pearl.exr | Bin 0 -> 70218 bytes release/datafiles/studiolights/matcap/resin.exr | Bin 0 -> 91009 bytes release/datafiles/studiolights/matcap/skin.exr | Bin 0 -> 55351 bytes release/datafiles/studiolights/matcap/toon.exr | Bin 0 -> 55733 bytes 47 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 release/datafiles/studiolights/matcap/basic_1.exr create mode 100644 release/datafiles/studiolights/matcap/basic_2.exr create mode 100644 release/datafiles/studiolights/matcap/basic_dark.exr create mode 100644 release/datafiles/studiolights/matcap/basic_side.exr create mode 100644 release/datafiles/studiolights/matcap/ceramic_dark.exr create mode 100644 release/datafiles/studiolights/matcap/ceramic_lightbulb.exr create mode 100644 release/datafiles/studiolights/matcap/check_normal+y.exr create mode 100644 release/datafiles/studiolights/matcap/check_reflection.exr create mode 100644 release/datafiles/studiolights/matcap/check_rim_dark.exr create mode 100644 release/datafiles/studiolights/matcap/check_rim_light.exr create mode 100644 release/datafiles/studiolights/matcap/clay_brown.exr create mode 100644 release/datafiles/studiolights/matcap/clay_muddy.exr create mode 100644 release/datafiles/studiolights/matcap/clay_studio.exr create mode 100644 release/datafiles/studiolights/matcap/jade.exr delete mode 100644 release/datafiles/studiolights/matcap/mc01.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc02.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc03.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc04.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc05.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc06.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc07.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc08.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc09.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc10.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc11.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc12.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc13.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc14.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc15.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc16.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc17.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc18.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc19.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc20.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc21.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc22.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc23.jpg delete mode 100644 release/datafiles/studiolights/matcap/mc24.jpg create mode 100644 release/datafiles/studiolights/matcap/metal_anisotropic.exr create mode 100644 release/datafiles/studiolights/matcap/metal_carpaint.exr create mode 100644 release/datafiles/studiolights/matcap/metal_lead.exr create mode 100644 release/datafiles/studiolights/matcap/metal_shiny.exr create mode 100644 release/datafiles/studiolights/matcap/pearl.exr create mode 100644 release/datafiles/studiolights/matcap/resin.exr create mode 100644 release/datafiles/studiolights/matcap/skin.exr create mode 100644 release/datafiles/studiolights/matcap/toon.exr diff --git a/release/datafiles/studiolights/matcap/basic_1.exr b/release/datafiles/studiolights/matcap/basic_1.exr new file mode 100644 index 00000000000..bb2e09abbd2 Binary files /dev/null and b/release/datafiles/studiolights/matcap/basic_1.exr differ diff --git a/release/datafiles/studiolights/matcap/basic_2.exr b/release/datafiles/studiolights/matcap/basic_2.exr new file mode 100644 index 00000000000..d97f7630d63 Binary files /dev/null and b/release/datafiles/studiolights/matcap/basic_2.exr differ diff --git a/release/datafiles/studiolights/matcap/basic_dark.exr b/release/datafiles/studiolights/matcap/basic_dark.exr new file mode 100644 index 00000000000..b623c8030f8 Binary files /dev/null and b/release/datafiles/studiolights/matcap/basic_dark.exr differ diff --git a/release/datafiles/studiolights/matcap/basic_side.exr b/release/datafiles/studiolights/matcap/basic_side.exr new file mode 100644 index 00000000000..6e4452e7511 Binary files /dev/null and b/release/datafiles/studiolights/matcap/basic_side.exr differ diff --git a/release/datafiles/studiolights/matcap/ceramic_dark.exr b/release/datafiles/studiolights/matcap/ceramic_dark.exr new file mode 100644 index 00000000000..837b020c96d Binary files /dev/null and b/release/datafiles/studiolights/matcap/ceramic_dark.exr differ diff --git a/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr new file mode 100644 index 00000000000..e05b6612e46 Binary files /dev/null and b/release/datafiles/studiolights/matcap/ceramic_lightbulb.exr differ diff --git a/release/datafiles/studiolights/matcap/check_normal+y.exr b/release/datafiles/studiolights/matcap/check_normal+y.exr new file mode 100644 index 00000000000..4e2a97ac3b9 Binary files /dev/null and b/release/datafiles/studiolights/matcap/check_normal+y.exr differ diff --git a/release/datafiles/studiolights/matcap/check_reflection.exr b/release/datafiles/studiolights/matcap/check_reflection.exr new file mode 100644 index 00000000000..245d6059241 Binary files /dev/null and b/release/datafiles/studiolights/matcap/check_reflection.exr differ diff --git a/release/datafiles/studiolights/matcap/check_rim_dark.exr b/release/datafiles/studiolights/matcap/check_rim_dark.exr new file mode 100644 index 00000000000..e6a32004ea1 Binary files /dev/null and b/release/datafiles/studiolights/matcap/check_rim_dark.exr differ diff --git a/release/datafiles/studiolights/matcap/check_rim_light.exr b/release/datafiles/studiolights/matcap/check_rim_light.exr new file mode 100644 index 00000000000..6318c0f9346 Binary files /dev/null and b/release/datafiles/studiolights/matcap/check_rim_light.exr differ diff --git a/release/datafiles/studiolights/matcap/clay_brown.exr b/release/datafiles/studiolights/matcap/clay_brown.exr new file mode 100644 index 00000000000..fe1e0305383 Binary files /dev/null and b/release/datafiles/studiolights/matcap/clay_brown.exr differ diff --git a/release/datafiles/studiolights/matcap/clay_muddy.exr b/release/datafiles/studiolights/matcap/clay_muddy.exr new file mode 100644 index 00000000000..d219578c62b Binary files /dev/null and b/release/datafiles/studiolights/matcap/clay_muddy.exr differ diff --git a/release/datafiles/studiolights/matcap/clay_studio.exr b/release/datafiles/studiolights/matcap/clay_studio.exr new file mode 100644 index 00000000000..7746e6d0e35 Binary files /dev/null and b/release/datafiles/studiolights/matcap/clay_studio.exr differ diff --git a/release/datafiles/studiolights/matcap/jade.exr b/release/datafiles/studiolights/matcap/jade.exr new file mode 100644 index 00000000000..fe1211f1b65 Binary files /dev/null and b/release/datafiles/studiolights/matcap/jade.exr differ diff --git a/release/datafiles/studiolights/matcap/license.txt b/release/datafiles/studiolights/matcap/license.txt index 358c8dcd832..09a0f7a439e 100644 --- a/release/datafiles/studiolights/matcap/license.txt +++ b/release/datafiles/studiolights/matcap/license.txt @@ -1,3 +1,3 @@ -These matcap images are licensed as GNU GPL 2 or later, like the rest of Blender's code. +These matcap images are licensed as CC0 or public domain. -Thanks to Kent Trammell, Aidy Burrows, John Herreno , Terry Wallwork and David Silverman for making the pictures. +Thanks to the Blender community for contributing these matcaps. diff --git a/release/datafiles/studiolights/matcap/mc01.jpg b/release/datafiles/studiolights/matcap/mc01.jpg deleted file mode 100644 index 8c7aef287ee..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc01.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc02.jpg b/release/datafiles/studiolights/matcap/mc02.jpg deleted file mode 100644 index 11deddfeaed..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc02.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc03.jpg b/release/datafiles/studiolights/matcap/mc03.jpg deleted file mode 100644 index 64d992fb61a..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc03.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc04.jpg b/release/datafiles/studiolights/matcap/mc04.jpg deleted file mode 100644 index 42be580ee93..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc04.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc05.jpg b/release/datafiles/studiolights/matcap/mc05.jpg deleted file mode 100644 index 586d233ef31..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc05.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc06.jpg b/release/datafiles/studiolights/matcap/mc06.jpg deleted file mode 100644 index 657883d0866..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc06.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc07.jpg b/release/datafiles/studiolights/matcap/mc07.jpg deleted file mode 100644 index 372caf7e87c..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc07.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc08.jpg b/release/datafiles/studiolights/matcap/mc08.jpg deleted file mode 100644 index 50eec402812..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc08.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc09.jpg b/release/datafiles/studiolights/matcap/mc09.jpg deleted file mode 100644 index e05d441aaf9..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc09.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc10.jpg b/release/datafiles/studiolights/matcap/mc10.jpg deleted file mode 100644 index ab82f17bb93..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc10.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc11.jpg b/release/datafiles/studiolights/matcap/mc11.jpg deleted file mode 100644 index 053550f082c..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc11.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc12.jpg b/release/datafiles/studiolights/matcap/mc12.jpg deleted file mode 100644 index beb16f3742e..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc12.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc13.jpg b/release/datafiles/studiolights/matcap/mc13.jpg deleted file mode 100644 index 7fb8fa58e8f..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc13.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc14.jpg b/release/datafiles/studiolights/matcap/mc14.jpg deleted file mode 100644 index ba868d2f95a..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc14.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc15.jpg b/release/datafiles/studiolights/matcap/mc15.jpg deleted file mode 100644 index b10ea326a42..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc15.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc16.jpg b/release/datafiles/studiolights/matcap/mc16.jpg deleted file mode 100644 index c6ce02d59df..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc16.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc17.jpg b/release/datafiles/studiolights/matcap/mc17.jpg deleted file mode 100644 index 14f15f70460..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc17.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc18.jpg b/release/datafiles/studiolights/matcap/mc18.jpg deleted file mode 100644 index db572856b07..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc18.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc19.jpg b/release/datafiles/studiolights/matcap/mc19.jpg deleted file mode 100644 index 56d2efb1734..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc19.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc20.jpg b/release/datafiles/studiolights/matcap/mc20.jpg deleted file mode 100644 index 002a0910dd9..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc20.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc21.jpg b/release/datafiles/studiolights/matcap/mc21.jpg deleted file mode 100644 index cb2fea573b8..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc21.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc22.jpg b/release/datafiles/studiolights/matcap/mc22.jpg deleted file mode 100644 index 2fc71b98c5a..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc22.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc23.jpg b/release/datafiles/studiolights/matcap/mc23.jpg deleted file mode 100644 index 3793c0fcaa5..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc23.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/mc24.jpg b/release/datafiles/studiolights/matcap/mc24.jpg deleted file mode 100644 index 2a9618d8fe1..00000000000 Binary files a/release/datafiles/studiolights/matcap/mc24.jpg and /dev/null differ diff --git a/release/datafiles/studiolights/matcap/metal_anisotropic.exr b/release/datafiles/studiolights/matcap/metal_anisotropic.exr new file mode 100644 index 00000000000..38ea94ac676 Binary files /dev/null and b/release/datafiles/studiolights/matcap/metal_anisotropic.exr differ diff --git a/release/datafiles/studiolights/matcap/metal_carpaint.exr b/release/datafiles/studiolights/matcap/metal_carpaint.exr new file mode 100644 index 00000000000..c5bcdf67abf Binary files /dev/null and b/release/datafiles/studiolights/matcap/metal_carpaint.exr differ diff --git a/release/datafiles/studiolights/matcap/metal_lead.exr b/release/datafiles/studiolights/matcap/metal_lead.exr new file mode 100644 index 00000000000..4d6b2954ccd Binary files /dev/null and b/release/datafiles/studiolights/matcap/metal_lead.exr differ diff --git a/release/datafiles/studiolights/matcap/metal_shiny.exr b/release/datafiles/studiolights/matcap/metal_shiny.exr new file mode 100644 index 00000000000..3b5d20ffda2 Binary files /dev/null and b/release/datafiles/studiolights/matcap/metal_shiny.exr differ diff --git a/release/datafiles/studiolights/matcap/pearl.exr b/release/datafiles/studiolights/matcap/pearl.exr new file mode 100644 index 00000000000..e657c67936e Binary files /dev/null and b/release/datafiles/studiolights/matcap/pearl.exr differ diff --git a/release/datafiles/studiolights/matcap/resin.exr b/release/datafiles/studiolights/matcap/resin.exr new file mode 100644 index 00000000000..80e405aaa67 Binary files /dev/null and b/release/datafiles/studiolights/matcap/resin.exr differ diff --git a/release/datafiles/studiolights/matcap/skin.exr b/release/datafiles/studiolights/matcap/skin.exr new file mode 100644 index 00000000000..ffc3213dad9 Binary files /dev/null and b/release/datafiles/studiolights/matcap/skin.exr differ diff --git a/release/datafiles/studiolights/matcap/toon.exr b/release/datafiles/studiolights/matcap/toon.exr new file mode 100644 index 00000000000..242f5055e2b Binary files /dev/null and b/release/datafiles/studiolights/matcap/toon.exr differ -- cgit v1.2.3 From d65df10216b8de09b8a1cfc695030649511337a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 12:23:23 +0200 Subject: DRW: Add DRW_shgroup_is_empty and DRW_pass_is_empty --- source/blender/draw/intern/DRW_render.h | 4 ++++ source/blender/draw/intern/draw_manager_data.c | 27 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index adcfe2524c7..cd2db3cfd0a 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -402,6 +402,8 @@ void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, co void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value); void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value); +bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup); + /* Passes */ DRWPass *DRW_pass_create(const char *name, DRWState state); void DRW_pass_state_set(DRWPass *pass, DRWState state); @@ -410,6 +412,8 @@ void DRW_pass_state_remove(DRWPass *pass, DRWState state); void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgrp), void *userData); void DRW_pass_sort_shgroup_z(DRWPass *pass); +bool DRW_pass_is_empty(DRWPass *pass); + /* Viewport */ typedef enum { /* keep in sync with the union struct DRWMatrixState. */ diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index dccb869c133..407eea16d91 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -998,6 +998,23 @@ void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask) shgroup->stencil_mask = mask; } +bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup) +{ + switch (shgroup->type) { + case DRW_SHG_NORMAL: + case DRW_SHG_FEEDBACK_TRANSFORM: + return shgroup->calls.first == NULL; + case DRW_SHG_POINT_BATCH: + case DRW_SHG_LINE_BATCH: + case DRW_SHG_TRIANGLE_BATCH: + case DRW_SHG_INSTANCE: + case DRW_SHG_INSTANCE_EXTERNAL: + return shgroup->instance_count == 0; + } + BLI_assert(!"Shading Group type not supported"); + return true; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1019,6 +1036,16 @@ DRWPass *DRW_pass_create(const char *name, DRWState state) return pass; } +bool DRW_pass_is_empty(DRWPass *pass) +{ + for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) { + if (!DRW_shgroup_is_empty(shgroup)) { + return false; + } + } + return true; +} + void DRW_pass_state_set(DRWPass *pass, DRWState state) { pass->state = state; -- cgit v1.2.3 From 0f97718c10e8c2a441f58a51eb923b1dfa3698d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 13:56:22 +0200 Subject: DRW: Add option to only resolve framebuffer colors without depth test --- source/blender/draw/intern/DRW_render.h | 13 +++++- source/blender/draw/intern/draw_manager.c | 49 ++++++++++++++------ source/blender/gpu/GPU_shader.h | 4 ++ source/blender/gpu/intern/gpu_shader.c | 20 ++++++++ .../gpu_shader_image_multisample_resolve_frag.glsl | 53 ++++++++++++---------- 5 files changed, 98 insertions(+), 41 deletions(-) diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index cd2db3cfd0a..d2c44cfef2a 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -120,7 +120,16 @@ typedef char DRWViewportEmptyList; if (dfbl->multisample_fb != NULL) { \ DRW_stats_query_start("Multisample Resolve"); \ GPU_framebuffer_bind(dfbl->default_fb); \ - DRW_multisamples_resolve(dtxl->multisample_depth, dtxl->multisample_color); \ + DRW_multisamples_resolve(dtxl->multisample_depth, dtxl->multisample_color, true); \ + DRW_stats_query_end(); \ + } \ +} + +#define MULTISAMPLE_SYNC_DISABLE_NO_DEPTH(dfbl, dtxl) { \ + if (dfbl->multisample_fb != NULL) { \ + DRW_stats_query_start("Multisample Resolve"); \ + GPU_framebuffer_bind(dfbl->default_fb); \ + DRW_multisamples_resolve(dtxl->multisample_depth, dtxl->multisample_color, false); \ DRW_stats_query_end(); \ } \ } @@ -228,7 +237,7 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); void DRW_transform_to_display(struct GPUTexture *tex); void DRW_transform_none(struct GPUTexture *tex); void DRW_multisamples_resolve( - struct GPUTexture *src_depth, struct GPUTexture *src_color); + struct GPUTexture *src_depth, struct GPUTexture *src_color, bool use_depth); /* Shaders */ struct GPUShader *DRW_shader_create( diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 0a15fb3a114..87239e7d93e 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -317,10 +317,14 @@ void DRW_transform_none(GPUTexture *tex) /* Use manual multisample resolve pass. * Much quicker than blitting back and forth. * Assume destination fb is bound*/ -void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color) +void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth) { - drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL | - DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL; + + if (use_depth) { + state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; + } + drw_state_set(state); int samples = GPU_texture_samples(src_depth); @@ -330,22 +334,39 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color) GPUBatch *geom = DRW_cache_fullscreen_quad_get(); int builtin; - switch (samples) { - case 2: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; break; - case 4: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4; break; - case 8: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8; break; - case 16: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16; break; - default: - BLI_assert(0); - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; - break; + if (use_depth) { + switch (samples) { + case 2: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST; break; + case 4: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST; break; + case 8: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST; break; + case 16: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST; break; + default: + BLI_assert("Mulisample count unsupported by blit shader."); + builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST; + break; + } + } + else { + switch (samples) { + case 2: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; break; + case 4: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4; break; + case 8: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8; break; + case 16: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16; break; + default: + BLI_assert("Mulisample count unsupported by blit shader."); + builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; + break; + } } GPU_batch_program_set_builtin(geom, builtin); - GPU_texture_bind(src_depth, 0); + if (use_depth) { + GPU_texture_bind(src_depth, 0); + GPU_batch_uniform_1i(geom, "depthMulti", 0); + } + GPU_texture_bind(src_color, 1); - GPU_batch_uniform_1i(geom, "depthMulti", 0); GPU_batch_uniform_1i(geom, "colorMulti", 1); float mat[4][4]; diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index b1a05faf863..7f334cec21f 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -158,6 +158,10 @@ typedef enum GPUBuiltinShader { GPU_SHADER_2D_IMAGE_MULTISAMPLE_4, GPU_SHADER_2D_IMAGE_MULTISAMPLE_8, GPU_SHADER_2D_IMAGE_MULTISAMPLE_16, + GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST, + GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST, + GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST, + GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST, GPU_SHADER_2D_CHECKER, GPU_SHADER_2D_DIAG_STRIPES, /* for simple 3D drawing */ diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 04b43d03c83..3543c73f71d 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -738,6 +738,10 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, + [GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, + [GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, + [GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, + [GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_image_multisample_resolve_frag_glsl }, [GPU_SHADER_2D_IMAGE_INTERLACE] = { datatoc_gpu_shader_2D_image_vert_glsl, datatoc_gpu_shader_image_interlace_frag_glsl }, @@ -873,15 +877,31 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) case GPU_SHADER_2D_IMAGE_MULTISAMPLE_2: defines = "#define SAMPLES 2\n"; break; + case GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST: + defines = "#define SAMPLES 2\n" + "#define USE_DEPTH\n"; + break; case GPU_SHADER_2D_IMAGE_MULTISAMPLE_4: defines = "#define SAMPLES 4\n"; break; + case GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST: + defines = "#define SAMPLES 4\n" + "#define USE_DEPTH\n"; + break; case GPU_SHADER_2D_IMAGE_MULTISAMPLE_8: defines = "#define SAMPLES 8\n"; break; + case GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST: + defines = "#define SAMPLES 8\n" + "#define USE_DEPTH\n"; + break; case GPU_SHADER_2D_IMAGE_MULTISAMPLE_16: defines = "#define SAMPLES 16\n"; break; + case GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST: + defines = "#define SAMPLES 16\n" + "#define USE_DEPTH\n"; + break; case GPU_SHADER_2D_WIDGET_BASE_INST: case GPU_SHADER_2D_NODELINK_INST: defines = "#define USE_INSTANCE\n"; diff --git a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl index 57362c88320..1f59c9dfdbd 100644 --- a/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_image_multisample_resolve_frag.glsl @@ -8,8 +8,6 @@ out vec4 fragColor; #error "Too many samples" #endif -// #define USE_DEPTH_WEIGHTING - void main() { ivec2 texel = ivec2(gl_FragCoord.xy); @@ -19,26 +17,26 @@ void main() vec4 d1, d2, d3, d4; vec4 c1, c2, c3, c4, c5, c6, c7, c8; vec4 c9, c10, c11, c12, c13, c14, c15, c16; - d1 = d2 = d3 = d4 = vec4(1.0); + d1 = d2 = d3 = d4 = vec4(0.5); w1 = w2 = w3 = w4 = vec4(0.0); c1 = c2 = c3 = c4 = c5 = c6 = c7 = c8 = vec4(0.0); c9 = c10 = c11 = c12 = c13 = c14 = c15 = c16 = vec4(0.0); +#ifdef USE_DEPTH /* Depth */ - d1.x = texelFetch(depthMulti, texel, 0).r; d1.y = texelFetch(depthMulti, texel, 1).r; -#if SAMPLES > 2 +# if SAMPLES > 2 d1.z = texelFetch(depthMulti, texel, 2).r; d1.w = texelFetch(depthMulti, texel, 3).r; -#endif -#if SAMPLES > 4 +# endif +# if SAMPLES > 4 d2.x = texelFetch(depthMulti, texel, 4).r; d2.y = texelFetch(depthMulti, texel, 5).r; d2.z = texelFetch(depthMulti, texel, 6).r; d2.w = texelFetch(depthMulti, texel, 7).r; -#endif -#if SAMPLES > 8 +# endif +# if SAMPLES > 8 d3.x = texelFetch(depthMulti, texel, 8).r; d3.y = texelFetch(depthMulti, texel, 9).r; d3.z = texelFetch(depthMulti, texel, 10).r; @@ -47,6 +45,7 @@ void main() d4.y = texelFetch(depthMulti, texel, 13).r; d4.z = texelFetch(depthMulti, texel, 14).r; d4.w = texelFetch(depthMulti, texel, 15).r; +# endif #endif /* COLOR */ @@ -89,22 +88,26 @@ void main() } #endif -#if SAMPLES > 8 - d1 = min(d1, min(d3, d4)); -#endif -#if SAMPLES > 4 - d1 = min(d1, d2); -#endif -#if SAMPLES > 2 - d1.xy = min(d1.xy, d1.zw); -#endif - gl_FragDepth = min(d1.x, d1.y); - -#ifdef USE_DEPTH_WEIGHTING - c1 *= w1.x; c2 *= w1.y; c3 *= w1.z; c4 *= w1.w; - c5 *= w2.x; c6 *= w2.y; c7 *= w2.z; c8 *= w2.w; - c9 *= w3.x; c10 *= w3.y; c11 *= w3.z; c12 *= w3.w; - c13 *= w4.x; c14 *= w4.y; c15 *= w4.z; c16 *= w4.w; +#ifdef USE_DEPTH + d1 *= 1.0 - step(1.0, d1); /* make far plane depth = 0 */ +# if SAMPLES > 8 + d4 *= 1.0 - step(1.0, d4); + d3 *= 1.0 - step(1.0, d3); + d1 = max(d1, max(d3, d4)); +# endif +# if SAMPLES > 4 + d2 *= 1.0 - step(1.0, d2); + d1 = max(d1, d2); + d1 = max(d1, d2); +# endif +# if SAMPLES > 2 + d1.xy = max(d1.xy, d1.zw); +# endif + gl_FragDepth = max(d1.x, d1.y); + /* Don't let the 0.0 farplane occlude other things */ + if (gl_FragDepth == 0.0) { + gl_FragDepth = 1.0; + } #endif c1 = c1 + c2; -- cgit v1.2.3 From 5a05683da1a9fd43cd611fe62f675ddafc8ba3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 14:15:40 +0200 Subject: Motion Path: Fix motion path when MSAA is enabled --- source/blender/draw/intern/draw_anim_viz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c index 95894783cfe..6bf7bf9ca08 100644 --- a/source/blender/draw/intern/draw_anim_viz.c +++ b/source/blender/draw/intern/draw_anim_viz.c @@ -327,7 +327,7 @@ static void MPATH_draw_scene(void *vedata) DRW_draw_pass(psl->lines); DRW_draw_pass(psl->points); - MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl) + MULTISAMPLE_SYNC_DISABLE_NO_DEPTH(dfbl, dtxl) } /* *************************** Draw Engine Defines ****************************** */ -- cgit v1.2.3 From 6c6ecdd2306b9680ac171b9b80d4a9911fdb8a19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 14:17:53 +0200 Subject: Armature: Fix bone always transparent when enabling MSAA --- source/blender/draw/intern/draw_armature.c | 29 +++++++++++++--------- source/blender/draw/intern/draw_common.c | 10 +++++--- source/blender/draw/intern/draw_common.h | 10 ++++---- source/blender/draw/modes/edit_armature_mode.c | 25 +++++++++++-------- source/blender/draw/modes/pose_mode.c | 12 +++++---- .../shaders/armature_envelope_solid_frag.glsl | 4 ++- .../modes/shaders/armature_shape_solid_frag.glsl | 4 ++- .../modes/shaders/armature_sphere_solid_frag.glsl | 4 +-- 8 files changed, 58 insertions(+), 40 deletions(-) diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index f0a32dfc8e0..8cd7431cfc0 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -95,6 +95,8 @@ static struct { DRWShadingGroup *lines_ik_spline; DRWArmaturePasses passes; + + bool transparent; } g_data = {NULL}; @@ -139,7 +141,8 @@ static void drw_shgroup_bone_octahedral( } if (g_data.bone_octahedral_solid == NULL) { struct GPUBatch *geom = DRW_cache_bone_octahedral_get(); - g_data.bone_octahedral_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom); + g_data.bone_octahedral_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom, + g_data.transparent); } float final_bonemat[4][4]; mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); @@ -160,7 +163,7 @@ static void drw_shgroup_bone_box( } if (g_data.bone_box_solid == NULL) { struct GPUBatch *geom = DRW_cache_bone_box_get(); - g_data.bone_box_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom); + g_data.bone_box_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom, g_data.transparent); } float final_bonemat[4][4]; mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); @@ -234,13 +237,13 @@ static void drw_shgroup_bone_envelope( g_data.bone_point_wire = shgroup_instance_bone_sphere_outline(g_data.passes.bone_wire); } if (g_data.bone_point_solid == NULL) { - g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(g_data.passes.bone_solid); + g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(g_data.passes.bone_solid, g_data.transparent); } if (g_data.bone_envelope_wire == NULL) { g_data.bone_envelope_wire = shgroup_instance_bone_envelope_outline(g_data.passes.bone_wire); } if (g_data.bone_envelope_solid == NULL) { - g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.passes.bone_solid); + g_data.bone_envelope_solid = shgroup_instance_bone_envelope_solid(g_data.passes.bone_solid, g_data.transparent); /* We can have a lot of overdraw if we don't do this. Also envelope are not subject to * inverted matrix. */ DRW_shgroup_state_enable(g_data.bone_envelope_solid, DRW_STATE_CULL_BACK); @@ -329,7 +332,8 @@ static void drw_shgroup_bone_custom_solid( } if (surf) { - DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, surf); + DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, surf, + g_data.transparent); DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color); } @@ -372,7 +376,7 @@ static void drw_shgroup_bone_point( g_data.bone_point_wire = shgroup_instance_bone_sphere_outline(g_data.passes.bone_wire); } if (g_data.bone_point_solid == NULL) { - g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(g_data.passes.bone_solid); + g_data.bone_point_solid = shgroup_instance_bone_sphere_solid(g_data.passes.bone_solid, g_data.transparent); } float final_bonemat[4][4]; mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); @@ -1732,11 +1736,12 @@ static void draw_armature_pose(Object *ob, const float const_color[4]) /** * This function set the object space to use for all subsequent `DRW_shgroup_bone_*` calls. */ -static void drw_shgroup_armature(Object *ob, DRWArmaturePasses passes) +static void drw_shgroup_armature(Object *ob, DRWArmaturePasses passes, bool transp) { memset(&g_data, 0x0, sizeof(g_data)); g_data.ob = ob; g_data.passes = passes; + g_data.transparent = transp; memset(&g_color, 0x0, sizeof(g_color)); } @@ -1745,19 +1750,19 @@ void DRW_shgroup_armature_object(Object *ob, ViewLayer *view_layer, DRWArmatureP float *color; DRW_object_wire_theme_get(ob, view_layer, &color); passes.bone_envelope = NULL; /* Don't do envelope distance in object mode. */ - drw_shgroup_armature(ob, passes); + drw_shgroup_armature(ob, passes, false); draw_armature_pose(ob, color); } -void DRW_shgroup_armature_pose(Object *ob, DRWArmaturePasses passes) +void DRW_shgroup_armature_pose(Object *ob, DRWArmaturePasses passes, bool transp) { - drw_shgroup_armature(ob, passes); + drw_shgroup_armature(ob, passes, transp); draw_armature_pose(ob, NULL); } -void DRW_shgroup_armature_edit(Object *ob, DRWArmaturePasses passes) +void DRW_shgroup_armature_edit(Object *ob, DRWArmaturePasses passes, bool transp) { - drw_shgroup_armature(ob, passes); + drw_shgroup_armature(ob, passes, transp); draw_armature_edit(ob); } diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index c9fc5eba079..77d6e888771 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -552,7 +552,7 @@ DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass) return grp; } -DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass) +DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, bool transp) { if (g_shaders.bone_envelope == NULL) { g_shaders.bone_envelope = DRW_shader_create( @@ -572,6 +572,7 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass) g_shaders.bone_envelope, pass, DRW_cache_bone_envelope_solid_get(), g_formats.instance_bone_envelope); + DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f); return grp; } @@ -623,7 +624,7 @@ DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct GPUBa return grp; } -DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatch *geom) +DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatch *geom, bool transp) { if (g_shaders.shape_solid == NULL) { g_shaders.shape_solid = DRW_shader_create( @@ -641,11 +642,12 @@ DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatc g_shaders.shape_solid, pass, geom, g_formats.instance_bone); DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1); + DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f); return grp; } -DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass) +DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass, bool transp) { if (g_shaders.bone_sphere == NULL) { g_shaders.bone_sphere = DRW_shader_create( @@ -662,6 +664,8 @@ DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass) DRWShadingGroup *grp = DRW_shgroup_instance_create( g_shaders.bone_sphere, pass, DRW_cache_bone_point_get(), g_formats.instance_bone); + /* More transparent than the shape to be less distractive. */ + DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.4f : 1.0f); return grp; } diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 80b2ec8db71..0ad1402f29e 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -128,11 +128,11 @@ struct DRWShadingGroup *shgroup_instance_mball_handles(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_axes(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_distance(struct DRWPass *pass); struct DRWShadingGroup *shgroup_instance_bone_envelope_outline(struct DRWPass *pass); -struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass); +struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, bool transp); struct DRWShadingGroup *shgroup_instance_bone_shape_outline(struct DRWPass *pass, struct GPUBatch *geom); -struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_bone_shape_solid(struct DRWPass *pass, struct GPUBatch *geom, bool transp); struct DRWShadingGroup *shgroup_instance_bone_sphere_outline(struct DRWPass *pass); -struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass); +struct DRWShadingGroup *shgroup_instance_bone_sphere_solid(struct DRWPass *pass, bool transp); struct DRWShadingGroup *shgroup_instance_bone_stick(struct DRWPass *pass); struct GPUShader *mpath_line_shader_get(void); @@ -155,8 +155,8 @@ typedef struct DRWArmaturePasses { } DRWArmaturePasses; void DRW_shgroup_armature_object(struct Object *ob, struct ViewLayer *view_layer, struct DRWArmaturePasses passes); -void DRW_shgroup_armature_pose(struct Object *ob, struct DRWArmaturePasses passes); -void DRW_shgroup_armature_edit(struct Object *ob, struct DRWArmaturePasses passes); +void DRW_shgroup_armature_pose(struct Object *ob, struct DRWArmaturePasses passes, bool transp); +void DRW_shgroup_armature_edit(struct Object *ob, struct DRWArmaturePasses passes, bool transp); /* draw_hair.c */ diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 285e703afbf..1e8293b5dbb 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -60,7 +60,7 @@ typedef struct EDIT_ARMATURE_Data { /* *********** STATIC *********** */ typedef struct EDIT_ARMATURE_PrivateData { - char pad; /* UNUSED */ + bool transparent_bones; } EDIT_ARMATURE_PrivateData; /* Transient data */ /* *********** FUNCTIONS *********** */ @@ -69,15 +69,18 @@ static void EDIT_ARMATURE_cache_init(void *vedata) { EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); if (!stl->g_data) { /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } + stl->g_data->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; { /* Solid bones */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; + state |= (stl->g_data->transparent_bones) ? DRW_STATE_BLEND : DRW_STATE_WRITE_DEPTH; psl->bone_solid = DRW_pass_create("Bone Solid Pass", state); } @@ -116,10 +119,12 @@ static void EDIT_ARMATURE_cache_init(void *vedata) static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) { bArmature *arm = ob->data; - EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; if (ob->type == OB_ARMATURE) { if (arm->edbo) { + EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; + EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; + DRWArmaturePasses passes = { .bone_solid = psl->bone_solid, .bone_outline = psl->bone_outline, @@ -128,7 +133,7 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship, }; - DRW_shgroup_armature_edit(ob, passes); + DRW_shgroup_armature_edit(ob, passes, stl->g_data->transparent_bones); } } } @@ -136,22 +141,20 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) static void EDIT_ARMATURE_draw_scene(void *vedata) { EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; + EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const bool transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; DRW_draw_pass(psl->bone_envelope); - if (transparent_bones) { - DRW_pass_state_add(psl->bone_solid, DRW_STATE_BLEND); - DRW_pass_state_remove(psl->bone_solid, DRW_STATE_WRITE_DEPTH); + if (stl->g_data->transparent_bones) { + /* For performance reason, avoid blending on MS target. */ DRW_draw_pass(psl->bone_solid); } MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl) - if (!transparent_bones) { + if (!stl->g_data->transparent_bones) { DRW_draw_pass(psl->bone_solid); } diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 040195b889b..7a4abcac179 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -75,6 +75,7 @@ typedef struct POSE_PrivateData { DRWShadingGroup *bone_selection_invert_shgrp; float blend_color[4]; float blend_color_invert[4]; + bool transparent_bones; } POSE_PrivateData; /* Transient data */ static struct { @@ -112,9 +113,10 @@ static void POSE_cache_init(void *vedata) if (!stl->g_data) { /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } POSE_PrivateData *ppd = stl->g_data; + ppd->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; { /* Solid bones */ @@ -195,7 +197,7 @@ static bool POSE_is_driven_by_active_armature(Object *ob) static void POSE_cache_populate(void *vedata, Object *ob) { POSE_PassList *psl = ((POSE_Data *)vedata)->psl; - POSE_StorageList *stl = ((POSE_Data *)vedata)->stl; + POSE_PrivateData *ppd = ((POSE_Data *)vedata)->stl->g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); /* In the future this will allow us to implement face gizmos, @@ -214,7 +216,7 @@ static void POSE_cache_populate(void *vedata, Object *ob) .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship, }; - DRW_shgroup_armature_pose(ob, passes); + DRW_shgroup_armature_pose(ob, passes, ppd->transparent_bones); } } else if (ob->type == OB_MESH && @@ -224,10 +226,10 @@ static void POSE_cache_populate(void *vedata, Object *ob) struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { if (POSE_is_driven_by_active_armature(ob)) { - DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob); + DRW_shgroup_call_object_add(ppd->bone_selection_shgrp, geom, ob); } else { - DRW_shgroup_call_object_add(stl->g_data->bone_selection_invert_shgrp, geom, ob); + DRW_shgroup_call_object_add(ppd->bone_selection_invert_shgrp, geom, ob); } } } diff --git a/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl index b20656ff326..78b29296601 100644 --- a/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl @@ -1,4 +1,6 @@ +uniform float alpha = 0.6; + flat in vec3 finalStateColor; flat in vec3 finalBoneColor; in vec3 normalView; @@ -12,5 +14,5 @@ void main() float n = normalize(normalView).z; float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0); fragColor.rgb = mix(finalStateColor, finalBoneColor, fac); - fragColor.a = 0.6; /* Hardcoded transparency factor. */ + fragColor.a = alpha; } diff --git a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl index 89f4d97f29b..45748bf5644 100644 --- a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl @@ -1,9 +1,11 @@ +uniform float alpha = 0.6; + in vec4 finalColor; out vec4 fragColor; void main() { - fragColor = vec4(finalColor.rgb, 0.6); /* Hardcoded transparency factor. */ + fragColor = vec4(finalColor.rgb, alpha); } diff --git a/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl index 3c80f629d79..a0fdd55931f 100644 --- a/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl @@ -3,6 +3,7 @@ uniform mat4 ViewMatrixInverse; uniform mat4 ProjectionMatrix; +uniform float alpha = 0.4; flat in vec3 finalStateColor; flat in vec3 finalBoneColor; @@ -73,8 +74,7 @@ void main() float dither = (0.5 + dot(vec2(ivec2(gl_FragCoord.xy) & ivec2(1)), vec2(1.0, 2.0))) * 0.25; dither *= (1.0 / 255.0); /* Assume 8bit per color buffer. */ - /* Hardcoded transparency factor. Less than shape to be less distractive. */ - fragColor = vec4(fragColor.rgb + dither, 0.4); + fragColor = vec4(fragColor.rgb + dither, alpha); t /= ray_len; gl_FragDepth = get_depth_from_view_z(ray_dir_view.z * t + ray_ori_view.z); -- cgit v1.2.3 From bfaf41663abd929b3756f81f7cbbcb57419d21fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 14:18:38 +0200 Subject: Motion Path: Don't blit MSAA buffer if there is no motion paths --- source/blender/draw/intern/draw_anim_viz.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c index 6bf7bf9ca08..f976c7b4d05 100644 --- a/source/blender/draw/intern/draw_anim_viz.c +++ b/source/blender/draw/intern/draw_anim_viz.c @@ -322,6 +322,13 @@ static void MPATH_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + if (DRW_pass_is_empty(psl->lines) && + DRW_pass_is_empty(psl->points)) + { + /* Nothing to draw. */ + return; + } + MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl) DRW_draw_pass(psl->lines); -- cgit v1.2.3 From 4473427d8175d68a97e8b803266b3751175f183f Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Mon, 30 Jul 2018 14:50:44 +0200 Subject: UI: Hide labels from MatCaps They were added as placeholder to show something until they lazy-load. But since the load is fast and it's hard to fit the text, and their name is displayed already in the tooltip, we can do without for now. In the future when we have insta-tooltips we should make them use this. --- release/scripts/startup/bl_ui/space_view3d.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e6d8b1ec2a7..8f77305994a 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3784,7 +3784,7 @@ class VIEW3D_PT_shading_lighting(Panel): sub.scale_y = 0.6 # smaller matcap/hdri preview if shading.light == 'STUDIO': - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) if shading.selected_studio_light.orientation == 'WORLD': col.prop(shading, "studiolight_rotate_z", text="Rotation") @@ -3793,7 +3793,7 @@ class VIEW3D_PT_shading_lighting(Panel): col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') elif shading.light == 'MATCAP': - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) col = split.column() col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') @@ -3810,7 +3810,7 @@ class VIEW3D_PT_shading_lighting(Panel): col = split.column() sub = col.row() sub.scale_y = 0.6 - sub.template_icon_view(shading, "studio_light", show_labels=True, scale=3) + sub.template_icon_view(shading, "studio_light", scale=3) col = split.column() col.operator('wm.studiolight_userpref_show', emboss=False, text="", icon='PREFERENCES') -- cgit v1.2.3 From 27567a6c760be523b77e4d95e544c60b6f9ddf84 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jul 2018 15:00:51 +0200 Subject: Fix T56020: Crash while opening .blend file made with older version. We need a NULL workspace check here, in some cases we get a SRTemp screen even though it's not tagged as temp... --- source/blender/blenloader/intern/versioning_280.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 39ceb527209..5b0a12a0b4c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -112,6 +112,9 @@ static void do_version_workspaces_create_from_screens(Main *bmain) else { workspace = BKE_workspace_add(bmain, screen->id.name + 2); } + if (workspace == NULL) { + continue; /* Not much we can do.. */ + } BKE_workspace_layout_add(bmain, workspace, screen, screen->id.name + 2); } } -- cgit v1.2.3 From b59d85b5a56c020c7b86b0cca4dc38e4950550f9 Mon Sep 17 00:00:00 2001 From: Stefan Werner Date: Mon, 30 Jul 2018 15:42:00 +0200 Subject: Cycles: Fixed OpenCL build. sqr(float4) is available on CUDA and CPU, but not on OpenCL. --- intern/cycles/kernel/kernel_light.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index b5a777efa78..2a300d3419e 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -75,7 +75,7 @@ ccl_device_inline float area_light_sample(float3 P, /* Compute internal angles (gamma_i). */ float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1); float4 nz = make_float4(y0, x1, y1, x0) * diff; - nz = nz / sqrt(sqr(z0 * diff) + sqr(nz)); + nz = nz / sqrt(z0 * z0 * diff * diff + nz * nz); float g0 = safe_acosf(-nz.x * nz.y); float g1 = safe_acosf(-nz.y * nz.z); float g2 = safe_acosf(-nz.z * nz.w); -- cgit v1.2.3 From 6d6deeb70086564418368a5213cd9d28cdfa51e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 30 Jul 2018 16:48:44 +0200 Subject: Workbench: Use FXAA instead of TAA when viewport is animated. Fix T55996 "Playback in "Active Editor Only" doesn't work" --- source/blender/draw/engines/workbench/workbench_effect_aa.c | 11 +++++++++++ source/blender/draw/engines/workbench/workbench_private.h | 7 +++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c index 66f1de7f9fc..6269496f568 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_aa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -23,6 +23,8 @@ * \ingroup draw_engine */ +#include "ED_screen.h" + #include "workbench_private.h" @@ -32,6 +34,15 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_EffectInfo *effect_info = stl->effects; + const DRWContextState *draw_ctx = DRW_context_state_get(); + + if (draw_ctx->evil_C != NULL) { + struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C); + wpd->is_playback = ED_screen_animation_playing(wm) != NULL; + } + else { + wpd->is_playback = false; + } if (TAA_ENABLED(wpd)) { psl->effect_aa_pass = workbench_taa_create_pass(vedata, tx); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 99d1b7060fd..dc2894f0207 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -53,8 +53,10 @@ #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW) #define IS_NAVIGATING(wpd) ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING)) -#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && (IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || ((wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8) && IS_NAVIGATING(wpd)))) -#define TAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd)) +#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && \ + (IN_RANGE(wpd->user_preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || \ + ((IS_NAVIGATING(wpd) || wpd->is_playback) && (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8)))) +#define TAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd) && !wpd->is_playback) #define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd))) #define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE) #define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd)) @@ -174,6 +176,7 @@ typedef struct WORKBENCH_PrivateData { float shadow_near_max[3]; float shadow_near_sides[2][4]; /* This is a parallelogram, so only 2 normal and distance to the edges. */ bool shadow_changed; + bool is_playback; /* Volumes */ bool volumes_do; -- cgit v1.2.3 From a3b6ae9fb9dd76538ec04b9fa6953490d321dd32 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jul 2018 16:54:40 +0200 Subject: Cleanup/Refactor: Move CurveCache runtime data into Object.runtime struct. Also, fix missing cleanup of Object.runtime when copying Object datablocks! --- source/blender/alembic/intern/abc_mball.cc | 2 +- source/blender/alembic/intern/abc_nurbs.cc | 4 +- source/blender/blenkernel/intern/anim.c | 14 +++---- source/blender/blenkernel/intern/armature_update.c | 2 +- source/blender/blenkernel/intern/cdderivedmesh.c | 4 +- source/blender/blenkernel/intern/constraint.c | 8 ++-- source/blender/blenkernel/intern/curve.c | 10 ++--- source/blender/blenkernel/intern/displist.c | 42 +++++++++---------- source/blender/blenkernel/intern/effect.c | 4 +- source/blender/blenkernel/intern/font.c | 6 +-- source/blender/blenkernel/intern/lattice.c | 30 +++++++------- source/blender/blenkernel/intern/material.c | 4 +- source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/mesh_convert.c | 24 +++++------ source/blender/blenkernel/intern/object.c | 48 +++++++++++----------- source/blender/blenloader/intern/readfile.c | 3 -- .../intern/eval/deg_eval_copy_on_write.cc | 8 +--- source/blender/draw/intern/draw_cache.c | 18 ++++---- .../blender/draw/intern/draw_cache_impl_metaball.c | 2 +- source/blender/draw/modes/object_mode.c | 4 +- source/blender/editors/curve/editcurve.c | 4 +- source/blender/editors/object/object_add.c | 6 +-- source/blender/editors/object/object_relations.c | 2 +- source/blender/editors/space_info/info_stats.c | 4 +- .../editors/space_view3d/view3d_iterators.c | 2 +- source/blender/makesdna/DNA_object_types.h | 7 ++-- source/blender/modifiers/intern/MOD_array.c | 5 ++- 27 files changed, 131 insertions(+), 138 deletions(-) diff --git a/source/blender/alembic/intern/abc_mball.cc b/source/blender/alembic/intern/abc_mball.cc index d6e54407922..62ab561274a 100644 --- a/source/blender/alembic/intern/abc_mball.cc +++ b/source/blender/alembic/intern/abc_mball.cc @@ -52,7 +52,7 @@ AbcMBallWriter::AbcMBallWriter( m_is_animated = isAnimated(); m_mesh_ob = BKE_object_copy(bmain, ob); - m_mesh_ob->curve_cache = (CurveCache *)MEM_callocN( + m_mesh_ob->runtime.curve_cache = (CurveCache *)MEM_callocN( sizeof(CurveCache), "CurveCache for AbcMBallWriter"); diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc index 95d06fc5efe..bf41b44e418 100644 --- a/source/blender/alembic/intern/abc_nurbs.cc +++ b/source/blender/alembic/intern/abc_nurbs.cc @@ -130,8 +130,8 @@ void AbcNurbsWriter::do_write() Curve *curve = static_cast(m_object->data); ListBase *nulb; - if (m_object->curve_cache->deformed_nurbs.first != NULL) { - nulb = &m_object->curve_cache->deformed_nurbs; + if (m_object->runtime.curve_cache->deformed_nurbs.first != NULL) { + nulb = &m_object->runtime.curve_cache->deformed_nurbs; } else { nulb = BKE_curve_nurbs_get(curve); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index a867accfe44..7df889d22b2 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -537,18 +537,18 @@ void calc_curvepath(Object *ob, ListBase *nurbs) return; } - if (ob->curve_cache->path) free_path(ob->curve_cache->path); - ob->curve_cache->path = NULL; + if (ob->runtime.curve_cache->path) free_path(ob->runtime.curve_cache->path); + ob->runtime.curve_cache->path = NULL; /* weak! can only use first curve */ - bl = ob->curve_cache->bev.first; + bl = ob->runtime.curve_cache->bev.first; if (bl == NULL || !bl->nr) { return; } nu = nurbs->first; - ob->curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); + ob->runtime.curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath"); /* if POLY: last vertice != first vertice */ cycl = (bl->poly != -1); @@ -665,15 +665,15 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua if (ob == NULL || ob->type != OB_CURVE) return 0; cu = ob->data; - if (ob->curve_cache == NULL || ob->curve_cache->path == NULL || ob->curve_cache->path->data == NULL) { + if (ob->runtime.curve_cache == NULL || ob->runtime.curve_cache->path == NULL || ob->runtime.curve_cache->path->data == NULL) { printf("no path!\n"); return 0; } - path = ob->curve_cache->path; + path = ob->runtime.curve_cache->path; pp = path->data; /* test for cyclic */ - bl = ob->curve_cache->bev.first; + bl = ob->runtime.curve_cache->bev.first; if (!bl) return 0; if (!bl->nr) return 0; if (bl->poly > -1) cycl = 1; diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 628f92c7803..26fbd22c67e 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -201,7 +201,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos /* get the current length of the curve */ /* NOTE: this is assumed to be correct even after the curve was resized */ - splineLen = ikData->tar->curve_cache->path->totdist; + splineLen = ikData->tar->runtime.curve_cache->path->totdist; /* calculate the scale factor to multiply all the path values by so that the * bone chain retains its current length, such that diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 72a1f941c26..3f50321b4d5 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -655,8 +655,8 @@ DerivedMesh *CDDM_from_curve(Object *ob) { ListBase disp = {NULL, NULL}; - if (ob->curve_cache) { - disp = ob->curve_cache->disp; + if (ob->runtime.curve_cache) { + disp = ob->runtime.curve_cache->disp; } return CDDM_from_curve_displist(ob, &disp); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 5aa192d527a..ef412f0006e 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -496,7 +496,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m { Lattice *lt = (Lattice *)ob->data; - DispList *dl = ob->curve_cache ? BKE_displist_find(&ob->curve_cache->disp, DL_VERTS) : NULL; + DispList *dl = ob->runtime.curve_cache ? BKE_displist_find(&ob->runtime.curve_cache->disp, DL_VERTS) : NULL; const float *co = dl ? dl->verts : NULL; BPoint *bp = lt->def; @@ -1266,7 +1266,7 @@ static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph), * currently for paths to work it needs to go through the bevlist/displist system (ton) */ - if (ct->tar->curve_cache && ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) { + if (ct->tar->runtime.curve_cache && ct->tar->runtime.curve_cache->path && ct->tar->runtime.curve_cache->path->data) { float quat[4]; if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ @@ -2037,7 +2037,7 @@ static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), #endif if (VALID_CONS_TARGET(ct)) { - if (ct->tar->type == OB_CURVE && ct->tar->curve_cache == NULL) { + if (ct->tar->type == OB_CURVE && ct->tar->runtime.curve_cache == NULL) { unit_m4(ct->matrix); return; } @@ -3104,7 +3104,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar BKE_object_minmax(ct->tar, curveMin, curveMax, true); /* get targetmatrix */ - if (data->tar->curve_cache && data->tar->curve_cache->path && data->tar->curve_cache->path->data) { + if (data->tar->runtime.curve_cache && data->tar->runtime.curve_cache->path && data->tar->runtime.curve_cache->path->data) { float vec[4], dir[3], totmat[4][4]; float curvetime; short clamp_axis; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 33a24f77937..39b28540205 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1752,11 +1752,11 @@ void BKE_curve_bevel_make( BKE_displist_make_curveTypes_forRender(depsgraph, scene, cu->bevobj, &bevdisp, NULL, false, use_render_resolution); dl = bevdisp.first; } - else if (cu->bevobj->curve_cache) { - dl = cu->bevobj->curve_cache->disp.first; + else if (cu->bevobj->runtime.curve_cache) { + dl = cu->bevobj->runtime.curve_cache->disp.first; } else { - BLI_assert(cu->bevobj->curve_cache != NULL); + BLI_assert(cu->bevobj->runtime.curve_cache != NULL); dl = NULL; } @@ -2669,14 +2669,14 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) ELEM(cu->bevfac2_mapping, CU_BEVFAC_MAP_SEGMENT, CU_BEVFAC_MAP_SPLINE); - bev = &ob->curve_cache->bev; + bev = &ob->runtime.curve_cache->bev; /* do we need to calculate the radius for each point? */ /* do_radius = (cu->bevobj || cu->taperobj || (cu->flag & CU_FRONT) || (cu->flag & CU_BACK)) ? 0 : 1; */ /* STEP 1: MAKE POLYS */ - BKE_curve_bevelList_free(&ob->curve_cache->bev); + BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); nu = nurbs->first; if (cu->editnurb && ob->type != OB_FONT) { is_editmode = 1; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 34fd32b2908..562e2257ea0 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -692,10 +692,10 @@ static float displist_calc_taper(Depsgraph *depsgraph, Scene *scene, Object *tap if (taperobj == NULL || taperobj->type != OB_CURVE) return 1.0; - dl = taperobj->curve_cache ? taperobj->curve_cache->disp.first : NULL; + dl = taperobj->runtime.curve_cache ? taperobj->runtime.curve_cache->disp.first : NULL; if (dl == NULL) { BKE_displist_make_curveTypes(depsgraph, scene, taperobj, 0); - dl = taperobj->curve_cache->disp.first; + dl = taperobj->runtime.curve_cache->disp.first; } if (dl) { float minx, dx, *fp; @@ -738,17 +738,17 @@ void BKE_displist_make_mball(Depsgraph *depsgraph, Scene *scene, Object *ob) return; if (ob == BKE_mball_basis_find(scene, ob)) { - if (ob->curve_cache) { - BKE_displist_free(&(ob->curve_cache->disp)); + if (ob->runtime.curve_cache) { + BKE_displist_free(&(ob->runtime.curve_cache->disp)); } else { - ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for MBall"); + ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for MBall"); } - BKE_mball_polygonize(depsgraph, scene, ob, &ob->curve_cache->disp); + BKE_mball_polygonize(depsgraph, scene, ob, &ob->runtime.curve_cache->disp); BKE_mball_texspace_calc(ob); - object_deform_mball(ob, &ob->curve_cache->disp); + object_deform_mball(ob, &ob->runtime.curve_cache->disp); /* NOP for MBALLs anyway... */ boundbox_displist_object(ob); @@ -1314,7 +1314,7 @@ void BKE_displist_make_surf( } if (!for_orco) { - BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); + BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); } @@ -1558,15 +1558,15 @@ static void do_makeDispListCurveTypes( ListBase dlbev; ListBase nubase = {NULL, NULL}; - BKE_curve_bevelList_free(&ob->curve_cache->bev); + BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); /* We only re-evaluate path if evaluation is not happening for orco. * If the calculation happens for orco, we should never free data which * was needed before and only not needed for orco calculation. */ if (!for_orco) { - if (ob->curve_cache->path) free_path(ob->curve_cache->path); - ob->curve_cache->path = NULL; + if (ob->runtime.curve_cache->path) free_path(ob->runtime.curve_cache->path); + ob->runtime.curve_cache->path = NULL; } if (ob->type == OB_FONT) { @@ -1590,7 +1590,7 @@ static void do_makeDispListCurveTypes( } else { float widfac = cu->width - 1.0f; - BevList *bl = ob->curve_cache->bev.first; + BevList *bl = ob->runtime.curve_cache->bev.first; Nurb *nu = nubase.first; for (; bl && nu; bl = bl->next, nu = nu->next) { @@ -1777,7 +1777,7 @@ static void do_makeDispListCurveTypes( } if (!for_orco) { - BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase); + BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution); } @@ -1801,11 +1801,11 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, Scene *scene, Object *ob BKE_object_free_derived_caches(ob); - if (!ob->curve_cache) { - ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); + if (!ob->runtime.curve_cache) { + ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); } - dispbase = &(ob->curve_cache->disp); + dispbase = &(ob->runtime.curve_cache->disp); do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, &ob->derivedFinal, 0, for_orco, 0); @@ -1817,8 +1817,8 @@ void BKE_displist_make_curveTypes_forRender( DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution) { - if (ob->curve_cache == NULL) { - ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); + if (ob->runtime.curve_cache == NULL) { + ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution); @@ -1827,8 +1827,8 @@ void BKE_displist_make_curveTypes_forRender( void BKE_displist_make_curveTypes_forOrco( Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *dispbase) { - if (ob->curve_cache == NULL) { - ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); + if (ob->runtime.curve_cache == NULL) { + ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); } do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, NULL, 1, 1, 1); @@ -1903,7 +1903,7 @@ static void boundbox_displist_object(Object *ob) float min[3], max[3]; INIT_MINMAX(min, max); - BKE_displist_minmax(&ob->curve_cache->disp, min, max); + BKE_displist_minmax(&ob->runtime.curve_cache->disp, min, max); BKE_boundbox_init_from_minmax(ob->bb, min, max); ob->bb->flag &= ~BOUNDBOX_DIRTY; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index b6eb26443ea..52ea4bf4a5e 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -163,10 +163,10 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) { Curve *cu= eff->ob->data; if (cu->flag & CU_PATH) { - if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL) + if (eff->ob->runtime.curve_cache == NULL || eff->ob->runtime.curve_cache->path==NULL || eff->ob->runtime.curve_cache->path->data==NULL) BKE_displist_make_curveTypes(depsgraph, eff->scene, eff->ob, 0); - if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) { + if (eff->ob->runtime.curve_cache->path && eff->ob->runtime.curve_cache->path->data) { where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL); mul_m4_v3(eff->ob->obmat, eff->guide_loc); mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 36633663f9d..b5fba6d30e8 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -1075,8 +1075,8 @@ makebreak: /* TEXT ON CURVE */ /* Note: Only OB_CURVE objects could have a path */ if (cu->textoncurve && cu->textoncurve->type == OB_CURVE) { - BLI_assert(cu->textoncurve->curve_cache != NULL); - if (cu->textoncurve->curve_cache->path) { + BLI_assert(cu->textoncurve->runtime.curve_cache != NULL); + if (cu->textoncurve->runtime.curve_cache->path) { float distfac, imat[4][4], imat3[3][3], cmat[3][3]; float minx, maxx, miny, maxy; float timeofs, sizefac; @@ -1106,7 +1106,7 @@ makebreak: /* we put the x-coordinaat exact at the curve, the y is rotated */ /* length correction */ - distfac = sizefac * cu->textoncurve->curve_cache->path->totdist / (maxx - minx); + distfac = sizefac * cu->textoncurve->runtime.curve_cache->path->totdist / (maxx - minx); timeofs = 0.0f; if (distfac > 1.0f) { diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 78ff43c2981..04830eb1081 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -211,9 +211,9 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb) /* works best if we force to linear type (endpoints match) */ lt->typeu = lt->typev = lt->typew = KEY_LINEAR; - if (ltOb->curve_cache) { + if (ltOb->runtime.curve_cache) { /* prevent using deformed locations */ - BKE_displist_free(<Ob->curve_cache->disp); + BKE_displist_free(<Ob->runtime.curve_cache->disp); } copy_m4_m4(mat, ltOb->obmat); @@ -349,7 +349,7 @@ LatticeDeformData *init_latt_deform(Object *oblatt, Object *ob) /* we make an array with all differences */ Lattice *lt = oblatt->data; BPoint *bp; - DispList *dl = oblatt->curve_cache ? BKE_displist_find(&oblatt->curve_cache->disp, DL_VERTS) : NULL; + DispList *dl = oblatt->runtime.curve_cache ? BKE_displist_find(&oblatt->runtime.curve_cache->disp, DL_VERTS) : NULL; const float *co = dl ? dl->verts : NULL; float *fp, imat[4][4]; float fu, fv, fw; @@ -558,7 +558,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di int cycl = 0; /* test for cyclic */ - bl = ob->curve_cache->bev.first; + bl = ob->runtime.curve_cache->bev.first; if (!bl->nr) return false; if (bl->poly > -1) cycl = 1; @@ -573,7 +573,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) { if (cycl == 0) { - Path *path = ob->curve_cache->path; + Path *path = ob->runtime.curve_cache->path; float dvec[3]; if (ctime < 0.0f) { @@ -610,12 +610,12 @@ static bool calc_curve_deform(Object *par, float co[3], short index; const bool is_neg_axis = (axis > 2); - if (par->curve_cache == NULL) { + if (par->runtime.curve_cache == NULL) { /* Happens with a cyclic dependencies. */ return false; } - if (par->curve_cache->path == NULL) { + if (par->runtime.curve_cache->path == NULL) { return false; /* happens on append, cyclic dependencies and empty curves */ } @@ -625,7 +625,7 @@ static bool calc_curve_deform(Object *par, float co[3], if (cu->flag & CU_STRETCH) fac = (-co[index] - cd->dmax[index]) / (cd->dmax[index] - cd->dmin[index]); else - fac = -(co[index] - cd->dmax[index]) / (par->curve_cache->path->totdist); + fac = -(co[index] - cd->dmax[index]) / (par->runtime.curve_cache->path->totdist); } else { index = axis; @@ -633,8 +633,8 @@ static bool calc_curve_deform(Object *par, float co[3], fac = (co[index] - cd->dmin[index]) / (cd->dmax[index] - cd->dmin[index]); } else { - if (LIKELY(par->curve_cache->path->totdist > FLT_EPSILON)) { - fac = +(co[index] - cd->dmin[index]) / (par->curve_cache->path->totdist); + if (LIKELY(par->runtime.curve_cache->path->totdist > FLT_EPSILON)) { + fac = +(co[index] - cd->dmin[index]) / (par->runtime.curve_cache->path->totdist); } else { fac = 0.0f; @@ -1035,11 +1035,11 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec int numVerts, editmode = (lt->editlatt != NULL); const ModifierEvalContext mectx = {depsgraph, ob, 0}; - if (ob->curve_cache) { - BKE_displist_free(&ob->curve_cache->disp); + if (ob->runtime.curve_cache) { + BKE_displist_free(&ob->runtime.curve_cache->disp); } else { - ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice"); + ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice"); } for (; md; md = md->next) { @@ -1071,7 +1071,7 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec dl->nr = numVerts; dl->verts = (float *) vertexCos; - BLI_addtail(&ob->curve_cache->disp, dl); + BLI_addtail(&ob->runtime.curve_cache->disp, dl); } } @@ -1145,7 +1145,7 @@ BoundBox *BKE_lattice_boundbox_get(Object *ob) void BKE_lattice_minmax_dl(Object *ob, Lattice *lt, float min[3], float max[3]) { - DispList *dl = ob->curve_cache ? BKE_displist_find(&ob->curve_cache->disp, DL_VERTS) : NULL; + DispList *dl = ob->runtime.curve_cache ? BKE_displist_find(&ob->runtime.curve_cache->disp, DL_VERTS) : NULL; if (!dl) { BKE_lattice_minmax(lt, min, max); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index ab8c8695495..28d75811185 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -926,8 +926,8 @@ bool BKE_object_material_slot_remove(Main *bmain, Object *ob) /* check indices from mesh */ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { material_data_index_remove_id((ID *)ob->data, actcol - 1); - if (ob->curve_cache) { - BKE_displist_free(&ob->curve_cache->disp); + if (ob->runtime.curve_cache) { + BKE_displist_free(&ob->runtime.curve_cache->disp); } } diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 2ff69c5ee6d..43b7eba2810 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -207,7 +207,7 @@ void BKE_mball_texspace_calc(Object *ob) (min)[0] = (min)[1] = (min)[2] = 1.0e30f; (max)[0] = (max)[1] = (max)[2] = -1.0e30f; - dl = ob->curve_cache->disp.first; + dl = ob->runtime.curve_cache->disp.first; while (dl) { tot = dl->nr; if (tot) do_it = true; diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 738f116310b..2e2afa6834b 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -217,8 +217,8 @@ int BKE_mesh_nurbs_to_mdata( { ListBase disp = {NULL, NULL}; - if (ob->curve_cache) { - disp = ob->curve_cache->disp; + if (ob->runtime.curve_cache) { + disp = ob->runtime.curve_cache->disp; } return BKE_mesh_nurbs_displist_to_mdata( @@ -537,8 +537,8 @@ Mesh *BKE_mesh_new_nomain_from_curve(Object *ob) { ListBase disp = {NULL, NULL}; - if (ob->curve_cache) { - disp = ob->curve_cache->disp; + if (ob->runtime.curve_cache) { + disp = ob->runtime.curve_cache->disp; } return BKE_mesh_new_nomain_from_curve_displist(ob, &disp); @@ -650,8 +650,8 @@ void BKE_mesh_from_nurbs(Main *bmain, Object *ob) bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0; ListBase disp = {NULL, NULL}; - if (ob->curve_cache) { - disp = ob->curve_cache->disp; + if (ob->runtime.curve_cache) { + disp = ob->runtime.curve_cache->disp; } BKE_mesh_from_nurbs_displist(bmain, ob, &disp, use_orco_uv, cu->id.name, false); @@ -871,11 +871,11 @@ Mesh *BKE_mesh_new_from_object( * * TODO(sergey): Look into more proper solution. */ - if (ob->curve_cache != NULL) { - if (tmpobj->curve_cache == NULL) { - tmpobj->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); + if (ob->runtime.curve_cache != NULL) { + if (tmpobj->runtime.curve_cache == NULL) { + tmpobj->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); } - BKE_displist_copy(&tmpobj->curve_cache->disp, &ob->curve_cache->disp); + BKE_displist_copy(&tmpobj->runtime.curve_cache->disp, &ob->runtime.curve_cache->disp); } /* if getting the original caged mesh, delete object modifiers */ @@ -953,8 +953,8 @@ Mesh *BKE_mesh_new_from_object( } else { ListBase disp = {NULL, NULL}; - if (ob->curve_cache) { - disp = ob->curve_cache->disp; + if (ob->runtime.curve_cache) { + disp = ob->runtime.curve_cache->disp; } BKE_mesh_from_metaball(&disp, tmpmesh); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1d6b23ce7f7..21b5bb89f19 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -170,15 +170,15 @@ void BKE_object_free_softbody(Object *ob) void BKE_object_free_curve_cache(Object *ob) { - if (ob->curve_cache) { - BKE_displist_free(&ob->curve_cache->disp); - BKE_curve_bevelList_free(&ob->curve_cache->bev); - if (ob->curve_cache->path) { - free_path(ob->curve_cache->path); + if (ob->runtime.curve_cache) { + BKE_displist_free(&ob->runtime.curve_cache->disp); + BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); + if (ob->runtime.curve_cache->path) { + free_path(ob->runtime.curve_cache->path); } - BKE_nurbList_free(&ob->curve_cache->deformed_nurbs); - MEM_freeN(ob->curve_cache); - ob->curve_cache = NULL; + BKE_nurbList_free(&ob->runtime.curve_cache->deformed_nurbs); + MEM_freeN(ob->runtime.curve_cache); + ob->runtime.curve_cache = NULL; } } @@ -460,12 +460,12 @@ void BKE_object_free(Object *ob) BLI_freelistN(&ob->lodlevels); /* Free runtime curves data. */ - if (ob->curve_cache) { - BKE_curve_bevelList_free(&ob->curve_cache->bev); - if (ob->curve_cache->path) - free_path(ob->curve_cache->path); - MEM_freeN(ob->curve_cache); - ob->curve_cache = NULL; + if (ob->runtime.curve_cache) { + BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); + if (ob->runtime.curve_cache->path) + free_path(ob->runtime.curve_cache->path); + MEM_freeN(ob->runtime.curve_cache); + ob->runtime.curve_cache = NULL; } BKE_previewimg_free(&ob->preview); @@ -1154,6 +1154,9 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con { ModifierData *md; + /* Do not copy runtime data. */ + BKE_object_runtime_reset(ob_dst); + /* We never handle usercount here for own data. */ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT; @@ -1212,9 +1215,6 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con copy_object_lod(ob_dst, ob_src, flag_subdata); - /* Do not copy runtime curve data. */ - ob_dst->curve_cache = NULL; - /* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */ BKE_previewimg_id_copy(&ob_dst->id, &ob_src->id); @@ -1725,7 +1725,7 @@ static bool ob_parcurve(Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob, } #endif - if (par->curve_cache->path == NULL) { + if (par->runtime.curve_cache->path == NULL) { return false; } @@ -1944,10 +1944,10 @@ static void give_parvert(Object *par, int nr, float vec[3]) ListBase *nurb; /* Unless there's some weird depsgraph failure the cache should exist. */ - BLI_assert(par->curve_cache != NULL); + BLI_assert(par->runtime.curve_cache != NULL); - if (par->curve_cache->deformed_nurbs.first != NULL) { - nurb = &par->curve_cache->deformed_nurbs; + if (par->runtime.curve_cache->deformed_nurbs.first != NULL) { + nurb = &par->runtime.curve_cache->deformed_nurbs; } else { Curve *cu = par->data; @@ -1958,7 +1958,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) } else if (par->type == OB_LATTICE) { Lattice *latt = par->data; - DispList *dl = par->curve_cache ? BKE_displist_find(&par->curve_cache->disp, DL_VERTS) : NULL; + DispList *dl = par->runtime.curve_cache ? BKE_displist_find(&par->runtime.curve_cache->disp, DL_VERTS) : NULL; float (*co)[3] = dl ? (float (*)[3])dl->verts : NULL; int tot; @@ -2539,10 +2539,10 @@ void BKE_object_foreach_display_point( func_cb(co, user_data); } } - else if (ob->curve_cache && ob->curve_cache->disp.first) { + else if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) { DispList *dl; - for (dl = ob->curve_cache->disp.first; dl; dl = dl->next) { + for (dl = ob->runtime.curve_cache->disp.first; dl; dl = dl->next) { const float *v3 = dl->verts; int totvert = dl->nr; int i; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index f226693b989..816a527d829 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5547,9 +5547,6 @@ static void direct_link_object(FileData *fd, Object *ob) BKE_object_runtime_reset(ob); link_list(fd, &ob->pc_ids); - /* Runtime curve data */ - ob->curve_cache = NULL; - /* in case this value changes in future, clamp else we get undefined behavior */ CLAMP(ob->rotmode, ROT_MODE_MIN, ROT_MODE_MAX); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 20aec0ba5ed..b5b33900105 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -732,7 +732,7 @@ static void deg_backup_object_runtime( Object *object, ObjectRuntimeBackup *object_runtime_backup) { - /* Store evaluated mesh, and make sure we don't free it. */ + /* Store evaluated mesh and curve_cache, and make sure we don't free it. */ Mesh *mesh_eval = object->runtime.mesh_eval; object_runtime_backup->runtime = object->runtime; BKE_object_runtime_reset(object); @@ -743,9 +743,6 @@ static void deg_backup_object_runtime( if (mesh_eval != NULL && object->data == mesh_eval) { object->data = object->runtime.mesh_orig; } - /* Store curve cache and make sure we don't free it. */ - object_runtime_backup->curve_cache = object->curve_cache; - object->curve_cache = NULL; /* Make a backup of base flags. */ object_runtime_backup->base_flag = object->base_flag; } @@ -783,9 +780,6 @@ static void deg_restore_object_runtime( } } } - if (object_runtime_backup->curve_cache != NULL) { - object->curve_cache = object_runtime_backup->curve_cache; - } object->base_flag = object_runtime_backup->base_flag; } diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index dff863b11bb..bdfa3211f7c 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2954,7 +2954,7 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache); + return DRW_curve_batch_cache_get_wire_edge(cu, ob->runtime.curve_cache); } GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) @@ -2962,7 +2962,7 @@ GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob, float normal_size) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_normal_edge(cu, ob->curve_cache, normal_size); + return DRW_curve_batch_cache_get_normal_edge(cu, ob->runtime.curve_cache, normal_size); } GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob) @@ -2986,7 +2986,7 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } /* Return list of batches */ @@ -2996,7 +2996,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get( BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); } /** \} */ @@ -3032,7 +3032,7 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob) BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wire_edge(cu, ob->curve_cache); + return DRW_curve_batch_cache_get_wire_edge(cu, ob->runtime.curve_cache); } GPUBatch *DRW_cache_text_surface_get(Object *ob) @@ -3042,7 +3042,7 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } GPUBatch **DRW_cache_text_surface_shaded_get( @@ -3053,7 +3053,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get( if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); } GPUBatch *DRW_cache_text_cursor_overlay_get(Object *ob) @@ -3082,7 +3082,7 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->curve_cache); + return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache); } /* Return list of batches */ @@ -3092,7 +3092,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get( BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, ob->curve_cache, gpumat_array, gpumat_array_len); + return DRW_curve_batch_cache_get_surface_shaded(cu, ob->runtime.curve_cache, gpumat_array, gpumat_array_len); } /** \} */ diff --git a/source/blender/draw/intern/draw_cache_impl_metaball.c b/source/blender/draw/intern/draw_cache_impl_metaball.c index 375b0ba6bb2..2172997a714 100644 --- a/source/blender/draw/intern/draw_cache_impl_metaball.c +++ b/source/blender/draw/intern/draw_cache_impl_metaball.c @@ -140,7 +140,7 @@ GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob) MetaBallBatchCache *cache = metaball_batch_cache_get(mb); if (cache->batch == NULL) { - ListBase *lb = &ob->curve_cache->disp; + ListBase *lb = &ob->runtime.curve_cache->disp; cache->batch = GPU_batch_create_ex( GPU_PRIM_TRIS, DRW_displist_vertbuf_calc_pos_with_normals(lb), diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 9e9785f5e5c..db906714dd5 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1663,7 +1663,7 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye } break; case PFIELD_GUIDE: - if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path && ob->runtime.curve_cache->path->data) { where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL); where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL); } @@ -1704,7 +1704,7 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye DRW_shgroup_call_dynamic_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat); break; case PFIELD_GUIDE: - if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path && ob->runtime.curve_cache->path->data) { DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat); DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat); } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 1d7a9ac46c7..f7d54e3bc4f 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6260,12 +6260,12 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) float min[3], max[3], size[3], loc[3]; int a; - if (object->curve_cache == NULL) { + if (object->runtime.curve_cache == NULL) { BKE_displist_make_curveTypes(depsgraph, scene, object, false); } INIT_MINMAX(min, max); - BKE_displist_minmax(&object->curve_cache->disp, min, max); + BKE_displist_minmax(&object->runtime.curve_cache->disp, min, max); mid_v3_v3v3(loc, min, max); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 8c60dd01e89..68e84ec3f3b 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1479,7 +1479,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ob_dst->parent = NULL; BKE_constraints_free(&ob_dst->constraints); - ob_dst->curve_cache = NULL; + ob_dst->runtime.curve_cache = NULL; ob_dst->transflag &= ~OB_DUPLI; copy_m4_m4(ob_dst->obmat, dob->mat); @@ -1638,7 +1638,7 @@ static const EnumPropertyItem convert_target_items[] = { static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob) { - if (ob->curve_cache == NULL) { + if (ob->runtime.curve_cache == NULL) { /* Force creation. This is normally not needed but on operator * redo we might end up with an object which isn't evaluated yet. */ @@ -1966,7 +1966,7 @@ static int convert_exec(bContext *C, wmOperator *op) } convert_ensure_curve_cache(depsgraph, scene, baseob); - BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data); + BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, newob->data); if (obact->type == OB_MBALL) { basact = basen; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 4745a484475..331b4af077d 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -716,7 +716,7 @@ bool ED_object_parent_set(ReportList *reports, const bContext *C, Scene *scene, if (md) { ((CurveModifierData *)md)->object = par; } - if (par->curve_cache && par->curve_cache->path == NULL) { + if (par->runtime.curve_cache && par->runtime.curve_cache->path == NULL) { DEG_id_tag_update(&par->id, OB_RECALC_DATA); } } diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 3830e6d2792..8aa37bb5e16 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -127,8 +127,8 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats) { int totv = 0, totf = 0, tottri = 0; - if (ob->curve_cache && ob->curve_cache->disp.first) - BKE_displist_count(&ob->curve_cache->disp, &totv, &totf, &tottri); + if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) + BKE_displist_count(&ob->runtime.curve_cache->disp, &totv, &totf, &tottri); totv *= totob; totf *= totob; diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index eae0cf8e459..74071e77901 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -380,7 +380,7 @@ void lattice_foreachScreenVert( Object *obedit = vc->obedit; Lattice *lt = obedit->data; BPoint *bp = lt->editlatt->latt->def; - DispList *dl = obedit->curve_cache ? BKE_displist_find(&obedit->curve_cache->disp, DL_VERTS) : NULL; + DispList *dl = obedit->runtime.curve_cache ? BKE_displist_find(&obedit->runtime.curve_cache->disp, DL_VERTS) : NULL; const float *co = dl ? dl->verts : NULL; int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index edc87c492a6..a8d50543e80 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -142,6 +142,10 @@ typedef struct Object_Runtime { * It has deforemation only modifiers applied on it. */ struct Mesh *mesh_deform_eval; + + + /* Runtime evaluated curve-specific data, not stored in the file. */ + struct CurveCache *curve_cache; } Object_Runtime; typedef struct Object { @@ -280,9 +284,6 @@ typedef struct Object { uint64_t lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */ uint64_t customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */ - /* Runtime valuated curve-specific data, not stored in the file */ - struct CurveCache *curve_cache; - ListBase pc_ids; struct RigidBodyOb *rigidbody_object; /* settings for Bullet rigid body */ diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 5ae0013aab0..085f21fe138 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -456,9 +456,10 @@ static Mesh *arrayModifier_doArray( if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) { Curve *cu = amd->curve_ob->data; if (cu) { - if (amd->curve_ob->curve_cache && amd->curve_ob->curve_cache->path) { + CurveCache *curve_cache = amd->curve_ob->runtime.curve_cache; + if (curve_cache != NULL && curve_cache->path != NULL) { float scale_fac = mat4_to_scale(amd->curve_ob->obmat); - length = scale_fac * amd->curve_ob->curve_cache->path->totdist; + length = scale_fac * curve_cache->path->totdist; } } } -- cgit v1.2.3 From d28248595b5936ed5f268418ff9905200660ec69 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 31 Jul 2018 02:57:53 +1200 Subject: Silencing a bunch of compiler warnings Most of these were mismatched const qualifiers --- source/blender/blenkernel/intern/collection.c | 2 +- source/blender/editors/include/ED_view3d.h | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 2 +- source/blender/editors/transform/transform_conversions.c | 2 +- source/blender/makesrna/intern/rna_define.c | 2 +- source/blender/nodes/composite/nodes/node_composite_cryptomatte.c | 2 +- source/blender/windowmanager/gizmo/WM_gizmo_api.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 0c93f304218..04e09d06405 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -57,7 +57,7 @@ /******************************** Prototypes ********************************/ -static bool collection_child_add(Collection *parent, Collection *collection, int flag, const bool add_us); +static bool collection_child_add(Collection *parent, Collection *collection, const int flag, const bool add_us); static bool collection_child_remove(Collection *parent, Collection *collection); static bool collection_object_add(Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us); static bool collection_object_remove(Main *bmain, Collection *collection, Object *ob, const bool free_us); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 516b121031e..6b0c59fb557 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -119,7 +119,7 @@ void ED_view3d_cursor3d_position_rotation( float cursor_co[3], float cursor_quat[4]); void ED_view3d_cursor3d_update( struct bContext *C, const int mval[2], - bool use_depth, enum eV3DCursorOrient orientation); + const bool use_depth, enum eV3DCursorOrient orientation); struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2cc1236e5c6..e94d3a13225 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -4625,7 +4625,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) /* cursor position in vec, result in vec, mval in region coords */ /* note: cannot use event->mval here (called by object_add() */ -void ED_view3d_cursor3d_position(bContext *C, const int mval[2], bool use_depth, float cursor_co[3]) +void ED_view3d_cursor3d_position(bContext *C, const int mval[2], const bool use_depth, float cursor_co[3]) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a5706f4a003..675441189b0 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -747,7 +747,7 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb) /* sets transform flags in the bones * returns total number of bones with BONE_TRANSFORM */ -int count_set_pose_transflags(Object *ob, const int mode, short around, bool has_translate_rotate[2]) +int count_set_pose_transflags(Object *ob, const int mode, const short around, bool has_translate_rotate[2]) { bArmature *arm = ob->data; bPoseChannel *pchan; diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index c84ce56c58b..4964e94652c 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -2282,7 +2282,7 @@ void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func) void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func) { if (prop->type == PROP_POINTER) { - ((PointerPropertyRNA *)prop)->poll = func; + ((PointerPropertyRNA *)prop)->poll = (void *)func; } else { fprintf(stderr, "%s: %s is not a Pointer Property.\n", __func__, prop->identifier); diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c index bf9ab4a5064..af988c0df39 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -37,7 +37,7 @@ /* this is taken from the cryptomatte specification 1.0 */ -static inline float hash_to_float(uint32_t hash) +BLI_INLINE float hash_to_float(uint32_t hash) { uint32_t mantissa = hash & ((1 << 23) - 1); uint32_t exponent = (hash >> 23) & ((1 << 8) - 1); diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h index 9b8cecfb4bc..dd39cc96d6f 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h @@ -104,7 +104,7 @@ void WM_gizmo_set_matrix_offset_rotation_from_yz_axis( struct wmGizmo *gz, const float y_axis[3], const float z_axis[3]); void WM_gizmo_set_flag(struct wmGizmo *gz, const int flag, const bool enable); -void WM_gizmo_set_scale(struct wmGizmo *gz, float scale); +void WM_gizmo_set_scale(struct wmGizmo *gz, const float scale); void WM_gizmo_set_line_width(struct wmGizmo *gz, const float line_width); void WM_gizmo_get_color(const struct wmGizmo *gz, float color[4]); -- cgit v1.2.3 From 885cc4cf9a1d5c167e4cbd26c3294d8b1ad400d8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 16:59:46 +0200 Subject: Build: require C11/C++11 for all operating systems in master. This is in preparation of upgrading our library dependencies, some of which need C++11. We already use C++11 in blender2.8 and for Windows and macOS, so this just affects Linux. On many distributions this will not require any changes, on some install_deps.sh will need to be run again to rebuild libraries. Differential Revision: https://developer.blender.org/D3568 --- CMakeLists.txt | 100 ++----------- build_files/build_environment/install_deps.sh | 41 +----- build_files/cmake/macros.cmake | 158 --------------------- .../cmake/platform/platform_apple_xcode.cmake | 2 +- build_files/cmake/platform/platform_win32.cmake | 3 - intern/cycles/CMakeLists.txt | 25 ---- intern/cycles/util/util_defines.h | 10 +- intern/cycles/util/util_foreach.h | 9 +- intern/cycles/util/util_function.h | 18 +-- intern/cycles/util/util_map.h | 27 +--- intern/cycles/util/util_set.h | 32 +---- intern/cycles/util/util_static_assert.h | 22 +-- intern/cycles/util/util_thread.cpp | 8 -- intern/cycles/util/util_thread.h | 24 +--- intern/cycles/util/util_vector.h | 4 - source/blender/alembic/intern/abc_customdata.cc | 9 +- source/blender/blenlib/BLI_compiler_compat.h | 6 +- source/blender/depsgraph/CMakeLists.txt | 22 --- source/blender/depsgraph/util/deg_util_foreach.h | 17 +-- source/blender/depsgraph/util/deg_util_function.h | 73 ---------- 20 files changed, 40 insertions(+), 570 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b018905e4f..f6435316fec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -505,27 +505,6 @@ if(WIN32) set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${}) endif() -# Experimental support of C11 and C++11 -# -# We default options to whatever default standard in the current compiler. -if(APPLE) - set(_c11_init ON) - set(_cxx11_init ON) - set(WITH_C11 ON) - set(WITH_CXX11 ON) -elseif(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11)) - set(_c11_init ON) - set(_cxx11_init ON) -else() - set(_c11_init OFF) - set(_cxx11_init OFF) -endif() - -option(WITH_C11 "Build with C11 standard enabled, for development use only!" ${_c11_init}) -mark_as_advanced(WITH_C11) -option(WITH_CXX11 "Build with C++11 standard enabled, for development use only!" ${_cxx11_init}) -mark_as_advanced(WITH_CXX11) - # Compiler toolchain if(CMAKE_COMPILER_IS_GNUCC) option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON) @@ -703,11 +682,8 @@ elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL O WITH_OPENVDB OR WITH_OPENCOLORIO) # Keep enabled else() - # New dependency graph needs either Boost or C++11 for function bindings. - if(NOT WITH_CXX11) - # Enabled but we don't need it - set(WITH_BOOST OFF) - endif() + # Disable boost if not needed. + set(WITH_BOOST OFF) endif() # auto enable openimageio for cycles @@ -764,9 +740,6 @@ if(WITH_BUILDINFO) endif() endif() -TEST_SHARED_PTR_SUPPORT() -TEST_UNORDERED_MAP_SUPPORT() - if(WITH_AUDASPACE) if(WITH_SYSTEM_AUDASPACE) set(AUDASPACE_DEFINITIONS @@ -1362,42 +1335,8 @@ endif() # Configure Ceres if(WITH_LIBMV) - set(CERES_DEFINES) - - if(WITH_CXX11) - # nothing to be done - elseif(SHARED_PTR_FOUND) - if(SHARED_PTR_TR1_MEMORY_HEADER) - list(APPEND CERES_DEFINES -DCERES_TR1_MEMORY_HEADER) - endif() - if(SHARED_PTR_TR1_NAMESPACE) - list(APPEND CERES_DEFINES -DCERES_TR1_SHARED_PTR) - endif() - else() - message(FATAL_ERROR "Ceres: Unable to find shared_ptr.") - endif() - - if(WITH_CXX11) - list(APPEND CERES_DEFINES -DCERES_STD_UNORDERED_MAP) - elseif(HAVE_STD_UNORDERED_MAP_HEADER) - if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - list(APPEND CERES_DEFINES -DCERES_STD_UNORDERED_MAP) - else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - list(APPEND CERES_DEFINES -DCERES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) - else() - list(APPEND CERES_DEFINES -DCERES_NO_UNORDERED_MAP) - message(STATUS "Ceres: Replacing unordered_map/set with map/set (warning: slower!)") - endif() - endif() - else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - list(APPEND CERES_DEFINES -DCERES_TR1_UNORDERED_MAP) - else() - list(APPEND CERES_DEFINES -DCERES_NO_UNORDERED_MAP) - message(STATUS "Ceres: Replacing unordered_map/set with map/set (warning: slower!)") - endif() - endif() + # We always have C++11 which includes unordered_map. + set(CERES_DEFINES -DCERES_STD_UNORDERED_MAP) endif() #----------------------------------------------------------------------------- @@ -1619,28 +1558,17 @@ if(WITH_PYTHON) endif() endif() -if(WITH_CXX11) - if( - CMAKE_COMPILER_IS_GNUCC OR - CMAKE_C_COMPILER_ID MATCHES "Clang" OR - CMAKE_C_COMPILER_ID MATCHES "Intel" - ) - # TODO(sergey): Do we want c++11 or gnu-c++11 here? - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - elseif(MSVC) - # Nothing special is needed, C++11 features are available by default. - else() - message(FATAL_ERROR "Compiler ${CMAKE_C_COMPILER_ID} is not supported for C++11 build yet") - endif() +if( + CMAKE_COMPILER_IS_GNUCC OR + CMAKE_C_COMPILER_ID MATCHES "Clang" OR + CMAKE_C_COMPILER_ID MATCHES "Intel" +) + # TODO(sergey): Do we want c++11 or gnu-c++11 here? + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +elseif(MSVC) + # Nothing special is needed, C++11 features are available by default. else() - # GCC-6 switched to C++11 by default, which would break linking with existing libraries - # by default. So we explicitly disable C++11 for a new GCC so no linking issues happens. - if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0")) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++98") - # We also disable any of C++11 ABI from usage, so we wouldn't even try to - # link to stuff from std::__cxx11 namespace. - add_definitions("-D_GLIBCXX_USE_CXX11_ABI=0") - endif() + message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++11 build") endif() # Visual Studio has all standards it supports available by default diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 6cd725494b3..8d277ac787e 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -290,7 +290,7 @@ SUDO="sudo" NO_BUILD=false NO_CONFIRM=false -USE_CXX11=false +USE_CXX11=true PYTHON_VERSION="3.6.2" PYTHON_VERSION_MIN="3.6" @@ -501,9 +501,6 @@ while true; do --no-confirm) NO_CONFIRM=true; shift; continue ;; - --use-cxx11) - USE_CXX11=true; shift; continue - ;; --with-all) WITH_ALL=true; shift; continue ;; @@ -802,20 +799,10 @@ OPENCOLLADA_REPO_BRANCH="master" FFMPEG_SOURCE=( "http://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.bz2" ) +# C++11 is required now CXXFLAGS_BACK=$CXXFLAGS -if [ "$USE_CXX11" = true ]; then - WARNING "You are trying to use c++11, this *should* go smoothely with any very recent distribution -However, if you are experiencing linking errors (also when building Blender itself), please try the following: - * Re-run this script with '--build-all --force-all' options. - * Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above. - -Please note that until the transition to C++11-built libraries if completed in your distribution, situation will -remain fuzzy and incompatibilities may happen..." - PRINT "" - PRINT "" - CXXFLAGS="$CXXFLAGS -std=c++11" - export CXXFLAGS -fi +CXXFLAGS="$CXXFLAGS -std=c++11" +export CXXFLAGS #### Show Dependencies #### @@ -1690,9 +1677,7 @@ compile_OIIO() { # fi cmake_d="$cmake_d -D USE_OCIO=OFF" - if [ "$USE_CXX11" = true ]; then - cmake_d="$cmake_d -D OIIO_BUILD_CPP11=ON" - fi + cmake_d="$cmake_d -D OIIO_BUILD_CPP11=ON" if file /bin/cp | grep -q '32-bit'; then cflags="-fPIC -m32 -march=i686" @@ -1905,9 +1890,7 @@ compile_OSL() { cmake_d="$cmake_d -D OSL_BUILD_PLUGINS=OFF" cmake_d="$cmake_d -D OSL_BUILD_TESTS=OFF" cmake_d="$cmake_d -D USE_SIMD=sse2" - if [ "$USE_CXX11" = true ]; then - cmake_d="$cmake_d -D OSL_BUILD_CPP11=1" - fi + cmake_d="$cmake_d -D OSL_BUILD_CPP11=1" #~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION" @@ -2293,12 +2276,6 @@ compile_ALEMBIC() { cmake_d="-D CMAKE_INSTALL_PREFIX=$_inst" - # Without Boost or TR1, Alembic requires C++11. - if [ "$USE_CXX11" != true ]; then - cmake_d="$cmake_d -D ALEMBIC_LIB_USES_BOOST=ON" - cmake_d="$cmake_d -D ALEMBIC_LIB_USES_TR1=OFF" - fi - if [ -d $INST/boost ]; then if [ -d $INST/boost ]; then cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost" @@ -4235,12 +4212,6 @@ print_info() { _buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CYCLES*" _buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC*" - if [ "$USE_CXX11" = true ]; then - _1="-D WITH_CXX11=ON" - PRINT " $_1" - _buildargs="$_buildargs $_1" - fi - _1="-D WITH_CODEC_SNDFILE=ON" PRINT " $_1" _buildargs="$_buildargs $_1" diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 5d5425a9fc6..54a41f95819 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -859,164 +859,6 @@ macro(message_first_run) endif() endmacro() -macro(TEST_UNORDERED_MAP_SUPPORT) - # - Detect unordered_map availability - # Test if a valid implementation of unordered_map exists - # and define the include path - # This module defines - # HAVE_UNORDERED_MAP, whether unordered_map implementation was found - # - # HAVE_STD_UNORDERED_MAP_HEADER, was found - # HAVE_UNORDERED_MAP_IN_STD_NAMESPACE, unordered_map is in namespace std - # HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE, unordered_map is in namespace std::tr1 - # - # UNORDERED_MAP_INCLUDE_PREFIX, include path prefix for unordered_map, if found - # UNORDERED_MAP_NAMESPACE, namespace for unordered_map, if found - - include(CheckIncludeFileCXX) - - # Workaround for newer GCC (6.x+) where C++11 was enabled by default, which lead us - # to a situation when there is include but which can't be used uless - # C++11 is enabled. - if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11)) - set(HAVE_STD_UNORDERED_MAP_HEADER False) - else() - CHECK_INCLUDE_FILE_CXX("unordered_map" HAVE_STD_UNORDERED_MAP_HEADER) - endif() - if(HAVE_STD_UNORDERED_MAP_HEADER) - # Even so we've found unordered_map header file it doesn't - # mean unordered_map and unordered_set will be declared in - # std namespace. - # - # Namely, MSVC 2008 have unordered_map header which declares - # unordered_map class in std::tr1 namespace. In order to support - # this, we do extra check to see which exactly namespace is - # to be used. - - include(CheckCXXSourceCompiles) - CHECK_CXX_SOURCE_COMPILES("#include - int main() { - std::unordered_map map; - return 0; - }" - HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - message_first_run(STATUS "Found unordered_map/set in std namespace.") - - set(HAVE_UNORDERED_MAP "TRUE") - set(UNORDERED_MAP_INCLUDE_PREFIX "") - set(UNORDERED_MAP_NAMESPACE "std") - else() - CHECK_CXX_SOURCE_COMPILES("#include - int main() { - std::tr1::unordered_map map; - return 0; - }" - HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - message_first_run(STATUS "Found unordered_map/set in std::tr1 namespace.") - - set(HAVE_UNORDERED_MAP "TRUE") - set(UNORDERED_MAP_INCLUDE_PREFIX "") - set(UNORDERED_MAP_NAMESPACE "std::tr1") - else() - message_first_run(STATUS "Found but cannot find either std::unordered_map " - "or std::tr1::unordered_map.") - endif() - endif() - else() - CHECK_INCLUDE_FILE_CXX("tr1/unordered_map" HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - message_first_run(STATUS "Found unordered_map/set in std::tr1 namespace.") - - set(HAVE_UNORDERED_MAP "TRUE") - set(UNORDERED_MAP_INCLUDE_PREFIX "tr1") - set(UNORDERED_MAP_NAMESPACE "std::tr1") - else() - message_first_run(STATUS "Unable to find or . ") - endif() - endif() -endmacro() - -macro(TEST_SHARED_PTR_SUPPORT) - # This check are coming from Ceres library. - # - # Find shared pointer header and namespace. - # - # This module defines the following variables: - # - # SHARED_PTR_FOUND: TRUE if shared_ptr found. - # SHARED_PTR_TR1_MEMORY_HEADER: True if header is to be used - # for the shared_ptr object, otherwise use . - # SHARED_PTR_TR1_NAMESPACE: TRUE if shared_ptr is defined in std::tr1 namespace, - # otherwise it's assumed to be defined in std namespace. - - include(CheckIncludeFileCXX) - include(CheckCXXSourceCompiles) - set(SHARED_PTR_FOUND FALSE) - # Workaround for newer GCC (6.x+) where C++11 was enabled by default, which lead us - # to a situation when there is include but which can't be used uless - # C++11 is enabled. - if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "6.0") AND (NOT WITH_CXX11)) - set(HAVE_STD_MEMORY_HEADER False) - else() - CHECK_INCLUDE_FILE_CXX(memory HAVE_STD_MEMORY_HEADER) - endif() - if(HAVE_STD_MEMORY_HEADER) - # Finding the memory header doesn't mean that shared_ptr is in std - # namespace. - # - # In particular, MSVC 2008 has shared_ptr declared in std::tr1. In - # order to support this, we do an extra check to see which namespace - # should be used. - CHECK_CXX_SOURCE_COMPILES("#include - int main() { - std::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_STD_NAMESPACE) - - if(HAVE_SHARED_PTR_IN_STD_NAMESPACE) - message_first_run("-- Found shared_ptr in std namespace using header.") - set(SHARED_PTR_FOUND TRUE) - else() - CHECK_CXX_SOURCE_COMPILES("#include - int main() { - std::tr1::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_TR1_NAMESPACE) - if(HAVE_SHARED_PTR_IN_TR1_NAMESPACE) - message_first_run("-- Found shared_ptr in std::tr1 namespace using header.") - set(SHARED_PTR_TR1_NAMESPACE TRUE) - set(SHARED_PTR_FOUND TRUE) - endif() - endif() - endif() - - if(NOT SHARED_PTR_FOUND) - # Further, gcc defines shared_ptr in std::tr1 namespace and - # is to be included for this. And what makes things - # even more tricky is that gcc does have header, so - # all the checks above wouldn't find shared_ptr. - CHECK_INCLUDE_FILE_CXX("tr1/memory" HAVE_TR1_MEMORY_HEADER) - if(HAVE_TR1_MEMORY_HEADER) - CHECK_CXX_SOURCE_COMPILES("#include - int main() { - std::tr1::shared_ptr int_ptr; - return 0; - }" - HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER) - if(HAVE_SHARED_PTR_IN_TR1_NAMESPACE_FROM_TR1_MEMORY_HEADER) - message_first_run("-- Found shared_ptr in std::tr1 namespace using header.") - set(SHARED_PTR_TR1_MEMORY_HEADER TRUE) - set(SHARED_PTR_TR1_NAMESPACE TRUE) - set(SHARED_PTR_FOUND TRUE) - endif() - endif() - endif() -endmacro() - # when we have warnings as errors applied globally this # needs to be removed for some external libs which we dont maintain. diff --git a/build_files/cmake/platform/platform_apple_xcode.cmake b/build_files/cmake/platform/platform_apple_xcode.cmake index 1b8e13a0623..7af69c092cc 100644 --- a/build_files/cmake/platform/platform_apple_xcode.cmake +++ b/build_files/cmake/platform/platform_apple_xcode.cmake @@ -104,7 +104,7 @@ endif() # 10.9 is our min. target, if you use higher sdk, weak linking happens if(CMAKE_OSX_DEPLOYMENT_TARGET) if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS 10.9) - message(STATUS "Setting deployment target to 10.9, lower versions are incompatible with WITH_CXX11") + message(STATUS "Setting deployment target to 10.9, lower versions are not supported") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) endif() else() diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index df96333e9f1..bfbc8d90859 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -131,9 +131,6 @@ include(InstallRequiredSystemLibraries) remove_cc_flag("/MDd" "/MD") if(MSVC_CLANG) # Clangs version of cl doesn't support all flags - if(NOT WITH_CXX11) # C++11 is on by default in clang-cl and can't be turned off, if c++11 is not enabled in blender repress some c++11 related warnings. - set(CXX_WARN_FLAGS "-Wno-inconsistent-missing-override") - endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference") else() diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 0740aa51039..00ac8e7e182 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -224,31 +224,6 @@ endif() # TODO(sergey): Consider removing it, only causes confusion in interface. set(WITH_CYCLES_DEVICE_MULTI TRUE) -if(CYCLES_STANDALONE_REPOSITORY) - TEST_UNORDERED_MAP_SUPPORT() -endif() -if(WITH_CXX11) - add_definitions(-DCYCLES_STD_UNORDERED_MAP) -elseif(HAVE_STD_UNORDERED_MAP_HEADER) - if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - add_definitions(-DCYCLES_STD_UNORDERED_MAP) - else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - add_definitions(-DCYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) - else() - add_definitions(-DCYCLES_NO_UNORDERED_MAP) - message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)") - endif() - endif() -else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - add_definitions(-DCYCLES_TR1_UNORDERED_MAP) - else() - add_definitions(-DCYCLES_NO_UNORDERED_MAP) - message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)") - endif() -endif() - # Logging capabilities using GLog library. if(WITH_CYCLES_LOGGING) add_definitions(-DWITH_CYCLES_LOGGING) diff --git a/intern/cycles/util/util_defines.h b/intern/cycles/util/util_defines.h index d994d4e08f4..1a09f659eb1 100644 --- a/intern/cycles/util/util_defines.h +++ b/intern/cycles/util/util_defines.h @@ -87,18 +87,10 @@ # define UNLIKELY(x) (x) #endif -#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800)) -# define HAS_CPP11_FEATURES -#endif - #if defined(__GNUC__) || defined(__clang__) -# if defined(HAS_CPP11_FEATURES) /* Some magic to be sure we don't have reference in the type. */ template static inline T decltype_helper(T x) { return x; } -# define TYPEOF(x) decltype(decltype_helper(x)) -# else -# define TYPEOF(x) typeof(x) -# endif +# define TYPEOF(x) decltype(decltype_helper(x)) #endif /* Causes warning: diff --git a/intern/cycles/util/util_foreach.h b/intern/cycles/util/util_foreach.h index 03fcefc67b9..2a74ff0a55d 100644 --- a/intern/cycles/util/util_foreach.h +++ b/intern/cycles/util/util_foreach.h @@ -17,13 +17,8 @@ #ifndef __UTIL_FOREACH_H__ #define __UTIL_FOREACH_H__ -/* Use Boost to get nice foreach() loops for STL data structures. */ +/* Nice foreach() loops for STL data structures. */ -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# define foreach(x, y) for(x : y) -#else -# include -# define foreach BOOST_FOREACH -#endif +#define foreach(x, y) for(x : y) #endif /* __UTIL_FOREACH_H__ */ diff --git a/intern/cycles/util/util_function.h b/intern/cycles/util/util_function.h index 958f8b4008c..f3cc00329ad 100644 --- a/intern/cycles/util/util_function.h +++ b/intern/cycles/util/util_function.h @@ -17,18 +17,12 @@ #ifndef __UTIL_FUNCTION_H__ #define __UTIL_FUNCTION_H__ -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# include -#else -# include -# include -#endif +#include CCL_NAMESPACE_BEGIN -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# define function_bind std::bind -# define function_null nullptr +#define function_bind std::bind +#define function_null nullptr using std::function; using std::placeholders::_1; using std::placeholders::_2; @@ -39,11 +33,7 @@ using std::placeholders::_6; using std::placeholders::_7; using std::placeholders::_8; using std::placeholders::_9; -#else -using boost::function; -# define function_bind boost::bind -# define function_null NULL -#endif + CCL_NAMESPACE_END #endif /* __UTIL_FUNCTION_H__ */ diff --git a/intern/cycles/util/util_map.h b/intern/cycles/util/util_map.h index b3d887f093c..3c9288417cf 100644 --- a/intern/cycles/util/util_map.h +++ b/intern/cycles/util/util_map.h @@ -18,38 +18,13 @@ #define __UTIL_MAP_H__ #include - -#if defined(CYCLES_TR1_UNORDERED_MAP) -# include -#endif - -#if defined(CYCLES_STD_UNORDERED_MAP) || defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) -# include -#endif - -#if !defined(CYCLES_NO_UNORDERED_MAP) && !defined(CYCLES_TR1_UNORDERED_MAP) && \ - !defined(CYCLES_STD_UNORDERED_MAP) && !defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) // NOLINT -# error One of: CYCLES_NO_UNORDERED_MAP, CYCLES_TR1_UNORDERED_MAP,\ - CYCLES_STD_UNORDERED_MAP, CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE must be defined! // NOLINT -#endif - +#include CCL_NAMESPACE_BEGIN using std::map; using std::pair; - -#if defined(CYCLES_NO_UNORDERED_MAP) -typedef std::map unordered_map; -#endif - -#if defined(CYCLES_TR1_UNORDERED_MAP) || defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) -using std::tr1::unordered_map; -#endif - -#if defined(CYCLES_STD_UNORDERED_MAP) using std::unordered_map; -#endif CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_set.h b/intern/cycles/util/util_set.h index 1d010e19996..298e1f7729a 100644 --- a/intern/cycles/util/util_set.h +++ b/intern/cycles/util/util_set.h @@ -18,24 +18,7 @@ #define __UTIL_SET_H__ #include -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# include -#else -# if defined(CYCLES_TR1_UNORDERED_MAP) -# include -# endif -# if defined(CYCLES_STD_UNORDERED_MAP) || \ - defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) -# include -# endif -# if !defined(CYCLES_NO_UNORDERED_MAP) && \ - !defined(CYCLES_TR1_UNORDERED_MAP) && \ - !defined(CYCLES_STD_UNORDERED_MAP) && \ - !defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) -# error One of: CYCLES_NO_UNORDERED_MAP, CYCLES_TR1_UNORDERED_MAP,\ - CYCLES_STD_UNORDERED_MAP, CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE must be defined! // NOLINT -# endif -#endif +#include #if defined(_MSC_VER) && (_MSC_VER >= 1900) # include @@ -44,19 +27,8 @@ CCL_NAMESPACE_BEGIN using std::set; -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -using std::unordered_set; -#else -# if defined(CYCLES_NO_UNORDERED_MAP) -typedef std::set unordered_set; -# endif -# if defined(CYCLES_TR1_UNORDERED_MAP) || defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) -using std::tr1::unordered_set; -# endif -# if defined(CYCLES_STD_UNORDERED_MAP) using std::unordered_set; -# endif -#endif + CCL_NAMESPACE_END #endif /* __UTIL_SET_H__ */ diff --git a/intern/cycles/util/util_static_assert.h b/intern/cycles/util/util_static_assert.h index e90049254de..dc3cb3f6ecc 100644 --- a/intern/cycles/util/util_static_assert.h +++ b/intern/cycles/util/util_static_assert.h @@ -22,27 +22,7 @@ CCL_NAMESPACE_BEGIN /* TODO(sergey): In theory CUDA might work with own static assert * implementation since it's just pure C++. */ -#ifndef __KERNEL_GPU__ -# if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -/* C++11 has built-in static_assert() */ -# elif defined(static_assert) -/* Some platforms might have static_assert() defined even tho their - * C++ support wouldn't be declared to be C++11. - */ -# else /* C++11 or MSVC2015 */ -template class StaticAssertFailure; -template <> class StaticAssertFailure {}; -# define _static_assert_private_glue_impl(A, B) A ## B -# define _static_assert_glue(A, B) _static_assert_private_glue_impl(A, B) -# ifdef __COUNTER__ -# define static_assert(condition, message) \ - enum {_static_assert_glue(q_static_assert_result, __COUNTER__) = sizeof(StaticAssertFailure)} // NOLINT -# else /* __COUNTER__ */ -# define static_assert(condition, message) \ - enum {_static_assert_glue(q_static_assert_result, __LINE__) = sizeof(StaticAssertFailure)} // NOLINT -# endif /* __COUNTER__ */ -# endif /* C++11 or MSVC2015 */ -#else /* __KERNEL_GPU__ */ +#ifdef __KERNEL_GPU__ # ifndef static_assert # define static_assert(statement, message) # endif diff --git a/intern/cycles/util/util_thread.cpp b/intern/cycles/util/util_thread.cpp index c66aa484264..16a8591a8a9 100644 --- a/intern/cycles/util/util_thread.cpp +++ b/intern/cycles/util/util_thread.cpp @@ -26,11 +26,7 @@ thread::thread(function run_cb, int group) joined_(false), group_(group) { -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) thread_ = std::thread(&thread::run, this); -#else - pthread_create(&pthread_id_, NULL, run, (void*)this); -#endif } thread::~thread() @@ -64,7 +60,6 @@ void *thread::run(void *arg) bool thread::join() { joined_ = true; -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) try { thread_.join(); return true; @@ -72,9 +67,6 @@ bool thread::join() catch (const std::system_error&) { return false; } -#else - return pthread_join(pthread_id_, NULL) == 0; -#endif } CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h index 77b51d37ea0..f39fcfb4279 100644 --- a/intern/cycles/util/util_thread.h +++ b/intern/cycles/util/util_thread.h @@ -17,15 +17,10 @@ #ifndef __UTIL_THREAD_H__ #define __UTIL_THREAD_H__ -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# include -# include -# include -# include -#else -# include -# include -#endif +#include +#include +#include +#include #include #ifdef _WIN32 @@ -42,16 +37,9 @@ CCL_NAMESPACE_BEGIN -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) typedef std::mutex thread_mutex; typedef std::unique_lock thread_scoped_lock; typedef std::condition_variable thread_condition_variable; -#else -/* use boost for mutexes */ -typedef boost::mutex thread_mutex; -typedef boost::mutex::scoped_lock thread_scoped_lock; -typedef boost::condition_variable thread_condition_variable; -#endif /* own pthread based implementation, to avoid boost version conflicts with * dynamically loaded blender plugins */ @@ -66,11 +54,7 @@ public: protected: function run_cb_; -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) std::thread thread_; -#else - pthread_t pthread_id_; -#endif bool joined_; int group_; }; diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 569f503b66e..0b33221ad4d 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -59,11 +59,7 @@ public: void shrink_to_fit(void) { -#if __cplusplus < 201103L - vector().swap(*this); -#else std::vector::shrink_to_fit(); -#endif } void free_memory(void) diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc index 87545007870..f2ae1c831d1 100644 --- a/source/blender/alembic/intern/abc_customdata.cc +++ b/source/blender/alembic/intern/abc_customdata.cc @@ -26,14 +26,7 @@ #include #include - -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1900) #include -typedef std::unordered_map uv_index_map; -#else -#include -typedef std::map uv_index_map; -#endif extern "C" { #include "DNA_customdata_types.h" @@ -60,6 +53,8 @@ using Alembic::AbcGeom::OV2fGeomParam; using Alembic::AbcGeom::OC4fGeomParam; +typedef std::unordered_map uv_index_map; + static inline uint64_t uv_to_hash_key(Imath::V2f v) { /* Convert -0.0f to 0.0f, so bitwise comparison works. */ diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h index 0726e3bb343..2b53975a106 100644 --- a/source/blender/blenlib/BLI_compiler_compat.h +++ b/source/blender/blenlib/BLI_compiler_compat.h @@ -32,11 +32,7 @@ # define alloca _alloca #endif -#if defined(__cplusplus) && ((__cplusplus >= 201103L) || defined(_MSC_VER)) -# define HAS_CPP11_FEATURES -#endif - -#if (defined(__GNUC__) || defined(__clang__)) && defined(HAS_CPP11_FEATURES) +#if (defined(__GNUC__) || defined(__clang__)) && defined(__cplusplus) extern "C++" { /* Some magic to be sure we don't have reference in the type. */ template static inline T decltype_helper(T x) { return x; } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 50c0910ef02..ced045e9e2f 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -100,28 +100,6 @@ set(SRC util/deg_util_function.h ) -if(WITH_CXX11) - add_definitions(-DDEG_STD_UNORDERED_MAP) -elseif(HAVE_STD_UNORDERED_MAP_HEADER) - if(HAVE_UNORDERED_MAP_IN_STD_NAMESPACE) - add_definitions(-DDEG_STD_UNORDERED_MAP) - else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - add_definitions(-DDEG_STD_UNORDERED_MAP_IN_TR1_NAMESPACE) - else() - add_definitions(-DDEG_NO_UNORDERED_MAP) - message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)") - endif() - endif() -else() - if(HAVE_UNORDERED_MAP_IN_TR1_NAMESPACE) - add_definitions(-DDEG_TR1_UNORDERED_MAP) - else() - add_definitions(-DDEG_NO_UNORDERED_MAP) - message(STATUS "Replacing unordered_map/set with map/set (warning: slower!)") - endif() -endif() - if(WITH_LEGACY_DEPSGRAPH) add_definitions(-DWITH_LEGACY_DEPSGRAPH) endif() diff --git a/source/blender/depsgraph/util/deg_util_foreach.h b/source/blender/depsgraph/util/deg_util_foreach.h index cb7361fc708..5484192207b 100644 --- a/source/blender/depsgraph/util/deg_util_foreach.h +++ b/source/blender/depsgraph/util/deg_util_foreach.h @@ -30,19 +30,4 @@ #pragma once -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800) -# define foreach(x, y) for(x : y) -#elif defined(HAVE_BOOST_FUNCTION_BINDINGS) -# include -# define foreach BOOST_FOREACH -#else -#pragma message("No available foreach() implementation. Using stub instead, disabling new depsgraph") - -#ifndef WITH_LEGACY_DEPSGRAPH -# error "Unable to build new depsgraph and legacy one is disabled." -#endif - -#define DISABLE_NEW_DEPSGRAPH - -# define foreach(x, y) for (x; false; (void)y) -#endif +#define foreach(x, y) for(x : y) diff --git a/source/blender/depsgraph/util/deg_util_function.h b/source/blender/depsgraph/util/deg_util_function.h index 38e753ce925..8863d92eb74 100644 --- a/source/blender/depsgraph/util/deg_util_function.h +++ b/source/blender/depsgraph/util/deg_util_function.h @@ -30,81 +30,8 @@ #pragma once -#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1900) - #include using std::function; using namespace std::placeholders; #define function_bind std::bind - -#elif defined(HAVE_BOOST_FUNCTION_BINDINGS) - -#include -#include - -using boost::function; -#define function_bind boost::bind - -#else - -#pragma message("No available function binding implementation. Using stub instead, disabling new depsgraph") - -#ifndef WITH_LEGACY_DEPSGRAPH -# error "Unable to build new depsgraph and legacy one is disabled." -#endif - -#define DISABLE_NEW_DEPSGRAPH - -#include "BLI_utildefines.h" -#include - -template -class function { -public: - function() {}; - function(void *) {} - operator bool() const { return false; } - bool operator== (void *) { return false; } - - template - void operator() (T1) { - BLI_assert(!"Should not be used"); - } -}; - -class Wrap { -public: - Wrap() {} - template - Wrap(T /*arg*/) {} -}; - -template -void *function_bind(T func, - Wrap arg1 = Wrap(), - Wrap arg2 = Wrap(), - Wrap arg3 = Wrap(), - Wrap arg4 = Wrap(), - Wrap arg5 = Wrap(), - Wrap arg6 = Wrap(), - Wrap arg7 = Wrap()) -{ - BLI_assert(!"Should not be used"); - (void)func; - (void)arg1; - (void)arg2; - (void)arg3; - (void)arg4; - (void)arg5; - (void)arg6; - (void)arg7; - return NULL; -} - -#define _1 Wrap() -#define _2 Wrap() -#define _3 Wrap() -#define _4 Wrap() - -#endif -- cgit v1.2.3 From dee31f2cb0c3eacbd1d7a33c7fbaf3841e4a7623 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jul 2018 17:42:28 +0200 Subject: Minor cleanup. --- source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index b5b33900105..ee814e11d40 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -719,13 +719,12 @@ static void deg_update_copy_on_write_animation(const Depsgraph *depsgraph, } typedef struct ObjectRuntimeBackup { - CurveCache *curve_cache; Object_Runtime runtime; short base_flag; } ObjectRuntimeBackup; /* Make a backup of object's evaluation runtime data, additionally - * male object to be safe for free without invalidating backed up + * make object to be safe for free without invalidating backed up * pointers. */ static void deg_backup_object_runtime( -- cgit v1.2.3 From f08f6c1adecd5f65c77a33213be3a1bd80968473 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 31 Jul 2018 03:48:37 +1200 Subject: Clean Keyframes operator tweaks By popular demand, the CLean Keyframes operator will now leave handles and other interpolation settings untouched. Previously, it would recreate the keyframes from scratch, keeping only the frame + value, under the assumption that the handle information was "bad" (i.e. the source of bumps and roughness, due to bad hand tweaking). However, since most animators use this on hand-keyed animation instead of motion-capture data, this assumption didn't hold, and was actually overly destructive - wiping out lots of hand-adjusted curve data. --- source/blender/editors/animation/keyframes_general.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index a6ed6643257..b98feac2384 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -183,7 +183,8 @@ void duplicate_fcurve_keys(FCurve *fcu) /* Various Tools */ /* Basic F-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on linear-segments only - * optionally clears up curve if one keyframe with default value remains */ + * optionally clears up curve if one keyframe with default value remains + */ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault) { FCurve *fcu = (FCurve *)ale->key_data; @@ -206,7 +207,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo /* now insert first keyframe, as it should be ok */ bezt = old_bezts; - insert_vert_fcurve(fcu, bezt->vec[1][0], bezt->vec[1][1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); if (!(bezt->f2 & SELECT)) { lastb = fcu->bezt; lastb->f1 = lastb->f2 = lastb->f3 = 0; @@ -235,7 +236,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1]; if (!(bezt->f2 & SELECT)) { - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); lastb = (fcu->bezt + (fcu->totvert - 1)); lastb->f1 = lastb->f2 = lastb->f3 = 0; continue; @@ -254,7 +255,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo if (cur[1] > next[1]) { if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); } } } @@ -262,7 +263,7 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo /* only add if values are a considerable distance apart */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); } } } @@ -271,19 +272,19 @@ void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, boo if (beztn) { /* does current have same value as previous and next? */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { - /* add new keyframe*/ - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + /* add new keyframe */ + insert_bezt_fcurve(fcu, bezt, 0); } else if (IS_EQT(cur[1], next[1], thresh) == 0) { /* add new keyframe */ - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); } } else { /* add if value doesn't equal that of previous */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_vert_fcurve(fcu, cur[0], cur[1], BEZKEYTYPE(bezt), 0); + insert_bezt_fcurve(fcu, bezt, 0); } } } -- cgit v1.2.3 From cc397b918ff1b2a51b3b82367506eb7684860cea Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Jul 2018 18:25:01 +0200 Subject: UI: make horizontal wheel scroll in 2D view match vertical scroll speed. --- source/blender/editors/interface/view2d_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index dfc401c1635..1c56dabb396 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -354,7 +354,7 @@ static int view_scrollright_exec(bContext *C, wmOperator *op) } /* set RNA-Props - only movement in positive x-direction */ - RNA_int_set(op->ptr, "deltax", 20); + RNA_int_set(op->ptr, "deltax", 40); RNA_int_set(op->ptr, "deltay", 0); /* apply movement, then we're done */ @@ -398,7 +398,7 @@ static int view_scrollleft_exec(bContext *C, wmOperator *op) } /* set RNA-Props - only movement in negative x-direction */ - RNA_int_set(op->ptr, "deltax", -20); + RNA_int_set(op->ptr, "deltax", -40); RNA_int_set(op->ptr, "deltay", 0); /* apply movement, then we're done */ -- cgit v1.2.3 From c86b5fa820d181c2beabdf4147ac17cb6ff8149b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Jul 2018 15:44:25 +0200 Subject: Viewport: use Filmic without scene exposure/gamma/curves for workbench. This ignores the scene color managment view settings for solid mode and lookdev when not using scene lights and world. The scene settings are intended for tweaking renders and should not affect studio lighting and matcaps. There may be cases where a simple sRGB transform is better than Filmic and we could add configuration for this. Not sure if it really matters and it may be better if we just assume matcaps and studiolights are all created for one view transform. Differential Revision: https://developer.blender.org/D3569 --- release/datafiles/colormanagement/config.ocio | 2 +- source/blender/draw/engines/eevee/eevee_engine.c | 23 ++++++++++++---------- source/blender/draw/engines/eevee/eevee_private.h | 3 +++ .../draw/engines/workbench/workbench_data.c | 3 +++ .../draw/engines/workbench/workbench_effect_aa.c | 12 +++++------ .../draw/engines/workbench/workbench_private.h | 3 +++ source/blender/draw/intern/DRW_render.h | 2 +- source/blender/draw/intern/draw_manager.c | 7 +++++-- 8 files changed, 35 insertions(+), 20 deletions(-) diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index ce79dfeb540..c8466ab99fc 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -70,7 +70,7 @@ displays: - ! {name: Default, colorspace: Raw} active_displays: [sRGB, DCIP3, Rec709, XYZ, None] -active_views: [Default, RRT, Raw, Log] +active_views: [Filmic, Default, RRT, Raw, Log] colorspaces: - ! diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index adbe165354a..8c66ba057b5 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -66,6 +66,7 @@ static void eevee_engine_init(void *ved) /* Alloc transient pointers */ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } + stl->g_data->use_color_view_settings = USE_SCENE_LIGHT(v3d) || !LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d); stl->g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f; stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL); @@ -316,37 +317,39 @@ static void eevee_draw_background(void *vedata) /* Tonemapping and transfer result to default framebuffer. */ + bool use_view_settings = stl->g_data->use_color_view_settings; + GPU_framebuffer_bind(dfbl->default_fb); - DRW_transform_to_display(stl->effects->final_tx); + DRW_transform_to_display(stl->effects->final_tx, use_view_settings); /* Debug : Ouput buffer to view. */ switch (G.debug_value) { case 1: - if (txl->maxzbuffer) DRW_transform_to_display(txl->maxzbuffer); + if (txl->maxzbuffer) DRW_transform_to_display(txl->maxzbuffer, use_view_settings); break; case 2: - if (effects->ssr_pdf_output) DRW_transform_to_display(effects->ssr_pdf_output); + if (effects->ssr_pdf_output) DRW_transform_to_display(effects->ssr_pdf_output, use_view_settings); break; case 3: - if (effects->ssr_normal_input) DRW_transform_to_display(effects->ssr_normal_input); + if (effects->ssr_normal_input) DRW_transform_to_display(effects->ssr_normal_input, use_view_settings); break; case 4: - if (effects->ssr_specrough_input) DRW_transform_to_display(effects->ssr_specrough_input); + if (effects->ssr_specrough_input) DRW_transform_to_display(effects->ssr_specrough_input, use_view_settings); break; case 5: - if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer); + if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer, use_view_settings); break; case 6: - if (effects->gtao_horizons_debug) DRW_transform_to_display(effects->gtao_horizons_debug); + if (effects->gtao_horizons_debug) DRW_transform_to_display(effects->gtao_horizons_debug, use_view_settings); break; case 7: - if (effects->gtao_horizons) DRW_transform_to_display(effects->gtao_horizons); + if (effects->gtao_horizons) DRW_transform_to_display(effects->gtao_horizons, use_view_settings); break; case 8: - if (effects->sss_data) DRW_transform_to_display(effects->sss_data); + if (effects->sss_data) DRW_transform_to_display(effects->sss_data, use_view_settings); break; case 9: - if (effects->velocity_tx) DRW_transform_to_display(effects->velocity_tx); + if (effects->velocity_tx) DRW_transform_to_display(effects->velocity_tx, use_view_settings); break; default: break; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 349a27a1765..bd1323dab3b 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -774,6 +774,9 @@ typedef struct EEVEE_PrivateData { /* Mist Settings */ float mist_start, mist_inv_dist, mist_falloff; + + /* Color Management */ + bool use_color_view_settings; } EEVEE_PrivateData; /* Transient data */ /* eevee_data.c */ diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 24eb0f38a46..2b716b8ffe3 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -21,14 +21,17 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) View3D *v3d = draw_ctx->v3d; if (!v3d) { wpd->shading = scene->display.shading; + wpd->use_color_view_settings = true; } else if (v3d->shading.type == OB_RENDER && BKE_scene_uses_blender_opengl(scene)) { wpd->shading = scene->display.shading; + wpd->use_color_view_settings = true; } else { wpd->shading = v3d->shading; + wpd->use_color_view_settings = false; } if (wpd->shading.light == V3D_LIGHTING_MATCAP) { diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c index 6269496f568..deb9a517f96 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_aa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -56,7 +56,7 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) } } -static void workspace_aa_draw_transform(GPUTexture *tx) +static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *wpd) { if (DRW_state_is_image_render()) { /* Linear result for render. */ @@ -64,7 +64,7 @@ static void workspace_aa_draw_transform(GPUTexture *tx) } else { /* Display space result for viewport. */ - DRW_transform_to_display(tx); + DRW_transform_to_display(tx, wpd->use_color_view_settings); } } @@ -79,7 +79,7 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (FXAA_ENABLED(wpd)) { GPU_framebuffer_bind(fbl->effect_fb); - workspace_aa_draw_transform(tx); + workspace_aa_draw_transform(tx, wpd); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -92,11 +92,11 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) */ if (effect_info->jitter_index == 1) { GPU_framebuffer_bind(dfbl->color_only_fb); - workspace_aa_draw_transform(tx); + workspace_aa_draw_transform(tx, wpd); } else { GPU_framebuffer_bind(fbl->effect_fb); - workspace_aa_draw_transform(tx); + workspace_aa_draw_transform(tx, wpd); GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->effect_aa_pass); } @@ -104,6 +104,6 @@ void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) } else { GPU_framebuffer_bind(dfbl->color_only_fb); - workspace_aa_draw_transform(tx); + workspace_aa_draw_transform(tx, wpd); } } diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index dc2894f0207..10ea0152b90 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -187,6 +187,9 @@ typedef struct WORKBENCH_PrivateData { float viewvecs[3][4]; float ssao_params[4]; float ssao_settings[4]; + + /* Color Management */ + bool use_color_view_settings; } WORKBENCH_PrivateData; /* Transient data */ typedef struct WORKBENCH_EffectInfo { diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index d2c44cfef2a..0db16ab5472 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -234,7 +234,7 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } \ } while (0) -void DRW_transform_to_display(struct GPUTexture *tex); +void DRW_transform_to_display(struct GPUTexture *tex, bool use_view_settings); void DRW_transform_none(struct GPUTexture *tex); void DRW_multisamples_resolve( struct GPUTexture *src_depth, struct GPUTexture *src_color, bool use_depth); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 87239e7d93e..714edc23719 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -224,7 +224,7 @@ bool DRW_check_psys_visible_within_active_context( * \{ */ /* Use color management profile to draw texture to framebuffer */ -void DRW_transform_to_display(GPUTexture *tex) +void DRW_transform_to_display(GPUTexture *tex, bool use_view_settings) { drw_state_set(DRW_STATE_WRITE_COLOR); @@ -239,8 +239,11 @@ void DRW_transform_to_display(GPUTexture *tex) /* View transform is already applied for offscreen, don't apply again, see: T52046 */ if (!(DST.options.is_image_render && !DST.options.is_scene_render)) { Scene *scene = DST.draw_ctx.scene; + ColorManagedDisplaySettings *display_settings = &scene->display_settings; + ColorManagedViewSettings *view_settings = (use_view_settings) ? &scene->view_settings : NULL; + use_ocio = IMB_colormanagement_setup_glsl_draw_from_space( - &scene->view_settings, &scene->display_settings, NULL, dither, false); + view_settings, display_settings, NULL, dither, false); } if (!use_ocio) { -- cgit v1.2.3 From 06e9d1683b76fa6c236f589671121c752e5cb374 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 30 Jul 2018 23:01:20 +0200 Subject: Fix build error in new build after recent merge. --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 419da9d94b7..708e5192c19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -601,12 +601,6 @@ if(NOT WITH_BLENDER AND NOT WITH_CYCLES_STANDALONE) ) endif() -if(NOT WITH_CXX11) - if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE) - message(FATAL_ERROR "WITH_AUDASPACE requires WITH_CXX11") - endif() -endif() - if(NOT WITH_AUDASPACE) if(WITH_OPENAL) message(WARNING "WITH_OPENAL requires WITH_AUDASPACE which is disabled") -- cgit v1.2.3 From 1195a4a040ba8ecffd3221f5aa38c7be5272124b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 10:37:46 +1000 Subject: UI: add check for any kind of popup Fixes T56155 when merging into 2.8 --- source/blender/editors/interface/interface_context_menu.c | 2 +- source/blender/editors/interface/interface_intern.h | 1 + source/blender/editors/interface/interface_query.c | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 0306139bac0..54e755f6cc6 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -533,7 +533,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) } /* Show header tools for header buttons. */ - if (ui_block_is_menu(but->block) == false) { + if (ui_block_is_popup_any(but->block) == false) { ARegion *ar = CTX_wm_region(C); if (ar && (ar->regiontype == RGN_TYPE_HEADER)) { uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index dc5e100b5f2..75f2efdf3aa 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -752,6 +752,7 @@ bool ui_but_is_toggle(const uiBut *but); extern bool ui_block_is_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; extern bool ui_block_is_pie_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; +extern bool ui_block_is_popup_any(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; /* interface_context_menu.c */ bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but); diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index f7dbb9b14ed..1ad4a7d7f31 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -86,6 +86,14 @@ bool ui_block_is_pie_menu(const uiBlock *block) return ((block->flag & UI_BLOCK_RADIAL) != 0); } +bool ui_block_is_popup_any(const uiBlock *block) +{ + return ( + ui_block_is_menu(block) || + ui_block_is_pie_menu(block) + ); +} + bool UI_block_is_empty(const uiBlock *block) { for (const uiBut *but = block->buttons.first; but; but = but->next) { -- cgit v1.2.3 From 0c955ed6eab2544ebad8823e509cc348b33c3556 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 10:45:35 +1000 Subject: Fix T56155: Header shows in popover context menu --- source/blender/editors/interface/interface_intern.h | 1 + source/blender/editors/interface/interface_query.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 4f260c35797..d4fccc48bfc 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -831,6 +831,7 @@ bool ui_but_is_toggle(const uiBut *but); bool ui_but_is_popover_once_compat(const uiBut *but); extern bool ui_block_is_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; +extern bool ui_block_is_popover(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; extern bool ui_block_is_pie_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; extern bool ui_block_is_popup_any(const uiBlock *block) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index 8893a5e17cc..d0f7e1341de 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -109,6 +109,11 @@ bool ui_block_is_menu(const uiBlock *block) ((block->flag & UI_BLOCK_KEEP_OPEN) == 0)); } +bool ui_block_is_popover(const uiBlock *block) +{ + return (block->flag & UI_BLOCK_POPOVER) != 0; +} + bool ui_block_is_pie_menu(const uiBlock *block) { return ((block->flag & UI_BLOCK_RADIAL) != 0); @@ -118,6 +123,7 @@ bool ui_block_is_popup_any(const uiBlock *block) { return ( ui_block_is_menu(block) || + ui_block_is_popover(block) || ui_block_is_pie_menu(block) ); } -- cgit v1.2.3 From 52c23021c4367511969c5868ea04e61fb49e94d3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 12:59:48 +1000 Subject: UI: consistent names for edit-mode overlay --- release/scripts/startup/bl_ui/space_view3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 8f77305994a..aed5faff73c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -4360,7 +4360,7 @@ class VIEW3D_PT_overlay_edit_curve(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'HEADER' bl_parent_id = 'VIEW3D_PT_overlay' - bl_label = "Edit Curve" + bl_label = "Curve Edit Mode" @classmethod def poll(cls, context): @@ -4435,7 +4435,7 @@ class VIEW3D_PT_overlay_edit_armature(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'HEADER' bl_parent_id = 'VIEW3D_PT_overlay' - bl_label = "Edit Armature" + bl_label = "Armature Edit Mode" @classmethod def poll(cls, context): -- cgit v1.2.3 From 18888b7b0c3556d3a2177fe7693fda02bf2a8cb5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 16:05:31 +1000 Subject: UI: use text hinting (now user preference) D3201 by @ambient w/ edits not to impact fonts used for rendering (only change display for UI text). --- release/scripts/startup/bl_ui/space_userpref.py | 2 ++ source/blender/editors/interface/interface_style.c | 22 ++++++++++++++++++++++ source/blender/makesdna/DNA_userdef_types.h | 3 ++- source/blender/makesrna/intern/rna_userdef.c | 6 ++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index ee1dcae29a1..e0902dd8636 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -539,6 +539,8 @@ class USERPREF_PT_system(Panel): col.label(text="Text Draw Options:") col.prop(system, "use_text_antialiasing") + if system.use_text_antialiasing: + col.prop(system, "use_text_hinting") col.separator() diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index eabc5150424..9a09ae67601 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -521,6 +521,28 @@ void uiStyleInit(void) BLF_size(blf_mono_font, 12 * U.pixelsize, 72); + /* Set default flags based on UI preferences (not render fonts) */ + { + int flag_enable = 0, flag_disable = 0; + if ((U.text_render & USER_TEXT_DISABLE_HINTING) == 0) { + flag_enable |= BLF_HINTING; + } + else { + flag_disable |= BLF_HINTING; + } + + for (font = U.uifonts.first; font; font = font->next) { + if (font->blf_id != -1) { + BLF_enable(font->blf_id, flag_enable); + BLF_disable(font->blf_id, flag_disable); + } + } + if (blf_mono_font != -1) { + BLF_enable(blf_mono_font, flag_enable); + BLF_disable(blf_mono_font, flag_disable); + } + } + /** * Second for rendering else we get threading problems, * diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 2d52c1a67de..6f0f97261ee 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -804,7 +804,8 @@ typedef enum eWM_DrawMethod { /* text draw options * UserDef.text_render */ typedef enum eText_Draw_Options { - USER_TEXT_DISABLE_AA = (1 << 0), + USER_TEXT_DISABLE_AA = (1 << 0), + USER_TEXT_DISABLE_HINTING = (1 << 1), } eText_Draw_Options; /* tw_flag (transform widget) */ diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 487f62cdfe6..739303e20ea 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -447,6 +447,7 @@ static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P static void rna_userdef_text_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { BLF_cache_clear(); + UI_reinit_font(); WM_main_add_notifier(NC_WINDOW, NULL); } @@ -4212,6 +4213,11 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased"); RNA_def_property_update(prop, 0, "rna_userdef_text_antialiasing_update"); + prop = RNA_def_property(srna, "use_text_hinting", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "text_render", USER_TEXT_DISABLE_HINTING); + RNA_def_property_ui_text(prop, "Text Hinting", "Draw user interface text with hinting"); + RNA_def_property_update(prop, 0, "rna_userdef_text_update"); + prop = RNA_def_property(srna, "select_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "gpu_select_method"); RNA_def_property_enum_items(prop, gpu_select_method_items); -- cgit v1.2.3 From b51dcb6f07f34c904b036887e24f96542d9fb76d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 16:44:35 +1000 Subject: Fix crash w/ missing matcaps Building w/o EXR caused this. --- source/blender/draw/engines/workbench/workbench_data.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index 2b716b8ffe3..49cdab256f0 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -42,6 +42,13 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->studio_light = BKE_studiolight_find( wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); } + + /* If matcaps are missing, use this as fallback. */ + if (UNLIKELY(wpd->studio_light == NULL)) { + wpd->studio_light = BKE_studiolight_find( + wpd->shading.studio_light, STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD); + } + wpd->shadow_multiplier = 1.0 - wpd->shading.shadow_intensity; WORKBENCH_UBO_World *wd = &wpd->world_data; -- cgit v1.2.3 From 21f61cbe73a1bc24d2e74b82b039ea5f36c960a5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 16:57:05 +1000 Subject: BLF: replace global aa pref w/ monochrome flag Now disabling anti-aliasing doesn't impact sequencer, render stamp etc. --- source/blender/blenfont/BLF_api.h | 4 +--- source/blender/blenfont/intern/blf.c | 11 ----------- source/blender/blenfont/intern/blf_glyph.c | 11 ++++++----- source/blender/editors/interface/interface_style.c | 7 +++++++ source/blender/makesrna/intern/rna_userdef.c | 8 +------- source/blender/python/generic/blf_py_api.c | 1 + source/blender/windowmanager/intern/wm_files.c | 2 -- 7 files changed, 16 insertions(+), 28 deletions(-) diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index eafcf74b611..9bb3dd39aa6 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -44,9 +44,6 @@ void BLF_exit(void); void BLF_default_dpi(int dpi); void BLF_default_set(int fontid); -void BLF_antialias_set(bool enabled); -bool BLF_antialias_get(void); - void BLF_cache_clear(void); int BLF_load(const char *name) ATTR_NONNULL(); @@ -223,6 +220,7 @@ void BLF_state_print(int fontid); #define BLF_ASPECT (1 << 5) #define BLF_HINTING (1 << 6) #define BLF_WORD_WRAP (1 << 7) +#define BLF_MONOCHROME (1 << 8) /* no-AA */ #define BLF_DRAW_STR_DUMMY_MAX 1024 diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 2a8fc14f4ae..75aabf1f713 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -84,7 +84,6 @@ static FontBLF *global_font[BLF_MAX_FONT] = {NULL}; static int global_font_default = -1; static int global_font_points = 11; static int global_font_dpi = 72; -static bool global_use_antialias = true; /* XXX, should these be made into global_font_'s too? */ int blf_mono_font = -1; @@ -176,16 +175,6 @@ void BLF_default_set(int fontid) } } -void BLF_antialias_set(bool enabled) -{ - global_use_antialias = enabled; -} - -bool BLF_antialias_get(void) -{ - return global_use_antialias; -} - int BLF_load(const char *name) { FontBLF *font; diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index 9af347908e1..f1301d38ab6 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -221,7 +221,6 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) GlyphBLF *g; FT_Error err; FT_Bitmap bitmap, tempbitmap; - const bool is_sharp = !BLF_antialias_get(); int flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; FT_BBox bbox; unsigned int key; @@ -246,10 +245,12 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) if (font->flags & BLF_HINTING) flags &= ~FT_LOAD_NO_HINTING; - if (is_sharp) + if (font->flags & BLF_MONOCHROME) { err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO); - else + } + else { err = FT_Load_Glyph(font->face, (FT_UInt)index, flags); + } if (err) { BLI_spin_unlock(font->ft_lib_mutex); @@ -259,7 +260,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) /* get the glyph. */ slot = font->face->glyph; - if (is_sharp) { + if (font->flags & BLF_MONOCHROME) { err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO); /* Convert result from 1 bit per pixel to 8 bit per pixel */ @@ -288,7 +289,7 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c) g->height = (int)bitmap.rows; if (g->width && g->height) { - if (is_sharp) { + if (font->flags & BLF_MONOCHROME) { /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */ int i; for (i = 0; i < (g->width * g->height); i++) { diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 9a09ae67601..0257fb0d428 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -531,6 +531,13 @@ void uiStyleInit(void) flag_disable |= BLF_HINTING; } + if (U.text_render & USER_TEXT_DISABLE_AA) { + flag_enable |= BLF_MONOCHROME; + } + else { + flag_disable |= BLF_MONOCHROME; + } + for (font = U.uifonts.first; font; font = font->next) { if (font->blf_id != -1) { BLF_enable(font->blf_id, flag_enable); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 739303e20ea..315ac26c1d2 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -451,12 +451,6 @@ static void rna_userdef_text_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P WM_main_add_notifier(NC_WINDOW, NULL); } -static void rna_userdef_text_antialiasing_update(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - BLF_antialias_set((U.text_render & USER_TEXT_DISABLE_AA) == 0); - rna_userdef_text_update(bmain, scene, ptr); -} - static PointerRNA rna_Theme_space_generic_get(PointerRNA *ptr) { return rna_pointer_inherit_refine(ptr, &RNA_ThemeSpaceGeneric, ptr->data); @@ -4211,7 +4205,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) prop = RNA_def_property(srna, "use_text_antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "text_render", USER_TEXT_DISABLE_AA); RNA_def_property_ui_text(prop, "Text Anti-aliasing", "Draw user interface text anti-aliased"); - RNA_def_property_update(prop, 0, "rna_userdef_text_antialiasing_update"); + RNA_def_property_update(prop, 0, "rna_userdef_text_update"); prop = RNA_def_property(srna, "use_text_hinting", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "text_render", USER_TEXT_DISABLE_HINTING); diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index 629335888e4..7d124966334 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -461,6 +461,7 @@ PyObject *BPyInit_blf(void) PyModule_AddIntConstant(submodule, "SHADOW", BLF_SHADOW); PyModule_AddIntConstant(submodule, "KERNING_DEFAULT", BLF_KERNING_DEFAULT); PyModule_AddIntConstant(submodule, "WORD_WRAP", BLF_WORD_WRAP); + PyModule_AddIntConstant(submodule, "MONOCHROME", BLF_MONOCHROME); return submodule; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 19b48e3f79e..a802c695dd1 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -343,8 +343,6 @@ static void wm_init_userdef(Main *bmain, const bool read_userdef_from_memory) /* update tempdir from user preferences */ BKE_tempdir_init(U.tempdir); - - BLF_antialias_set((U.text_render & USER_TEXT_DISABLE_AA) == 0); } -- cgit v1.2.3 From 51c38b5d495e406a0c13216470927c5ce0f71e4f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 25 Jul 2018 16:51:48 +0200 Subject: Subsurf: Rework in a way that patches boundaries are merged together The idea is to create vertices along the coarse edges once, without splitting coarse edges on separate ptex faces. This requires some indexing magic, vertices within a patch are no longer sequential. Not sure how to make it nicer without such a black magic looking calculations (which are basically boiling down to mimicking order of verts/edges creation). In the current offsets calculation loose verts and edges are not properly taken into account, but those are causing topology refiner to fail anyway, so it needs a bit deeper change. Reviewers: brecht Differential Revision: https://developer.blender.org/D3570 --- source/blender/blenkernel/BKE_subdiv.h | 3 + source/blender/blenkernel/intern/subdiv_mesh.c | 1707 +++++++++++++++++++---- source/blender/blenkernel/intern/subdiv_stats.c | 4 + source/blender/blenlib/BLI_bitmap.h | 6 + source/blender/modifiers/intern/MOD_subsurf.c | 2 +- 5 files changed, 1464 insertions(+), 258 deletions(-) diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 003dc7a37d3..ad829946db8 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -57,6 +57,7 @@ typedef struct SubdivSettings { typedef enum eSubdivStatsValue { SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME = 0, SUBDIV_STATS_SUBDIV_TO_MESH, + SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY, SUBDIV_STATS_EVALUATOR_CREATE, SUBDIV_STATS_EVALUATOR_REFINE, @@ -73,6 +74,8 @@ typedef struct SubdivStats { double topology_refiner_creation_time; /* Total time spent in BKE_subdiv_to_mesh(). */ double subdiv_to_mesh_time; + /* Geometry (MVert and co) creation time during SUBDIV_TYO_MESH. */ + double subdiv_to_mesh_geometry_time; /* Time spent on evaluator creation from topology refiner. */ double evaluator_creation_time; /* Time spent on evaluator->refine(). */ diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 76f41d512bc..40c95964fb3 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -29,10 +29,13 @@ #include "BKE_subdiv.h" +#include "atomic_ops.h" + #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "BLI_alloca.h" +#include "BLI_bitmap.h" #include "BLI_math_vector.h" #include "BLI_task.h" @@ -55,6 +58,15 @@ BLI_INLINE int num_edges_per_ptex_face_get(const int resolution) return 2 * (resolution - 1) * resolution; } +BLI_INLINE int num_inner_edges_per_ptex_face_get(const int resolution) +{ + if (resolution < 2) { + return 0; + } + return (resolution - 2) * resolution + + (resolution - 1) * (resolution - 1); +} + /* Number of subdivision polygons per ptex face. */ BLI_INLINE int num_polys_per_ptex_get(const int resolution) { @@ -85,7 +97,19 @@ typedef struct SubdivMeshContext { /* UV layers interpolation. */ int num_uv_layers; MLoopUV *uv_layers[MAX_MTFACE]; - + /* Counters of geometry in subdivided mesh, initialized as a part of + * offsets calculation. + */ + int num_subdiv_vertices; + int num_subdiv_edges; + int num_subdiv_loops; + int num_subdiv_polygons; + /* Offsets of various geometry in the subdivision mesh arrays. */ + int vertices_corner_offset; + int vertices_edge_offset; + int vertices_inner_offset; + int edge_boundary_offset; + int edge_inner_offset; /* Indexed by coarse polygon index, indicates offset in subdivided mesh * vertices, edges and polygons arrays, where first element of the poly * begins. @@ -97,14 +121,18 @@ typedef struct SubdivMeshContext { * created for preceding base faces. */ int *face_ptex_offset; - - /* Counters of geometry in subdivided mesh, initialized as a part of - * offsets calculation. + /* Bitmap indicating whether vertex was used already or not. + * - During patch evaluation indicates whether coarse vertex was already + * evaluated and its position on limit is already known. */ - int num_subdiv_vertices; - int num_subdiv_edges; - int num_subdiv_loops; - int num_subdiv_polygons; + BLI_bitmap *coarse_vertices_used_map; + /* Bitmap indicating whether edge was used already or not. This includes: + * - During context initialization it indicates whether subdivided verticies + * for corresponding edge were already calculated or not. + * - During patch evaluation it indicates whether vertices along this edge + * were already evaluated. + */ + BLI_bitmap *coarse_edges_used_map; } SubdivMeshContext; static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) @@ -134,60 +162,162 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) subdiv_mesh_ctx_cache_uv_layers(ctx); } +/* NOTE: Expects edge map to be zeroed. */ +static void subdiv_mesh_ctx_count(SubdivMeshContext *ctx) +{ + /* Reset counters. */ + ctx->num_subdiv_vertices = 0; + ctx->num_subdiv_edges = 0; + ctx->num_subdiv_loops = 0; + ctx->num_subdiv_polygons = 0; + /* Static geometry counters. */ + const int resolution = ctx->settings->resolution; + const int no_quad_patch_resolution = ((resolution >> 1) + 1); + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int num_inner_vertices_per_quad = (resolution - 2) * (resolution - 2); + const int num_inner_vertices_per_noquad_patch = + (no_quad_patch_resolution - 2) * (no_quad_patch_resolution - 2); + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MLoop *coarse_mloop = coarse_mesh->mloop; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + ctx->num_subdiv_vertices = coarse_mesh->totvert; + ctx->num_subdiv_edges = + coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); + for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + const int num_ptex_faces_per_poly = + num_ptex_faces_per_poly_get(coarse_poly); + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *loop = &coarse_mloop[coarse_poly->loopstart + corner]; + const bool is_edge_used = + BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, loop->e); + /* Edges which aren't counted yet. */ + if (!is_edge_used) { + BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e); + ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge; + } + } + /* Inner verticies of polygon. */ + if (num_ptex_faces_per_poly == 1) { + ctx->num_subdiv_vertices += num_inner_vertices_per_quad; + ctx->num_subdiv_edges += + num_edges_per_ptex_face_get(resolution - 2) + + 4 * num_subdiv_vertices_per_coarse_edge; + ctx->num_subdiv_polygons += num_polys_per_ptex_get(resolution); + } + else { + ctx->num_subdiv_vertices += + 1 + + num_ptex_faces_per_poly * (no_quad_patch_resolution - 2) + + num_ptex_faces_per_poly * num_inner_vertices_per_noquad_patch; + ctx->num_subdiv_edges += + num_ptex_faces_per_poly * + (num_inner_edges_per_ptex_face_get( + no_quad_patch_resolution - 1) + + (no_quad_patch_resolution - 2) + + num_subdiv_vertices_per_coarse_edge); + if (no_quad_patch_resolution >= 3) { + ctx->num_subdiv_edges += coarse_poly->totloop; + } + ctx->num_subdiv_polygons += + num_ptex_faces_per_poly * + num_polys_per_ptex_get(no_quad_patch_resolution); + } + } + ctx->num_subdiv_loops = ctx->num_subdiv_polygons * 4; +} + static void subdiv_mesh_ctx_init_offsets(SubdivMeshContext *ctx) { const Mesh *coarse_mesh = ctx->coarse_mesh; + const int resolution = ctx->settings->resolution; + const int resolution_2 = resolution - 2; + const int resolution_2_squared = resolution_2 * resolution_2; + const int no_quad_patch_resolution = ((resolution >> 1) + 1); + const int num_irregular_vertices_per_patch = + (no_quad_patch_resolution - 2) * (no_quad_patch_resolution - 1); + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int num_subdiv_edges_per_coarse_edge = resolution - 1; + /* Constant offsets in arrays. */ + ctx->vertices_corner_offset = 0; + ctx->vertices_edge_offset = coarse_mesh->totvert; + ctx->vertices_inner_offset = + ctx->vertices_edge_offset + + coarse_mesh->totedge * num_subdiv_vertices_per_coarse_edge; + ctx->edge_boundary_offset = 0; + ctx->edge_inner_offset = + ctx->edge_boundary_offset + + coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge; + /* "Indexed" offsets. */ const MPoly *coarse_mpoly = coarse_mesh->mpoly; - /* Allocate memory. */ - ctx->subdiv_vertex_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, - sizeof(*ctx->subdiv_vertex_offset), - "vertex_offset"); - ctx->subdiv_edge_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, - sizeof(*ctx->subdiv_edge_offset), - "subdiv_edge_offset"); - ctx->subdiv_polygon_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, - sizeof(*ctx->subdiv_polygon_offset), - "subdiv_polygon_offset"); - ctx->face_ptex_offset = MEM_malloc_arrayN(coarse_mesh->totpoly, - sizeof(*ctx->face_ptex_offset), - "face_ptex_offset"); - /* Fill in offsets. */ int vertex_offset = 0; int edge_offset = 0; int polygon_offset = 0; int face_ptex_offset = 0; for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; - const int ptex_face_resolution = ptex_face_resolution_get( - coarse_poly, ctx->settings->resolution); - const int ptex_face_resolution2 = - ptex_face_resolution * ptex_face_resolution; const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); + ctx->face_ptex_offset[poly_index] = face_ptex_offset; ctx->subdiv_vertex_offset[poly_index] = vertex_offset; ctx->subdiv_edge_offset[poly_index] = edge_offset; ctx->subdiv_polygon_offset[poly_index] = polygon_offset; - ctx->face_ptex_offset[poly_index] = face_ptex_offset; - vertex_offset += num_ptex_faces_per_poly * ptex_face_resolution2; - edge_offset += num_ptex_faces_per_poly * - num_edges_per_ptex_face_get(ptex_face_resolution); - polygon_offset += - num_ptex_faces_per_poly * - num_polys_per_ptex_get(ptex_face_resolution); face_ptex_offset += num_ptex_faces_per_poly; + if (num_ptex_faces_per_poly == 1) { + vertex_offset += resolution_2_squared; + edge_offset += num_edges_per_ptex_face_get(resolution - 2) + + 4 * num_subdiv_vertices_per_coarse_edge; + polygon_offset += num_polys_per_ptex_get(resolution); + } + else { + vertex_offset += + 1 + + num_ptex_faces_per_poly * num_irregular_vertices_per_patch; + edge_offset += + num_ptex_faces_per_poly * + (num_inner_edges_per_ptex_face_get( + no_quad_patch_resolution - 1) + + (no_quad_patch_resolution - 2) + + num_subdiv_vertices_per_coarse_edge); + if (no_quad_patch_resolution >= 3) { + edge_offset += coarse_poly->totloop; + } + polygon_offset += + num_ptex_faces_per_poly * + num_polys_per_ptex_get(no_quad_patch_resolution); + } } - ctx->num_subdiv_vertices = vertex_offset; - ctx->num_subdiv_edges = edge_offset; - ctx->num_subdiv_polygons = polygon_offset; - ctx->num_subdiv_loops = 4 * ctx->num_subdiv_polygons; } static void subdiv_mesh_ctx_init(SubdivMeshContext *ctx) { + const Mesh *coarse_mesh = ctx->coarse_mesh; + /* Allocate maps and offsets. */ + ctx->coarse_vertices_used_map = + BLI_BITMAP_NEW(coarse_mesh->totvert, "vertices used map"); + ctx->coarse_edges_used_map = + BLI_BITMAP_NEW(coarse_mesh->totedge, "edges used map"); + ctx->subdiv_vertex_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_vertex_offset), + "vertex_offset"); + ctx->subdiv_edge_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_edge_offset), + "subdiv_edge_offset"); + ctx->subdiv_polygon_offset = MEM_malloc_arrayN( + coarse_mesh->totpoly, + sizeof(*ctx->subdiv_polygon_offset), + "subdiv_edge_offset"); + ctx->face_ptex_offset = MEM_malloc_arrayN(coarse_mesh->totpoly, + sizeof(*ctx->face_ptex_offset), + "face_ptex_offset"); + /* Initialize all offsets. */ subdiv_mesh_ctx_init_offsets(ctx); + /* Calculate number of geometry in the result subdivision mesh. */ + subdiv_mesh_ctx_count(ctx); + /* Re-set maps which were used at this step. */ + BLI_BITMAP_SET_ALL(ctx->coarse_edges_used_map, false, coarse_mesh->totedge); } static void subdiv_mesh_ctx_init_result(SubdivMeshContext *ctx) @@ -197,8 +327,11 @@ static void subdiv_mesh_ctx_init_result(SubdivMeshContext *ctx) static void subdiv_mesh_ctx_free(SubdivMeshContext *ctx) { + MEM_freeN(ctx->coarse_vertices_used_map); + MEM_freeN(ctx->coarse_edges_used_map); MEM_freeN(ctx->subdiv_vertex_offset); MEM_freeN(ctx->subdiv_edge_offset); + MEM_freeN(ctx->subdiv_polygon_offset); MEM_freeN(ctx->face_ptex_offset); } @@ -220,10 +353,11 @@ static void loops_of_ptex_get( const SubdivMeshContext *ctx, LoopsOfPtex *loops_of_ptex, const MPoly *coarse_poly, - const int ptex_face_index) + const int ptex_of_poly_index) { const MLoop *coarse_mloop = ctx->coarse_mesh->mloop; - const int first_ptex_loop_index = coarse_poly->loopstart + ptex_face_index; + const int first_ptex_loop_index = + coarse_poly->loopstart + ptex_of_poly_index; /* Loop which look in the (opposite) V direction of the current * ptex face. * @@ -231,7 +365,8 @@ static void loops_of_ptex_get( */ const int last_ptex_loop_index = coarse_poly->loopstart + - (ptex_face_index + coarse_poly->totloop - 1) % coarse_poly->totloop; + (ptex_of_poly_index + coarse_poly->totloop - 1) % + coarse_poly->totloop; loops_of_ptex->first_loop = &coarse_mloop[first_ptex_loop_index]; loops_of_ptex->last_loop = &coarse_mloop[last_ptex_loop_index]; if (coarse_poly->totloop == 4) { @@ -248,6 +383,8 @@ static void loops_of_ptex_get( * Edge custom data copy helpers. */ +#if 0 + typedef struct EdgesOfPtex { /* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */ const MEdge *first_edge; @@ -281,6 +418,8 @@ static void edges_of_ptex_get( } } +#endif + /* ============================================================================= * Vertex custom data interpolation helpers. */ @@ -370,7 +509,7 @@ static void vertex_interpolation_from_ptex( const SubdivMeshContext *ctx, VerticesForInterpolation *vertex_interpolation, const MPoly *coarse_poly, - const int ptex_face_index) + const int ptex_of_poly_index) { if (coarse_poly->totloop == 4) { /* Nothing to do, all indices and data is already assigned. */ @@ -380,12 +519,12 @@ static void vertex_interpolation_from_ptex( const Mesh *coarse_mesh = ctx->coarse_mesh; const MLoop *coarse_mloop = coarse_mesh->mloop; LoopsOfPtex loops_of_ptex; - loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index); + loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_of_poly_index); /* Ptex face corner corresponds to a poly loop with same index. */ CustomData_copy_data( vertex_data, &vertex_interpolation->vertex_data_storage, - coarse_mloop[coarse_poly->loopstart + ptex_face_index].v, + coarse_mloop[coarse_poly->loopstart + ptex_of_poly_index].v, 0, 1); /* Interpolate remaining ptex face corners, which hits loops @@ -563,13 +702,28 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation) * Vertex subdivision process. */ -static void subdiv_copy_vertex_data( +/* Custom data interpolation helpers. */ + +static void subdiv_vertex_data_copy( + const SubdivMeshContext *ctx, + const MVert *coarse_vertex, + MVert *subdiv_vertex) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert; + const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert; + CustomData_copy_data(&coarse_mesh->vdata, + &ctx->subdiv_mesh->vdata, + coarse_vertex_index, + subdiv_vertex_index, + 1); +} + +static void subdiv_vertex_data_interpolate( const SubdivMeshContext *ctx, MVert *subdiv_vertex, - const Mesh *UNUSED(coarse_mesh), - const MPoly *coarse_poly, const VerticesForInterpolation *vertex_interpolation, - const int UNUSED(ptex_of_poly_index), const float u, const float v) { const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert; @@ -585,93 +739,384 @@ static void subdiv_copy_vertex_data( subdiv_vertex_index); if (ctx->vert_origindex != NULL) { ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; - if (coarse_poly->totloop == 4) { - if (u == 0.0f && v == 0.0f) { - // ctx->vert_origindex[subdiv_vertex_index] = - // vertex_interpolation->vertex_indices[0]; - } - else if (u == 1.0f && v == 0.0f) { - // ctx->vert_origindex[subdiv_vertex_index] = - // vertex_interpolation->vertex_indices[1]; - } - else if (u == 1.0f && v == 1.0f) { - // ctx->vert_origindex[subdiv_vertex_index] = - // vertex_interpolation->vertex_indices[2]; - } - else if (u == 0.0f && v == 1.0f) { - // ctx->vert_origindex[subdiv_vertex_index] = - // vertex_interpolation->vertex_indices[3]; + } +} + +/* Evaluation of corner vertices. They are coming from coarse vertices. */ + +static void subdiv_evaluate_corner_vertices_regular( + SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + const float weights[4][2] = {{0.0f, 0.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f}, + {0.0f, 1.0f}}; + Subdiv *subdiv = ctx->subdiv; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MVert *coarse_mvert = coarse_mesh->mvert; + const MLoop *coarse_mloop = coarse_mesh->mloop; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, + coarse_loop->v)) { + continue; + } + const MVert *coarse_vert = &coarse_mvert[coarse_loop->v]; + MVert *subdiv_vert = &subdiv_mvert[ + ctx->vertices_corner_offset + coarse_loop->v]; + subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + weights[corner][0], weights[corner][1], + subdiv_vert->co, subdiv_vert->no); + } +} + +static void subdiv_evaluate_corner_vertices_special( + SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + Subdiv *subdiv = ctx->subdiv; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MVert *coarse_mvert = coarse_mesh->mvert; + const MLoop *coarse_mloop = coarse_mesh->mloop; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + int ptex_face_index = ctx->face_ptex_offset[poly_index]; + for (int corner = 0; + corner < coarse_poly->totloop; + corner++, ptex_face_index++) + { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, + coarse_loop->v)) { + continue; + } + const MVert *coarse_vert = &coarse_mvert[coarse_loop->v]; + MVert *subdiv_vert = &subdiv_mvert[ + ctx->vertices_corner_offset + coarse_loop->v]; + subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + 0.0f, 0.0f, + subdiv_vert->co, subdiv_vert->no); + } +} + +static void subdiv_evaluate_corner_vertices(SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + if (coarse_poly->totloop == 4) { + subdiv_evaluate_corner_vertices_regular(ctx, coarse_poly); + } + else { + subdiv_evaluate_corner_vertices_special(ctx, coarse_poly); + } +} + +/* Evaluation of edge vertices. They are coming from coarse edges. */ + +static void subdiv_evaluate_edge_vertices_regular( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) +{ + const int resolution = ctx->settings->resolution; + const int resolution_1 = resolution - 1; + const float inv_resolution_1 = 1.0f / (float)resolution_1; + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + Subdiv *subdiv = ctx->subdiv; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, + coarse_loop->e)) { + continue; + } + vertex_interpolation_from_ptex(ctx, + vertex_interpolation, + coarse_poly, + corner); + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + MVert *subdiv_vert = &subdiv_mvert[ + ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge]; + for (int vertex_index = 0; + vertex_index < num_subdiv_vertices_per_coarse_edge; + vertex_index++, subdiv_vert++) + { + float fac = (vertex_index + 1) * inv_resolution_1; + if (flip) { + fac = 1.0f - fac; } - else { - ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; + if (corner >= 2) { + fac = 1.0f - fac; } - } else { - if (u == 0.0f && v == 0.0f) { - // const MLoop *coarse_mloop = coarse_mesh->mloop; - // ctx->vert_origindex[subdiv_vertex_index] = - // coarse_mloop[coarse_poly->loopstart + - // ptex_of_poly_index].v; + float u, v; + if ((corner & 1) == 0) { + u = fac; + v = (corner == 2) ? 1.0f : 0.0f; } else { - ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE; + u = (corner == 1) ? 1.0f : 0.0f; + v = fac; } + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + u, v); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + u, v, + subdiv_vert->co, subdiv_vert->no); } } } -static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, - const int poly_index) +static void subdiv_evaluate_edge_vertices_special( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) { - Subdiv *subdiv = ctx->subdiv; const int resolution = ctx->settings->resolution; - const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; - /* Base/coarse mesh information. */ + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1); + const float inv_ptex_resolution_1 = + 1.0f / (float)(num_vertices_per_ptex_edge - 1); + Subdiv *subdiv = ctx->subdiv; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[poly_index]; - const int num_ptex_faces_per_poly = - num_ptex_faces_per_poly_get(coarse_poly); - const int ptex_resolution = - ptex_face_resolution_get(coarse_poly, resolution); - const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1); - /* Hi-poly subdivided mesh. */ + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_vertex = subdiv_mesh->mvert; - MVert *subdiv_vert = &subdiv_vertex[start_vertex_index]; - /* Actual evaluation. */ - VerticesForInterpolation vertex_interpolation; - vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly); - const int ptex_face_index = ctx->face_ptex_offset[poly_index]; - for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_ptex_faces_per_poly; - ptex_of_poly_index++) + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int ptex_face_start_index = ctx->face_ptex_offset[poly_index]; + int ptex_face_index = ptex_face_start_index; + for (int corner = 0; + corner < coarse_poly->totloop; + corner++, ptex_face_index++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, + coarse_loop->e)) { + continue; + } vertex_interpolation_from_ptex(ctx, - &vertex_interpolation, + vertex_interpolation, coarse_poly, - ptex_of_poly_index); - const int current_ptex_face_index = - ptex_face_index + ptex_of_poly_index; - BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal( - subdiv, - current_ptex_face_index, - ptex_resolution, - subdiv_vert, offsetof(MVert, co), sizeof(MVert), - subdiv_vert, offsetof(MVert, no), sizeof(MVert)); - for (int y = 0; y < ptex_resolution; y++) { - const float v = y * inv_ptex_resolution_1; - for (int x = 0; x < ptex_resolution; x++, subdiv_vert++) { - const float u = x * inv_ptex_resolution_1; - subdiv_copy_vertex_data(ctx, - subdiv_vert, - coarse_mesh, - coarse_poly, - &vertex_interpolation, - ptex_of_poly_index, - u, v); + corner); + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + MVert *subdiv_vert = &subdiv_mvert[ + ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge]; + int veretx_delta = 1; + if (flip) { + subdiv_vert += num_subdiv_vertices_per_coarse_edge - 1; + veretx_delta = -1; + } + for (int vertex_index = 1; + vertex_index < num_vertices_per_ptex_edge; + vertex_index++, subdiv_vert += veretx_delta) + { + float u = vertex_index * inv_ptex_resolution_1; + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + u, 0.0f); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + u, 0.0f, + subdiv_vert->co, subdiv_vert->no); + } + const int next_ptex_face_index = + ptex_face_start_index + (corner + 1) % coarse_poly->totloop; + for (int vertex_index = 1; + vertex_index < num_vertices_per_ptex_edge - 1; + vertex_index++, subdiv_vert += veretx_delta) + { + float v = 1.0f - vertex_index * inv_ptex_resolution_1; + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + 0.0f, v); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + next_ptex_face_index, + 0.0f, v, + subdiv_vert->co, subdiv_vert->no); + } + } +} + +static void subdiv_evaluate_edge_vertices( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) +{ + if (coarse_poly->totloop == 4) { + subdiv_evaluate_edge_vertices_regular( + ctx, coarse_poly, vertex_interpolation); + } + else { + subdiv_evaluate_edge_vertices_special( + ctx, coarse_poly, vertex_interpolation); + } +} + +/* Evaluation of inner vertices, they are coming from ptex patches. */ + +static void subdiv_evaluate_inner_vertices_regular( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) +{ + const int resolution = ctx->settings->resolution; + const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + Subdiv *subdiv = ctx->subdiv; + const Mesh *coarse_mesh = ctx->coarse_mesh; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; + MVert *subdiv_vert = + &subdiv_mvert[ctx->vertices_inner_offset + start_vertex_index]; + vertex_interpolation_from_ptex(ctx, + vertex_interpolation, + coarse_poly, + 0); + for (int y = 1; y < resolution - 1; y++) { + const float v = y * inv_resolution_1; + for (int x = 1; x < resolution - 1; x++, subdiv_vert++) { + const float u = x * inv_resolution_1; + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + u, v); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + u, v, + subdiv_vert->co, subdiv_vert->no); + } + } +} + +static void subdiv_evaluate_inner_vertices_special( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) +{ + const int resolution = ctx->settings->resolution; + const int ptex_face_resolution = ptex_face_resolution_get( + coarse_poly, resolution); + const float inv_ptex_face_resolution_1 = + 1.0f / (float)(ptex_face_resolution - 1); + Subdiv *subdiv = ctx->subdiv; + const Mesh *coarse_mesh = ctx->coarse_mesh; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + const int poly_index = coarse_poly - coarse_mesh->mpoly; + int ptex_face_index = ctx->face_ptex_offset[poly_index]; + const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; + MVert *subdiv_vert = + &subdiv_mvert[ctx->vertices_inner_offset + start_vertex_index]; + vertex_interpolation_from_ptex(ctx, + vertex_interpolation, + coarse_poly, + 0); + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + 1.0f, 1.0f); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + 1.0f, 1.0f, + subdiv_vert->co, subdiv_vert->no); + subdiv_vert++; + for (int corner = 0; + corner < coarse_poly->totloop; + corner++, ptex_face_index++) + { + if (corner != 0) { + vertex_interpolation_from_ptex(ctx, + vertex_interpolation, + coarse_poly, + corner); + } + for (int y = 1; y < ptex_face_resolution - 1; y++) { + const float v = y * inv_ptex_face_resolution_1; + for (int x = 1; x < ptex_face_resolution; x++, subdiv_vert++) { + const float u = x * inv_ptex_face_resolution_1; + subdiv_vertex_data_interpolate(ctx, + subdiv_vert, + vertex_interpolation, + u, v); + BKE_subdiv_eval_limit_point_and_short_normal( + subdiv, + ptex_face_index, + u, v, + subdiv_vert->co, subdiv_vert->no); } } } +} + +static void subdiv_evaluate_inner_vertices( + SubdivMeshContext *ctx, + const MPoly *coarse_poly, + VerticesForInterpolation *vertex_interpolation) +{ + if (coarse_poly->totloop == 4) { + subdiv_evaluate_inner_vertices_regular( + ctx, coarse_poly, vertex_interpolation); + } + else { + subdiv_evaluate_inner_vertices_special( + ctx, coarse_poly, vertex_interpolation); + } +} + +/* Evaluate all vertices which are emitted from given coarse polygon. */ +static void subdiv_evaluate_vertices(SubdivMeshContext *ctx, + const int poly_index) +{ + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + /* Initialize vertex interpolation, it is reused by corner vertices, coarse + * edges and patch evaluation. + */ + VerticesForInterpolation vertex_interpolation; + vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly); + (void) vertex_interpolation; + subdiv_evaluate_corner_vertices(ctx, coarse_poly); + subdiv_evaluate_edge_vertices(ctx, coarse_poly, &vertex_interpolation); + subdiv_evaluate_inner_vertices(ctx, coarse_poly, &vertex_interpolation); vertex_interpolation_end(&vertex_interpolation); } @@ -700,20 +1145,17 @@ static void subdiv_copy_edge_data( coarse_edge_index, subdiv_edge_index, 1); - if (ctx->edge_origindex != NULL) { - ctx->edge_origindex[subdiv_edge_index] = coarse_edge_index; - } } static MEdge *subdiv_create_edges_row(SubdivMeshContext *ctx, MEdge *subdiv_edge, const MEdge *coarse_edge, const int start_vertex_index, - const int resolution) + const int num_edges_per_row) { int vertex_index = start_vertex_index; for (int edge_index = 0; - edge_index < resolution - 1; + edge_index < num_edges_per_row - 1; edge_index++, subdiv_edge++) { subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); @@ -729,104 +1171,330 @@ static MEdge *subdiv_create_edges_column(SubdivMeshContext *ctx, const MEdge *coarse_start_edge, const MEdge *coarse_end_edge, const int start_vertex_index, - const int resolution) + const int num_edges_per_row) { int vertex_index = start_vertex_index; for (int edge_index = 0; - edge_index < resolution; + edge_index < num_edges_per_row; edge_index++, subdiv_edge++) { const MEdge *coarse_edge = NULL; if (edge_index == 0) { coarse_edge = coarse_start_edge; } - else if (edge_index == resolution - 1) { + else if (edge_index == num_edges_per_row - 1) { coarse_edge = coarse_end_edge; } subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); subdiv_edge->v1 = vertex_index; - subdiv_edge->v2 = vertex_index + resolution; + subdiv_edge->v2 = vertex_index + num_edges_per_row; vertex_index += 1; } return subdiv_edge; } -static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) +/* Create edges between inner vertices of patch, and also edges to the + * boundary. + */ + +/* Consider a subdivision of base face at level 1: + * + * y + * ^ + * | (6) ---- (7) ---- (8) + * | | | | + * | (3) ---- (4) ---- (5) + * | | | | + * | (0) ---- (1) ---- (2) + * o---------------------------> x + * + * This is illustrate which parts of geometry is created by code below. + */ + +static void subdiv_create_edges_all_patches_regular( + SubdivMeshContext *ctx, + const MPoly *coarse_poly) { - const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; - const int start_edge_index = ctx->subdiv_edge_offset[poly_index]; - /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[poly_index]; - const int num_ptex_faces_per_poly = - num_ptex_faces_per_poly_get(coarse_poly); - const int ptex_face_resolution = ptex_face_resolution_get( - coarse_poly, ctx->settings->resolution); - const int ptex_face_resolution2 = - ptex_face_resolution * ptex_face_resolution; - /* Hi-poly subdivided mesh. */ + const int poly_index = coarse_poly - coarse_mpoly; + const int resolution = ctx->settings->resolution; + const int start_vertex_index = + ctx->vertices_inner_offset + + ctx->subdiv_vertex_offset[poly_index]; + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; Mesh *subdiv_mesh = ctx->subdiv_mesh; MEdge *subdiv_medge = subdiv_mesh->medge; - MEdge *subdiv_edge = &subdiv_medge[start_edge_index]; - /* Consider a subdivision of base face at level 1: - * - * y - * ^ - * | (6) ---- (7) ---- (8) - * | | | | - * | (3) ---- (4) ---- (5) - * | | | | - * | (0) ---- (1) ---- (2) - * o---------------------------> x - * - * This is illustrate which parts of geometry is created by code below. - */ - for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_ptex_faces_per_poly; - ptex_of_poly_index++) - { + MEdge *subdiv_edge = &subdiv_medge[ + ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index]]; + /* Create bottom row of edges (0-1, 1-2). */ + subdiv_edge = subdiv_create_edges_row( + ctx, + subdiv_edge, + NULL, + start_vertex_index, + resolution - 2); + /* Create remaining edges. */ + for (int row = 0; row < resolution - 3; row++) { + const int start_row_vertex_index = + start_vertex_index + row * (resolution - 2); + /* Create vertical columns. + * + * At first iteration it will be edges (0-3. 1-4, 2-5), then it + * will be (3-6, 4-7, 5-8) and so on. + */ + subdiv_edge = subdiv_create_edges_column( + ctx, + subdiv_edge, + NULL, + NULL, + start_row_vertex_index, + resolution - 2); + /* Create horizontal edge row. + * + * At first iteration it will be edges (3-4, 4-5), then it will be + * (6-7, 7-8) and so on. + */ + subdiv_edge = subdiv_create_edges_row( + ctx, + subdiv_edge, + NULL, + start_row_vertex_index + resolution - 2, + resolution - 2); + } + /* Connect inner part of patch to boundary. */ + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const int start_edge_vertex = ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + int side_start_index = start_vertex_index; + int side_stride = 0; + /* Calculate starting veretx of corresponding inner part of ptex. */ + if (corner == 0) { + side_stride = 1; + } + else if (corner == 1) { + side_start_index += resolution - 3; + side_stride = resolution - 2; + } + else if (corner == 2) { + side_start_index += num_subdiv_vertices_per_coarse_edge * + num_subdiv_vertices_per_coarse_edge - 1; + side_stride = -1; + } + else if (corner == 3) { + side_start_index += num_subdiv_vertices_per_coarse_edge * + (num_subdiv_vertices_per_coarse_edge - 1); + side_stride = -(resolution - 2); + } + for (int i = 0; i < resolution - 2; i++, subdiv_edge++) { + subdiv_copy_edge_data(ctx, subdiv_edge, NULL); + if (flip) { + subdiv_edge->v1 = start_edge_vertex + (resolution - i - 3); + } + else { + subdiv_edge->v1 = start_edge_vertex + i; + } + subdiv_edge->v2 = side_start_index + side_stride * i; + } + } +} + +static void subdiv_create_edges_all_patches_special( + SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; + const int resolution = ctx->settings->resolution; + const int ptex_face_resolution = + ptex_face_resolution_get(coarse_poly, resolution); + const int ptex_face_inner_resolution = ptex_face_resolution - 2; + const int num_inner_vertices_per_ptex = + (ptex_face_resolution - 1) * (ptex_face_resolution - 2); + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int center_vertex_index = + ctx->vertices_inner_offset + + ctx->subdiv_vertex_offset[poly_index]; + const int start_vertex_index = center_vertex_index + 1; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MEdge *subdiv_medge = subdiv_mesh->medge; + MEdge *subdiv_edge = &subdiv_medge[ + ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index]]; + /* Create inner ptex edges. */ + for (int corner = 0; corner < coarse_poly->totloop; corner++) { const int start_ptex_face_vertex_index = - start_vertex_index + ptex_of_poly_index * ptex_face_resolution2; - EdgesOfPtex edges_of_ptex; - edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, ptex_of_poly_index); - /* Create bottom row of edges (0-1, 1-2). */ + start_vertex_index + corner * num_inner_vertices_per_ptex; + /* Similar steps to regular patch case. */ subdiv_edge = subdiv_create_edges_row( ctx, subdiv_edge, - edges_of_ptex.first_edge, + NULL, start_ptex_face_vertex_index, - ptex_face_resolution); - /* Create remaining edges. */ - for (int row = 0; row < ptex_face_resolution - 1; row++) { + ptex_face_inner_resolution + 1); + for (int row = 0; row < ptex_face_inner_resolution - 1; row++) { const int start_row_vertex_index = - start_ptex_face_vertex_index + row * ptex_face_resolution; - /* Create vertical columns. - * - * At first iteration it will be edges (0-3. 1-4, 2-5), then it - * will be (3-6, 4-7, 5-8) and so on. - */ + start_ptex_face_vertex_index + + row * (ptex_face_inner_resolution + 1); subdiv_edge = subdiv_create_edges_column( ctx, subdiv_edge, - edges_of_ptex.last_edge, - edges_of_ptex.second_edge, + NULL, + NULL, start_row_vertex_index, - ptex_face_resolution); - /* Create horizontal edge row. - * - * At first iteration it will be edges (3-4, 4-5), then it will be - * (6-7, 7-8) and so on. - */ + ptex_face_inner_resolution + 1); subdiv_edge = subdiv_create_edges_row( ctx, subdiv_edge, - (row == ptex_face_resolution - 2) ? edges_of_ptex.third_edge - : NULL, - start_row_vertex_index + ptex_face_resolution, - ptex_face_resolution); + NULL, + start_row_vertex_index + ptex_face_inner_resolution + 1, + ptex_face_inner_resolution + 1); } } + /* Create connections between ptex faces. */ + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const int next_corner = (corner + 1) % coarse_poly->totloop; + int current_patch_vertex_index = + start_vertex_index + corner * num_inner_vertices_per_ptex + + ptex_face_inner_resolution; + int next_path_vertex_index = + start_vertex_index + next_corner * num_inner_vertices_per_ptex + + num_inner_vertices_per_ptex - ptex_face_resolution + 1; + for (int row = 0; + row < ptex_face_inner_resolution; + row++, subdiv_edge++) + { + subdiv_copy_edge_data(ctx, subdiv_edge, NULL); + subdiv_edge->v1 = current_patch_vertex_index; + subdiv_edge->v2 = next_path_vertex_index; + current_patch_vertex_index += ptex_face_inner_resolution + 1; + next_path_vertex_index += 1; + } + } + /* Create edges from center. */ + if (ptex_face_resolution >= 3) { + for (int corner = 0; + corner < coarse_poly->totloop; + corner++, subdiv_edge++) + { + const int current_patch_end_vertex_index = + start_vertex_index + corner * num_inner_vertices_per_ptex + + num_inner_vertices_per_ptex - 1; + subdiv_copy_edge_data(ctx, subdiv_edge, NULL); + subdiv_edge->v1 = center_vertex_index; + subdiv_edge->v2 = current_patch_end_vertex_index; + } + } + /* Connect inner path of patch to boundary. */ + const MLoop *prev_coarse_loop = + &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1]; + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + { + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const int start_edge_vertex = ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + int side_start_index; + if (ptex_face_resolution >= 3) { + side_start_index = + start_vertex_index + num_inner_vertices_per_ptex * corner; + } + else { + side_start_index = center_vertex_index; + } + for (int i = 0; i < ptex_face_resolution - 1; i++, subdiv_edge++) { + subdiv_copy_edge_data(ctx, subdiv_edge, NULL); + if (flip) { + subdiv_edge->v1 = start_edge_vertex + (resolution - i - 3); + } else { + subdiv_edge->v1 = start_edge_vertex + i; + } + subdiv_edge->v2 = side_start_index + i; + } + } + if (ptex_face_resolution >= 3) { + const MEdge *coarse_edge = &coarse_medge[prev_coarse_loop->e]; + const int start_edge_vertex = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + int side_start_index = + start_vertex_index + num_inner_vertices_per_ptex * corner; + for (int i = 0; i < ptex_face_resolution - 2; i++, subdiv_edge++) { + subdiv_copy_edge_data(ctx, subdiv_edge, NULL); + if (flip) { + subdiv_edge->v1 = start_edge_vertex + (resolution - i - 3); + } else { + subdiv_edge->v1 = start_edge_vertex + i; + } + subdiv_edge->v2 = side_start_index + + (ptex_face_inner_resolution + 1) * i; + } + } + prev_coarse_loop = coarse_loop; + } +} + +static void subdiv_create_edges_all_patches( + SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + if (coarse_poly->totloop == 4) { + subdiv_create_edges_all_patches_regular(ctx, coarse_poly); + } + else { + subdiv_create_edges_all_patches_special(ctx, coarse_poly); + } +} + +static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + subdiv_create_edges_all_patches(ctx, coarse_poly); +} + +static void subdiv_create_boundary_edges( + SubdivMeshContext *ctx, + int edge_index) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MEdge *coarse_edge = &coarse_medge[edge_index]; + const int resolution = ctx->settings->resolution; + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int num_subdiv_edges_per_coarse_edge = resolution - 1; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MEdge *subdiv_medge = subdiv_mesh->medge; + MEdge *subdiv_edge = &subdiv_medge[ + ctx->edge_boundary_offset + + edge_index * num_subdiv_edges_per_coarse_edge]; + int last_vertex_index = ctx->vertices_corner_offset + coarse_edge->v1; + for (int i = 0; + i < num_subdiv_edges_per_coarse_edge - 1; + i++, subdiv_edge++) + { + subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); + subdiv_edge->v1 = last_vertex_index; + subdiv_edge->v2 = + ctx->vertices_edge_offset + + edge_index * num_subdiv_vertices_per_coarse_edge + + i; + last_vertex_index = subdiv_edge->v2; + } + subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); + subdiv_edge->v1 = last_vertex_index; + subdiv_edge->v2 = ctx->vertices_corner_offset + coarse_edge->v2; } /* ============================================================================= @@ -857,15 +1525,13 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, MLoop *subdiv_loop, const int ptex_face_index, const float u, const float v, - const float inv_resolution_1) + const float du, const float dv) { if (ctx->num_uv_layers == 0) { return; } Subdiv *subdiv = ctx->subdiv; const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop; - const float du = inv_resolution_1; - const float dv = inv_resolution_1; for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index]; BKE_subdiv_eval_face_varying(subdiv, @@ -891,24 +1557,85 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, } } -static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) +static void rotate_indices(const int rot, int *a, int *b, int *c, int *d) +{ + int values[4] = {*a, *b, *c, *d}; + *a = values[(0 - rot + 4) % 4]; + *b = values[(1 - rot + 4) % 4]; + *c = values[(2 - rot + 4) % 4]; + *d = values[(3 - rot + 4) % 4]; +} + +static void subdiv_create_loops_of_poly( + SubdivMeshContext *ctx, + LoopsForInterpolation *loop_interpolation, + MLoop *subdiv_loop_start, + const int ptex_face_index, + const int rotation, + /*const*/ int v0, /*const*/ int e0, + /*const*/ int v1, /*const*/ int e1, + /*const*/ int v2, /*const*/ int e2, + /*const*/ int v3, /*const*/ int e3, + const float u, const float v, + const float du, const float dv) +{ + rotate_indices(rotation, &v0, &v1, &v2, &v3); + rotate_indices(rotation, &e0, &e1, &e2, &e3); + subdiv_copy_loop_data(ctx, + &subdiv_loop_start[0], + loop_interpolation, + u, v); + subdiv_loop_start[0].v = v0; + subdiv_loop_start[0].e = e0; + subdiv_copy_loop_data(ctx, + &subdiv_loop_start[1], + loop_interpolation, + u + du, v); + subdiv_loop_start[1].v = v1; + subdiv_loop_start[1].e = e1; + subdiv_copy_loop_data(ctx, + &subdiv_loop_start[2], + loop_interpolation, + u + du, v + dv); + subdiv_loop_start[2].v = v2; + subdiv_loop_start[2].e = e2; + subdiv_copy_loop_data(ctx, + &subdiv_loop_start[3], + loop_interpolation, + u, v + dv); + subdiv_loop_start[3].v = v3; + subdiv_loop_start[3].e = e3; + /* Interpolate UV layers using OpenSubdiv. */ + subdiv_eval_uv_layer(ctx, + subdiv_loop_start, + ptex_face_index, + u, v, du, dv); +} + +static void subdiv_create_loops_regular(SubdivMeshContext *ctx, + const MPoly *coarse_poly) { const int resolution = ctx->settings->resolution; - const int ptex_face_index = ctx->face_ptex_offset[poly_index]; - const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index]; - const int start_edge_index = ctx->subdiv_edge_offset[poly_index]; - const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[poly_index]; - const int num_ptex_faces_per_poly = - num_ptex_faces_per_poly_get(coarse_poly); + const int poly_index = coarse_poly - coarse_mpoly; const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution); - const int ptex_resolution2 = ptex_resolution * ptex_resolution; + const int ptex_inner_resolution = ptex_resolution - 2; + const int num_subdiv_edges_per_coarse_edge = resolution - 1; + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1); - const int num_edges_per_ptex = num_edges_per_ptex_face_get(ptex_resolution); + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + const int start_vertex_index = + ctx->vertices_inner_offset + + ctx->subdiv_vertex_offset[poly_index]; + const int start_edge_index = + ctx->edge_inner_offset + + ctx->subdiv_edge_offset[poly_index]; + const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; const int start_loop_index = 4 * start_poly_index; const float du = inv_ptex_resolution_1; const float dv = inv_ptex_resolution_1; @@ -918,74 +1645,526 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) MLoop *subdiv_loop = &subdiv_loopoop[start_loop_index]; LoopsForInterpolation loop_interpolation; loop_interpolation_init(ctx, &loop_interpolation, coarse_poly); - for (int ptex_of_poly_index = 0; - ptex_of_poly_index < num_ptex_faces_per_poly; - ptex_of_poly_index++) + loop_interpolation_from_ptex(ctx, + &loop_interpolation, + coarse_poly, + 0); + /* Loops for inner part of ptex. */ + for (int y = 1; y < ptex_resolution - 2; y++) { + const float v = y * inv_ptex_resolution_1; + const int inner_y = y - 1; + for (int x = 1; x < ptex_resolution - 2; x++, subdiv_loop += 4) { + const int inner_x = x - 1; + const float u = x * inv_ptex_resolution_1; + /* Vertex indicies ordered counter-clockwise. */ + const int v0 = start_vertex_index + + (inner_y * ptex_inner_resolution + inner_x); + const int v1 = v0 + 1; + const int v2 = v0 + ptex_inner_resolution + 1; + const int v3 = v0 + ptex_inner_resolution; + /* Edge indicies ordered counter-clockwise. */ + const int e0 = start_edge_index + + (inner_y * (2 * ptex_inner_resolution - 1) + inner_x); + const int e1 = e0 + ptex_inner_resolution; + const int e2 = e0 + (2 * ptex_inner_resolution - 1); + const int e3 = e0 + ptex_inner_resolution - 1; + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, ptex_face_index, 0, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); + } + } + /* Loops for faces connecting inner ptex part with boundary. */ + const MLoop *prev_coarse_loop = + &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1]; + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e]; + const int start_edge_vertex = ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + int side_start_index = start_vertex_index; + int side_stride = 0; + int v0 = ctx->vertices_corner_offset + coarse_loop->v; + int v3, e3; + int e2_offset, e2_stride; + float u, v, delta_u, delta_v; + if (prev_coarse_loop->v == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + num_subdiv_vertices_per_coarse_edge - 1; + e3 = ctx->edge_boundary_offset + + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + + num_subdiv_edges_per_coarse_edge - 1; + } + else { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + e3 = ctx->edge_boundary_offset + + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; + } + /* Calculate starting veretx of corresponding inner part of ptex. */ + if (corner == 0) { + side_stride = 1; + e2_offset = 0; + e2_stride = 1; + u = 0.0f; + v = 0.0f; + delta_u = du; + delta_v = 0.0f; + } + else if (corner == 1) { + side_start_index += resolution - 3; + side_stride = resolution - 2; + e2_offset = 2 * num_subdiv_edges_per_coarse_edge - 4; + e2_stride = 2 * num_subdiv_edges_per_coarse_edge - 3; + u = 1.0f - du; + v = 0; + delta_u = 0.0f; + delta_v = dv; + } + else if (corner == 2) { + side_start_index += num_subdiv_vertices_per_coarse_edge * + num_subdiv_vertices_per_coarse_edge - 1; + side_stride = -1; + e2_offset = num_edges_per_ptex_face_get(resolution - 2) - 1; + e2_stride = -1; + u = 1.0f - du; + v = 1.0f - dv; + delta_u = -du; + delta_v = 0.0f; + } + else if (corner == 3) { + side_start_index += num_subdiv_vertices_per_coarse_edge * + (num_subdiv_vertices_per_coarse_edge - 1); + side_stride = -(resolution - 2); + e2_offset = num_edges_per_ptex_face_get(resolution - 2) - + (2 * num_subdiv_edges_per_coarse_edge - 3); + e2_stride = -(2 * num_subdiv_edges_per_coarse_edge - 3); + u = 0.0f; + v = 1.0f - dv; + delta_u = 0.0f; + delta_v = -dv; + } + for (int i = 0; i < resolution - 2; i++, subdiv_loop += 4) { + int v1; + if (flip) { + v1 = start_edge_vertex + (resolution - i - 3); + } + else { + v1 = start_edge_vertex + i; + } + const int v2 = side_start_index + side_stride * i; + int e0; + if (flip) { + e0 = ctx->edge_boundary_offset + + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + num_subdiv_edges_per_coarse_edge - i - 1; + } else { + e0 = ctx->edge_boundary_offset + + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + i; + } + int e1 = start_edge_index + + num_edges_per_ptex_face_get(resolution - 2) + + corner * num_subdiv_vertices_per_coarse_edge + + i; + int e2; + if (i == 0) { + e2 = start_edge_index + + num_edges_per_ptex_face_get(resolution - 2) + + ((corner - 1 + coarse_poly->totloop) % + coarse_poly->totloop) * + num_subdiv_vertices_per_coarse_edge + + num_subdiv_vertices_per_coarse_edge - 1; + } + else { + e2 = start_edge_index + e2_offset + e2_stride * (i - 1); + } + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index, corner, + v0, e0, v1, e1, v2, e2, v3, e3, + u + delta_u * i, v + delta_v * i, du, dv); + v0 = v1; + v3 = v2; + e3 = e1; + } + prev_coarse_loop = coarse_loop; + } + loop_interpolation_end(&loop_interpolation); +} + +static void subdiv_create_loops_special(SubdivMeshContext *ctx, + const MPoly *coarse_poly) +{ + const int resolution = ctx->settings->resolution; + /* Base/coarse mesh information. */ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + const MLoop *coarse_mloop = coarse_mesh->mloop; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; + const int ptex_face_resolution = + ptex_face_resolution_get(coarse_poly, resolution); + const int ptex_face_inner_resolution = ptex_face_resolution - 2; + const float inv_ptex_resolution_1 = + 1.0f / (float)(ptex_face_resolution - 1); + const int num_inner_vertices_per_ptex = + (ptex_face_resolution - 1) * (ptex_face_resolution - 2); + const int num_inner_edges_per_ptex_face = + num_inner_edges_per_ptex_face_get( + ptex_face_inner_resolution + 1); + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const int num_subdiv_edges_per_coarse_edge = resolution - 1; + const int ptex_face_index = ctx->face_ptex_offset[poly_index]; + const int center_vertex_index = + ctx->vertices_inner_offset + + ctx->subdiv_vertex_offset[poly_index]; + const int start_vertex_index = center_vertex_index + 1; + const int start_inner_vertex_index = center_vertex_index + 1; + const int start_edge_index = ctx->edge_inner_offset + + ctx->subdiv_edge_offset[poly_index]; + const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; + const int start_loop_index = 4 * start_poly_index; + const float du = inv_ptex_resolution_1; + const float dv = inv_ptex_resolution_1; + /* Hi-poly subdivided mesh. */ + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MLoop *subdiv_loopoop = subdiv_mesh->mloop; + MLoop *subdiv_loop = &subdiv_loopoop[start_loop_index]; + LoopsForInterpolation loop_interpolation; + loop_interpolation_init(ctx, &loop_interpolation, coarse_poly); + for (int corner = 0; + corner < coarse_poly->totloop; + corner++) { + const int corner_vertex_index = + start_vertex_index + corner * num_inner_vertices_per_ptex; + const int corner_edge_index = + start_edge_index + corner * num_inner_edges_per_ptex_face; loop_interpolation_from_ptex(ctx, &loop_interpolation, coarse_poly, - ptex_of_poly_index); - const int current_ptex_face_index = - ptex_face_index + ptex_of_poly_index; - for (int y = 0; y < ptex_resolution - 1; y++) { + corner); + for (int y = 1; y < ptex_face_inner_resolution; y++) { const float v = y * inv_ptex_resolution_1; - for (int x = 0; x < ptex_resolution - 1; x++, subdiv_loop += 4) { + const int inner_y = y - 1; + for (int x = 1; + x < ptex_face_inner_resolution + 1; + x++, subdiv_loop += 4) + { + const int inner_x = x - 1; const float u = x * inv_ptex_resolution_1; /* Vertex indicies ordered counter-clockwise. */ - const int v0 = start_vertex_index + - (ptex_of_poly_index * ptex_resolution2) + - (y * ptex_resolution + x); + const int v0 = + corner_vertex_index + + (inner_y * (ptex_face_inner_resolution + 1) + inner_x); const int v1 = v0 + 1; - const int v2 = v0 + ptex_resolution + 1; - const int v3 = v0 + ptex_resolution; + const int v2 = v0 + ptex_face_inner_resolution + 2; + const int v3 = v0 + ptex_face_inner_resolution + 1; /* Edge indicies ordered counter-clockwise. */ - const int e0 = start_edge_index + - (ptex_of_poly_index * num_edges_per_ptex) + - (y * (2 * ptex_resolution - 1) + x); - const int e1 = e0 + ptex_resolution; - const int e2 = e0 + (2 * ptex_resolution - 1); - const int e3 = e0 + ptex_resolution - 1; - /* Initialize 4 loops of corresponding hi-poly poly. */ - /* TODO(sergey): For ptex boundaries we should use loops from - * coarse mesh. - */ - subdiv_copy_loop_data(ctx, - &subdiv_loop[0], - &loop_interpolation, - u, v); - subdiv_loop[0].v = v0; - subdiv_loop[0].e = e0; - subdiv_copy_loop_data(ctx, - &subdiv_loop[1], - &loop_interpolation, - u + du, v); - subdiv_loop[1].v = v1; - subdiv_loop[1].e = e1; - subdiv_copy_loop_data(ctx, - &subdiv_loop[2], - &loop_interpolation, - u + du, v + dv); - subdiv_loop[2].v = v2; - subdiv_loop[2].e = e2; - subdiv_copy_loop_data(ctx, - &subdiv_loop[3], - &loop_interpolation, - u, v + dv); - subdiv_loop[3].v = v3; - subdiv_loop[3].e = e3; - /* Interpolate UV layers using OpenSubdiv. */ - subdiv_eval_uv_layer(ctx, - subdiv_loop, - current_ptex_face_index, - u, v, - inv_ptex_resolution_1); + const int e0 = corner_edge_index + + (inner_y * (2 * ptex_face_inner_resolution + 1) + inner_x); + const int e1 = e0 + ptex_face_inner_resolution + 1; + const int e2 = e0 + (2 * ptex_face_inner_resolution + 1); + const int e3 = e0 + ptex_face_inner_resolution; + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index + corner, 0, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); } } } + /* Create connections between ptex faces. */ + for (int corner = 0; corner < coarse_poly->totloop; corner++) { + const int next_corner = (corner + 1) % coarse_poly->totloop; + const int corner_edge_index = + start_edge_index + corner * num_inner_edges_per_ptex_face; + const int next_corner_edge_index = + start_edge_index + next_corner * num_inner_edges_per_ptex_face; + int current_patch_vertex_index = + start_inner_vertex_index + + corner * num_inner_vertices_per_ptex + + ptex_face_inner_resolution; + int next_path_vertex_index = + start_inner_vertex_index + + next_corner * num_inner_vertices_per_ptex + + num_inner_vertices_per_ptex - ptex_face_resolution + 1; + int v0 = current_patch_vertex_index; + int v1 = next_path_vertex_index; + current_patch_vertex_index += ptex_face_inner_resolution + 1; + next_path_vertex_index += 1; + int e0 = start_edge_index + + coarse_poly->totloop * num_inner_edges_per_ptex_face + + corner * (ptex_face_resolution - 2); + int e1 = next_corner_edge_index + num_inner_edges_per_ptex_face - + ptex_face_resolution + 2; + int e3 = corner_edge_index + 2 * ptex_face_resolution - 4; + loop_interpolation_from_ptex(ctx, + &loop_interpolation, + coarse_poly, + next_corner); + for (int row = 1; + row < ptex_face_inner_resolution; + row++, subdiv_loop += 4) + { + const int v2 = next_path_vertex_index; + const int v3 = current_patch_vertex_index; + const int e2 = e0 + 1; + const float u = row * du; + const float v = 1.0f - dv; + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index + next_corner, 3, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); + current_patch_vertex_index += ptex_face_inner_resolution + 1; + next_path_vertex_index += 1; + v0 = v3; + v1 = v2; + e0 = e2; + e1 += 1; + e3 += 2 * ptex_face_resolution - 3; + } + } + /* Create loops from center. */ + if (ptex_face_resolution >= 3) { + const int start_center_edge_index = + start_edge_index + + (num_inner_edges_per_ptex_face + + ptex_face_inner_resolution) * coarse_poly->totloop; + const int start_boundary_edge = + start_edge_index + + coarse_poly->totloop * num_inner_edges_per_ptex_face + + ptex_face_inner_resolution - 1; + for (int corner = 0, prev_corner = coarse_poly->totloop - 1; + corner < coarse_poly->totloop; + prev_corner = corner, corner++, subdiv_loop += 4) + { + loop_interpolation_from_ptex(ctx, + &loop_interpolation, + coarse_poly, + corner); + const int corner_edge_index = + start_edge_index + + corner * num_inner_edges_per_ptex_face; + const int current_patch_end_vertex_index = + start_vertex_index + corner * num_inner_vertices_per_ptex + + num_inner_vertices_per_ptex - 1; + const int prev_current_patch_end_vertex_index = + start_vertex_index + prev_corner * + num_inner_vertices_per_ptex + + num_inner_vertices_per_ptex - 1; + const int v0 = center_vertex_index; + const int v1 = prev_current_patch_end_vertex_index; + const int v2 = current_patch_end_vertex_index - 1; + const int v3 = current_patch_end_vertex_index; + const int e0 = start_center_edge_index + prev_corner; + const int e1 = start_boundary_edge + + prev_corner * (ptex_face_inner_resolution); + const int e2 = corner_edge_index + + num_inner_edges_per_ptex_face - 1; + const int e3 = start_center_edge_index + corner; + const float u = 1.0f - du; + const float v = 1.0f - dv; + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index + corner, 2, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); + } + } + /* Loops for faces connecting inner ptex part with boundary. */ + const MLoop *prev_coarse_loop = + &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1]; + for (int prev_corner = coarse_poly->totloop - 1, corner = 0; + corner < coarse_poly->totloop; + prev_corner = corner, corner++) + { + loop_interpolation_from_ptex(ctx, + &loop_interpolation, + coarse_poly, + corner); + const MLoop *coarse_loop = + &coarse_mloop[coarse_poly->loopstart + corner]; + const MEdge *coarse_edge = &coarse_medge[coarse_loop->e]; + const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e]; + const bool flip = (coarse_edge->v2 == coarse_loop->v); + const int start_edge_vertex = ctx->vertices_edge_offset + + coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + const int corner_vertex_index = + start_vertex_index + corner * num_inner_vertices_per_ptex; + const int corner_edge_index = + start_edge_index + corner * num_inner_edges_per_ptex_face; + /* Create loops for polygons along U axis. */ + int v0 = ctx->vertices_corner_offset + coarse_loop->v; + int v3, e3; + if (prev_coarse_loop->v == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + num_subdiv_vertices_per_coarse_edge - 1; + e3 = ctx->edge_boundary_offset + + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + + num_subdiv_edges_per_coarse_edge - 1; + } + else { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + e3 = ctx->edge_boundary_offset + + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; + } + for (int i = 0; + i <= ptex_face_inner_resolution; + i++, subdiv_loop += 4) + { + int v1; + if (flip) { + v1 = start_edge_vertex + (resolution - i - 3); + } + else { + v1 = start_edge_vertex + i; + } + int v2; + if (ptex_face_inner_resolution >= 1) { + v2 = corner_vertex_index + i; + } + else { + v2 = center_vertex_index; + } + int e0; + if (flip) { + e0 = ctx->edge_boundary_offset + + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + num_subdiv_edges_per_coarse_edge - i - 1; + } else { + e0 = ctx->edge_boundary_offset + + coarse_loop->e * num_subdiv_edges_per_coarse_edge + + i; + } + int e1 = start_edge_index + + corner * (2 * ptex_face_inner_resolution + 1); + if (ptex_face_resolution >= 3) { + e1 += coarse_poly->totloop * (num_inner_edges_per_ptex_face + + ptex_face_inner_resolution + 1) + + i; + } + int e2 = 0; + if (i == 0 && ptex_face_resolution >= 3) { + e2 = start_edge_index + + coarse_poly->totloop * + (num_inner_edges_per_ptex_face + + ptex_face_inner_resolution + 1) + + corner * (2 * ptex_face_inner_resolution + 1) + + ptex_face_inner_resolution + 1; + } + else if (i == 0 && ptex_face_resolution < 3) { + e2 = start_edge_index + + prev_corner * (2 * ptex_face_inner_resolution + 1); + } + else { + e2 = corner_edge_index + i - 1; + } + const float u = du * i; + const float v = 0.0f; + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index + corner, 0, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); + v0 = v1; + v3 = v2; + e3 = e1; + } + /* Create loops for polygons along V axis. */ + const bool flip_prev = (prev_coarse_edge->v2 == coarse_loop->v); + v0 = corner_vertex_index; + if (prev_coarse_loop->v == prev_coarse_edge->v1) { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + + num_subdiv_vertices_per_coarse_edge - 1; + } + else { + v3 = ctx->vertices_edge_offset + + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; + } + e3 = start_edge_index + + coarse_poly->totloop * + (num_inner_edges_per_ptex_face + + ptex_face_inner_resolution + 1) + + corner * (2 * ptex_face_inner_resolution + 1) + + ptex_face_inner_resolution + 1; + for (int i = 0; + i <= ptex_face_inner_resolution - 1; + i++, subdiv_loop += 4) + { + int v1; + int e0, e1; + if (i == ptex_face_inner_resolution - 1) { + v1 = start_vertex_index + + prev_corner * num_inner_vertices_per_ptex + + ptex_face_inner_resolution; + e1 = start_edge_index + + coarse_poly->totloop * + (num_inner_edges_per_ptex_face + + ptex_face_inner_resolution + 1) + + prev_corner * (2 * ptex_face_inner_resolution + 1) + + ptex_face_inner_resolution; + e0 = start_edge_index + + coarse_poly->totloop * num_inner_edges_per_ptex_face + + prev_corner * ptex_face_inner_resolution; + } + else { + v1 = v0 + ptex_face_inner_resolution + 1; + e0 = corner_edge_index + ptex_face_inner_resolution + + i * (2 * ptex_face_inner_resolution + 1); + e1 = e3 + 1; + } + int v2 = flip_prev ? v3 - 1 : v3 + 1; + int e2; + if (flip_prev) { + e2 = ctx->edge_boundary_offset + + prev_coarse_loop->e * + num_subdiv_edges_per_coarse_edge + + num_subdiv_edges_per_coarse_edge - 2 - i; + } + else { + e2 = ctx->edge_boundary_offset + + prev_coarse_loop->e * + num_subdiv_edges_per_coarse_edge + 1 + i; + } + const float u = 0.0f; + const float v = du * (i + 1); + subdiv_create_loops_of_poly( + ctx, &loop_interpolation, subdiv_loop, + ptex_face_index + corner, 1, + v0, e0, v1, e1, v2, e2, v3, e3, + u, v, du, dv); + v0 = v1; + v3 = v2; + e3 = e1; + } + prev_coarse_loop = coarse_loop; + } loop_interpolation_end(&loop_interpolation); } +static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_poly = &coarse_mpoly[poly_index]; + if (coarse_poly->totloop == 4) { + subdiv_create_loops_regular(ctx, coarse_poly); + } + else { + subdiv_create_loops_special(ctx, coarse_poly); + } +} + /* ============================================================================= * Polygons subdivision process. */ @@ -1001,9 +2180,6 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, coarse_poly_index, subdiv_poly_index, 1); - if (ctx->poly_origindex != NULL) { - // ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index; - } } static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) @@ -1051,13 +2227,22 @@ static void subdiv_eval_task( const int poly_index, const ParallelRangeTLS *__restrict UNUSED(tls)) { - SubdivMeshContext *data = userdata; + SubdivMeshContext *ctx = userdata; /* Evaluate hi-poly vertex coordinates and normals. */ - subdiv_evaluate_vertices(data, poly_index); + subdiv_evaluate_vertices(ctx, poly_index); /* Create mesh geometry for the given base poly index. */ - subdiv_create_edges(data, poly_index); - subdiv_create_loops(data, poly_index); - subdiv_create_polys(data, poly_index); + subdiv_create_edges(ctx, poly_index); + subdiv_create_loops(ctx, poly_index); + subdiv_create_polys(ctx, poly_index); +} + +static void subdiv_create_boundary_edges_task( + void *__restrict userdata, + const int edge_index, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SubdivMeshContext *ctx = userdata; + subdiv_create_boundary_edges(ctx, edge_index); } Mesh *BKE_subdiv_to_mesh( @@ -1065,6 +2250,7 @@ Mesh *BKE_subdiv_to_mesh( const SubdivToMeshSettings *settings, const Mesh *coarse_mesh) { + // printf("================ MESH SUBDIVISION ================\n"); BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); /* Make sure evaluator is up to date with possible new topology, and that * is is refined for the new positions of coarse vertices. @@ -1086,12 +2272,19 @@ Mesh *BKE_subdiv_to_mesh( subdiv_mesh_ctx_init_result(&ctx); /* Multi-threaded evaluation. */ ParallelRangeSettings parallel_range_settings; + BKE_subdiv_stats_begin(&subdiv->stats, + SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY); BLI_parallel_range_settings_defaults(¶llel_range_settings); BLI_task_parallel_range(0, coarse_mesh->totpoly, &ctx, subdiv_eval_task, ¶llel_range_settings); + BLI_task_parallel_range(0, coarse_mesh->totedge, + &ctx, + subdiv_create_boundary_edges_task, + ¶llel_range_settings); subdiv_mesh_ctx_free(&ctx); + BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY); // BKE_mesh_validate(result, true, true); BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); return result; diff --git a/source/blender/blenkernel/intern/subdiv_stats.c b/source/blender/blenkernel/intern/subdiv_stats.c index 5da63fdbacb..f2219961ab7 100644 --- a/source/blender/blenkernel/intern/subdiv_stats.c +++ b/source/blender/blenkernel/intern/subdiv_stats.c @@ -37,6 +37,7 @@ void BKE_subdiv_stats_init(SubdivStats *stats) { stats->topology_refiner_creation_time = 0.0; stats->subdiv_to_mesh_time = 0.0; + stats->subdiv_to_mesh_geometry_time = 0.0; stats->evaluator_creation_time = 0.0; stats->evaluator_refine_time = 0.0; } @@ -69,6 +70,9 @@ void BKE_subdiv_stats_print(const SubdivStats *stats) STATS_PRINT_TIME(stats, subdiv_to_mesh_time, "Subdivision to mesh time"); + STATS_PRINT_TIME(stats, + subdiv_to_mesh_geometry_time, + " Geometry time"); STATS_PRINT_TIME(stats, evaluator_creation_time, "Evaluator creation time"); diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index 82704e95fdd..bf3329f8ed5 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -70,6 +70,12 @@ typedef unsigned int BLI_bitmap; ((_bitmap)[(_index) >> _BITMAP_POWER] & \ (1u << ((_index) & _BITMAP_MASK)))) +#define BLI_BITMAP_TEST_AND_SET_ATOMIC(_bitmap, _index) \ + (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ + (atomic_fetch_and_or_uint8((uint8_t*)&(_bitmap)[(_index) >> _BITMAP_POWER], \ + (1u << ((_index) & _BITMAP_MASK))) & \ + (1u << ((_index) & _BITMAP_MASK)))) + #define BLI_BITMAP_TEST_BOOL(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ (BLI_BITMAP_TEST(_bitmap, _index) != 0)) diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 08dc7c92693..7c605dd4f78 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -57,7 +57,7 @@ #include "intern/CCGSubSurf.h" -// #define USE_OPENSUBDIV +#define USE_OPENSUBDIV static void initData(ModifierData *md) { -- cgit v1.2.3 From fe6e751e695dbb32e4dc7ed20726ee3d266d0c7e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 10:25:54 +0200 Subject: Workbench: Correct ifndef after recent changes Usage of matcap image uniform had different ifdef than definition of that uniform. Assuming the usage was correct, and the definition needed an update. Prevents shader from compilation failure and from aborts in debug builds. --- .../workbench/shaders/workbench_forward_transparent_accum_frag.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index 81b6b2567a9..67a22073a4b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -19,7 +19,7 @@ in vec3 normal_viewport; #ifdef V3D_SHADING_TEXTURE_COLOR in vec2 uv_interp; #endif -#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL +#ifdef V3D_LIGHTING_MATCAP uniform sampler2D matcapImage; #endif -- cgit v1.2.3 From 36389444b03ec149fb9c013b744b9d5126f85ae2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 18:42:22 +1000 Subject: Fix Shape Key retime starting at frame 10 D3571 by @alm --- source/blender/editors/object/object_shapekey.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index eec8b60cef0..e67b62ea624 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -376,8 +376,10 @@ static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op)) if (!key || !kb) return OPERATOR_CANCELLED; - for (kb = key->block.first; kb; kb = kb->next) - kb->pos = (cfra += 0.1f); + for (kb = key->block.first; kb; kb = kb->next) { + kb->pos = cfra; + cfra += 0.1f; + } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); -- cgit v1.2.3 From 66da2f537ae80ce2b31d1eaf34ad8c03d858938d Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 10:22:19 +0200 Subject: New Grease Pencil object for 2D animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit merge the full development done in greasepencil-object branch and include mainly the following features. - New grease pencil object. - New drawing engine. - New grease pencil modes Draw/Sculpt/Edit and Weight Paint. - New brushes for grease pencil. - New modifiers for grease pencil. - New shaders FX. - New material system (replace old palettes and colors). - Split of annotations (old grease pencil) and new grease pencil object. - UI adapted to blender 2.8. You can get more info here: https://code.blender.org/2017/12/drawing-2d-animation-in-blender-2-8/ https://code.blender.org/2018/07/grease-pencil-status-update/ This is the result of nearly two years of development and I want thanks firstly the other members of the grease pencil team: Daniel M. Lara, Matias Mendiola and Joshua Leung for their support, ideas and to keep working in the project all the time, without them this project had been impossible. Also, I want thanks other Blender developers for their help, advices and to be there always to help me, and specially to Clément Foucault, Dalai Felinto, Pablo Vázquez and Campbell Barton. --- build_files/cmake/macros.cmake | 5 +- intern/cycles/blender/addon/ui.py | 5 +- release/datafiles/brushicons/gp_brush_block.png | Bin 0 -> 6088 bytes release/datafiles/brushicons/gp_brush_clone.png | Bin 0 -> 2586 bytes .../datafiles/brushicons/gp_brush_erase_hard.png | Bin 0 -> 6107 bytes .../datafiles/brushicons/gp_brush_erase_soft.png | Bin 0 -> 6252 bytes .../datafiles/brushicons/gp_brush_erase_stroke.png | Bin 0 -> 5955 bytes release/datafiles/brushicons/gp_brush_fill.png | Bin 0 -> 5707 bytes release/datafiles/brushicons/gp_brush_grab.png | Bin 0 -> 2741 bytes release/datafiles/brushicons/gp_brush_ink.png | Bin 0 -> 4034 bytes release/datafiles/brushicons/gp_brush_inknoise.png | Bin 0 -> 5591 bytes release/datafiles/brushicons/gp_brush_marker.png | Bin 0 -> 5996 bytes release/datafiles/brushicons/gp_brush_pen.png | Bin 0 -> 4920 bytes release/datafiles/brushicons/gp_brush_pencil.png | Bin 0 -> 3965 bytes release/datafiles/brushicons/gp_brush_pinch.png | Bin 0 -> 5432 bytes release/datafiles/brushicons/gp_brush_push.png | Bin 0 -> 2914 bytes .../datafiles/brushicons/gp_brush_randomize.png | Bin 0 -> 5726 bytes release/datafiles/brushicons/gp_brush_smooth.png | Bin 0 -> 3105 bytes release/datafiles/brushicons/gp_brush_strength.png | Bin 0 -> 3229 bytes .../datafiles/brushicons/gp_brush_thickness.png | Bin 0 -> 5066 bytes release/datafiles/brushicons/gp_brush_twist.png | Bin 0 -> 4776 bytes release/datafiles/brushicons/gp_brush_weight.png | Bin 0 -> 2460 bytes .../icons/brush.gpencil.draw.eraser_hard.dat | Bin 0 -> 1736 bytes .../icons/brush.gpencil.draw.eraser_soft.dat | Bin 0 -> 1880 bytes .../icons/brush.gpencil.draw.eraser_stroke.dat | Bin 0 -> 2456 bytes .../datafiles/icons/brush.gpencil.draw_block.dat | Bin 0 -> 2006 bytes .../datafiles/icons/brush.gpencil.draw_fill.dat | Bin 0 -> 6326 bytes release/datafiles/icons/brush.gpencil.draw_ink.dat | Bin 0 -> 2240 bytes .../datafiles/icons/brush.gpencil.draw_marker.dat | Bin 0 -> 2690 bytes .../datafiles/icons/brush.gpencil.draw_noise.dat | Bin 0 -> 3086 bytes release/datafiles/icons/brush.gpencil.draw_pen.dat | Bin 0 -> 3158 bytes .../datafiles/icons/brush.gpencil.draw_pencil.dat | Bin 0 -> 2780 bytes release/datafiles/icons/ops.gpencil.draw.dat | Bin 0 -> 2492 bytes .../datafiles/icons/ops.gpencil.draw.eraser.dat | Bin 0 -> 2384 bytes release/datafiles/icons/ops.gpencil.draw.line.dat | Bin 0 -> 1664 bytes release/datafiles/icons/ops.gpencil.draw.poly.dat | Bin 0 -> 1736 bytes release/datafiles/icons/ops.gpencil.edit_bend.dat | Bin 0 -> 2330 bytes .../datafiles/icons/ops.gpencil.edit_mirror.dat | Bin 0 -> 620 bytes release/datafiles/icons/ops.gpencil.edit_shear.dat | Bin 0 -> 332 bytes .../datafiles/icons/ops.gpencil.edit_to_sphere.dat | Bin 0 -> 1790 bytes .../datafiles/icons/ops.gpencil.sculpt_clone.dat | Bin 0 -> 4328 bytes .../datafiles/icons/ops.gpencil.sculpt_grab.dat | Bin 0 -> 1664 bytes .../datafiles/icons/ops.gpencil.sculpt_pinch.dat | Bin 0 -> 3482 bytes .../datafiles/icons/ops.gpencil.sculpt_push.dat | Bin 0 -> 1664 bytes .../icons/ops.gpencil.sculpt_randomize.dat | Bin 0 -> 6254 bytes .../datafiles/icons/ops.gpencil.sculpt_smooth.dat | Bin 0 -> 3788 bytes .../icons/ops.gpencil.sculpt_strength.dat | Bin 0 -> 5228 bytes .../icons/ops.gpencil.sculpt_thickness.dat | Bin 0 -> 1700 bytes .../datafiles/icons/ops.gpencil.sculpt_twist.dat | Bin 0 -> 2942 bytes .../datafiles/icons/ops.gpencil.sculpt_weight.dat | Bin 0 -> 1736 bytes release/datafiles/preview_grease_pencil.blend | Bin 0 -> 947876 bytes release/datafiles/userdef/userdef_default_theme.c | 10 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- .../scripts/modules/bpy_extras/keyconfig_utils.py | 6 + release/scripts/startup/bl_operators/presets.py | 37 + release/scripts/startup/bl_ui/__init__.py | 3 + .../startup/bl_ui/properties_data_gpencil.py | 402 ++++ .../startup/bl_ui/properties_data_modifier.py | 445 +++- .../startup/bl_ui/properties_data_shaderfx.py | 134 ++ .../bl_ui/properties_grease_pencil_common.py | 785 ++----- .../scripts/startup/bl_ui/properties_material.py | 7 +- .../startup/bl_ui/properties_material_gpencil.py | 322 +++ release/scripts/startup/bl_ui/properties_scene.py | 35 +- release/scripts/startup/bl_ui/space_clip.py | 45 +- release/scripts/startup/bl_ui/space_image.py | 55 +- release/scripts/startup/bl_ui/space_node.py | 56 +- release/scripts/startup/bl_ui/space_sequencer.py | 10 - .../startup/bl_ui/space_toolsystem_toolbar.py | 564 ++++- release/scripts/startup/bl_ui/space_topbar.py | 11 + release/scripts/startup/bl_ui/space_userpref.py | 11 +- release/scripts/startup/bl_ui/space_view3d.py | 324 ++- .../scripts/startup/bl_ui/space_view3d_toolbar.py | 415 +++- source/blender/CMakeLists.txt | 4 + source/blender/blenkernel/BKE_brush.h | 8 +- source/blender/blenkernel/BKE_context.h | 12 +- source/blender/blenkernel/BKE_gpencil.h | 103 +- source/blender/blenkernel/BKE_gpencil_modifier.h | 256 +++ source/blender/blenkernel/BKE_icons.h | 7 + source/blender/blenkernel/BKE_lattice.h | 1 - source/blender/blenkernel/BKE_material.h | 4 + source/blender/blenkernel/BKE_object.h | 12 + source/blender/blenkernel/BKE_paint.h | 3 +- source/blender/blenkernel/BKE_shader_fx.h | 180 ++ source/blender/blenkernel/CMakeLists.txt | 6 + source/blender/blenkernel/intern/anim_sys.c | 7 + source/blender/blenkernel/intern/brush.c | 380 +++- source/blender/blenkernel/intern/colortools.c | 19 + source/blender/blenkernel/intern/context.c | 20 +- source/blender/blenkernel/intern/deform.c | 4 +- source/blender/blenkernel/intern/gpencil.c | 1383 +++++++----- .../blender/blenkernel/intern/gpencil_modifier.c | 679 ++++++ source/blender/blenkernel/intern/icons.c | 44 +- source/blender/blenkernel/intern/library.c | 1 + source/blender/blenkernel/intern/library_query.c | 25 +- source/blender/blenkernel/intern/material.c | 76 +- source/blender/blenkernel/intern/object.c | 194 +- source/blender/blenkernel/intern/object_deform.c | 16 +- source/blender/blenkernel/intern/object_update.c | 4 + source/blender/blenkernel/intern/paint.c | 13 +- source/blender/blenkernel/intern/scene.c | 81 +- source/blender/blenkernel/intern/shader_fx.c | 245 ++ source/blender/blenlib/BLI_math_vector.h | 3 + source/blender/blenlib/BLI_rand.h | 3 + source/blender/blenlib/intern/listbase.c | 3 + source/blender/blenlib/intern/math_vector_inline.c | 13 + source/blender/blenlib/intern/rand.c | 12 + source/blender/blenloader/intern/readfile.c | 246 +- source/blender/blenloader/intern/versioning_260.c | 4 +- source/blender/blenloader/intern/versioning_270.c | 85 +- source/blender/blenloader/intern/versioning_280.c | 199 +- .../blenloader/intern/versioning_defaults.c | 50 +- source/blender/blenloader/intern/writefile.c | 105 +- source/blender/collada/SceneExporter.cpp | 2 + .../depsgraph/intern/builder/deg_builder_nodes.cc | 34 +- .../intern/builder/deg_builder_nodes_view_layer.cc | 4 - .../intern/builder/deg_builder_relations.cc | 124 +- .../builder/deg_builder_relations_view_layer.cc | 4 - source/blender/depsgraph/intern/depsgraph_tag.cc | 9 +- source/blender/draw/CMakeLists.txt | 34 + source/blender/draw/DRW_engine.h | 3 + .../draw/engines/gpencil/gpencil_cache_utils.c | 296 +++ .../draw/engines/gpencil/gpencil_draw_cache_impl.c | 739 ++++++ .../draw/engines/gpencil/gpencil_draw_utils.c | 1336 +++++++++++ .../blender/draw/engines/gpencil/gpencil_engine.c | 794 +++++++ .../blender/draw/engines/gpencil/gpencil_engine.h | 355 +++ .../blender/draw/engines/gpencil/gpencil_render.c | 353 +++ .../draw/engines/gpencil/gpencil_shader_fx.c | 848 +++++++ .../gpencil/shaders/fx/gpencil_fx_blur_frag.glsl | 60 + .../shaders/fx/gpencil_fx_colorize_frag.glsl | 86 + .../gpencil/shaders/fx/gpencil_fx_flip_frag.glsl | 37 + .../gpencil/shaders/fx/gpencil_fx_light_frag.glsl | 70 + .../gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl | 50 + .../shaders/fx/gpencil_fx_rim_prepare_frag.glsl | 64 + .../shaders/fx/gpencil_fx_rim_resolve_frag.glsl | 101 + .../gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl | 70 + .../gpencil/shaders/fx/gpencil_fx_wave_frag.glsl | 40 + .../gpencil/shaders/gpencil_background_frag.glsl | 12 + .../gpencil/shaders/gpencil_edit_point_frag.glsl | 17 + .../gpencil/shaders/gpencil_edit_point_geom.glsl | 48 + .../gpencil/shaders/gpencil_edit_point_vert.glsl | 15 + .../engines/gpencil/shaders/gpencil_fill_frag.glsl | 140 ++ .../engines/gpencil/shaders/gpencil_fill_vert.glsl | 14 + .../gpencil/shaders/gpencil_paper_frag.glsl | 9 + .../gpencil/shaders/gpencil_point_frag.glsl | 49 + .../gpencil/shaders/gpencil_point_geom.glsl | 82 + .../gpencil/shaders/gpencil_point_vert.glsl | 37 + .../gpencil/shaders/gpencil_simple_mix_frag.glsl | 15 + .../gpencil/shaders/gpencil_stroke_frag.glsl | 46 + .../gpencil/shaders/gpencil_stroke_geom.glsl | 208 ++ .../gpencil/shaders/gpencil_stroke_vert.glsl | 37 + .../gpencil/shaders/gpencil_zdepth_mix_frag.glsl | 45 + source/blender/draw/intern/DRW_render.h | 1 + source/blender/draw/intern/draw_cache.c | 60 +- source/blender/draw/intern/draw_cache.h | 3 + source/blender/draw/intern/draw_cache_impl.h | 4 + source/blender/draw/intern/draw_manager.c | 145 +- source/blender/draw/modes/draw_mode_engines.h | 1 + source/blender/draw/modes/object_mode.c | 18 + .../editors/animation/anim_channels_defines.c | 15 +- .../blender/editors/animation/anim_channels_edit.c | 3 +- source/blender/editors/animation/anim_deps.c | 10 + source/blender/editors/animation/anim_draw.c | 4 +- source/blender/editors/animation/anim_filter.c | 13 +- source/blender/editors/animation/keyframes_draw.c | 9 +- source/blender/editors/datafiles/CMakeLists.txt | 52 + source/blender/editors/gpencil/CMakeLists.txt | 6 + source/blender/editors/gpencil/annotate_draw.c | 1065 +++++++++ source/blender/editors/gpencil/annotate_paint.c | 2382 ++++++++++++++++++++ source/blender/editors/gpencil/drawgpencil.c | 989 ++++---- .../blender/editors/gpencil/editaction_gpencil.c | 2 + .../blender/editors/gpencil/gpencil_add_monkey.c | 1567 +++++++++++++ source/blender/editors/gpencil/gpencil_brush.c | 695 ++++-- source/blender/editors/gpencil/gpencil_convert.c | 70 +- source/blender/editors/gpencil/gpencil_data.c | 1809 +++++++++------ source/blender/editors/gpencil/gpencil_edit.c | 1635 +++++++++++--- source/blender/editors/gpencil/gpencil_fill.c | 1246 ++++++++++ source/blender/editors/gpencil/gpencil_intern.h | 271 ++- .../blender/editors/gpencil/gpencil_interpolate.c | 71 +- source/blender/editors/gpencil/gpencil_old.c | 219 ++ source/blender/editors/gpencil/gpencil_ops.c | 547 ++++- source/blender/editors/gpencil/gpencil_paint.c | 1337 +++++++---- source/blender/editors/gpencil/gpencil_primitive.c | 712 ++++++ source/blender/editors/gpencil/gpencil_select.c | 293 ++- source/blender/editors/gpencil/gpencil_undo.c | 6 + source/blender/editors/gpencil/gpencil_utils.c | 1262 ++++++++--- source/blender/editors/include/ED_anim_api.h | 5 + source/blender/editors/include/ED_datafiles.h | 63 + source/blender/editors/include/ED_gpencil.h | 188 +- source/blender/editors/include/ED_keyframes_draw.h | 5 +- source/blender/editors/include/ED_object.h | 35 + source/blender/editors/include/UI_icons.h | 24 + source/blender/editors/include/UI_interface.h | 9 +- source/blender/editors/interface/interface_icons.c | 100 +- .../blender/editors/interface/interface_layout.c | 8 + .../editors/interface/interface_templates.c | 308 ++- source/blender/editors/interface/resources.c | 20 +- source/blender/editors/object/CMakeLists.txt | 4 + source/blender/editors/object/object_add.c | 131 +- source/blender/editors/object/object_edit.c | 42 +- .../editors/object/object_gpencil_modifier.c | 637 ++++++ source/blender/editors/object/object_intern.h | 15 + source/blender/editors/object/object_modes.c | 18 +- source/blender/editors/object/object_modifier.c | 238 +- source/blender/editors/object/object_ops.c | 15 + source/blender/editors/object/object_relations.c | 23 +- source/blender/editors/object/object_select.c | 5 +- source/blender/editors/object/object_shader_fx.c | 469 ++++ source/blender/editors/object/object_transform.c | 103 +- source/blender/editors/render/render_opengl.c | 94 +- source/blender/editors/render/render_preview.c | 38 +- source/blender/editors/render/render_shading.c | 8 +- source/blender/editors/screen/area.c | 28 +- source/blender/editors/screen/screen_context.c | 84 +- source/blender/editors/screen/screen_ops.c | 7 +- source/blender/editors/sculpt_paint/paint_ops.c | 46 +- .../blender/editors/space_action/action_select.c | 69 +- .../editors/space_buttons/buttons_context.c | 44 +- .../editors/space_buttons/buttons_texture.c | 17 + .../blender/editors/space_buttons/space_buttons.c | 41 +- source/blender/editors/space_clip/clip_buttons.c | 2 +- source/blender/editors/space_clip/space_clip.c | 6 +- source/blender/editors/space_image/image_buttons.c | 2 +- source/blender/editors/space_info/info_stats.c | 32 + source/blender/editors/space_nla/nla_buttons.c | 3 +- source/blender/editors/space_nla/nla_channels.c | 1 + source/blender/editors/space_node/drawnode.c | 30 +- .../blender/editors/space_outliner/outliner_draw.c | 415 ++-- .../editors/space_outliner/outliner_select.c | 30 + .../blender/editors/space_outliner/outliner_tree.c | 2 - source/blender/editors/space_topbar/space_topbar.c | 4 + source/blender/editors/space_view3d/drawobject.c | 1 + source/blender/editors/space_view3d/space_view3d.c | 13 +- source/blender/editors/space_view3d/view3d_draw.c | 2 +- .../editors/space_view3d/view3d_draw_legacy.c | 2 +- source/blender/editors/space_view3d/view3d_edit.c | 8 +- .../editors/space_view3d/view3d_gizmo_ruler.c | 33 +- source/blender/editors/space_view3d/view3d_ruler.c | 33 +- .../blender/editors/space_view3d/view3d_select.c | 24 + source/blender/editors/transform/transform.c | 69 +- .../editors/transform/transform_conversions.c | 330 +-- .../blender/editors/transform/transform_generics.c | 22 +- .../blender/editors/transform/transform_gizmo_3d.c | 9 +- .../editors/transform/transform_snap_object.c | 7 +- source/blender/editors/undo/ed_undo.c | 27 + source/blender/gpencil_modifiers/CMakeLists.txt | 70 + .../gpencil_modifiers/MOD_gpencil_modifiertypes.h | 53 + .../gpencil_modifiers/intern/MOD_gpencil_util.c | 142 ++ .../gpencil_modifiers/intern/MOD_gpencil_util.h | 47 + .../gpencil_modifiers/intern/MOD_gpencilbuild.c | 558 +++++ .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 178 ++ .../gpencil_modifiers/intern/MOD_gpencilhook.c | 355 +++ .../gpencil_modifiers/intern/MOD_gpencilinstance.c | 360 +++ .../gpencil_modifiers/intern/MOD_gpencillattice.c | 213 ++ .../gpencil_modifiers/intern/MOD_gpencilmirror.c | 239 ++ .../gpencil_modifiers/intern/MOD_gpencilnoise.c | 285 +++ .../gpencil_modifiers/intern/MOD_gpenciloffset.c | 143 ++ .../gpencil_modifiers/intern/MOD_gpencilopacity.c | 171 ++ .../gpencil_modifiers/intern/MOD_gpencilsimplify.c | 123 + .../gpencil_modifiers/intern/MOD_gpencilsmooth.c | 152 ++ .../gpencil_modifiers/intern/MOD_gpencilsubdiv.c | 193 ++ .../gpencil_modifiers/intern/MOD_gpencilthick.c | 171 ++ .../gpencil_modifiers/intern/MOD_gpenciltint.c | 186 ++ source/blender/gpu/CMakeLists.txt | 8 + source/blender/gpu/GPU_shader.h | 5 +- source/blender/gpu/intern/gpu_shader.c | 14 + .../gpu/shaders/gpu_shader_gpencil_fill_frag.glsl | 166 ++ .../gpu/shaders/gpu_shader_gpencil_fill_vert.glsl | 11 + .../shaders/gpu_shader_gpencil_stroke_frag.glsl | 20 + .../shaders/gpu_shader_gpencil_stroke_geom.glsl | 196 ++ .../shaders/gpu_shader_gpencil_stroke_vert.glsl | 33 + source/blender/makesdna/DNA_ID.h | 2 +- source/blender/makesdna/DNA_brush_types.h | 109 +- source/blender/makesdna/DNA_color_types.h | 1 + .../blender/makesdna/DNA_gpencil_modifier_types.h | 404 ++++ source/blender/makesdna/DNA_gpencil_types.h | 319 ++- source/blender/makesdna/DNA_material_types.h | 76 + source/blender/makesdna/DNA_object_enums.h | 5 +- source/blender/makesdna/DNA_object_types.h | 19 +- source/blender/makesdna/DNA_scene_types.h | 105 +- source/blender/makesdna/DNA_shader_fx_types.h | 196 ++ source/blender/makesdna/DNA_space_types.h | 3 +- source/blender/makesdna/DNA_userdef_types.h | 6 +- source/blender/makesdna/DNA_view3d_types.h | 29 +- source/blender/makesdna/intern/makesdna.c | 4 + source/blender/makesrna/RNA_access.h | 28 +- source/blender/makesrna/RNA_enum_types.h | 4 + source/blender/makesrna/intern/CMakeLists.txt | 2 + source/blender/makesrna/intern/makesrna.c | 2 + source/blender/makesrna/intern/rna_brush.c | 441 ++++ source/blender/makesrna/intern/rna_context.c | 4 + source/blender/makesrna/intern/rna_gpencil.c | 1003 +++------ .../blender/makesrna/intern/rna_gpencil_modifier.c | 1314 +++++++++++ source/blender/makesrna/intern/rna_internal.h | 7 + source/blender/makesrna/intern/rna_main_api.c | 13 + source/blender/makesrna/intern/rna_material.c | 337 +++ source/blender/makesrna/intern/rna_movieclip.c | 1 + source/blender/makesrna/intern/rna_nodetree.c | 1 + source/blender/makesrna/intern/rna_object.c | 212 +- source/blender/makesrna/intern/rna_palette.c | 4 +- source/blender/makesrna/intern/rna_scene.c | 425 +--- source/blender/makesrna/intern/rna_sculpt_paint.c | 149 +- source/blender/makesrna/intern/rna_shader_fx.c | 538 +++++ source/blender/makesrna/intern/rna_space.c | 151 +- source/blender/makesrna/intern/rna_tracking.c | 1 + source/blender/makesrna/intern/rna_ui_api.c | 26 + source/blender/makesrna/intern/rna_userdef.c | 8 + .../blender/render/intern/source/external_engine.c | 3 + source/blender/shader_fx/CMakeLists.txt | 64 + source/blender/shader_fx/FX_shader_types.h | 47 + source/blender/shader_fx/intern/FX_shader_blur.c | 66 + .../blender/shader_fx/intern/FX_shader_colorize.c | 69 + source/blender/shader_fx/intern/FX_shader_flip.c | 69 + source/blender/shader_fx/intern/FX_shader_light.c | 104 + source/blender/shader_fx/intern/FX_shader_pixel.c | 66 + source/blender/shader_fx/intern/FX_shader_rim.c | 70 + source/blender/shader_fx/intern/FX_shader_swirl.c | 103 + source/blender/shader_fx/intern/FX_shader_util.c | 56 + source/blender/shader_fx/intern/FX_shader_util.h | 36 + source/blender/shader_fx/intern/FX_shader_wave.c | 71 + source/blender/windowmanager/intern/wm_operators.c | 2 +- source/creator/creator.c | 4 + 322 files changed, 39490 insertions(+), 6439 deletions(-) create mode 100644 release/datafiles/brushicons/gp_brush_block.png create mode 100644 release/datafiles/brushicons/gp_brush_clone.png create mode 100644 release/datafiles/brushicons/gp_brush_erase_hard.png create mode 100644 release/datafiles/brushicons/gp_brush_erase_soft.png create mode 100644 release/datafiles/brushicons/gp_brush_erase_stroke.png create mode 100644 release/datafiles/brushicons/gp_brush_fill.png create mode 100644 release/datafiles/brushicons/gp_brush_grab.png create mode 100644 release/datafiles/brushicons/gp_brush_ink.png create mode 100644 release/datafiles/brushicons/gp_brush_inknoise.png create mode 100644 release/datafiles/brushicons/gp_brush_marker.png create mode 100644 release/datafiles/brushicons/gp_brush_pen.png create mode 100644 release/datafiles/brushicons/gp_brush_pencil.png create mode 100644 release/datafiles/brushicons/gp_brush_pinch.png create mode 100644 release/datafiles/brushicons/gp_brush_push.png create mode 100644 release/datafiles/brushicons/gp_brush_randomize.png create mode 100644 release/datafiles/brushicons/gp_brush_smooth.png create mode 100644 release/datafiles/brushicons/gp_brush_strength.png create mode 100644 release/datafiles/brushicons/gp_brush_thickness.png create mode 100644 release/datafiles/brushicons/gp_brush_twist.png create mode 100644 release/datafiles/brushicons/gp_brush_weight.png create mode 100644 release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_block.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_fill.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_ink.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_marker.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_noise.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_pen.dat create mode 100644 release/datafiles/icons/brush.gpencil.draw_pencil.dat create mode 100644 release/datafiles/icons/ops.gpencil.draw.dat create mode 100644 release/datafiles/icons/ops.gpencil.draw.eraser.dat create mode 100644 release/datafiles/icons/ops.gpencil.draw.line.dat create mode 100644 release/datafiles/icons/ops.gpencil.draw.poly.dat create mode 100644 release/datafiles/icons/ops.gpencil.edit_bend.dat create mode 100644 release/datafiles/icons/ops.gpencil.edit_mirror.dat create mode 100644 release/datafiles/icons/ops.gpencil.edit_shear.dat create mode 100644 release/datafiles/icons/ops.gpencil.edit_to_sphere.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_clone.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_grab.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_pinch.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_push.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_randomize.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_smooth.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_strength.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_thickness.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_twist.dat create mode 100644 release/datafiles/icons/ops.gpencil.sculpt_weight.dat create mode 100644 release/datafiles/preview_grease_pencil.blend create mode 100644 release/scripts/startup/bl_ui/properties_data_gpencil.py create mode 100644 release/scripts/startup/bl_ui/properties_data_shaderfx.py create mode 100644 release/scripts/startup/bl_ui/properties_material_gpencil.py create mode 100644 source/blender/blenkernel/BKE_gpencil_modifier.h create mode 100644 source/blender/blenkernel/BKE_shader_fx.h create mode 100644 source/blender/blenkernel/intern/gpencil_modifier.c create mode 100644 source/blender/blenkernel/intern/shader_fx.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_cache_utils.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_draw_utils.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_engine.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_engine.h create mode 100644 source/blender/draw/engines/gpencil/gpencil_render.c create mode 100644 source/blender/draw/engines/gpencil/gpencil_shader_fx.c create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl create mode 100644 source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl create mode 100644 source/blender/editors/gpencil/annotate_draw.c create mode 100644 source/blender/editors/gpencil/annotate_paint.c create mode 100644 source/blender/editors/gpencil/gpencil_add_monkey.c create mode 100644 source/blender/editors/gpencil/gpencil_fill.c create mode 100644 source/blender/editors/gpencil/gpencil_old.c create mode 100644 source/blender/editors/gpencil/gpencil_primitive.c create mode 100644 source/blender/editors/object/object_gpencil_modifier.c create mode 100644 source/blender/editors/object/object_shader_fx.c create mode 100644 source/blender/gpencil_modifiers/CMakeLists.txt create mode 100644 source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c create mode 100644 source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c create mode 100644 source/blender/gpu/shaders/gpu_shader_gpencil_fill_frag.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_gpencil_fill_vert.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_gpencil_stroke_frag.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_gpencil_stroke_vert.glsl create mode 100644 source/blender/makesdna/DNA_gpencil_modifier_types.h create mode 100644 source/blender/makesdna/DNA_shader_fx_types.h create mode 100644 source/blender/makesrna/intern/rna_gpencil_modifier.c create mode 100644 source/blender/makesrna/intern/rna_shader_fx.c create mode 100644 source/blender/shader_fx/CMakeLists.txt create mode 100644 source/blender/shader_fx/FX_shader_types.h create mode 100644 source/blender/shader_fx/intern/FX_shader_blur.c create mode 100644 source/blender/shader_fx/intern/FX_shader_colorize.c create mode 100644 source/blender/shader_fx/intern/FX_shader_flip.c create mode 100644 source/blender/shader_fx/intern/FX_shader_light.c create mode 100644 source/blender/shader_fx/intern/FX_shader_pixel.c create mode 100644 source/blender/shader_fx/intern/FX_shader_rim.c create mode 100644 source/blender/shader_fx/intern/FX_shader_swirl.c create mode 100644 source/blender/shader_fx/intern/FX_shader_util.c create mode 100644 source/blender/shader_fx/intern/FX_shader_util.h create mode 100644 source/blender/shader_fx/intern/FX_shader_wave.c diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index ae265654724..65f962d2dd9 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -598,12 +598,12 @@ function(SETUP_BLENDER_SORTED_LIBS) bf_editor_util bf_editor_uvedit bf_editor_curve - bf_editor_gpencil bf_editor_interface bf_editor_gizmo_library bf_editor_mesh bf_editor_metaball bf_editor_object + bf_editor_gpencil bf_editor_lattice bf_editor_armature bf_editor_physics @@ -626,12 +626,15 @@ function(SETUP_BLENDER_SORTED_LIBS) bf_freestyle bf_ikplugin bf_modifiers + bf_gpencil_modifiers bf_alembic bf_bmesh bf_gpu bf_draw bf_blenloader bf_blenkernel + bf_shader_fx + bf_gpencil_modifiers bf_physics bf_nodes bf_rna diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index a1941ce6176..737f7416486 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -895,7 +895,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): @classmethod def poll(cls, context): - return (context.material or context.object) and CyclesButtonsPanel.poll(context) + if context.active_object and context.active_object.type == 'GPENCIL': + return False + else: + return (context.material or context.object) and CyclesButtonsPanel.poll(context) def draw(self, context): layout = self.layout diff --git a/release/datafiles/brushicons/gp_brush_block.png b/release/datafiles/brushicons/gp_brush_block.png new file mode 100644 index 00000000000..2db3964e573 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_block.png differ diff --git a/release/datafiles/brushicons/gp_brush_clone.png b/release/datafiles/brushicons/gp_brush_clone.png new file mode 100644 index 00000000000..8358ace23b3 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_clone.png differ diff --git a/release/datafiles/brushicons/gp_brush_erase_hard.png b/release/datafiles/brushicons/gp_brush_erase_hard.png new file mode 100644 index 00000000000..2ac52840678 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_hard.png differ diff --git a/release/datafiles/brushicons/gp_brush_erase_soft.png b/release/datafiles/brushicons/gp_brush_erase_soft.png new file mode 100644 index 00000000000..416923004dd Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_soft.png differ diff --git a/release/datafiles/brushicons/gp_brush_erase_stroke.png b/release/datafiles/brushicons/gp_brush_erase_stroke.png new file mode 100644 index 00000000000..cd6d21532cf Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_erase_stroke.png differ diff --git a/release/datafiles/brushicons/gp_brush_fill.png b/release/datafiles/brushicons/gp_brush_fill.png new file mode 100644 index 00000000000..9dac633139c Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_fill.png differ diff --git a/release/datafiles/brushicons/gp_brush_grab.png b/release/datafiles/brushicons/gp_brush_grab.png new file mode 100644 index 00000000000..2123ac69aef Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_grab.png differ diff --git a/release/datafiles/brushicons/gp_brush_ink.png b/release/datafiles/brushicons/gp_brush_ink.png new file mode 100644 index 00000000000..410a77f6117 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_ink.png differ diff --git a/release/datafiles/brushicons/gp_brush_inknoise.png b/release/datafiles/brushicons/gp_brush_inknoise.png new file mode 100644 index 00000000000..5356f697e01 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_inknoise.png differ diff --git a/release/datafiles/brushicons/gp_brush_marker.png b/release/datafiles/brushicons/gp_brush_marker.png new file mode 100644 index 00000000000..c7a62b78ca7 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_marker.png differ diff --git a/release/datafiles/brushicons/gp_brush_pen.png b/release/datafiles/brushicons/gp_brush_pen.png new file mode 100644 index 00000000000..9aaaa861f49 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pen.png differ diff --git a/release/datafiles/brushicons/gp_brush_pencil.png b/release/datafiles/brushicons/gp_brush_pencil.png new file mode 100644 index 00000000000..2d1fbdfd916 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pencil.png differ diff --git a/release/datafiles/brushicons/gp_brush_pinch.png b/release/datafiles/brushicons/gp_brush_pinch.png new file mode 100644 index 00000000000..e38236d1be0 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_pinch.png differ diff --git a/release/datafiles/brushicons/gp_brush_push.png b/release/datafiles/brushicons/gp_brush_push.png new file mode 100644 index 00000000000..542764309cc Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_push.png differ diff --git a/release/datafiles/brushicons/gp_brush_randomize.png b/release/datafiles/brushicons/gp_brush_randomize.png new file mode 100644 index 00000000000..0dd1a131d86 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_randomize.png differ diff --git a/release/datafiles/brushicons/gp_brush_smooth.png b/release/datafiles/brushicons/gp_brush_smooth.png new file mode 100644 index 00000000000..7518a358219 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_smooth.png differ diff --git a/release/datafiles/brushicons/gp_brush_strength.png b/release/datafiles/brushicons/gp_brush_strength.png new file mode 100644 index 00000000000..a0513119f29 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_strength.png differ diff --git a/release/datafiles/brushicons/gp_brush_thickness.png b/release/datafiles/brushicons/gp_brush_thickness.png new file mode 100644 index 00000000000..6026716f026 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_thickness.png differ diff --git a/release/datafiles/brushicons/gp_brush_twist.png b/release/datafiles/brushicons/gp_brush_twist.png new file mode 100644 index 00000000000..84b9a90e9d6 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_twist.png differ diff --git a/release/datafiles/brushicons/gp_brush_weight.png b/release/datafiles/brushicons/gp_brush_weight.png new file mode 100644 index 00000000000..171e9221e92 Binary files /dev/null and b/release/datafiles/brushicons/gp_brush_weight.png differ diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat new file mode 100644 index 00000000000..1e909ca8ac9 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat new file mode 100644 index 00000000000..7242f76a0f9 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat new file mode 100644 index 00000000000..6bf620bf3c2 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_block.dat b/release/datafiles/icons/brush.gpencil.draw_block.dat new file mode 100644 index 00000000000..7a7402ef673 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_block.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_fill.dat b/release/datafiles/icons/brush.gpencil.draw_fill.dat new file mode 100644 index 00000000000..809aed7f3cf Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_fill.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_ink.dat b/release/datafiles/icons/brush.gpencil.draw_ink.dat new file mode 100644 index 00000000000..3c654712783 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_ink.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_marker.dat b/release/datafiles/icons/brush.gpencil.draw_marker.dat new file mode 100644 index 00000000000..77a52dd83d4 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_marker.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_noise.dat b/release/datafiles/icons/brush.gpencil.draw_noise.dat new file mode 100644 index 00000000000..127f469b9fb Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_noise.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_pen.dat b/release/datafiles/icons/brush.gpencil.draw_pen.dat new file mode 100644 index 00000000000..cb6fb77924a Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_pen.dat differ diff --git a/release/datafiles/icons/brush.gpencil.draw_pencil.dat b/release/datafiles/icons/brush.gpencil.draw_pencil.dat new file mode 100644 index 00000000000..a8898a94917 Binary files /dev/null and b/release/datafiles/icons/brush.gpencil.draw_pencil.dat differ diff --git a/release/datafiles/icons/ops.gpencil.draw.dat b/release/datafiles/icons/ops.gpencil.draw.dat new file mode 100644 index 00000000000..3adc50ab17d Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.dat differ diff --git a/release/datafiles/icons/ops.gpencil.draw.eraser.dat b/release/datafiles/icons/ops.gpencil.draw.eraser.dat new file mode 100644 index 00000000000..323d8c23245 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.eraser.dat differ diff --git a/release/datafiles/icons/ops.gpencil.draw.line.dat b/release/datafiles/icons/ops.gpencil.draw.line.dat new file mode 100644 index 00000000000..238db63807a Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.line.dat differ diff --git a/release/datafiles/icons/ops.gpencil.draw.poly.dat b/release/datafiles/icons/ops.gpencil.draw.poly.dat new file mode 100644 index 00000000000..8351e48fec1 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.draw.poly.dat differ diff --git a/release/datafiles/icons/ops.gpencil.edit_bend.dat b/release/datafiles/icons/ops.gpencil.edit_bend.dat new file mode 100644 index 00000000000..32f7b2e9631 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_bend.dat differ diff --git a/release/datafiles/icons/ops.gpencil.edit_mirror.dat b/release/datafiles/icons/ops.gpencil.edit_mirror.dat new file mode 100644 index 00000000000..ee073664f78 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_mirror.dat differ diff --git a/release/datafiles/icons/ops.gpencil.edit_shear.dat b/release/datafiles/icons/ops.gpencil.edit_shear.dat new file mode 100644 index 00000000000..e6b51f988f8 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_shear.dat differ diff --git a/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat new file mode 100644 index 00000000000..bf1181cd500 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.edit_to_sphere.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_clone.dat b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat new file mode 100644 index 00000000000..dbae6a68159 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_clone.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_grab.dat b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat new file mode 100644 index 00000000000..291b4fd12dc Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_grab.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat new file mode 100644 index 00000000000..cb2b43f5597 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_pinch.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_push.dat b/release/datafiles/icons/ops.gpencil.sculpt_push.dat new file mode 100644 index 00000000000..e1c4961ff86 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_push.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat new file mode 100644 index 00000000000..35042936757 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat new file mode 100644 index 00000000000..3a132ed4049 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_smooth.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat new file mode 100644 index 00000000000..7e52b0d7648 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat new file mode 100644 index 00000000000..1e558806888 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_twist.dat b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat new file mode 100644 index 00000000000..4ce958cb7ec Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_twist.dat differ diff --git a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat new file mode 100644 index 00000000000..41b58abfda7 Binary files /dev/null and b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat differ diff --git a/release/datafiles/preview_grease_pencil.blend b/release/datafiles/preview_grease_pencil.blend new file mode 100644 index 00000000000..82661d80029 Binary files /dev/null and b/release/datafiles/preview_grease_pencil.blend differ diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c index 11a9fbaca00..69ad58ea1c5 100644 --- a/release/datafiles/userdef/userdef_default_theme.c +++ b/release/datafiles/userdef/userdef_default_theme.c @@ -1,8 +1,8 @@ /* - * Generated by 'source/tools/utils/blender_theme_as_c.py' - * - * Do not hand edit this file! - */ +* Generated by 'source/tools/utils/blender_theme_as_c.py' +* +* Do not hand edit this file! +*/ #include "DNA_userdef_types.h" @@ -1040,5 +1040,5 @@ const bTheme U_theme_default = { .select = RGBA(0x000000ff), .active = RGBA(0x000000ff), }, - }, +}, }; diff --git a/release/scripts/addons b/release/scripts/addons index c87ee4d46f1..371960484a3 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit c87ee4d46f16d60a2e1db7514c8d5ab42c5d93df +Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 15b25a42783..47470215783 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 15b25a42783d1e516b5298d70b582fae2559ae17 +Subproject commit 474702157831f1a58bb50f5240ab8b1b02b6ba37 diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index 6859e327b66..4e5cb7daad9 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -121,6 +121,12 @@ KM_HIERARCHY = [ ('Grease Pencil', 'EMPTY', 'WINDOW', [ # grease pencil stuff (per region) ('Grease Pencil Stroke Edit Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint (Draw brush)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint (Fill)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint (Erase)', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Paint Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Sculpt Mode', 'EMPTY', 'WINDOW', []), + ('Grease Pencil Stroke Weight Mode', 'EMPTY', 'WINDOW', []), ]), ('Mask Editing', 'EMPTY', 'WINDOW', []), ('Frames', 'EMPTY', 'WINDOW', []), # frame navigation (per region) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index fe09fada297..0fe45f8fee3 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -670,6 +670,42 @@ class AddPresetUnitsLength(AddPresetBase, Operator): preset_subdir = "units_length" +class AddPresetGpencilBrush(AddPresetBase, Operator): + """Add or remove grease pencil brush preset""" + bl_idname = "scene.gpencil_brush_preset_add" + bl_label = "Add Grease Pencil Brush Preset" + preset_menu = "VIEW3D_PT_gpencil_brush_presets" + + preset_defines = [ + "brush = bpy.context.active_gpencil_brush", + "settings = brush.gpencil_settings" + ] + + preset_values = [ + "settings.input_samples", + "settings.active_smooth_factor", + "settings.angle", + "settings.angle_factor", + "settings.use_stabilizer", + "brush.smooth_stroke_radius", + "brush.smooth_stroke_factor", + "settings.pen_smooth_factor", + "settings.pen_smooth_steps", + "settings.pen_thick_smooth_factor", + "settings.pen_thick_smooth_steps", + "settings.pen_subdivision_steps", + "settings.random_subdiv", + "settings.enable_random", + "settings.random_pressure", + "settings.random_strength", + "settings.uv_random", + "settings.pen_jitter", + "settings.use_jitter_pressure", + ] + + preset_subdir = "gpencil_brush" + + classes = ( AddPresetCamera, AddPresetCloth, @@ -686,6 +722,7 @@ classes = ( AddPresetTrackingSettings, AddPresetTrackingTrackColor, AddPresetUnitsLength, + AddPresetGpencilBrush, ExecutePreset, WM_MT_operator_presets, ) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 51ba45cdcd7..89aed37f055 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -34,16 +34,19 @@ _modules = [ "properties_data_camera", "properties_data_curve", "properties_data_empty", + "properties_data_gpencil", "properties_data_light", "properties_data_lattice", "properties_data_mesh", "properties_data_metaball", "properties_data_modifier", + "properties_data_shaderfx", "properties_data_lightprobe", "properties_data_speaker", "properties_data_workspace", "properties_mask_common", "properties_material", + "properties_material_gpencil", "properties_object", "properties_paint_common", "properties_grease_pencil_common", diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py new file mode 100644 index 00000000000..14407afa8f2 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -0,0 +1,402 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy +from bpy.types import Menu, Panel, UIList +from rna_prop_ui import PropertyPanel +from .properties_grease_pencil_common import ( + GreasePencilDataPanel, + GreasePencilOnionPanel, + ) + +############################### +# Base-Classes (for shared stuff - e.g. poll, attributes, etc.) + +class DataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + return context.object and context.object.type == 'GPENCIL' + + +class LayerDataButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + + @classmethod + def poll(cls, context): + return (context.object and + context.object.type == 'GPENCIL' and + context.active_gpencil_layer) + + +############################### +# GP Object Properties Panels and Helper Classes + +class DATA_PT_gpencil(DataButtonsPanel, Panel): + bl_label = "" + bl_options = {'HIDE_HEADER'} + + def draw(self, context): + layout = self.layout + + # Grease Pencil data selector + gpd_owner = context.gpencil_data_owner + gpd = context.gpencil_data + + layout.template_ID(gpd_owner, "data") + + +class GPENCIL_UL_layer(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # assert(isinstance(item, bpy.types.GPencilLayer) + gpl = item + gpd = context.gpencil_data + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + if gpl.lock: + layout.active = False + + row = layout.row(align=True) + if gpl.is_parented: + icon = 'BONE_DATA' + else: + icon = 'BLANK1' + + row.label(text="", icon=icon) + row.prop(gpl, "info", text="", emboss=False) + + row = layout.row(align=True) + row.prop(gpl, "lock", text="", emboss=False) + row.prop(gpl, "hide", text="", emboss=False) + row.prop(gpl, "unlock_color", text="", emboss=False) + if gpl.use_onion_skinning is False: + icon = 'GHOST_DISABLED' + else: + icon = 'GHOST_ENABLED' + subrow = row.row(align=True) + subrow.prop(gpl, "use_onion_skinning", text="", icon=icon, emboss=False) + subrow.active = gpd.use_onion_skinning + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + +class GPENCIL_MT_layer_specials(Menu): + bl_label = "Layer" + + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.layer_duplicate", icon='COPY_ID') # XXX: needs a dedicated icon + + layout.separator() + + layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All") + layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True + + layout.separator() + + layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All") + layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All") + + layout.separator() + + layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down") + + +class DATA_PT_gpencil_datapanel(Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_label = "Layers" + + @classmethod + def poll(cls, context): + if context.gpencil_data is None: + return False + + ob = context.object + if ob is not None and ob.type == 'GPENCIL': + return True + + return False + + @staticmethod + def draw(self, context): + layout = self.layout + #layout.use_property_split = True + layout.use_property_decorate = False + + gpd = context.gpencil_data + + # Grease Pencil data... + if (gpd is None) or (not gpd.layers): + layout.operator("gpencil.layer_add", text="New Layer") + else: + self.draw_layers(context, layout, gpd) + + def draw_layers(self, context, layout, gpd): + row = layout.row() + + col = row.column() + if len(gpd.layers) >= 2: + layer_rows = 5 + else: + layer_rows = 2 + col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows) + + col = row.column() + + sub = col.column(align=True) + sub.operator("gpencil.layer_add", icon='ZOOMIN', text="") + sub.operator("gpencil.layer_remove", icon='ZOOMOUT', text="") + + gpl = context.active_gpencil_layer + if gpl: + sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="") + + if len(gpd.layers) > 1: + col.separator() + + sub = col.column(align=True) + sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' + sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + + col.separator() + + sub = col.column(align=True) + sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False + sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True + + row = layout.row(align=True) + if gpl: + row.prop(gpl, "opacity", text="Opacity", slider=True) + + +class DATA_PT_gpencil_layer_optionpanel(LayerDataButtonsPanel, Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_label = "Adjustments" + bl_parent_id = 'DATA_PT_gpencil_datapanel' + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + gpl = context.active_gpencil_layer + layout.active = not gpl.lock + + # Layer options + # Offsets - Color Tint + layout.enabled = not gpl.lock + col = layout.column(align=True) + col.prop(gpl, "tint_color") + col.prop(gpl, "tint_factor", slider=True) + + # Offsets - Thickness + col = layout.row(align=True) + col.prop(gpl, "line_change", text="Stroke Thickness") + + +class DATA_PT_gpencil_parentpanel(LayerDataButtonsPanel, Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_label = "Relations" + bl_parent_id = 'DATA_PT_gpencil_datapanel' + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + gpl = context.active_gpencil_layer + col = layout.column(align=True) + col.active = not gpl.lock + col.prop(gpl, "parent", text="Parent") + col.prop(gpl, "parent_type", text="Parent Type") + parent = gpl.parent + + if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE': + col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone") + + +class DATA_PT_gpencil_onionpanel(Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_label = "Onion Skinning" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return bool(context.active_gpencil_layer) + + @staticmethod + def draw_header(self, context): + self.layout.prop(context.gpencil_data, "use_onion_skinning", text="") + + def draw(self, context): + gpd = context.gpencil_data + + layout = self.layout + layout.use_property_split = True + layout.enabled = gpd.use_onion_skinning + + GreasePencilOnionPanel.draw_settings(layout, gpd) + + +class GPENCIL_MT_gpencil_vertex_group(Menu): + bl_label = "GP Vertex Groups" + + def draw(self, context): + layout = self.layout + + layout.operator_context = 'EXEC_AREA' + layout.operator("object.vertex_group_add") + + ob = context.active_object + if ob.vertex_groups.active: + layout.separator() + + layout.operator("gpencil.vertex_group_assign", text="Assign to Active Group") + layout.operator("gpencil.vertex_group_remove_from", text="Remove from Active Group") + + layout.separator() + layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group") + layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False + layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True + + layout.separator() + layout.operator("gpencil.vertex_group_select", text="Select Points") + layout.operator("gpencil.vertex_group_deselect", text="Deselect Points") + + +class GPENCIL_UL_vgroups(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + vgroup = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon) + # icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED' + # layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + +class DATA_PT_gpencil_vertexpanel(DataButtonsPanel, Panel): + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_label = "Vertex Groups" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + + ob = context.object + group = ob.vertex_groups.active + + rows = 2 + if group: + rows = 4 + + row = layout.row() + row.template_list("GPENCIL_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows) + + col = row.column(align=True) + col.operator("object.vertex_group_add", icon='ZOOMIN', text="") + col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="").all = False + + if ob.vertex_groups: + row = layout.row() + + sub = row.row(align=True) + sub.operator("gpencil.vertex_group_assign", text="Assign") + sub.operator("gpencil.vertex_group_remove_from", text="Remove") + + sub = row.row(align=True) + sub.operator("gpencil.vertex_group_select", text="Select") + sub.operator("gpencil.vertex_group_deselect", text="Deselect") + + layout.prop(context.tool_settings, "vertex_group_weight", text="Weight") + + +class DATA_PT_gpencil_display(DataButtonsPanel, Panel): + bl_label = "Viewport Display" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + + gpd = context.gpencil_data + gpl = context.active_gpencil_layer + + layout.prop(gpd, "xray_mode", text="Depth Ordering") + layout.prop(gpd, "edit_line_color", text="Edit Line Color") + layout.prop(ob, "empty_draw_size", text="Marker Size") + + col = layout.column(align=True) + col.prop(gpd, "show_constant_thickness") + sub = col.column() + sub.active = not gpd.show_constant_thickness + sub.prop(gpd, "pixfactor", text="Thickness Scale") + + if gpl: + layout.prop(gpd, "show_stroke_direction", text="Show Stroke Directions") + + +class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel): + _context_path = "object.data" + _property_type = bpy.types.GreasePencil + +############################### + +classes = ( + DATA_PT_gpencil, + DATA_PT_gpencil_datapanel, + DATA_PT_gpencil_onionpanel, + DATA_PT_gpencil_layer_optionpanel, + DATA_PT_gpencil_parentpanel, + DATA_PT_gpencil_vertexpanel, + DATA_PT_gpencil_display, + DATA_PT_custom_props_gpencil, + + GPENCIL_UL_layer, + GPENCIL_UL_vgroups, + + GPENCIL_MT_layer_specials, + GPENCIL_MT_gpencil_vertex_group, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 03ebea69d2b..2328925bbad 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -28,10 +28,14 @@ class ModifierButtonsPanel: bl_context = "modifier" bl_options = {'HIDE_HEADER'} - class DATA_PT_modifiers(ModifierButtonsPanel, Panel): bl_label = "Modifiers" + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type != 'GPENCIL' + def draw(self, context): layout = self.layout @@ -1563,8 +1567,447 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind") +class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): + bl_label = "Modifiers" + + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type == 'GPENCIL' + + def draw(self, context): + layout = self.layout + + ob = context.object + + layout.operator_menu_enum("object.gpencil_modifier_add", "type") + + for md in ob.grease_pencil_modifiers: + box = layout.template_greasepencil_modifier(md) + if box: + # match enum type to our functions, avoids a lookup table. + getattr(self, md.type)(box, ob, md) + + # the mt.type enum is (ab)used for a lookup on function names + # ...to avoid lengthy if statements + # so each type must have a function here. + + def GP_NOISE(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + row = col.row(align=True) + row.prop(md, "factor") + row.prop(md, "random", text="", icon="TIME", toggle=True) + row = col.row() + row.enabled = md.random + row.prop(md, "step") + col.prop(md, "full_stroke") + col.prop(md, "move_extreme") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row(align=True) + row.label("Affect:") + row = layout.row(align=True) + row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True) + row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True) + row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True) + row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) + + def GP_SMOOTH(self, layout, ob, md): + gpd = ob.data + row = layout.row(align=False) + row.prop(md, "factor") + row.prop(md, "step") + + split = layout.split() + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col = split.column() + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row(align=True) + row.label("Affect:") + row = layout.row(align=True) + row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True) + row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True) + row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True) + row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True) + + def GP_SUBDIV(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + row = col.row(align=True) + row.prop(md, "level") + row.prop(md, "simple", text="", icon="PARTICLE_POINT") + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + def GP_SIMPLIFY(self, layout, ob, md): + gpd = ob.data + + row = layout.row() + row.prop(md, "mode") + + split = layout.split() + + col = split.column() + col.label("Settings:") + row = col.row(align=True) + row.enabled = md.mode == 'FIXED' + row.prop(md, "step") + + row = col.row(align=True) + row.enabled = not md.mode == 'FIXED' + row.prop(md, "factor") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + def GP_THICK(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + row = col.row(align=True) + row.prop(md, "thickness") + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + col.prop(md, "normalize_thickness") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + if not md.normalize_thickness: + split = layout.split() + col = split.column() + col.prop(md, "use_custom_curve") + + if md.use_custom_curve: + col.template_curve_mapping(md, "curve") + + def GP_TINT(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.prop(md, "color") + col.prop(md, "factor") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row() + row.prop(md, "create_colors") + + def GP_COLOR(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.label("Color:") + col.prop(md, "hue", text="H") + col.prop(md, "saturation", text="S") + col.prop(md, "value", text="V") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row() + row.prop(md, "create_colors") + + def GP_OPACITY(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.label("Opacity:") + col.prop(md, "factor") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + def GP_INSTANCE(self, layout, ob, md): + gpd = ob.data + + col = layout.column() + col.prop(md, "count") + col.prop(md, "use_make_objects") + + split = layout.split() + col = split.column() + col.label("Offset:") + col.prop(md, "offset", text="") + + col = split.column() + col.label("Shift:") + col.prop(md, "shift", text="") + row = col.row(align=True) + row.prop(md, "lock_axis", expand=True) + + split = layout.split() + col = split.column() + col.label("Rotation:") + col.prop(md, "rotation", text="") + col.separator() + row = col.row(align=True) + row.prop(md, "random_rot", text="", icon="TIME", toggle=True) + row.prop(md, "rot_factor", text="") + + col = split.column() + col.label("Scale:") + col.prop(md, "scale", text="") + col.separator() + row = col.row(align=True) + row.prop(md, "random_scale", text="", icon="TIME", toggle=True) + row.prop(md, "scale_factor", text="") + + split = layout.split() + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + def GP_BUILD(self, layout, ob, md): + gpd = ob.data + + split = layout.split() + + col = split.column() + col.prop(md, "mode") + if md.mode == 'CONCURRENT': + col.prop(md, "concurrent_time_alignment") + else: + col.separator() # For spacing + col.separator() + col.separator() + + col.prop(md, "transition") + sub = col.column(align=True) + sub.prop(md, "start_delay") + sub.prop(md, "length") + + col = split.column(align=True) + col.prop(md, "use_restrict_frame_range") + sub = col.column(align=True) + sub.active = md.use_restrict_frame_range + sub.prop(md, "frame_start", text="Start") + sub.prop(md, "frame_end", text="End") + col.separator() + + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + def GP_LATTICE(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.label(text="Object:") + col.prop(md, "object", text="") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + layout.separator() + layout.prop(md, "strength", slider=True) + + def GP_MIRROR(self, layout, ob, md): + gpd = ob.data + + row = layout.row(align=True) + row.prop(md, "x_axis") + row.prop(md, "y_axis") + row.prop(md, "z_axis") + + # GPXX: Not implemented yet + # layout.separator() + # layout.prop(md, "clip") + + layout.label("Layer:") + row = layout.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + layout.label(text="Object:") + layout.prop(md, "object", text="") + + + def GP_HOOK(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.label(text="Object:") + col.prop(md, "object", text="") + if md.object and md.object.type == 'ARMATURE': + col.label(text="Bone:") + col.prop_search(md, "subtarget", md.object.data, "bones", text="") + + col = split.column() + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + use_falloff = (md.falloff_type != 'NONE') + split = layout.split() + + layout.separator() + + row = layout.row(align=True) + if use_falloff: + row.prop(md, "falloff_radius") + row.prop(md, "strength", slider=True) + layout.prop(md, "falloff_type") + + col = layout.column() + if use_falloff: + if md.falloff_type == 'CURVE': + col.template_curve_mapping(md, "falloff_curve") + + split = layout.split() + + col = split.column() + col.prop(md, "use_falloff_uniform") + + + def GP_OFFSET(self, layout, ob, md): + gpd = ob.data + split = layout.split() + + col = split.column() + col.prop(md, "location") + col.prop(md, "scale") + + col = split.column() + col.prop(md, "rotation") + + + col.label("Layer:") + row = col.row(align=True) + row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') + row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT") + + col.label("Vertex Group:") + row = col.row(align=True) + row.prop_search(md, "vertex_group", ob, "vertex_groups", text="") + row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT") + + row = col.row(align=True) + row.prop(md, "pass_index", text="Pass") + row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + classes = ( DATA_PT_modifiers, + DATA_PT_gpencil_modifiers, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_data_shaderfx.py b/release/scripts/startup/bl_ui/properties_data_shaderfx.py new file mode 100644 index 00000000000..5010f56d234 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_data_shaderfx.py @@ -0,0 +1,134 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy +from bpy.types import Panel +from bpy.app.translations import pgettext_iface as iface_ + + +class ShaderFxButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "shaderfx" + bl_options = {'HIDE_HEADER'} + +class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): + bl_label = "Effects" + + @classmethod + def poll(cls, context): + return True + ob = context.object + return ob and ob.type == 'GPENCIL' + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + + layout.operator_menu_enum("object.shaderfx_add", "type") + + for fx in ob.shader_effects: + box = layout.template_shaderfx(fx) + if box: + # match enum type to our functions, avoids a lookup table. + getattr(self, fx.type)(box, fx) + + # the mt.type enum is (ab)used for a lookup on function names + # ...to avoid lengthy if statements + # so each type must have a function here. + + def FX_BLUR(self, layout, fx): + + layout.prop(fx, "factor", text="Factor") + layout.prop(fx, "samples", text="Samples") + + layout.separator() + layout.prop(fx, "use_dof_mode") + if fx.use_dof_mode: + layout.prop(fx, "coc") + + def FX_COLORIZE(self, layout, fx): + layout.prop(fx, "mode", text="Mode") + + if fx.mode == 'BITONE': + layout.prop(fx, "low_color", text="Low Color") + if fx.mode == 'CUSTOM': + layout.prop(fx, "low_color", text="Color") + + if fx.mode == 'BITONE': + layout.prop(fx, "high_color", text="High Color") + + if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}: + layout.prop(fx, "factor") + + def FX_WAVE(self, layout,fx): + layout.prop(fx, "orientation", expand=True) + + layout.separator() + layout.prop(fx, "amplitude") + layout.prop(fx, "period") + layout.prop(fx, "phase") + + def FX_PIXEL(self, layout, fx): + layout.prop(fx, "size", text="Size") + + layout.prop(fx, "use_lines", text="Display Lines") + + col = layout.column() + col.enabled = fx.use_lines + col.prop(fx, "color") + + def FX_RIM(self, layout, fx): + layout.prop(fx, "offset", text="Offset") + + layout.prop(fx, "rim_color") + layout.prop(fx, "mask_color") + layout.prop(fx, "mode") + layout.prop(fx, "blur") + layout.prop(fx, "samples") + + def FX_SWIRL(self, layout, fx): + layout.prop(fx, "object", text="Object") + + layout.prop(fx, "radius") + layout.prop(fx, "angle") + + layout.prop(fx, "transparent") + + def FX_FLIP(self, layout, fx): + layout.prop(fx, "flip_horizontal") + layout.prop(fx, "flip_vertical") + + def FX_LIGHT(self, layout, fx): + layout.prop(fx, "object", text="Object") + + layout.prop(fx, "energy") + layout.prop(fx, "ambient") + + +classes = ( + DATA_PT_shader_fx, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 55b798d103a..252f87d369f 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -18,45 +18,30 @@ # - +import bpy from bpy.types import Menu, UIList from bpy.app.translations import pgettext_iface as iface_ def gpencil_stroke_placement_settings(context, layout): if context.space_data.type == 'VIEW_3D': - propname = "gpencil_stroke_placement_view3d" + propname = "annotation_stroke_placement_view3d" elif context.space_data.type == 'SEQUENCE_EDITOR': - propname = "gpencil_stroke_placement_sequencer_preview" + propname = "annotation_stroke_placement_sequencer_preview" elif context.space_data.type == 'IMAGE_EDITOR': - propname = "gpencil_stroke_placement_image_editor" + propname = "annotation_stroke_placement_image_editor" else: - propname = "gpencil_stroke_placement_view2d" + propname = "annotation_stroke_placement_view2d" ts = context.tool_settings col = layout.column(align=True) - col.label(text="Stroke Placement:") - - row = col.row(align=True) - row.prop_enum(ts, propname, 'VIEW') - row.prop_enum(ts, propname, 'CURSOR') - - if context.space_data.type == 'VIEW_3D': + if context.space_data.type != 'VIEW_3D': + col.label(text="Stroke Placement:") row = col.row(align=True) - row.prop_enum(ts, propname, 'SURFACE') - row.prop_enum(ts, propname, 'STROKE') - - row = col.row(align=False) - row.active = getattr(ts, propname) in {'SURFACE', 'STROKE'} - row.prop(ts, "use_gpencil_stroke_endpoints") - - if context.scene.tool_settings.gpencil_stroke_placement_view3d == 'CURSOR': - row = col.row(align=True) - row.label("Lock axis:") - row = col.row(align=True) - row.prop(ts.gpencil_sculpt, "lockaxis", expand=True) + row.prop_enum(ts, propname, 'VIEW') + row.prop_enum(ts, propname, 'CURSOR', text="Cursor") def gpencil_active_brush_settings_simple(context, layout): @@ -73,7 +58,7 @@ def gpencil_active_brush_settings_simple(context, layout): row.operator_menu_enum("gpencil.brush_change", "brush", text="", icon='BRUSH_DATA') row.prop(brush, "name", text="") - col.prop(brush, "line_width", slider=True) + col.prop(brush, "size", slider=True) row = col.row(align=True) row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE') row.prop(brush, "pen_sensitivity_factor", slider=True) @@ -90,6 +75,7 @@ def gpencil_active_brush_settings_simple(context, layout): row.prop(brush, "angle_factor", text="Factor", slider=True) +# XXX: To be replaced with active tools class GreasePencilDrawingToolsPanel: # subclass must set # bl_space_type = 'IMAGE_EDITOR' @@ -99,8 +85,7 @@ class GreasePencilDrawingToolsPanel: @classmethod def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False + return True @staticmethod def draw(self, context): @@ -113,12 +98,12 @@ class GreasePencilDrawingToolsPanel: col.label(text="Draw:") row = col.row(align=True) - row.operator("gpencil.draw", icon='GREASEPENCIL', text="Draw").mode = 'DRAW' - row.operator("gpencil.draw", icon='FORCE_CURVE', text="Erase").mode = 'ERASER' # XXX: Needs a dedicated icon + row.operator("gpencil.annotate", icon='GREASEPENCIL', text="Draw").mode = 'DRAW' + row.operator("gpencil.annotate", icon='FORCE_CURVE', text="Erase").mode = 'ERASER' # XXX: Needs a dedicated icon row = col.row(align=True) - row.operator("gpencil.draw", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT' - row.operator("gpencil.draw", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY' + row.operator("gpencil.annotate", icon='LINE_DATA', text="Line").mode = 'DRAW_STRAIGHT' + row.operator("gpencil.annotate", icon='MESH_DATA', text="Poly").mode = 'DRAW_POLY' col.separator() @@ -126,15 +111,15 @@ class GreasePencilDrawingToolsPanel: sub.operator("gpencil.blank_frame_add", icon='NEW') sub.operator("gpencil.active_frames_delete_all", icon='X', text="Delete Frame(s)") - sub = col.column(align=True) - sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing") - sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing") - sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back") + #sub = col.column(align=True) + #sub.prop(context.tool_settings, "use_gpencil_additive_drawing", text="Additive Drawing") + #sub.prop(context.tool_settings, "use_gpencil_continuous_drawing", text="Continuous Drawing") + #sub.prop(context.tool_settings, "use_gpencil_draw_onback", text="Draw on Back") col.separator() col.separator() - if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}: + if context.space_data.type in {'CLIP_EDITOR'}: col.separator() col.label("Data Source:") row = col.row(align=True) @@ -143,8 +128,8 @@ class GreasePencilDrawingToolsPanel: elif is_clip_editor: row.prop(context.space_data, "grease_pencil_source", expand=True) - col.separator() - col.separator() + #col.separator() + #col.separator() gpencil_stroke_placement_settings(context, col) @@ -157,28 +142,16 @@ class GreasePencilDrawingToolsPanel: col = layout.column(align=True) col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True) - if is_3d_view: - col.separator() - col.separator() - - col.label(text="Tools:") - col.operator_menu_enum("gpencil.convert", text="Convert to Geometry...", property="type") - col.operator("view3d.ruler") - class GreasePencilStrokeEditPanel: # subclass must set # bl_space_type = 'IMAGE_EDITOR' bl_label = "Edit Strokes" - bl_category = "Grease Pencil" + bl_category = "Tools" bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False - if context.gpencil_data is None: return False @@ -204,7 +177,7 @@ class GreasePencilStrokeEditPanel: col.operator("gpencil.select_linked") col.operator("gpencil.select_more") col.operator("gpencil.select_less") - col.operator("gpencil.palettecolor_select") + col.operator("gpencil.select_alternate") layout.label(text="Edit:") row = layout.row(align=True) @@ -228,258 +201,124 @@ class GreasePencilStrokeEditPanel: layout.separator() - col = layout.column(align=True) - col.operator("transform.bend", text="Bend") - col.operator("transform.mirror", text="Mirror") - col.operator("transform.shear", text="Shear") - col.operator("transform.tosphere", text="To Sphere") - layout.separator() col = layout.column(align=True) col.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction") col.operator("gpencil.stroke_change_color", text="Move to Color") - if is_3d_view: - layout.separator() - layout.separator() col = layout.column(align=True) col.operator("gpencil.stroke_subdivide", text="Subdivide") - col.operator("gpencil.stroke_join", text="Join").type = 'JOIN' - col.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' - col.operator("gpencil.stroke_flip", text="Flip Direction") - - gpd = context.gpencil_data - if gpd: - col.prop(gpd, "show_stroke_direction", text="Show Directions") - - if is_3d_view: - layout.separator() - layout.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type") - - -class GreasePencilInterpolatePanel: - bl_space_type = 'VIEW_3D' - bl_label = "Interpolate" - bl_category = "Grease Pencil" - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False - - if context.gpencil_data is None: - return False - elif context.space_data.type != 'VIEW_3D': - return False - - gpd = context.gpencil_data - return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode) - - @staticmethod - def draw(self, context): - layout = self.layout - settings = context.tool_settings.gpencil_interpolate - - col = layout.column(align=True) - col.operator("gpencil.interpolate", text="Interpolate") - col.operator("gpencil.interpolate_sequence", text="Sequence") - col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns") - - col = layout.column(align=True) - col.label(text="Options:") - col.prop(settings, "interpolate_all_layers") - col.prop(settings, "interpolate_selected_only") - - col = layout.column(align=True) - col.label(text="Sequence Options:") - col.prop(settings, "type") - if settings.type == 'CUSTOM': - box = layout.box() - # TODO: Options for loading/saving curve presets? - box.template_curve_mapping(settings, "interpolation_curve", brush=True) - elif settings.type != 'LINEAR': - col.prop(settings, "easing") - - if settings.type == 'BACK': - layout.prop(settings, "back") - elif setting.type == 'ELASTIC': - sub = layout.column(align=True) - sub.prop(settings, "amplitude") - sub.prop(settings, "period") - - -class GreasePencilBrushPanel: - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Drawing Brushes" - bl_category = "Grease Pencil" - bl_region_type = 'TOOLS' - - @classmethod - def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False + row = col.row(align=True) + row.operator("gpencil.stroke_simplify_fixed", text="Simplify") + row.operator("gpencil.stroke_simplify", text="Adaptative") - @staticmethod - def draw(self, context): - layout = self.layout + col.separator() - row = layout.row() - col = row.column() - ts = context.scene.tool_settings - if len(ts.gpencil_brushes) >= 2: - brows = 3 - else: - brows = 2 - col.template_list("GPENCIL_UL_brush", "", ts, "gpencil_brushes", ts.gpencil_brushes, "active_index", rows=brows) + row = col.row(align=True) + row.operator("gpencil.stroke_join", text="Join").type = 'JOIN' + row.operator("gpencil.stroke_join", text="& Copy").type = 'JOINCOPY' - col = row.column() + col.operator("gpencil.stroke_flip", text="Flip Direction") - sub = col.column(align=True) - sub.operator("gpencil.brush_add", icon='ZOOMIN', text="") - sub.operator("gpencil.brush_remove", icon='ZOOMOUT', text="") - sub.menu("GPENCIL_MT_brush_specials", icon='DOWNARROW_HLT', text="") - brush = context.active_gpencil_brush - if brush: - if len(ts.gpencil_brushes) > 1: - col.separator() - sub = col.column(align=True) - sub.operator("gpencil.brush_move", icon='TRIA_UP', text="").type = 'UP' - sub.operator("gpencil.brush_move", icon='TRIA_DOWN', text="").type = 'DOWN' + if is_3d_view: + layout.separator() - # Brush details - if brush is not None: - row = layout.row() - row.prop(brush, "line_width") - row = layout.row(align=True) - row.prop(brush, "use_random_pressure", text="", icon='RNDCURVE') - row.prop(brush, "pen_sensitivity_factor", slider=True) - row.prop(brush, "use_pressure", text="", icon='STYLUS_PRESSURE') - row = layout.row(align=True) - row.prop(brush, "use_random_strength", text="", icon='RNDCURVE') - row.prop(brush, "strength", slider=True) - row.prop(brush, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') - row = layout.row(align=True) - row.prop(brush, "random_press", slider=True) + col = layout.column(align=True) + col.operator_menu_enum("gpencil.stroke_separate", text="Separate...", property="mode") + col.operator("gpencil.stroke_split", text="Split") - row = layout.row(align=True) - row.prop(brush, "jitter", slider=True) - row.prop(brush, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') - row = layout.row() - row.prop(brush, "angle", slider=True) - row.prop(brush, "angle_factor", text="Factor", slider=True) - - box = layout.box() - col = box.column(align=True) - col.label(text="Stroke Quality:") - col.prop(brush, "pen_smooth_factor") - col.prop(brush, "pen_smooth_steps") - col.separator() - row = col.row(align=False) - row.prop(brush, "pen_subdivision_steps") - row.prop(brush, "random_subdiv", text="Randomness", slider=True) + col = layout.column(align=True) + col.label(text="Cleanup:") + col.operator_menu_enum("gpencil.reproject", text="Reproject Strokes...", property="type") + col.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode") class GreasePencilStrokeSculptPanel: # subclass must set # bl_space_type = 'IMAGE_EDITOR' bl_label = "Sculpt Strokes" - bl_category = "Grease Pencil" - bl_region_type = 'TOOLS' - - @classmethod - def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False - - if context.gpencil_data is None: - return False - - gpd = context.gpencil_data - return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode) + bl_category = "Tools" @staticmethod def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False settings = context.tool_settings.gpencil_sculpt tool = settings.tool brush = settings.brush - layout.column().prop(settings, "tool") + layout.template_icon_view(settings, "tool", show_labels=True) - col = layout.column() - col.prop(brush, "size", slider=True) - row = col.row(align=True) + layout.prop(brush, "size", slider=True) + row = layout.row(align=True) row.prop(brush, "strength", slider=True) row.prop(brush, "use_pressure_strength", text="") - col.prop(brush, "use_falloff") - if tool in {'SMOOTH', 'RANDOMIZE'}: - row = layout.row(align=True) - row.prop(settings, "affect_position", text="Position", icon='MESH_DATA', toggle=True) - row.prop(settings, "affect_strength", text="Strength", icon='COLOR', toggle=True) - row.prop(settings, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True) - layout.separator() + layout.prop(brush, "use_falloff") - if tool == 'THICKNESS': - layout.row().prop(brush, "direction", expand=True) - elif tool == 'PINCH': - row = layout.row(align=True) - row.prop_enum(brush, "direction", 'ADD', text="Pinch") - row.prop_enum(brush, "direction", 'SUBTRACT', text="Inflate") - elif settings.tool == 'TWIST': - row = layout.row(align=True) - row.prop_enum(brush, "direction", 'SUBTRACT', text="CW") - row.prop_enum(brush, "direction", 'ADD', text="CCW") + if tool in {'SMOOTH', 'RANDOMIZE'}: + layout.prop(settings, "affect_position", text="Affect Position") + layout.prop(settings, "affect_strength", text="Affect Strength") + layout.prop(settings, "affect_thickness", text="Affect Thickness") - row = layout.row(align=True) - row.prop(settings, "use_select_mask") - row = layout.row(align=True) - row.prop(settings, "selection_alpha", slider=True) + if tool == 'SMOOTH': + layout.prop(brush, "affect_pressure") - if tool == 'SMOOTH': - layout.prop(brush, "affect_pressure") + layout.prop(settings, "affect_uv", text="Affect UV") + if tool in {'THICKNESS', 'PINCH', 'TWIST'}: + layout.prop(brush, "direction", expand=True) -class GreasePencilBrushCurvesPanel: - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Brush Curves" - bl_category = "Grease Pencil" - bl_region_type = 'TOOLS' + +# GP Object Tool Settings +class GreasePencilAppearancePanel: + bl_label = "Brush Appearance" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False - - if context.active_gpencil_brush is None: - return False - - brush = context.active_gpencil_brush - return bool(brush) + ob = context.active_object + return ob and ob.type == 'GPENCIL' @staticmethod def draw(self, context): layout = self.layout - brush = context.active_gpencil_brush - # Brush - layout.label("Sensitivity") - box = layout.box() - box.template_curve_mapping(brush, "curve_sensitivity", brush=True) + layout.use_property_split = True + layout.use_property_decorate = False - layout.label("Strength") - box = layout.box() - box.template_curve_mapping(brush, "curve_strength", brush=True) + ob = context.active_object - layout.label("Jitter") - box = layout.box() - box.template_curve_mapping(brush, "curve_jitter", brush=True) + if ob.mode == 'GPENCIL_PAINT': + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + + layout.prop(gp_settings, "gpencil_brush_type", text="Brush Type") + + sub = layout.column(align=True) + sub.enabled = not brush.use_custom_icon + sub.prop(gp_settings, "gp_icon", text="Icon") + + layout.prop(brush, "use_custom_icon") + sub = layout.column() + sub.active = brush.use_custom_icon + sub.prop(brush, "icon_filepath", text="") + + layout.prop(gp_settings, "use_cursor", text="Show Brush") + + if gp_settings.gpencil_brush_type == 'FILL': + layout.prop(brush, "cursor_color_add", text="Color") + + elif ob.mode in ('GPENCIL_SCULPT', 'GPENCIL_WEIGHT'): + settings = context.tool_settings.gpencil_sculpt + brush = settings.brush + + col = layout.column(align=True) + col.prop(brush, "use_cursor", text="Show Brush") + col.row().prop(brush, "cursor_color_add", text="Add") + col.row().prop(brush, "cursor_color_sub", text="Subtract") ############################### @@ -539,6 +378,7 @@ class GPENCIL_MT_pie_tool_palette(Menu): col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT') col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY') col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO') + col.operator("gpencil.select_alternate", text="Alternate Select", icon='BORDER_LASSO') # SW - Edit Tools col = pie.column() @@ -566,7 +406,7 @@ class GPENCIL_MT_pie_settings_palette(Menu): pie = layout.menu_pie() gpd = context.gpencil_data gpl = context.active_gpencil_layer - palcolor = context.active_gpencil_palettecolor + palcolor = None #context.active_gpencil_palettecolor brush = context.active_gpencil_brush is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) @@ -737,6 +577,16 @@ class GPENCIL_MT_snap(Menu): layout.operator("view3d.snap_cursor_to_grid", text="Cursor to Grid") +class GPENCIL_MT_separate(Menu): + bl_label = "Separate" + + def draw(self, context): + layout = self.layout + layout.operator("gpencil.stroke_separate", text="Selected Points").mode = 'POINT' + layout.operator("gpencil.stroke_separate", text="Selected Strokes").mode = 'STROKE' + layout.operator("gpencil.stroke_separate", text="Active Layer").mode = 'LAYER' + + class GPENCIL_MT_gpencil_edit_specials(Menu): bl_label = "GPencil Specials" @@ -747,6 +597,14 @@ class GPENCIL_MT_gpencil_edit_specials(Menu): layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") + layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") + + layout.separator() + layout.menu("GPENCIL_MT_separate", text="Separate") + + layout.separator() + layout.operator("gpencil.stroke_split", text="Split") layout.separator() @@ -754,167 +612,129 @@ class GPENCIL_MT_gpencil_edit_specials(Menu): layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' layout.operator("gpencil.stroke_flip", text="Flip Direction") + layout.separator() + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' + if is_3d_view: layout.separator() layout.operator("gpencil.reproject") -############################### - - -class GPENCIL_UL_brush(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.GPencilBrush) - brush = item - - if self.layout_type in {'DEFAULT', 'COMPACT'}: - row = layout.row(align=True) - row.prop(brush, "name", text="", emboss=False, icon='BRUSH_DATA') - elif self.layout_type == 'GRID': - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) - - -class GPENCIL_UL_palettecolor(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.PaletteColor) - palcolor = item - - if self.layout_type in {'DEFAULT', 'COMPACT'}: - if palcolor.lock: - layout.active = False - - split = layout.split(percentage=0.25) - row = split.row(align=True) - row.enabled = not palcolor.lock - row.prop(palcolor, "color", text="", emboss=palcolor.is_stroke_visible) - row.prop(palcolor, "fill_color", text="", emboss=palcolor.is_fill_visible) - split.prop(palcolor, "name", text="", emboss=False) - - row = layout.row(align=True) - row.prop(palcolor, "lock", text="", emboss=False) - row.prop(palcolor, "hide", text="", emboss=False) - if palcolor.ghost is True: - icon = 'GHOST_DISABLED' - else: - icon = 'GHOST_ENABLED' - row.prop(palcolor, "ghost", text="", icon=icon, emboss=False) - - elif self.layout_type == 'GRID': - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) - +class GPENCIL_MT_gpencil_sculpt_specials(Menu): + bl_label = "GPencil Specials" -class GPENCIL_UL_layer(UIList): - def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): - # assert(isinstance(item, bpy.types.GPencilLayer) - gpl = item + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' - if self.layout_type in {'DEFAULT', 'COMPACT'}: - if gpl.lock: - layout.active = False + layout.operator_context = 'INVOKE_REGION_WIN' - row = layout.row(align=True) - if gpl.is_parented: - icon = 'BONE_DATA' - else: - icon = 'BLANK1' + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' - row.label(text="", icon=icon) - row.prop(gpl, "info", text="", emboss=False) + layout.separator() - row = layout.row(align=True) - row.prop(gpl, "lock", text="", emboss=False) - row.prop(gpl, "hide", text="", emboss=False) - row.prop(gpl, "unlock_color", text="", emboss=False) - elif self.layout_type == 'GRID': - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) + layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") + layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") -class GPENCIL_MT_layer_specials(Menu): - bl_label = "Layer" +class GPENCIL_MT_gpencil_draw_specials(Menu): + bl_label = "GPencil Draw Specials" def draw(self, context): layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' - layout.operator("gpencil.layer_duplicate", icon='COPY_ID') # XXX: needs a dedicated icon - - layout.separator() + layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All") - layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' layout.separator() + layout.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE' + layout.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX' + layout.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE' - layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All") - layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All") - + # colors layout.separator() + layout.operator("gpencil.colorpick", text="Colors", icon="GROUP_VCOL") - layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down") - -class GPENCIL_MT_brush_specials(Menu): - bl_label = "Layer" +class GPENCIL_MT_gpencil_draw_delete(Menu): + bl_label = "GPencil Draw Delete" def draw(self, context): layout = self.layout - layout.operator("gpencil.brush_copy", icon='PASTEDOWN', text="Copy Current Drawing Brush") - layout.operator("gpencil.brush_presets_create", icon='HELP', text="Create a Set of Predefined Brushes") - + is_3d_view = context.space_data.type == 'VIEW_3D' -class GPENCIL_MT_palettecolor_specials(Menu): - bl_label = "Layer" + layout.operator_context = 'INVOKE_REGION_WIN' - def draw(self, context): - layout = self.layout + layout.operator("gpencil.active_frames_delete_all", text="Delete Frame") - layout.operator("gpencil.palettecolor_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") - layout.operator("gpencil.palettecolor_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True - layout.separator() +class GPENCIL_UL_annotation_layer(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + # assert(isinstance(item, bpy.types.GPencilLayer) + gpl = item + gpd = context.gpencil_data - layout.operator("gpencil.palettecolor_lock_all", icon='LOCKED', text="Lock All") - layout.operator("gpencil.palettecolor_unlock_all", icon='UNLOCKED', text="UnLock All") - layout.operator("gpencil.palettecolor_copy", icon='PASTEDOWN', text="Copy Color") + if self.layout_type in {'DEFAULT', 'COMPACT'}: + if gpl.lock: + layout.active = False - layout.separator() + split = layout.split(percentage=0.2) + split.prop(gpl, "color", text="", emboss=True) + split.prop(gpl, "info", text="", emboss=False) - layout.operator("gpencil.palettecolor_select", icon='COLOR', text="Select Strokes") - layout.operator("gpencil.stroke_change_color", icon='MAN_TRANS', text="Move to Color") + row = layout.row(align=True) + # row.prop(gpl, "lock", text="", emboss=False) + row.prop(gpl, "hide", text="", emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) class GreasePencilDataPanel: - # subclass must set - # bl_space_type = 'IMAGE_EDITOR' - bl_label = "Grease Pencil Layers" + bl_label = "Annotations" bl_region_type = 'UI' + @classmethod + def poll(cls, context): + # Show this panel as long as someone that might own this exists + # AND the owner isn't an object (e.g. GP Object) + if context.gpencil_data_owner is None: + return False + elif type(context.gpencil_data_owner) is bpy.types.Object: + return False + else: + return True + @staticmethod def draw_header(self, context): - self.layout.prop(context.space_data, "show_grease_pencil", text="") + if context.space_data.type != 'VIEW_3D': + self.layout.prop(context.space_data, "show_annotation", text="") @staticmethod def draw(self, context): layout = self.layout + #layout.use_property_split = True + layout.use_property_decorate = False # owner of Grease Pencil data gpd_owner = context.gpencil_data_owner gpd = context.gpencil_data # Owner Selector - if context.space_data.type == 'VIEW_3D': - layout.row().prop(context.tool_settings, "grease_pencil_source", expand=True) - elif context.space_data.type == 'CLIP_EDITOR': + if context.space_data.type == 'CLIP_EDITOR': layout.row().prop(context.space_data, "grease_pencil_source", expand=True) - # Grease Pencil data selector layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink") # Grease Pencil data... if (gpd is None) or (not gpd.layers): - layout.operator("gpencil.layer_add", text="New Layer") + layout.operator("gpencil.layer_add", text="New Note") else: self.draw_layers(context, layout, gpd) @@ -926,7 +746,7 @@ class GreasePencilDataPanel: layer_rows = 5 else: layer_rows = 2 - col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows) + col.template_list("GPENCIL_UL_annotation_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows) col = row.column() @@ -936,8 +756,6 @@ class GreasePencilDataPanel: gpl = context.active_gpencil_layer if gpl: - sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="") - if len(gpd.layers) > 1: col.separator() @@ -945,203 +763,70 @@ class GreasePencilDataPanel: sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' - col.separator() - - sub = col.column(align=True) - sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False - sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True - if gpl: - self.draw_layer(context, layout, gpl) - - def draw_layer(self, context, layout, gpl): - row = layout.row(align=True) - row.prop(gpl, "opacity", text="Opacity", slider=True) - - # Layer options - split = layout.split(percentage=0.5) - split.active = not gpl.lock - split.prop(gpl, "show_x_ray") - split.prop(gpl, "show_points") - - # Offsets + Parenting (where available) - if context.space_data.type == 'VIEW_3D': - split = layout.split(percentage=0.5) - else: - split = layout.column() # parenting is not available in 2D editors... - split.active = not gpl.lock - - # Offsets - Color Tint - col = split.column() - subcol = col.column(align=True) - subcol.label("Tint") - subcol.enabled = not gpl.lock - subcol.prop(gpl, "tint_color", text="") - subcol.prop(gpl, "tint_factor", text="Factor", slider=True) - - # Offsets - Thickness - row = col.row(align=True) - row.prop(gpl, "line_change", text="Thickness Change", slider=True) - row.operator("gpencil.stroke_apply_thickness", icon='STYLUS_PRESSURE', text="") + # layout.prop(gpl, "opacity", text="Opacity", slider=True) + # layout.prop(gpl, "thickness", text="Thickness") + # + # layout.separator() - # Parenting - if context.space_data.type == 'VIEW_3D': - col = split.column(align=True) - col.label(text="Parent:") - col.prop(gpl, "parent", text="") + # Full-Row - Frame Locking (and Delete Frame) + row = layout.row(align=True) + row.active = not gpl.lock - sub = col.column() - sub.prop(gpl, "parent_type", text="") - parent = gpl.parent - if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE': - sub.prop_search(gpl, "parent_bone", parent.data, "bones", text="") + if gpl.active_frame: + lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked") + lock_label = iface_("Frame: %d (%s)") % (gpl.active_frame.frame_number, lock_status) + else: + lock_label = iface_("Lock Frame") + row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED') + row.operator("gpencil.active_frame_delete", text="", icon='X') - layout.separator() - # Full-Row - Frame Locking (and Delete Frame) - row = layout.row(align=True) - row.active = not gpl.lock - if gpl.active_frame: - lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked") - lock_label = iface_("Frame: %d (%s)") % (gpl.active_frame.frame_number, lock_status) - else: - lock_label = iface_("Lock Frame") - row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED') - row.operator("gpencil.active_frame_delete", text="", icon='X') - - layout.separator() +class GreasePencilOnionPanel: + @staticmethod + def draw_settings(layout, gp): + col = layout.column() - # Onion skinning - col = layout.column(align=True) - col.active = not gpl.lock + col.prop(gp, "onion_mode") row = col.row() - row.prop(gpl, "use_onion_skinning") - sub = row.row(align=True) - icon = 'RESTRICT_RENDER_OFF' if gpl.use_ghosts_always else 'RESTRICT_RENDER_ON' - sub.prop(gpl, "use_ghosts_always", text="", icon=icon) - sub.prop(gpl, "use_ghost_custom_colors", text="", icon='COLOR') - - split = col.split(percentage=0.5) - split.active = gpl.use_onion_skinning + row.prop(gp, "onion_factor", text="Opacity", slider=True) # - Before Frames - sub = split.column(align=True) + sub = layout.column(align=True) row = sub.row(align=True) - row.active = gpl.use_ghost_custom_colors - row.prop(gpl, "before_color", text="") - sub.prop(gpl, "ghost_before_range", text="Before") + row.active = gp.use_ghost_custom_colors + row.prop(gp, "before_color", text="Color Before") - # - After Frames - sub = split.column(align=True) row = sub.row(align=True) - row.active = gpl.use_ghost_custom_colors - row.prop(gpl, "after_color", text="") - sub.prop(gpl, "ghost_after_range", text="After") - - -class GreasePencilPaletteColorPanel: - # subclass must set - bl_label = "Grease Pencil Colors" - bl_region_type = 'UI' - - @classmethod - def poll(cls, context): - # XXX - disabled in 2.8 branch. - return False - - if context.gpencil_data is None: - return False - - gpd = context.gpencil_data - return bool(gpd.layers.active) - - @staticmethod - def draw(self, context): - layout = self.layout - palette = context.active_gpencil_palette + row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE') + row.prop(gp, "ghost_before_range", text="Frames Before") - if palette: - row = layout.row(align=True) - row.operator_context = 'EXEC_REGION_WIN' - row.operator_menu_enum("gpencil.palette_change", "palette", text="", icon='COLOR') - row.prop(palette, "name", text="") - row.operator("gpencil.palette_add", icon='ZOOMIN', text="") - row.operator("gpencil.palette_remove", icon='X', text="") - - # Palette colors - row = layout.row() - col = row.column() - if len(palette.colors) >= 2: - color_rows = 5 - else: - color_rows = 2 - col.template_list("GPENCIL_UL_palettecolor", "", palette, "colors", palette.colors, "active_index", - rows=color_rows) - - col = row.column() + # - After Frames + sub = layout.column(align=True) + row = sub.row(align=True) + row.active = gp.use_ghost_custom_colors + row.prop(gp, "after_color", text="Color After") - sub = col.column(align=True) - sub.operator("gpencil.palettecolor_add", icon='ZOOMIN', text="") - sub.operator("gpencil.palettecolor_remove", icon='ZOOMOUT', text="") + row = sub.row(align=True) + row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE') + row.prop(gp, "ghost_after_range", text="Frames After") - palcol = context.active_gpencil_palettecolor - if palcol: - sub.menu("GPENCIL_MT_palettecolor_specials", icon='DOWNARROW_HLT', text="") + layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Color") + layout.prop(gp, "use_ghosts_always", text="View In Render") - if len(palette.colors) > 1: - col.separator() + # - fade and loop + row = layout.row() + row.active = gp.use_onion_skinning + row.prop(gp, "use_onion_fade", text="Fade") + if hasattr(gp, "use_onion_loop"): # XXX + subrow = layout.row() + subrow.active = gp.onion_mode in ('RELATIVE', 'SELECTED') + subrow.prop(gp, "use_onion_loop", text="Loop") - sub = col.column(align=True) - sub.operator("gpencil.palettecolor_move", icon='TRIA_UP', text="").direction = 'UP' - sub.operator("gpencil.palettecolor_move", icon='TRIA_DOWN', text="").direction = 'DOWN' - - row = layout.row() - sub = row.row(align=True) - sub.label(text="Isolate:") # based on active color only - sub.operator("gpencil.palettecolor_isolate", icon='LOCKED', text="").affect_visibility = False - sub.operator("gpencil.palettecolor_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True - sub = row.row(align=True) - sub.label(text="Lock:") # based on other stuff... - sub.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="") - sub.operator("gpencil.palette_lock_layer", icon='COLOR', text="") - - pcolor = palette.colors.active - if pcolor: - self.draw_palettecolors(layout, pcolor) - - # Draw palette colors - def draw_palettecolors(self, layout, pcolor): - # color settings - split = layout.split(percentage=0.5) - split.active = not pcolor.lock - - # Column 1 - Stroke - col = split.column(align=True) - col.enabled = not pcolor.lock - col.label(text="Stroke:") - col.prop(pcolor, "color", text="") - col.prop(pcolor, "alpha", slider=True) - - # Column 2 - Fill - col = split.column(align=True) - col.enabled = not pcolor.lock - col.label(text="Fill:") - col.prop(pcolor, "fill_color", text="") - col.prop(pcolor, "fill_alpha", text="Opacity", slider=True) - - # Options - split = layout.split(percentage=0.5) - split.active = not pcolor.lock - - col = split.column(align=True) - col.active = not pcolor.lock - col.prop(pcolor, "use_volumetric_strokes") - col = split.column(align=True) - col.active = not pcolor.lock - col.prop(pcolor, "use_hq_fill") +############################### class GreasePencilToolsPanel: # For use in "2D" Editors without their own toolbar @@ -1150,6 +835,7 @@ class GreasePencilToolsPanel: # bl_options = {'DEFAULT_CLOSED'} bl_label = "Grease Pencil Settings" bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -1183,20 +869,23 @@ class GreasePencilToolsPanel: gpencil_stroke_placement_settings(context, layout) +############################### classes = ( GPENCIL_MT_pie_tool_palette, GPENCIL_MT_pie_settings_palette, GPENCIL_MT_pie_tools_more, GPENCIL_MT_pie_sculpt, + GPENCIL_MT_snap, + GPENCIL_MT_separate, + GPENCIL_MT_gpencil_edit_specials, - GPENCIL_UL_brush, - GPENCIL_UL_palettecolor, - GPENCIL_UL_layer, - GPENCIL_MT_layer_specials, - GPENCIL_MT_brush_specials, - GPENCIL_MT_palettecolor_specials, + GPENCIL_MT_gpencil_sculpt_specials, + GPENCIL_MT_gpencil_draw_specials, + GPENCIL_MT_gpencil_draw_delete, + + GPENCIL_UL_annotation_layer, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 0e3e50b3497..5d12f762073 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -86,8 +86,11 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): @classmethod def poll(cls, context): - engine = context.engine - return (context.material or context.object) and (engine in cls.COMPAT_ENGINES) + if context.active_object and context.active_object.type == 'GPENCIL': + return False + else: + engine = context.engine + return (context.material or context.object) and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py new file mode 100644 index 00000000000..2d823594547 --- /dev/null +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -0,0 +1,322 @@ +# ##### 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. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy +from bpy.types import Menu, Panel, UIList +from rna_prop_ui import PropertyPanel + + +class GPENCIL_MT_color_specials(Menu): + bl_label = "Layer" + + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.color_reveal", icon='RESTRICT_VIEW_OFF', text="Show All") + layout.operator("gpencil.color_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True + + layout.separator() + + layout.operator("gpencil.color_lock_all", icon='LOCKED', text="Lock All") + layout.operator("gpencil.color_unlock_all", icon='UNLOCKED', text="UnLock All") + + layout.separator() + + layout.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="Lock Unselected") + layout.operator("gpencil.lock_layer", icon='COLOR', text="Lock Unused") + + +class GPENCIL_UL_matslots(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + slot = item + ma = slot.material + if (ma is not None) and (ma.grease_pencil is not None): + gpcolor = ma.grease_pencil + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + if gpcolor.lock: + layout.active = False + + row = layout.row(align=True) + row.enabled = not gpcolor.lock + row.prop(ma, "name", text="", emboss=False, icon_value=icon) + + row = layout.row(align=True) + row.prop(gpcolor, "lock", text="", emboss=False) + row.prop(gpcolor, "hide", text="", emboss=False) + if gpcolor.ghost is True: + icon = 'GHOST_DISABLED' + else: + icon = 'GHOST_ENABLED' + row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False) + + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + +class GPMaterialButtonsPanel: + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "material" + + @classmethod + def poll(cls, context): + ob = context.object + return (ob and ob.type == 'GPENCIL' and + ob.active_material and + ob.active_material.grease_pencil) + + + +class MATERIAL_PT_gpencil_slots(Panel): + bl_label = "Grease Pencil Material Slots" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "material" + bl_options = {'HIDE_HEADER'} + + @classmethod + def poll(cls, context): + ob = context.object + return ob and ob.type == 'GPENCIL' + + @staticmethod + def draw(self, context): + layout = self.layout + gpd = context.gpencil_data + + mat = context.object.active_material + ob = context.object + slot = context.material_slot + space = context.space_data + + if ob: + is_sortable = len(ob.material_slots) > 1 + rows = 1 + if (is_sortable): + rows = 4 + + row = layout.row() + + row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows) + + col = row.column(align=True) + col.operator("object.material_slot_add", icon='ZOOMIN', text="") + col.operator("object.material_slot_remove", icon='ZOOMOUT', text="") + + col.menu("GPENCIL_MT_color_specials", icon='DOWNARROW_HLT', text="") + + if is_sortable: + col.separator() + + col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + + col.separator() + + sub = col.column(align=True) + sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False + sub.operator("gpencil.color_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True + + row = layout.row() + + if ob: + row.template_ID(ob, "active_material", new="material.new", live_icon=True) + + if slot: + icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA' + row.prop(slot, "link", icon=icon_link, icon_only=True) + + if gpd.use_stroke_edit_mode: + row = layout.row(align=True) + row.operator("gpencil.stroke_change_color", text="Assign") + row.operator("gpencil.color_select", text="Select") + + elif mat: + row.template_ID(space, "pin_id") + + +# Used as parent for "Stroke" and "Fill" panels +class MATERIAL_PT_gpencil_surface(GPMaterialButtonsPanel, Panel): + bl_label = "Surface" + + @classmethod + def poll(cls, context): + ob = context.object + ma = context.object.active_material + if ma is None or ma.grease_pencil is None: + return False + + return ob and ob.type == 'GPENCIL' + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + +class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel): + bl_label = "Stroke" + bl_parent_id = 'MATERIAL_PT_gpencil_surface' + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ma = context.object.active_material + if ma is not None and ma.grease_pencil is not None: + gpcolor = ma.grease_pencil + + col = layout.column() + col.active = not gpcolor.lock + + col.prop(gpcolor, "mode") + + col.prop(gpcolor, "stroke_style", text="Style") + + if gpcolor.stroke_style == 'TEXTURE': + row = col.row() + row.enabled = not gpcolor.lock + col = row.column(align=True) + col.template_ID(gpcolor, "stroke_image", open="image.open") + col.prop(gpcolor, "pixel_size", text="UV Factor") + col.prop(gpcolor, "use_stroke_pattern", text="Use As Pattern") + + if gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern is True: + col.prop(gpcolor, "color", text="Color") + + +class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel): + bl_label = "Fill" + bl_parent_id = 'MATERIAL_PT_gpencil_surface' + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ma = context.object.active_material + if ma is not None and ma.grease_pencil: + gpcolor = ma.grease_pencil + + # color settings + col = layout.column() + col.active = not gpcolor.lock + col.prop(gpcolor, "fill_style", text="Style") + + if gpcolor.fill_style == 'GRADIENT': + col.prop(gpcolor, "gradient_type") + + if gpcolor.fill_style != 'TEXTURE': + col.prop(gpcolor, "fill_color", text="Color") + + if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'): + col.prop(gpcolor, "mix_color", text="Secondary Color") + + if gpcolor.fill_style == 'GRADIENT': + col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) + + if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'): + col.prop(gpcolor, "flip", text="Flip Colors") + + col.prop(gpcolor, "pattern_shift", text="Location") + col.prop(gpcolor, "pattern_scale", text="Scale") + + if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in ('SOLID', 'CHESSBOARD'): + col.prop(gpcolor, "pattern_radius", text="Radius") + else: + if gpcolor.fill_style != 'SOLID': + col.prop(gpcolor, "pattern_angle", text="Angle") + + if gpcolor.fill_style == 'CHESSBOARD': + col.prop(gpcolor, "pattern_gridsize", text="Box Size") + + # Texture + if gpcolor.fill_style == 'TEXTURE' or (gpcolor.texture_mix is True and gpcolor.fill_style == 'SOLID'): + col.template_ID(gpcolor, "fill_image", open="image.open") + + if gpcolor.fill_style == 'TEXTURE': + col.prop(gpcolor, "use_fill_pattern", text="Use As Pattern") + if gpcolor.use_fill_pattern is True: + col.prop(gpcolor, "fill_color", text="Color") + + col.prop(gpcolor, "texture_offset", text="Offset") + col.prop(gpcolor, "texture_scale", text="Scale") + col.prop(gpcolor, "texture_angle") + col.prop(gpcolor, "texture_opacity") + col.prop(gpcolor, "texture_clamp", text="Clip Image") + + if gpcolor.use_fill_pattern is False: + col.prop(gpcolor, "texture_mix", text="Mix With Color") + + if gpcolor.texture_mix is True: + col.prop(gpcolor, "fill_color", text="Mix Color") + col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True) + + +class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel): + bl_label = "Preview" + COMPAT_ENGINES = {'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + ma = context.object.active_material + self.layout.label(ma.name) + self.layout.template_preview(ma) + + +class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel): + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'} + _context_path = "object.active_material" + _property_type = bpy.types.Material + + +class MATERIAL_PT_gpencil_options(GPMaterialButtonsPanel, Panel): + bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ma = context.object.active_material + if ma is not None and ma.grease_pencil is not None: + gpcolor = ma.grease_pencil + layout.prop(gpcolor, "pass_index") + + +classes = ( + GPENCIL_UL_matslots, + GPENCIL_MT_color_specials, + MATERIAL_PT_gpencil_slots, + MATERIAL_PT_gpencil_preview, + MATERIAL_PT_gpencil_surface, + MATERIAL_PT_gpencil_strokecolor, + MATERIAL_PT_gpencil_fillcolor, + MATERIAL_PT_gpencil_options, + MATERIAL_PT_gpencil_custom_props, +) + +if __name__ == "__main__": # only for live edit. + from bpy.utils import register_class + for cls in classes: + register_class(cls) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 38bfc6ad294..91be9bb5d0a 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -28,9 +28,9 @@ from rna_prop_ui import PropertyPanel from bl_operators.presets import PresetMenu from .properties_physics_common import ( - point_cache_ui, - effector_weights_ui, -) + point_cache_ui, + effector_weights_ui, + ) class SCENE_PT_units_length_presets(PresetMenu): @@ -104,7 +104,6 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): col.prop(unit, "scale_length") col.prop(unit, "use_separate") - class SceneKeyingSetsPanel: @staticmethod @@ -568,6 +567,33 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): col.prop(rd, "simplify_child_particles_render", text="Max Child Particles") +class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel): + bl_label = "Simplify Grease Pencil" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} + bl_options = {'DEFAULT_CLOSED'} + + def draw_header(self, context): + rd = context.scene.render + self.layout.prop(rd, "simplify_gpencil", text="") + + def draw(self, context): + layout = self.layout + + rd = context.scene.render + + layout.active = rd.simplify_gpencil + + row = layout.row() + row.prop(rd, "simplify_gpencil_onplay", text="Only on Play") + + split = layout.split() + + col = split.column() + col.prop(rd, "simplify_gpencil_view_fill", text="Fill") + col.prop(rd, "simplify_gpencil_remove_lines", text="Remove Fill Lines") + col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") + + class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} _context_path = "scene" @@ -593,6 +619,7 @@ classes = ( SCENE_PT_simplify, SCENE_PT_simplify_viewport, SCENE_PT_simplify_render, + SCENE_PT_simplify_greasepencil, SCENE_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 23c3e97ac9a..8e32d98529b 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -23,14 +23,8 @@ from bpy.types import Panel, Header, Menu, UIList from bpy.app.translations import pgettext_iface as iface_ from bl_operators.presets import PresetMenu from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilStrokeEditPanel, - GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel, - GreasePencilDataPanel, - GreasePencilPaletteColorPanel, -) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel) class CLIP_UL_tracking_objects(UIList): @@ -1154,40 +1148,12 @@ class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Pane # But, this should only be visible in "clip" view -# Grease Pencil palette colors -class CLIP_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, CLIP_PT_clip_view_panel, Panel): - bl_space_type = 'CLIP_EDITOR' - bl_region_type = 'UI' - bl_options = {'DEFAULT_CLOSED'} - - # NOTE: this is just a wrapper around the generic GP Panel - # But, this should only be visible in "clip" view - - # Grease Pencil drawing tools class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' -# Grease Pencil stroke editing tools -class CLIP_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel): - bl_space_type = 'CLIP_EDITOR' - - -# Grease Pencil stroke sculpting tools -class CLIP_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel): - bl_space_type = 'CLIP_EDITOR' - - -# Grease Pencil drawing brushes -class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel): - bl_space_type = 'CLIP_EDITOR' - - -# Grease Pencil drawing curves -class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel): - bl_space_type = 'CLIP_EDITOR' - class CLIP_MT_view(Menu): bl_label = "View" @@ -1515,12 +1481,7 @@ classes = ( CLIP_PT_footage_info, CLIP_PT_tools_scenesetup, CLIP_PT_grease_pencil, - CLIP_PT_grease_pencil_palettecolor, CLIP_PT_tools_grease_pencil_draw, - CLIP_PT_tools_grease_pencil_edit, - CLIP_PT_tools_grease_pencil_sculpt, - CLIP_PT_tools_grease_pencil_brush, - CLIP_PT_tools_grease_pencil_brushcurves, CLIP_MT_view, CLIP_MT_clip, CLIP_MT_proxy, diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 1303e46ab6c..501f58e9901 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -21,20 +21,15 @@ import bpy import math from bpy.types import Header, Menu, Panel, UIList from .properties_paint_common import ( - UnifiedPaintPanel, - brush_texture_settings, - brush_texpaint_common, - brush_mask_texture_settings, -) + UnifiedPaintPanel, + brush_texture_settings, + brush_texpaint_common, + brush_mask_texture_settings, + ) from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilStrokeEditPanel, - GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel, - GreasePencilDataPanel, - GreasePencilPaletteColorPanel, -) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel + ) from bpy.app.translations import pgettext_iface as iface_ @@ -1346,39 +1341,12 @@ class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel): # NOTE: this is just a wrapper around the generic GP Panel - -# Grease Pencil palette colors -class IMAGE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel): - bl_space_type = 'IMAGE_EDITOR' - bl_region_type = 'UI' - - # NOTE: this is just a wrapper around the generic GP Panel - - # Grease Pencil drawing tools class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'TOOLS' -# Grease Pencil stroke editing tools -class IMAGE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel): - bl_space_type = 'IMAGE_EDITOR' - - -# Grease Pencil stroke sculpting tools -class IMAGE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel): - bl_space_type = 'IMAGE_EDITOR' - - -# Grease Pencil drawing brushes -class IMAGE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel): - bl_space_type = 'IMAGE_EDITOR' - - -# Grease Pencil drawing curves -class IMAGE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel): - bl_space_type = 'IMAGE_EDITOR' - classes = ( IMAGE_MT_view, @@ -1430,12 +1398,7 @@ classes = ( IMAGE_PT_sample_line, IMAGE_PT_scope_sample, IMAGE_PT_grease_pencil, - IMAGE_PT_grease_pencil_palettecolor, IMAGE_PT_tools_grease_pencil_draw, - IMAGE_PT_tools_grease_pencil_edit, - IMAGE_PT_tools_grease_pencil_sculpt, - IMAGE_PT_tools_grease_pencil_brush, - IMAGE_PT_tools_grease_pencil_brushcurves, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 45343c09b27..affbf70b1a0 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -23,15 +23,10 @@ from bpy.types import Header, Menu, Panel from bpy.app.translations import pgettext_iface as iface_ from bl_operators.presets import PresetMenu from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilStrokeEditPanel, - GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel, - GreasePencilDataPanel, - GreasePencilPaletteColorPanel, - GreasePencilToolsPanel -) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel, + GreasePencilToolsPanel + ) class NODE_HT_header(Header): @@ -539,19 +534,6 @@ class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel): return snode is not None and snode.node_tree is not None -# Grease Pencil palette colors -class NODE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'UI' - - # NOTE: this is just a wrapper around the generic GP Panel - - @classmethod - def poll(cls, context): - snode = context.space_data - return snode is not None and snode.node_tree is not None - - class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' @@ -571,31 +553,6 @@ class NODE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_region_type = 'TOOLS' -# Grease Pencil stroke editing tools -class NODE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'TOOLS' - - -# Grease Pencil stroke sculpting tools -class NODE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'TOOLS' - -# Grease Pencil drawing brushes - - -class NODE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'TOOLS' - -# Grease Pencil drawing curves - - -class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel): - bl_space_type = 'NODE_EDITOR' - bl_region_type = 'TOOLS' - # ----------------------------- @@ -620,13 +577,8 @@ classes = ( NODE_PT_quality, NODE_UL_interface_sockets, NODE_PT_grease_pencil, - NODE_PT_grease_pencil_palettecolor, NODE_PT_grease_pencil_tools, NODE_PT_tools_grease_pencil_draw, - NODE_PT_tools_grease_pencil_edit, - NODE_PT_tools_grease_pencil_sculpt, - NODE_PT_tools_grease_pencil_brush, - NODE_PT_tools_grease_pencil_brushcurves, ) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index bac462dcbab..84ae59772b6 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -22,7 +22,6 @@ from bpy.types import Header, Menu, Panel from rna_prop_ui import PropertyPanel from .properties_grease_pencil_common import ( GreasePencilDataPanel, - GreasePencilPaletteColorPanel, GreasePencilToolsPanel, ) from bpy.app.translations import pgettext_iface as iface_ @@ -1281,14 +1280,6 @@ class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Ou # But, it should only show up when there are images in the preview region -class SEQUENCER_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, SequencerButtonsPanel_Output, Panel): - bl_space_type = 'SEQUENCE_EDITOR' - bl_region_type = 'UI' - - # NOTE: this is just a wrapper around the generic GP Panel - # But, it should only show up when there are images in the preview region - - class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel): bl_space_type = 'SEQUENCE_EDITOR' bl_region_type = 'UI' @@ -1333,7 +1324,6 @@ classes = ( SEQUENCER_PT_view_safe_areas, SEQUENCER_PT_modifiers, SEQUENCER_PT_grease_pencil, - SEQUENCER_PT_grease_pencil_palettecolor, SEQUENCER_PT_grease_pencil_tools, SEQUENCER_PT_custom_props, ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 3101ffc8336..b682588629b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -24,6 +24,7 @@ # For now keep this in a single file since it's an area that may change, # so avoid making changes all over the place. +import bpy from bpy.types import Panel from .space_toolsystem_common import ( @@ -39,21 +40,77 @@ def generate_from_brushes_ex( brush_category_attr, brush_category_layout, ): + def draw_settings(context, layout, tool): + _defs_gpencil_paint.draw_settings_common(context, layout, tool) + # Categories brush_categories = {} - for brush in context.blend_data.brushes: - if getattr(brush, brush_test_attr): - category = getattr(brush, brush_category_attr) - name = brush.name - brush_categories.setdefault(category, []).append( - ToolDef.from_dict( - dict( - text=name, - icon=icon_prefix + category.lower(), - data_block=name, + if context.mode != 'GPENCIL_PAINT': + for brush in context.blend_data.brushes: + if getattr(brush, brush_test_attr) and brush.gpencil_settings is None: + category = getattr(brush, brush_category_attr) + name = brush.name + brush_categories.setdefault(category, []).append( + ToolDef.from_dict( + dict( + text=name, + icon=icon_prefix + category.lower(), + data_block=name, + ) ) ) - ) + else: + for brush_type in brush_category_layout: + for brush in context.blend_data.brushes: + if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]: + category = brush_type[0] + name = brush.name + + # rename default brushes for tool bar + if name.startswith("Draw "): + text = name.replace("Draw ", "") + elif name.startswith("Eraser "): + text = name.replace("Eraser ", "") + elif name.startswith("Fill "): + text = name.replace(" Area", "") + else: + text = name + + # define icon + gp_icon = brush.gpencil_settings.gp_icon + if gp_icon == 'PENCIL': + icon_name = 'draw_pencil' + elif gp_icon == 'PEN': + icon_name = 'draw_pen' + elif gp_icon == 'INK': + icon_name = 'draw_ink' + elif gp_icon == 'INKNOISE': + icon_name = 'draw_noise' + elif gp_icon == 'BLOCK': + icon_name = 'draw_block' + elif gp_icon == 'MARKER': + icon_name = 'draw_marker' + elif gp_icon == 'FILL': + icon_name = 'draw_fill' + elif gp_icon == 'SOFT': + icon_name = 'draw.eraser_soft' + elif gp_icon == 'HARD': + icon_name = 'draw.eraser_hard' + elif gp_icon == 'STROKE': + icon_name = 'draw.eraser_stroke' + + brush_categories.setdefault(category, []).append( + ToolDef.from_dict( + dict( + text=text, + icon=icon_prefix + icon_name, + data_block=name, + widget=None, + operator="gpencil.draw", + draw_settings=draw_settings, + ) + ) + ) def tools_from_brush_group(groups): assert(type(groups) is tuple) @@ -61,6 +118,7 @@ def generate_from_brushes_ex( tool_defs = tuple(brush_categories.pop(groups[0], ())) else: tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ())) + if len(tool_defs) > 1: return (tool_defs,) else: @@ -125,6 +183,112 @@ class _defs_view3d_generic: ) +class _defs_annotate: + @classmethod + def draw_settings_common(cls, context, layout, tool): + user_prefs = context.user_preferences + ts = context.tool_settings + + # XXX: These context checks are needed for layer-dependent settings, + # but this breaks for using topbar for 2D editor active tools, etc. + if type(context.gpencil_data_owner) is bpy.types.Object: + gpd = context.scene.grease_pencil + else: + gpd = context.gpencil_data + + gpl = gpd.layers.active if gpd else None + + if gpd and gpl: + layout.prop(gpd.layers, "active_note", text="") + layout.prop(gpl, "thickness", text="Thickness") + else: + layout.prop(user_prefs.edit, "grease_pencil_default_color", text="Color") + layout.prop(ts, "annotation_thickness", text="Thickness") + + # For 3D view, show the stroke placement settings + # XXX: How to tell what editor the active tool comes from? + is_3d_view = True + if is_3d_view: + layout.separator() + + row = layout.row(align=True) + row.prop(ts, "annotation_stroke_placement_view3d", text="Orientation") + if ts.gpencil_stroke_placement_view3d == 'CURSOR': + row.prop(ts.gpencil_sculpt, "lockaxis") + elif ts.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}: + row.prop(ts, "use_gpencil_stroke_endpoints") + + @ToolDef.from_fn + def scribble(): + def draw_settings(context, layout, tool): + _defs_annotate.draw_settings_common(context, layout, tool) + + return dict( + text="Annotate", + icon="ops.gpencil.draw", + cursor='PAINT_BRUSH', + keymap=( + ("gpencil.annotate", + dict(mode='DRAW', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def line(): + def draw_settings(context, layout, tool): + _defs_annotate.draw_settings_common(context, layout, tool) + + return dict( + text="Draw Line", + icon="ops.gpencil.draw.line", + cursor='CROSSHAIR', + keymap=( + ("gpencil.annotate", + dict(mode='DRAW_STRAIGHT', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def poly(): + def draw_settings(context, layout, tool): + _defs_annotate.draw_settings_common(context, layout, tool) + + return dict( + text="Draw Polygon", + icon="ops.gpencil.draw.poly", + cursor='CROSSHAIR', + keymap=( + ("gpencil.annotate", + dict(mode='DRAW_POLY', wait_for_input=False), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def eraser(): + def draw_settings(context, layout, tool): + # TODO: Move this setting to toolsettings + user_prefs = context.user_preferences + layout.prop(user_prefs.edit, "grease_pencil_eraser_radius", text="Radius") + + return dict( + text="Eraser", + icon="ops.gpencil.draw.eraser", + cursor='CROSSHAIR', # XXX: Always show brush circle when enabled + keymap=( + ("gpencil.annotate", + dict(mode='ERASER', wait_for_input=False), + dict(type='ACTIONMOUSE', value='PRESS')), + ), + draw_settings=draw_settings, + ) + + class _defs_transform: @ToolDef.from_fn @@ -865,6 +1029,331 @@ class _defs_uv_select: ), ) +class _defs_gpencil_paint: + @classmethod + def draw_color_selector(cls, context, layout): + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + ts = context.tool_settings + row = layout.row(align=True) + row.prop(ts, "use_gpencil_thumbnail_list", text="", icon="IMGDISPLAY") + if ts.use_gpencil_thumbnail_list is False: + row.template_ID(gp_settings, "material", live_icon=True) + else: + row.template_greasepencil_color(gp_settings, "material", rows=3, cols=8, scale=0.8) + + @classmethod + def draw_settings_common(cls, context, layout, tool): + ob = context.active_object + if ob and ob.mode == 'GPENCIL_PAINT': + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + tool_settings= context.tool_settings + + if gp_settings.gpencil_brush_type == 'ERASE': + row = layout.row() + row.prop(brush, "size", text="Radius") + elif gp_settings.gpencil_brush_type == 'FILL': + row = layout.row() + row.prop(gp_settings, "gpencil_fill_leak", text="Leak Size") + row.prop(brush, "size", text="Thickness") + row.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify") + + _defs_gpencil_paint.draw_color_selector(context, layout) + + row = layout.row(align=True) + row.prop(gp_settings, "gpencil_fill_draw_mode", text="") + row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID') + + else: # bgpsettings.gpencil_brush_type == 'DRAW': + row = layout.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + _defs_gpencil_paint.draw_color_selector(context, layout) + + + @staticmethod + def generate_from_brushes(context): + return generate_from_brushes_ex( + context, + icon_prefix="brush.gpencil.", + brush_test_attr="use_paint_grease_pencil", + brush_category_attr="grease_pencil_tool", + brush_category_layout=( + ('PENCIL',), + ('PEN',), + ('INK',), + ('INKNOISE',), + ('BLOCK',), + ('MARKER',), + ('FILL',), + ('SOFT',), + ('HARD',), + ('STROKE',), + ) + ) + + +class _defs_gpencil_edit: + @ToolDef.from_fn + def bend(): + return dict( + text="Bend", + icon="ops.gpencil.edit_bend", + widget=None, + keymap=( + ("transform.bend", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def mirror(): + return dict( + text="Mirror", + icon="ops.gpencil.edit_mirror", + widget=None, + keymap=( + ("transform.mirror", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def shear(): + return dict( + text="Shear", + icon="ops.gpencil.edit_shear", + widget=None, + keymap=( + ("transform.shear", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + @ToolDef.from_fn + def tosphere(): + return dict( + text="To Sphere", + icon="ops.gpencil.edit_to_sphere", + widget=None, + keymap=( + ("transform.tosphere", + dict(), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + ) + + +class _defs_gpencil_sculpt: + @classmethod + def draw_settings_common(cls, context, layout, tool): + ob = context.active_object + if ob and ob.mode == 'GPENCIL_SCULPT': + ts = context.tool_settings + settings = ts.gpencil_sculpt + brush = settings.brush + + layout.prop(brush, "size", slider=True) + + row = layout.row(align=True) + row.prop(brush, "strength", slider=True) + row.prop(brush, "use_pressure_strength", text="") + row.separator() + row.prop(ts.gpencil_sculpt, "use_select_mask", text="") + + @ToolDef.from_fn + def smooth(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Smooth", + icon="ops.gpencil.sculpt_smooth", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='SMOOTH', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def thickness(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Thickness", + icon="ops.gpencil.sculpt_thickness", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='THICKNESS', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def strength(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Strength", + icon="ops.gpencil.sculpt_strength", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='STRENGTH', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def grab(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Grab", + icon="ops.gpencil.sculpt_grab", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='GRAB', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def push(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Push", + icon="ops.gpencil.sculpt_push", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='PUSH', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def twist(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Twist", + icon="ops.gpencil.sculpt_twist", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='TWIST', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def pinch(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Pinch", + icon="ops.gpencil.sculpt_pinch", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='PINCH', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def randomize(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Randomize", + icon="ops.gpencil.sculpt_randomize", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='RANDOMIZE', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + @ToolDef.from_fn + def clone(): + def draw_settings(context, layout, tool): + _defs_gpencil_sculpt.draw_settings_common(context, layout, tool) + + return dict( + text="Clone", + icon="ops.gpencil.sculpt_clone", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='CLONE', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + + +class _defs_gpencil_weight: + @classmethod + def draw_settings_common(cls, context, layout, tool): + ob = context.active_object + if ob and ob.mode == 'GPENCIL_WEIGHT': + settings = context.tool_settings.gpencil_sculpt + brush = settings.brush + + layout.prop(brush, "size", slider=True) + + row = layout.row(align=True) + row.prop(brush, "strength", slider=True) + row.prop(brush, "use_pressure_strength", text="") + + @ToolDef.from_fn + def paint(): + def draw_settings(context, layout, tool): + _defs_gpencil_weight.draw_settings_common(context, layout, tool) + + return dict( + text="Draw", + icon="ops.gpencil.sculpt_weight", + widget=None, + keymap=( + ("gpencil.brush_paint", + dict(mode='WEIGHT', wait_for_input=False), + dict(type='EVT_TWEAK_A', value='ANY')), + ), + draw_settings=draw_settings, + ) + class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): bl_space_type = 'IMAGE_EDITOR' @@ -951,8 +1440,6 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_transform.scale, _defs_transform.scale_cage, ), - None, - _defs_view3d_generic.ruler, ) _tools_select = ( @@ -963,6 +1450,16 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ), ) + _tools_annotate = ( + ( + _defs_annotate.scribble, + _defs_annotate.line, + _defs_annotate.poly, + _defs_annotate.eraser, + ), + _defs_view3d_generic.ruler, + ) + _tools = { None: [ _defs_view3d_generic.cursor, @@ -972,21 +1469,27 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): *_tools_select, None, *_tools_transform, + None, + *_tools_annotate, ], 'POSE': [ *_tools_select, *_tools_transform, None, + *_tools_annotate, + None, ( _defs_pose.breakdown, _defs_pose.push, _defs_pose.relax, - ) + ), ], 'EDIT_ARMATURE': [ *_tools_select, None, *_tools_transform, + None, + *_tools_annotate, _defs_edit_armature.roll, ( _defs_edit_armature.bone_size, @@ -996,13 +1499,15 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ( _defs_edit_armature.extrude, _defs_edit_armature.extrude_cursor, - ) + ), ], 'EDIT_MESH': [ *_tools_select, None, *_tools_transform, None, + *_tools_annotate, + None, _defs_edit_mesh.cube_add, None, ( @@ -1047,6 +1552,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, *_tools_transform, None, + *_tools_annotate, + None, _defs_edit_curve.draw, _defs_edit_curve.extrude_cursor, ], @@ -1075,6 +1582,33 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): None, _defs_weight_paint.gradient, ], + 'GPENCIL_PAINT': [ + _defs_gpencil_paint.generate_from_brushes, + ], + 'GPENCIL_EDIT': [ + *_tools_select, + None, + *_tools_transform, + None, + _defs_gpencil_edit.bend, + _defs_gpencil_edit.mirror, + _defs_gpencil_edit.shear, + _defs_gpencil_edit.tosphere, + ], + 'GPENCIL_SCULPT': [ + _defs_gpencil_sculpt.smooth, + _defs_gpencil_sculpt.thickness, + _defs_gpencil_sculpt.strength, + _defs_gpencil_sculpt.grab, + _defs_gpencil_sculpt.push, + _defs_gpencil_sculpt.twist, + _defs_gpencil_sculpt.pinch, + _defs_gpencil_sculpt.randomize, + _defs_gpencil_sculpt.clone, + ], + 'GPENCIL_WEIGHT': [ + _defs_gpencil_weight.paint, + ], } diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 55129aa0ce1..0d837ae413a 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -128,6 +128,8 @@ class TOPBAR_HT_lower_bar(Header): pass elif mode == 'PARTICLE': layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="") + elif mode == 'GPENCIL_PAINT': + layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".greasepencil_paint", category="") def draw_center(self, context): pass @@ -165,6 +167,15 @@ class TOPBAR_HT_lower_bar(Header): layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".particlemode", category="") elif mode == 'OBJECT': layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".objectmode", category="") + elif mode == 'GPENCIL_PAINT': + layout.prop(context.tool_settings, "gpencil_stroke_placement_view3d", text='') + if context.tool_settings.gpencil_stroke_placement_view3d in ('ORIGIN', 'CURSOR'): + layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='') + layout.prop(context.tool_settings, "use_gpencil_draw_onback", text="", icon='ORTHO') + layout.prop(context.tool_settings, "use_gpencil_additive_drawing", text="", icon='FREEZE') + + elif mode == 'GPENCIL_SCULPT': + layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='') class _draw_left_context_mode: diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 53aaff7c4bf..52d4640806d 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -361,14 +361,16 @@ class USERPREF_PT_edit(Panel): row.separator() col = row.column() - col.label(text="Grease Pencil:") + col.label(text="Annotations:") + sub = col.row() + sub.prop(edit, "grease_pencil_default_color", text="Default Color") col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius") col.separator() + col.label(text="Grease Pencil/Annotations:") + col.separator() col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance") col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance") col.separator() - col.prop(edit, "grease_pencil_default_color", text="Default Color") - col.separator() col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke") col.separator() col.separator() @@ -527,7 +529,10 @@ class USERPREF_PT_system(Panel): col.prop(system, "gpu_viewport_quality") col.separator() + col.label(text="Grease Pencil Options:") + col.prop(system, "gpencil_multi_sample", text="") + col.separator() col.label(text="Text Draw Options:") col.prop(system, "use_text_antialiasing") if system.use_text_antialiasing: diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index aed5faff73c..eb595e9f12d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -19,11 +19,8 @@ # import bpy from bpy.types import Header, Menu, Panel -from .properties_grease_pencil_common import ( - GreasePencilDataPanel, - GreasePencilPaletteColorPanel, -) from .properties_paint_common import UnifiedPaintPanel +from .properties_grease_pencil_common import GreasePencilDataPanel from bpy.app.translations import contexts as i18n_contexts @@ -80,18 +77,40 @@ class VIEW3D_HT_header(Header): row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True - # GPencil - if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: - row = layout.row(align=True) - row.operator("gpencil.copy", text="", icon='COPYDOWN') - row.operator("gpencil.paste", text="", icon='PASTEDOWN') + # Grease Pencil + if obj and obj.type == 'GPENCIL' and context.gpencil_data: + gpd = context.gpencil_data - # XXX: icon - layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH') + if gpd.is_stroke_paint_mode: + row = layout.row(align=True) + row.popover( + panel="VIEW3D_PT_tools_grease_pencil_shapes", + text="Shapes" + ) - row = layout.row(align=True) - row.prop(tool_settings.gpencil_sculpt, "use_select_mask") - row.prop(tool_settings.gpencil_sculpt, "selection_alpha", slider=True) + if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode: + row = layout.row(align=True) + row.prop(gpd, "use_multiedit", text="", icon="FORCE_HARMONIC") + + sub = row.row(align=True) + sub.active = gpd.use_multiedit + sub.popover( + panel="VIEW3D_PT_gpencil_multi_frame", + text="Multiframe" + ) + + if gpd.use_stroke_edit_mode: + row = layout.row(align=True) + row.operator("gpencil.copy", text="", icon='COPYDOWN') + row.operator("gpencil.paste", text="", icon='PASTEDOWN') + + row = layout.row(align=True) + row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="") + + row.popover( + panel="VIEW3D_PT_tools_grease_pencil_interpolate", + text="Interpolate" + ) VIEW3D_MT_editor_menus.draw_collapsible(context, layout) @@ -101,7 +120,7 @@ class VIEW3D_HT_header(Header): scene = context.scene # Orientation - if object_mode in {'OBJECT', 'EDIT', 'POSE'}: + if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT'}: orientation = scene.transform_orientation current_orientation = scene.current_orientation @@ -126,7 +145,8 @@ class VIEW3D_HT_header(Header): if obj is None: show_snap = True else: - if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}: + if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT', + 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}: show_snap = True else: @@ -160,13 +180,15 @@ class VIEW3D_HT_header(Header): # Proportional editing if obj: - if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode: - row = layout.row(align=True) - row.prop(tool_settings, "proportional_edit", icon_only=True) + gpd = context.gpencil_data + if gpd is not None: + if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode: + row = layout.row(align=True) + row.prop(tool_settings, "proportional_edit", icon_only=True) - sub = row.row(align=True) - sub.active = tool_settings.proportional_edit != 'DISABLED' - sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True) + sub = row.row(align=True) + sub.active = tool_settings.proportional_edit != 'DISABLED' + sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True) elif object_mode in {'EDIT', 'PARTICLE_EDIT'}: row = layout.row(align=True) @@ -190,7 +212,7 @@ class VIEW3D_HT_header(Header): sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True) # Pivot - if object_mode in {'OBJECT', 'EDIT', 'POSE'}: + if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT', 'GPENCIL_SCULPT'}: pivot_point = tool_settings.transform_pivot_point act_pivot_point = bpy.types.ToolSettings.bl_rna.properties["transform_pivot_point"].enum_items[pivot_point] row = layout.row(align=True) @@ -234,13 +256,14 @@ class VIEW3D_MT_editor_menus(Menu): obj = context.active_object mode_string = context.mode edit_object = context.edit_object - gp_edit = context.gpencil_data and context.gpencil_data.use_stroke_edit_mode + gp_edit = obj and obj.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'} layout.menu("VIEW3D_MT_view") # Select Menu if gp_edit: - layout.menu("VIEW3D_MT_select_gpencil") + if mode_string not in {'GPENCIL_PAINT', 'GPENCIL_WEIGHT'}: + layout.menu("VIEW3D_MT_select_gpencil") elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}: mesh = obj.data if mesh.use_paint_mask: @@ -266,7 +289,15 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("INFO_MT_edit_armature_add", text="Add") if gp_edit: - layout.menu("VIEW3D_MT_edit_gpencil") + if obj and obj.mode == 'GPENCIL_PAINT': + layout.menu("VIEW3D_MT_paint_gpencil") + elif obj and obj.mode == 'GPENCIL_EDIT': + layout.menu("VIEW3D_MT_edit_gpencil") + elif obj and obj.mode == 'GPENCIL_SCULPT': + layout.menu("VIEW3D_MT_sculpt_gpencil") + elif obj and obj.mode == 'GPENCIL_WEIGHT': + layout.menu("VIEW3D_MT_weight_gpencil") + elif edit_object: layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower()) @@ -1194,6 +1225,7 @@ class VIEW3D_MT_select_gpencil(Menu): layout.separator() layout.operator("gpencil.select_linked", text="Linked") + layout.operator("gpencil.select_alternate") layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped") layout.separator() @@ -1454,6 +1486,7 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE') layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE' layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY') + layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') layout.separator() layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') @@ -3110,12 +3143,17 @@ class VIEW3D_MT_edit_gpencil_delete(Menu): layout.separator() - layout.operator("gpencil.dissolve") + layout.operator_enum("gpencil.dissolve", "type") layout.separator() layout.operator("gpencil.active_frames_delete_all") + layout.separator() + + layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE' + layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL' + # Edit Curve # draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface @@ -3476,11 +3514,34 @@ class VIEW3D_MT_edit_armature_delete(Menu): layout.operator("armature.dissolve", text="Dissolve") -# ********** GPencil Stroke Edit menu ********** +# ********** Grease Pencil Stroke menus ********** +class VIEW3D_MT_gpencil_simplify(Menu): + bl_label = "Simplify" + + def draw(self, context): + layout = self.layout + layout.operator("gpencil.stroke_simplify_fixed", text="Fixed") + layout.operator("gpencil.stroke_simplify", text="Adaptative") + + +class VIEW3D_MT_paint_gpencil(Menu): + bl_label = "Strokes" + + def draw(self, context): + + layout = self.layout + + layout.menu("VIEW3D_MT_gpencil_animation") + layout.menu("VIEW3D_MT_edit_gpencil_interpolate") + + layout.separator() + + layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME' + layout.operator("gpencil.active_frames_delete_all") class VIEW3D_MT_edit_gpencil(Menu): - bl_label = "GPencil" + bl_label = "Strokes" def draw(self, context): tool_settings = context.tool_settings @@ -3488,53 +3549,126 @@ class VIEW3D_MT_edit_gpencil(Menu): layout = self.layout layout.menu("VIEW3D_MT_edit_gpencil_transform") - layout.operator("transform.mirror", text="Mirror") + + layout.separator() layout.menu("GPENCIL_MT_snap") layout.separator() - layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True - layout.prop_menu_enum(tool_settings.gpencil_sculpt, "tool", text="Sculpt Brush") + layout.menu("VIEW3D_MT_gpencil_animation") layout.separator() - layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access... layout.menu("VIEW3D_MT_edit_gpencil_interpolate") layout.separator() layout.operator("gpencil.duplicate_move", text="Duplicate") layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.menu("VIEW3D_MT_gpencil_simplify") layout.separator() + layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...") + layout.operator("gpencil.stroke_split", text="Split") layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...") layout.operator("gpencil.stroke_flip", text="Flip Direction") layout.separator() layout.operator("gpencil.copy", text="Copy") - layout.operator("gpencil.paste", text="Paste") + layout.operator("gpencil.paste", text="Paste").type = 'COPY' + layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE' + + layout.separator() + + layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") + layout.operator("gpencil.stroke_change_color", text="Change Color") + layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") + + layout.separator() + + layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") + + layout.separator() + + layout.menu("VIEW3D_MT_edit_gpencil_delete") + layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE' + + layout.separator() + + layout.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode") + + +class VIEW3D_MT_sculpt_gpencil(Menu): + bl_label = "Strokes" + + def draw(self, context): + layout = self.layout + + layout.menu("VIEW3D_MT_edit_gpencil_transform") layout.separator() + layout.menu("GPENCIL_MT_snap") - layout.operator("gpencil.reveal") - layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True - layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False + layout.separator() + + layout.operator("gpencil.duplicate_move", text="Duplicate") + layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.menu("VIEW3D_MT_gpencil_simplify") + + layout.separator() + + layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...") + layout.operator("gpencil.stroke_split", text="Split") + layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...") + layout.operator("gpencil.stroke_flip", text="Flip Direction") + + layout.separator() + + layout.operator("gpencil.copy", text="Copy") + layout.operator("gpencil.paste", text="Paste").type = 'COPY' + layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE' layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator("gpencil.stroke_change_color", text="Move to Color") + layout.operator("gpencil.stroke_change_color", text="Change Color") layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") layout.separator() layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...") - layout.separator() - layout.menu("VIEW3D_MT_edit_gpencil_delete") +class VIEW3D_MT_weight_gpencil(Menu): + bl_label = "Weights" + + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.vertex_group_invert", text="Invert") + layout.operator("gpencil.vertex_group_smooth", text="Smooth") + + +class VIEW3D_MT_gpencil_animation(Menu): + bl_label = "Animation" + + @classmethod + def poll(cls, context): + ob = context.active_object + return ob and ob.type == 'GPENCIL' and ob.mode != 'OBJECT' + + @staticmethod + def draw(self, context): + layout = self.layout + + layout.operator("gpencil.blank_frame_add") + layout.operator("gpencil.active_frames_delete_all", text="Delete Frame(s)") + + layout.separator() + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers").mode = 'ALL' class VIEW3D_MT_edit_gpencil_transform(Menu): @@ -3595,20 +3729,6 @@ class VIEW3D_MT_view_pie(Menu): # ********** Panel ********** -class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - - # NOTE: this is just a wrapper around the generic GP Panel - - -class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel): - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - - # NOTE: this is just a wrapper around the generic GP Panel - - class VIEW3D_PT_view3d_properties(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -3720,6 +3840,7 @@ class VIEW3D_PT_object_type_visibility(Panel): "armature", "lattice", "empty", + "grease_pencil", "camera", "light", "light_probe", @@ -4040,6 +4161,8 @@ class VIEW3D_PT_overlay_guides(Panel): if shading.type == 'MATERIAL': col.prop(overlay, "show_look_dev") + col.prop(overlay, "show_annotation", text="Annotations") + class VIEW3D_PT_overlay_object(Panel): bl_space_type = 'VIEW_3D' @@ -4578,6 +4701,60 @@ class VIEW3D_PT_transform_orientations(Panel): row.operator("transform.delete_orientation", text="", icon='X', emboss=False) +class VIEW3D_PT_overlay_gpencil_options(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_parent_id = 'VIEW3D_PT_overlay' + bl_label = "" + + @classmethod + def poll(cls, context): + return context.object and context.object.type == 'GPENCIL' + + def draw_header(self, context): + layout = self.layout + layout.label(text={ + 'GPENCIL_PAINT': "Draw Grease Pencil", + 'GPENCIL_EDIT': "Edit Grease Pencil", + 'GPENCIL_SCULPT': "Sculpt Grease Pencil", + 'GPENCIL_WEIGHT': "Weight Grease Pencil", + 'OBJECT': "Grease Pencil", + }[context.mode]) + + def draw(self, context): + layout = self.layout + view = context.space_data + overlay = view.overlay + + layout.prop(overlay, "use_gpencil_onion_skin", text="Onion Skin") + + col = layout.column() + row = col.row() + row.prop(overlay, "use_gpencil_paper", text="") + sub = row.row() + sub.active = overlay.use_gpencil_paper + sub.prop(overlay, "gpencil_paper_opacity", text="Fade 3D Objects", slider=True) + + col = layout.column() + row = col.row() + row.prop(overlay, "use_gpencil_grid", text="") + sub = row.row() + sub.active = overlay.use_gpencil_grid + sub.prop(overlay, "gpencil_grid_opacity", text="Canvas Grid", slider=True) + + if overlay.use_gpencil_grid: + row = layout.row(align=True) + row.prop(overlay, "gpencil_grid_scale") + col = row.column() + col.prop(overlay, "gpencil_grid_lines", text="Subdivisions") + col.prop(overlay, "gpencil_grid_axis") + + if context.object.mode in {'GPENCIL_EDIT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}: + layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines") + layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe") + layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True) + + class VIEW3D_PT_quad_view(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -4605,6 +4782,14 @@ class VIEW3D_PT_quad_view(Panel): row.prop(region, "use_box_clip") +# Annotation properties +class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + + # NOTE: this is just a wrapper around the generic GP Panel + + class VIEW3D_PT_view3d_stereo(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'UI' @@ -4684,6 +4869,27 @@ class VIEW3D_PT_context_properties(Panel): rna_prop_ui.draw(self.layout, context, member, object, False) +# Grease Pencil Object - Multiframe falloff tools +class VIEW3D_PT_gpencil_multi_frame(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Multi Frame" + + @staticmethod + def draw(self, context): + gpd = context.gpencil_data + settings = context.tool_settings.gpencil_sculpt + + layout = self.layout + col = layout.column(align=True) + col.prop(settings, "use_multiframe_falloff") + + # Falloff curve + if gpd.use_multiedit and settings.use_multiframe_falloff: + layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True) + + + classes = ( VIEW3D_HT_header, VIEW3D_MT_editor_menus, @@ -4791,8 +4997,13 @@ classes = ( VIEW3D_MT_edit_mesh_clean, VIEW3D_MT_edit_mesh_delete, VIEW3D_MT_edit_mesh_showhide, + VIEW3D_MT_paint_gpencil, VIEW3D_MT_edit_gpencil, VIEW3D_MT_edit_gpencil_delete, + VIEW3D_MT_sculpt_gpencil, + VIEW3D_MT_weight_gpencil, + VIEW3D_MT_gpencil_animation, + VIEW3D_MT_gpencil_simplify, VIEW3D_MT_edit_curve, VIEW3D_MT_edit_curve_ctrlpoints, VIEW3D_MT_edit_curve_segments, @@ -4815,12 +5026,12 @@ classes = ( VIEW3D_MT_edit_gpencil_interpolate, VIEW3D_MT_object_mode_pie, VIEW3D_MT_view_pie, - VIEW3D_PT_grease_pencil, - VIEW3D_PT_grease_pencil_palettecolor, VIEW3D_PT_view3d_properties, VIEW3D_PT_view3d_camera_lock, VIEW3D_PT_view3d_cursor, VIEW3D_PT_object_type_visibility, + VIEW3D_PT_grease_pencil, + VIEW3D_PT_gpencil_multi_frame, VIEW3D_PT_quad_view, VIEW3D_PT_view3d_stereo, VIEW3D_PT_shading, @@ -4849,6 +5060,7 @@ classes = ( VIEW3D_PT_pivot_point, VIEW3D_PT_snapping, VIEW3D_PT_transform_orientations, + VIEW3D_PT_overlay_gpencil_options, VIEW3D_PT_context_properties, ) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 87c6a3840ae..70d8c4089d3 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -20,19 +20,17 @@ import bpy from bpy.types import Menu, Panel, UIList from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilStrokeEditPanel, - GreasePencilInterpolatePanel, - GreasePencilStrokeSculptPanel, - GreasePencilBrushPanel, - GreasePencilBrushCurvesPanel -) + GreasePencilStrokeEditPanel, + GreasePencilStrokeSculptPanel, + GreasePencilAppearancePanel, + ) from .properties_paint_common import ( - UnifiedPaintPanel, - brush_texture_settings, - brush_texpaint_common, - brush_mask_texture_settings, -) + UnifiedPaintPanel, + brush_texture_settings, + brush_texpaint_common, + brush_mask_texture_settings, + ) +from bl_operators.presets import PresetMenu class View3DPanel: @@ -70,6 +68,12 @@ def draw_vpaint_symmetry(layout, vpaint): col.use_property_split = True col.prop(vpaint, "radial_symmetry", text="Radial") +# Most of these panels should not be visible in GP edit modes +def is_not_gpencil_edit_mode(context): + is_gpmode = context.active_object and \ + context.active_object.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'} + return not is_gpmode + # ********** default tools for editmode_mesh **************** @@ -1341,9 +1345,272 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): sub.prop(pe, "fade_frames", slider=True) -# Grease Pencil drawing tools -class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): +# ********** grease pencil object tool panels **************** + +# Grease Pencil drawing brushes +class VIEW3D_PT_tools_grease_pencil_brush(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Brush" + + @classmethod + def poll(cls, context): + is_3d_view = context.space_data.type == 'VIEW_3D' + if is_3d_view: + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(gpd.is_stroke_paint_mode) + else: + return True + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + ts = context.scene.tool_settings + settings = ts.gpencil_paint + + row = layout.row() + col = row.column() + col.template_ID_preview(settings, "brush", new="brush.add_gpencil", rows=3, cols=8) + + col = row.column() + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + + sub = col.column(align=True) + sub.operator("gpencil.brush_presets_create", icon='HELP', text="") + + if brush is not None: + # XXX: Items in "sub" currently show up beside the brush selector in a separate column + if gp_settings.gpencil_brush_type == 'ERASE': + sub.prop(gp_settings, "default_eraser", text="") + + # Brush details + if gp_settings.gpencil_brush_type == 'ERASE': + col = layout.column(align=True) + col.prop(brush, "size", text="Radius") + + col.separator() + row = col.row() + row.prop(gp_settings, "eraser_mode", expand=True) + elif gp_settings.gpencil_brush_type == 'FILL': + col = layout.column(align=True) + col.prop(gp_settings, "gpencil_fill_leak", text="Leak Size") + col.prop(brush, "size", text="Thickness") + col.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify") + + col = layout.row(align=True) + col.template_ID(gp_settings, "material") + + row = layout.row(align=True) + row.prop(gp_settings, "gpencil_fill_draw_mode", text="Boundary Draw Mode") + row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID') + + col = layout.column(align=True) + col.enabled = gp_settings.gpencil_fill_draw_mode != "STROKE" + col.prop(gp_settings, "gpencil_fill_hide", text="Hide Transparent Lines") + sub = col.row(align=True) + sub.enabled = gp_settings.gpencil_fill_hide + sub.prop(gp_settings, "gpencil_fill_threshold", text="Threshold") + else: # bgpsettings.gpencil_brush_type == 'DRAW': + row = layout.row(align=True) + row.prop(brush, "size", text="Radius") + row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE') + row = layout.row(align=True) + row.prop(gp_settings, "pen_strength", slider=True) + row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE') + + row = layout.row(align=True) + row.template_ID(gp_settings, "material") + + +# Grease Pencil drawing brushes options +class VIEW3D_PT_tools_grease_pencil_brush_option(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} + + def draw_header_preset(self, context): + VIEW3D_PT_gpencil_brush_presets.draw_panel_header(self.layout) + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + + if brush is not None: + col = layout.column(align=True) + col.prop(gp_settings, "input_samples") + col.separator() + + col.prop(gp_settings, "active_smooth_factor") + col.separator() + + col.prop(gp_settings, "angle", slider=True) + col.prop(gp_settings, "angle_factor", text="Factor", slider=True) + col.separator() + + +class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option' + bl_label = "Stabilizer" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + + return brush is not None and gp_settings.gpencil_brush_type == 'DRAW' + + def draw_header(self, context): + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + self.layout.prop(gp_settings, "use_stabilizer", text="") + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + layout.active = gp_settings.use_stabilizer + + layout.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) + layout.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) + + +class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option' + bl_label = "Post-processing Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + brush = context.active_gpencil_brush + + return brush is not None + + def draw_header(self, context): + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + self.layout.prop(gp_settings, "enable_settings", text="") + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + layout.active = gp_settings.enable_settings + + layout.prop(gp_settings, "pen_smooth_factor") + layout.prop(gp_settings, "pen_smooth_steps") + + layout.prop(gp_settings, "pen_thick_smooth_factor") + layout.prop(gp_settings, "pen_thick_smooth_steps") + + layout.prop(gp_settings, "pen_subdivision_steps") + layout.prop(gp_settings, "random_subdiv", text="Randomness", slider=True) + + +class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option' + bl_label = "Random Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + brush = context.active_gpencil_brush + + return brush is not None + + def draw_header(self, context): + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + self.layout.prop(gp_settings, "enable_random", text="") + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + layout.active = gp_settings.enable_random + + layout.prop(gp_settings, "random_pressure", text="Pressure", slider=True) + layout.prop(gp_settings, "random_strength", text="Strength", slider=True) + layout.prop(gp_settings, "uv_random", text="UV", slider=True) + + row = layout.row(align=True) + row.prop(gp_settings, "pen_jitter", slider=True) + row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE') + + +# Grease Pencil drawingcurves +class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Curves" + bl_options = {'DEFAULT_CLOSED'} + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + brush = context.active_gpencil_brush + gp_settings = brush.gpencil_settings + + # Brush + layout.label("Sensitivity") + layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True) + + layout.label("Strength") + layout.template_curve_mapping(gp_settings, "curve_strength", brush=True) + + layout.label("Jitter") + layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True) + + +# Grease Pencil create shapes +class VIEW3D_PT_tools_grease_pencil_shapes(View3DPanel, Panel): bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Shapes" + + @classmethod + def poll(cls, context): + ob = context.active_object + return ob and ob.type == 'GPENCIL' + + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + col = layout.column(align=True) + col.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE' + col.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX' + col.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE' + + layout.operator("object.gpencil_add", text="Monkey", icon='MONKEY').type = 'MONKEY' # Grease Pencil stroke editing tools @@ -1352,24 +1619,109 @@ class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel): # Grease Pencil stroke interpolation tools -class VIEW3D_PT_tools_grease_pencil_interpolate(GreasePencilInterpolatePanel, Panel): +class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Interpolate" + + @classmethod + def poll(cls, context): + if context.gpencil_data is None: + return False + + gpd = context.gpencil_data + return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode) + + @staticmethod + def draw(self, context): + layout = self.layout + settings = context.tool_settings.gpencil_interpolate + + col = layout.column(align=True) + col.label("Interpolate Strokes") + col.operator("gpencil.interpolate", text="Interpolate") + col.operator("gpencil.interpolate_sequence", text="Sequence") + col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns") + + col = layout.column(align=True) + col.label(text="Options:") + col.prop(settings, "interpolate_all_layers") + col.prop(settings, "interpolate_selected_only") + + col = layout.column(align=True) + col.label(text="Sequence Options:") + col.prop(settings, "type") + if settings.type == 'CUSTOM': + # TODO: Options for loading/saving curve presets? + col.template_curve_mapping(settings, "interpolation_curve", brush=True) + elif settings.type != 'LINEAR': + col.prop(settings, "easing") + + if settings.type == 'BACK': + layout.prop(settings, "back") + elif setting.type == 'ELASTIC': + sub = layout.column(align=True) + sub.prop(settings, "amplitude") + sub.prop(settings, "period") # Grease Pencil stroke sculpting tools -class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel): - bl_space_type = 'VIEW_3D' +class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, View3DPanel, Panel): + bl_context = ".greasepencil_sculpt" + bl_category = "Tools" + bl_label = "Sculpt Strokes" -# Grease Pencil drawing brushes -class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel): - bl_space_type = 'VIEW_3D' +# Grease Pencil weight painting tools +class VIEW3D_PT_tools_grease_pencil_weight_paint(View3DPanel, Panel): + bl_context = ".greasepencil_weight" + bl_category = "Tools" + bl_label = "Weight Paint" -# Grease Pencil drawingcurves + @staticmethod + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + gpd = context.gpencil_data + settings = context.tool_settings.gpencil_sculpt + tool = settings.tool + brush = settings.brush -class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel): - bl_space_type = 'VIEW_3D' + layout.template_icon_view(settings, "weight_tool", show_labels=True) + + col = layout.column() + col.prop(brush, "size", slider=True) + row = col.row(align=True) + row.prop(brush, "strength", slider=True) + row.prop(brush, "use_pressure_strength", text="") + + col.prop(brush, "use_falloff") + + +# Grease Pencil Brush Appeareance (one for each mode) +class VIEW3D_PT_tools_grease_pencil_paint_appearance(GreasePencilAppearancePanel, View3DPanel, Panel): + bl_context = ".greasepencil_paint" + bl_label = "Appearance" + + +class VIEW3D_PT_tools_grease_pencil_sculpt_appearance(GreasePencilAppearancePanel, View3DPanel, Panel): + bl_context = ".greasepencil_sculpt" + bl_label = "Appearance" + + +class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilAppearancePanel, View3DPanel, Panel): + bl_context = ".greasepencil_weight" + bl_label = "Appearance" + + +class VIEW3D_PT_gpencil_brush_presets(PresetMenu): + """Brush settings""" + bl_label = "Brush Presets" + preset_subdir = "gpencil_brush" + preset_operator = "script.execute_preset" + preset_add_operator = "scene.gpencil_brush_preset_add" classes = ( @@ -1401,12 +1753,21 @@ classes = ( VIEW3D_PT_tools_projectpaint, VIEW3D_MT_tools_projectpaint_stencil, VIEW3D_PT_tools_particlemode, - VIEW3D_PT_tools_grease_pencil_draw, - VIEW3D_PT_tools_grease_pencil_edit, - VIEW3D_PT_tools_grease_pencil_interpolate, - VIEW3D_PT_tools_grease_pencil_sculpt, + + VIEW3D_PT_gpencil_brush_presets, VIEW3D_PT_tools_grease_pencil_brush, + VIEW3D_PT_tools_grease_pencil_brush_option, + VIEW3D_PT_tools_grease_pencil_brush_settings, + VIEW3D_PT_tools_grease_pencil_brush_stabilizer, + VIEW3D_PT_tools_grease_pencil_brush_random, VIEW3D_PT_tools_grease_pencil_brushcurves, + VIEW3D_PT_tools_grease_pencil_shapes, + VIEW3D_PT_tools_grease_pencil_sculpt, + VIEW3D_PT_tools_grease_pencil_weight_paint, + VIEW3D_PT_tools_grease_pencil_paint_appearance, + VIEW3D_PT_tools_grease_pencil_sculpt_appearance, + VIEW3D_PT_tools_grease_pencil_weight_appearance, + VIEW3D_PT_tools_grease_pencil_interpolate, ) if __name__ == "__main__": # only for live edit. diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 5709ac723f4..2c9b1efe2f4 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -44,7 +44,9 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_fileglobal_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_shader_fx_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_group_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h @@ -112,6 +114,8 @@ add_subdirectory(gpu) add_subdirectory(imbuf) add_subdirectory(nodes) add_subdirectory(modifiers) +add_subdirectory(gpencil_modifiers) +add_subdirectory(shader_fx) add_subdirectory(makesdna) add_subdirectory(makesrna) diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index eda1c51bbc2..489746cbfd9 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -28,11 +28,14 @@ */ enum eCurveMappingPreset; +struct bContext; struct Brush; +struct Paint; struct ImBuf; struct ImagePool; struct Main; struct Scene; +struct ToolSettings; struct UnifiedPaintSettings; // enum eCurveMappingPreset; @@ -45,14 +48,17 @@ void BKE_brush_system_exit(void); /* datablock functions */ void BKE_brush_init(struct Brush *brush); struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode); +struct Brush *BKE_brush_add_gpencil(struct Main *bmain, struct ToolSettings *ts, const char *name); struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode); void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag); struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush); void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local); -void BKE_brush_unlink(struct Main *bmain, struct Brush *brush); void BKE_brush_free(struct Brush *brush); void BKE_brush_sculpt_reset(struct Brush *brush); +void BKE_brush_gpencil_presets(struct bContext *C); +struct Brush *BKE_brush_getactive_gpencil(struct ToolSettings *ts); +struct Paint *BKE_brush_get_gpencil_paint(struct ToolSettings *ts); /* image icon function */ struct ImBuf *get_brush_icon(struct Brush *brush); diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 9f57859d318..28dcf9cb127 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -65,9 +65,7 @@ struct bPoseChannel; struct bGPdata; struct bGPDlayer; struct bGPDframe; -struct bGPDpalette; -struct bGPDpalettecolor; -struct bGPDbrush; +struct Brush; struct wmWindow; struct wmWindowManager; struct RenderEngineType; @@ -120,6 +118,10 @@ enum { CTX_MODE_PAINT_TEXTURE, CTX_MODE_PARTICLE, CTX_MODE_OBJECT, + CTX_MODE_GPENCIL_PAINT, + CTX_MODE_GPENCIL_EDIT, + CTX_MODE_GPENCIL_SCULPT, + CTX_MODE_GPENCIL_WEIGHT, CTX_MODE_NUM /* must be last */ }; @@ -313,9 +315,7 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list); struct bGPdata *CTX_data_gpencil_data(const bContext *C); struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C); struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C); -struct bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C); -struct bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C); -struct bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C); +struct Brush *CTX_data_active_gpencil_brush(const bContext *C); int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list); int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list); int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list); diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 3a951b7860d..887a7f4f67b 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -31,25 +31,45 @@ * \author Joshua Leung */ +struct CurveMapping; +struct Depsgraph; +struct GpencilModifierData; struct ToolSettings; struct ListBase; struct bGPdata; struct bGPDlayer; struct bGPDframe; +struct bGPDspoint; struct bGPDstroke; +struct Material; struct bGPDpalette; struct bGPDpalettecolor; struct Main; +struct BoundBox; +struct Brush; +struct Object; +struct bDeformGroup; +struct SimplifyGpencilModifierData; +struct InstanceGpencilModifierData; +struct LatticeGpencilModifierData; + +struct MDeformVert; +struct MDeformWeight; /* ------------ Grease-Pencil API ------------------ */ +void BKE_gpencil_free_point_weights(struct MDeformVert *dvert); +void BKE_gpencil_free_stroke_weights(struct bGPDstroke *gps); void BKE_gpencil_free_stroke(struct bGPDstroke *gps); bool BKE_gpencil_free_strokes(struct bGPDframe *gpf); void BKE_gpencil_free_frames(struct bGPDlayer *gpl); void BKE_gpencil_free_layers(struct ListBase *list); -void BKE_gpencil_free_brushes(struct ListBase *list); -void BKE_gpencil_free_palettes(struct ListBase *list); -void BKE_gpencil_free(struct bGPdata *gpd, bool free_palettes); +bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *derived_gpf); +void BKE_gpencil_free_derived_frames(struct bGPdata *gpd); +void BKE_gpencil_free(struct bGPdata *gpd, bool free_all); + +void BKE_gpencil_batch_cache_dirty(struct bGPdata *gpd); +void BKE_gpencil_batch_cache_free(struct bGPdata *gpd); void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps); @@ -60,21 +80,36 @@ struct bGPdata *BKE_gpencil_data_addnew(struct Main *bmain, const char name[]) struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src); struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src); +void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst); +struct bGPDstroke *BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src); + void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag); +struct bGPdata *BKE_gpencil_copy(struct Main *bmain, const struct bGPdata *gpd); struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy); void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local); void BKE_gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf); -struct bGPDpalette *BKE_gpencil_palette_addnew(struct bGPdata *gpd, const char *name, bool setactive); -struct bGPDpalette *BKE_gpencil_palette_duplicate(const struct bGPDpalette *palette_src); -struct bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(struct bGPDpalette *palette, const char *name, bool setactive); +/* materials */ +void BKE_gpencil_material_index_remove(struct bGPdata *gpd, int index); +void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len); -struct bGPDbrush *BKE_gpencil_brush_addnew(struct ToolSettings *ts, const char *name, bool setactive); -struct bGPDbrush *BKE_gpencil_brush_duplicate(const struct bGPDbrush *brush_src); -void BKE_gpencil_brush_init_presets(struct ToolSettings *ts); +/* statistics functions */ +void BKE_gpencil_stats_update(struct bGPdata *gpd); +/* Utilities for creating and populating GP strokes */ +/* - Number of values defining each point in the built-in data + * buffers for primitives (e.g. 2D Monkey) + */ +#define GP_PRIM_DATABUF_SIZE 5 + +void BKE_gpencil_stroke_add_points( + struct bGPDstroke *gps, + const float *array, const int totpoints, + const float mat[4][4]); + +struct bGPDstroke *BKE_gpencil_add_stroke(struct bGPDframe *gpf, int mat_idx, int totpoints, short thickness); /* Stroke and Fill - Alpha Visibility Threshold */ #define GPENCIL_ALPHA_OPACITY_THRESH 0.001f @@ -103,20 +138,40 @@ struct bGPDlayer *BKE_gpencil_layer_getactive(struct bGPdata *gpd); void BKE_gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active); void BKE_gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl); -struct bGPDbrush *BKE_gpencil_brush_getactive(struct ToolSettings *ts); -void BKE_gpencil_brush_setactive(struct ToolSettings *ts, struct bGPDbrush *active); -void BKE_gpencil_brush_delete(struct ToolSettings *ts, struct bGPDbrush *brush); - -struct bGPDpalette *BKE_gpencil_palette_getactive(struct bGPdata *gpd); -void BKE_gpencil_palette_setactive(struct bGPdata *gpd, struct bGPDpalette *active); -void BKE_gpencil_palette_delete(struct bGPdata *gpd, struct bGPDpalette *palette); -void BKE_gpencil_palette_change_strokes(struct bGPdata *gpd); - -struct bGPDpalettecolor *BKE_gpencil_palettecolor_getactive(struct bGPDpalette *palette); -void BKE_gpencil_palettecolor_setactive(struct bGPDpalette *palette, struct bGPDpalettecolor *active); -void BKE_gpencil_palettecolor_delete(struct bGPDpalette *palette, struct bGPDpalettecolor *palcolor); -struct bGPDpalettecolor *BKE_gpencil_palettecolor_getbyname(struct bGPDpalette *palette, char *name); -void BKE_gpencil_palettecolor_changename(struct bGPdata *gpd, char *oldname, const char *newname); -void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name); +struct Material *BKE_gpencil_get_material_from_brush(struct Brush *brush); +struct Material *BKE_gpencil_material_ensure(struct Main *bmain, struct Object *ob); + +/* object boundbox */ +bool BKE_gpencil_stroke_minmax( + const struct bGPDstroke *gps, const bool use_select, + float r_min[3], float r_max[3]); + +struct BoundBox *BKE_gpencil_boundbox_get(struct Object *ob); +void BKE_gpencil_centroid_3D(struct bGPdata *gpd, float r_centroid[3]); + +/* vertex groups */ +float BKE_gpencil_vgroup_use_index(struct MDeformVert *dvert, int index); +void BKE_gpencil_vgroup_remove(struct Object *ob, struct bDeformGroup *defgroup); +struct MDeformWeight *BKE_gpencil_vgroup_add_point_weight(struct MDeformVert *dvert, int index, float weight); +bool BKE_gpencil_vgroup_remove_point_weight(struct MDeformVert *dvert, int index); +void BKE_gpencil_stroke_weights_duplicate(struct bGPDstroke *gps_src, struct bGPDstroke *gps_dst); + +/* GPencil geometry evaluation */ +void BKE_gpencil_eval_geometry(struct Depsgraph *depsgraph, struct bGPdata *gpd); + +/* stroke geometry utilities */ +void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]); +void BKE_gpencil_simplify_stroke(struct bGPDstroke *gps, float factor); +void BKE_gpencil_simplify_fixed(struct bGPDstroke *gps); + +void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]); + +bool BKE_gpencil_smooth_stroke(struct bGPDstroke *gps, int i, float inf); +bool BKE_gpencil_smooth_stroke_strength(struct bGPDstroke *gps, int point_index, float influence); +bool BKE_gpencil_smooth_stroke_thickness(struct bGPDstroke *gps, int point_index, float influence); +bool BKE_gpencil_smooth_stroke_uv(struct bGPDstroke *gps, int point_index, float influence); + +void BKE_gpencil_get_range_selected(struct bGPDlayer *gpl, int *r_initframe, int *r_endframe); +float BKE_gpencil_multiframe_falloff_calc(struct bGPDframe *gpf, int actnum, int f_init, int f_end, struct CurveMapping *cur_falloff); #endif /* __BKE_GPENCIL_H__ */ diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h new file mode 100644 index 00000000000..cd6b6540012 --- /dev/null +++ b/source/blender/blenkernel/BKE_gpencil_modifier.h @@ -0,0 +1,256 @@ +/* + * ***** 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: all of this file. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __BKE_GPENCIL_MODIFIER_H__ +#define __BKE_GPENCIL_MODIFIER_H__ + +/** \file BKE_greasepencil_modifier.h + * \ingroup bke + */ + +#include "DNA_gpencil_modifier_types.h" /* needed for all enum typdefs */ +#include "BLI_compiler_attrs.h" +#include "BKE_customdata.h" + +struct ID; +struct Depsgraph; +struct DerivedMesh; +struct bContext; /* NOTE: bakeModifier() - called from UI - needs to create new datablocks, hence the need for this */ +struct Mesh; +struct Object; +struct Scene; +struct ViewLayer; +struct ListBase; +struct bArmature; +struct Main; +struct GpencilModifierData; +struct BMEditMesh; +struct DepsNodeHandle; +struct bGPDlayer; +struct bGPDframe; +struct bGPDstroke; +struct ModifierUpdateDepsgraphContext; + +#define GPENCIL_MODIFIER_ACTIVE(_md, _is_render) (((_md->mode & eGpencilModifierMode_Realtime) && (_is_render == false)) || \ + ((_md->mode & eGpencilModifierMode_Render) && (_is_render == true))) +#define GPENCIL_MODIFIER_EDIT(_md, _is_edit) (((_md->mode & eGpencilModifierMode_Editmode) == 0) && (_is_edit)) + +typedef enum { + /* Should not be used, only for None modifier type */ + eGpencilModifierTypeType_None, + + /* grease pencil modifiers */ + eGpencilModifierTypeType_Gpencil, +} GpencilModifierTypeType; + +typedef enum { + eGpencilModifierTypeFlag_SupportsMapping = (1 << 0), + eGpencilModifierTypeFlag_SupportsEditmode = (1 << 1), + + /* For modifiers that support editmode this determines if the + * modifier should be enabled by default in editmode. This should + * only be used by modifiers that are relatively speedy and + * also generally used in editmode, otherwise let the user enable + * it by hand. + */ + eGpencilModifierTypeFlag_EnableInEditmode = (1 << 2), + + /* For modifiers that require original data and so cannot + * be placed after any non-deformative modifier. + */ + eGpencilModifierTypeFlag_RequiresOriginalData = (1 << 3), + + /* max one per type */ + eGpencilModifierTypeFlag_Single = (1 << 4), + + /* can't be added manually by user */ + eGpencilModifierTypeFlag_NoUserAdd = (1 << 5), +} GpencilModifierTypeFlag; + +/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */ +typedef void(*GreasePencilObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag); +typedef void(*GreasePencilIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag); +typedef void(*GreasePencilTexWalkFunc)(void *userData, struct Object *ob, struct GpencilModifierData *md, const char *propname); + +typedef struct GpencilModifierTypeInfo { + /* The user visible name for this modifier */ + char name[32]; + + /* The DNA struct name for the modifier data type, used to + * write the DNA data out. + */ + char struct_name[32]; + + /* The size of the modifier data type, used by allocation. */ + int struct_size; + + GpencilModifierType type; + GpencilModifierTypeFlag flags; + + + /********************* Non-optional functions *********************/ + + /* Copy instance data for this modifier type. Should copy all user + * level settings to the target modifier. + */ + void (*copyData)(const struct GpencilModifierData *md, struct GpencilModifierData *target); + + /* Callback for GP "stroke" modifiers that operate on the + * shape and parameters of the provided strokes (e.g. Thickness, Noise, etc.) + * + * The gpl parameter contains the GP layer that the strokes come from. + * While access is provided to this data, you should not directly access + * the gpl->frames data from the modifier. Instead, use the gpf parameter + * instead. + * + * The gps parameter contains the GP stroke to operate on. This is usually a copy + * of the original (unmodified and saved to files) stroke data. + */ + void (*deformStroke)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, + struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps); + + /* Callback for GP "geometry" modifiers that create extra geometry + * in the frame (e.g. Array) + * + * The gpf parameter contains the GP frame/strokes to operate on. This is + * usually a copy of the original (unmodified and saved to files) stroke data. + * Modifiers should only add any generated strokes to this frame (and not one accessed + * via the gpl parameter). + * + * The modifier_index parameter indicates where the modifier is + * in the modifier stack in relation to other modifiers. + */ + void (*generateStrokes)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, + struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf); + + /* Bake-down GP modifier's effects into the GP datablock. + * + * This gets called when the user clicks the "Apply" button in the UI. + * As such, this callback needs to go through all layers/frames in the + * datablock, mutating the geometry and/or creating new datablocks/objects + */ + void (*bakeModifier)(struct Main *bmain, struct Depsgraph *depsgraph, + struct GpencilModifierData *md, struct Object *ob); + + /********************* Optional functions *********************/ + + /* Initialize new instance data for this modifier type, this function + * should set modifier variables to their default values. + * + * This function is optional. + */ + void (*initData)(struct GpencilModifierData *md); + + /* Free internal modifier data variables, this function should + * not free the md variable itself. + * + * This function is optional. + */ + void (*freeData)(struct GpencilModifierData *md); + + /* Return a boolean value indicating if this modifier is able to be + * calculated based on the modifier data. This is *not* regarding the + * md->flag, that is tested by the system, this is just if the data + * validates (for example, a lattice will return false if the lattice + * object is not defined). + * + * This function is optional (assumes never disabled if not present). + */ + bool (*isDisabled)(struct GpencilModifierData *md, int userRenderParams); + + /* Add the appropriate relations to the dependency graph. + * + * This function is optional. + */ + void (*updateDepsgraph)(struct GpencilModifierData *md, + const struct ModifierUpdateDepsgraphContext *ctx); + + /* Should return true if the modifier needs to be recalculated on time + * changes. + * + * This function is optional (assumes false if not present). + */ + bool (*dependsOnTime)(struct GpencilModifierData *md); + + + /* Should call the given walk function on with a pointer to each Object + * pointer that the modifier data stores. This is used for linking on file + * load and for unlinking objects or forwarding object references. + * + * This function is optional. + */ + void (*foreachObjectLink)(struct GpencilModifierData *md, struct Object *ob, + GreasePencilObjectWalkFunc walk, void *userData); + + /* Should call the given walk function with a pointer to each ID + * pointer (i.e. each datablock pointer) that the modifier data + * stores. This is used for linking on file load and for + * unlinking datablocks or forwarding datablock references. + * + * This function is optional. If it is not present, foreachObjectLink + * will be used. + */ + void (*foreachIDLink)(struct GpencilModifierData *md, struct Object *ob, + GreasePencilIDWalkFunc walk, void *userData); + + /* Should call the given walk function for each texture that the + * modifier data stores. This is used for finding all textures in + * the context for the UI. + * + * This function is optional. If it is not present, it will be + * assumed the modifier has no textures. + */ + void (*foreachTexLink)(struct GpencilModifierData *md, struct Object *ob, + GreasePencilTexWalkFunc walk, void *userData); +} GpencilModifierTypeInfo; + +void BKE_gpencil_instance_modifier_instance_tfm(struct InstanceGpencilModifierData *mmd, const int elem_idx[3], float r_mat[4][4]); + +/* Initialize modifier's global data (type info and some common global storages). */ +void BKE_gpencil_modifier_init(void); + +const GpencilModifierTypeInfo *BKE_gpencil_modifierType_getInfo(GpencilModifierType type); +struct GpencilModifierData *BKE_gpencil_modifier_new(int type); +void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag); +void BKE_gpencil_modifier_free(struct GpencilModifierData *md); +bool BKE_gpencil_modifier_unique_name(struct ListBase *modifiers, struct GpencilModifierData *gmd); +bool BKE_gpencil_modifier_dependsOnTime(struct GpencilModifierData *md); +struct GpencilModifierData *BKE_gpencil_modifiers_findByType(struct Object *ob, GpencilModifierType type); +struct GpencilModifierData *BKE_gpencil_modifiers_findByName(struct Object *ob, const char *name); +void BKE_gpencil_modifier_copyData_generic(const struct GpencilModifierData *md_src, struct GpencilModifierData *md_dst); +void BKE_gpencil_modifier_copyData(struct GpencilModifierData *md, struct GpencilModifierData *target); +void BKE_gpencil_modifier_copyData_ex(struct GpencilModifierData *md, struct GpencilModifierData *target, const int flag); +void BKE_gpencil_modifiers_foreachIDLink(struct Object *ob, GreasePencilIDWalkFunc walk, void *userData); +void BKE_gpencil_modifiers_foreachTexLink(struct Object *ob, GreasePencilTexWalkFunc walk, void *userData); + +bool BKE_gpencil_has_geometry_modifiers(struct Object *ob); + +void BKE_gpencil_stroke_modifiers( + struct Depsgraph *depsgraph, struct Object *ob, + struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps, bool is_render); +void BKE_gpencil_geometry_modifiers( + struct Depsgraph *depsgraph, struct Object *ob, + struct bGPDlayer *gpl, struct bGPDframe *gpf, bool is_render); + +void BKE_gpencil_lattice_init(struct Object *ob); +void BKE_gpencil_lattice_clear(struct Object *ob); + +#endif /* __BKE_GPENCIL_MODIFIER_H__ */ diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index 22897d2ea80..7a5262e0a14 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -43,7 +43,10 @@ enum { ICON_DATA_PREVIEW, /** 2D triangles: obj is #Icon_Geom */ ICON_DATA_GEOM, + /** Studiolight */ ICON_DATA_STUDIOLIGHT, + /** GPencil Layer color preview (annotations): obj is #bGPDlayer */ + ICON_DATA_GPLAYER, }; struct Icon { @@ -79,6 +82,7 @@ struct ImBuf; struct PreviewImage; struct ID; struct StudioLight; +struct bGPDlayer; enum eIconSizes; @@ -87,6 +91,9 @@ void BKE_icons_init(int first_dyn_id); /* return icon id for library object or create new icon if not found */ int BKE_icon_id_ensure(struct ID *id); +/* return icon id for Grease Pencil layer (color preview) or create new icon if not found */ +int BKE_icon_gplayer_color_ensure(struct bGPDlayer *gpl); + int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview); /* retrieve icon for id */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index c2ac5e98f76..67e6a32edfd 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -54,7 +54,6 @@ void BKE_lattice_free(struct Lattice *lt); void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local); void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); -struct LatticeDeformData; struct LatticeDeformData *init_latt_deform(struct Object *oblatt, struct Object *ob) ATTR_WARN_UNUSED_RESULT; void calc_latt_deform(struct LatticeDeformData *lattice_deform_data, float co[3], float weight); void end_latt_deform(struct LatticeDeformData *lattice_deform_data); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index c85017a2216..1ca8928c61d 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -54,11 +54,13 @@ void BKE_material_init(struct Material *ma); void BKE_material_remap_object(struct Object *ob, const unsigned int *remap); void BKE_material_remap_object_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst); struct Material *BKE_material_add(struct Main *bmain, const char *name); +struct Material *BKE_material_add_gpencil(struct Main *bmain, const char *name); void BKE_material_copy_data(struct Main *bmain, struct Material *ma_dst, const struct Material *ma_src, const int flag); struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma); struct Material *BKE_material_localize(struct Material *ma); struct Material *give_node_material(struct Material *ma); /* returns node material or self */ void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local); +void BKE_material_init_gpencil_settings(struct Material *ma); /* UNUSED */ // void automatname(struct Material *); @@ -87,6 +89,8 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob); bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob); +struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act); + void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma); void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 79e4f1d448a..7d795c25a04 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -37,8 +37,11 @@ extern "C" { struct Base; struct Depsgraph; +struct GpencilModifierData; struct Scene; +struct ShaderFxData; struct ViewLayer; +struct ID; struct Object; struct BoundBox; struct View3D; @@ -49,6 +52,7 @@ struct Mesh; struct RigidBodyWorld; struct HookModifierData; struct ModifierData; +struct HookGpencilModifierData; #include "DNA_object_enums.h" @@ -69,11 +73,16 @@ void BKE_object_free_derived_mesh_caches(struct Object *ob); void BKE_object_free_caches(struct Object *object); void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd); +void BKE_object_modifier_gpencil_hook_reset(struct Object *ob, struct HookGpencilModifierData *hmd); +bool BKE_object_modifier_gpencil_use_time(struct Object *ob, struct GpencilModifierData *md); + +bool BKE_object_shaderfx_use_time(struct Object *ob, struct ShaderFxData *md); bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifier_type); void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src); void BKE_object_free_modifiers(struct Object *ob, const int flag); +void BKE_object_free_shaderfx(struct Object *ob, const int flag); void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob); void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target); @@ -108,6 +117,9 @@ struct Object *BKE_object_add_from( struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, int type, const char *name, struct Object *ob_src) ATTR_NONNULL(1, 2, 3, 6) ATTR_RETURNS_NONNULL; +struct Object *BKE_object_add_for_data( + struct Main *bmain, struct ViewLayer *view_layer, + int type, const char *name, struct ID *data, bool do_id_user) ATTR_RETURNS_NONNULL; void *BKE_object_obdata_add_from_type( struct Main *bmain, int type, const char *name) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 6ade14b275c..c440a634c9f 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -77,7 +77,8 @@ typedef enum ePaintMode { ePaintTextureProjective = 3, ePaintTexture2D = 4, ePaintSculptUV = 5, - ePaintInvalid = 6 + ePaintInvalid = 6, + ePaintGpencil = 7 } ePaintMode; /* overlay invalidation */ diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h new file mode 100644 index 00000000000..11c5983106a --- /dev/null +++ b/source/blender/blenkernel/BKE_shader_fx.h @@ -0,0 +1,180 @@ +/* + * ***** 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: all of this file. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef __BKE_SHADER_FX_H__ +#define __BKE_SHADER_FX_H__ + +/** \file BKE_shader_fx.h + * \ingroup bke + */ + +#include "DNA_shader_fx_types.h" /* needed for all enum typdefs */ +#include "BLI_compiler_attrs.h" +#include "BKE_customdata.h" + +struct ID; +struct Depsgraph; +struct DerivedMesh; +struct Mesh; +struct Object; +struct Scene; +struct ViewLayer; +struct ListBase; +struct bArmature; +struct Main; +struct ShaderFxData; +struct DepsNodeHandle; +struct bGPDlayer; +struct bGPDframe; +struct bGPDstroke; +struct ModifierUpdateDepsgraphContext; + +#define SHADER_FX_ACTIVE(_fx, _is_render) (((_fx->mode & eShaderFxMode_Realtime) && (_is_render == false)) || \ + ((_fx->mode & eShaderFxMode_Render) && (_is_render == true))) +#define SHADER_FX_EDIT(_fx, _is_edit) (((_fx->mode & eShaderFxMode_Editmode) == 0) && (_is_edit)) + +typedef enum { + /* Should not be used, only for None type */ + eShaderFxType_NoneType, + + /* grease pencil effects */ + eShaderFxType_GpencilType, +} ShaderFxTypeType; + +typedef enum { + eShaderFxTypeFlag_SupportsEditmode = (1 << 0), + + /* For effects that support editmode this determines if the + * effect should be enabled by default in editmode. + */ + eShaderFxTypeFlag_EnableInEditmode = (1 << 2), + + /* max one per type */ + eShaderFxTypeFlag_Single = (1 << 4), + + /* can't be added manually by user */ + eShaderFxTypeFlag_NoUserAdd = (1 << 5), +} ShaderFxTypeFlag; + +/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */ +typedef void(*ShaderFxObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag); +typedef void(*ShaderFxIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag); +typedef void(*ShaderFxTexWalkFunc)(void *userData, struct Object *ob, struct ShaderFxData *fx, const char *propname); + +typedef struct ShaderFxTypeInfo { + /* The user visible name for this effect */ + char name[32]; + + /* The DNA struct name for the effect data type, used to + * write the DNA data out. + */ + char struct_name[32]; + + /* The size of the effect data type, used by allocation. */ + int struct_size; + + ShaderFxTypeType type; + ShaderFxTypeFlag flags; + + /* Copy instance data for this effect type. Should copy all user + * level settings to the target effect. + */ + void(*copyData)(const struct ShaderFxData *fx, struct ShaderFxData *target); + + /* Initialize new instance data for this effect type, this function + * should set effect variables to their default values. + * + * This function is optional. + */ + void (*initData)(struct ShaderFxData *fx); + + /* Free internal effect data variables, this function should + * not free the fx variable itself. + * + * This function is optional. + */ + void (*freeData)(struct ShaderFxData *fx); + + /* Return a boolean value indicating if this effect is able to be + * calculated based on the effect data. This is *not* regarding the + * fx->flag, that is tested by the system, this is just if the data + * validates (for example, a lattice will return false if the lattice + * object is not defined). + * + * This function is optional (assumes never disabled if not present). + */ + bool (*isDisabled)(struct ShaderFxData *fx, int userRenderParams); + + /* Add the appropriate relations to the dependency graph. + * + * This function is optional. + */ + void (*updateDepsgraph)(struct ShaderFxData *fx, + const struct ModifierUpdateDepsgraphContext *ctx); + + /* Should return true if the effect needs to be recalculated on time + * changes. + * + * This function is optional (assumes false if not present). + */ + bool (*dependsOnTime)(struct ShaderFxData *fx); + + + /* Should call the given walk function on with a pointer to each Object + * pointer that the effect data stores. This is used for linking on file + * load and for unlinking objects or forwarding object references. + * + * This function is optional. + */ + void (*foreachObjectLink)(struct ShaderFxData *fx, struct Object *ob, + ShaderFxObjectWalkFunc walk, void *userData); + + /* Should call the given walk function with a pointer to each ID + * pointer (i.e. each datablock pointer) that the effect data + * stores. This is used for linking on file load and for + * unlinking datablocks or forwarding datablock references. + * + * This function is optional. If it is not present, foreachObjectLink + * will be used. + */ + void (*foreachIDLink)(struct ShaderFxData *fx, struct Object *ob, + ShaderFxIDWalkFunc walk, void *userData); +} ShaderFxTypeInfo; + +/* Initialize global data (type info and some common global storages). */ +void BKE_shaderfx_init(void); + +const ShaderFxTypeInfo *BKE_shaderfxType_getInfo(ShaderFxType type); +struct ShaderFxData *BKE_shaderfx_new(int type); +void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag); +void BKE_shaderfx_free(struct ShaderFxData *fx); +bool BKE_shaderfx_unique_name(struct ListBase *shaderfx, struct ShaderFxData *fx); +bool BKE_shaderfx_dependsOnTime(struct ShaderFxData *fx); +struct ShaderFxData *BKE_shaderfx_findByType(struct Object *ob, ShaderFxType type); +struct ShaderFxData *BKE_shaderfx_findByName(struct Object *ob, const char *name); +void BKE_shaderfx_copyData_generic(const struct ShaderFxData *fx_src, struct ShaderFxData *fx_dst); +void BKE_shaderfx_copyData(struct ShaderFxData *fx, struct ShaderFxData *target); +void BKE_shaderfx_copyData_ex(struct ShaderFxData *fx, struct ShaderFxData *target, const int flag); +void BKE_shaderfx_foreachIDLink(struct Object *ob, ShaderFxIDWalkFunc walk, void *userData); + +bool BKE_shaderfx_has_gpencil(struct Object *ob); + +#endif /* __BKE_SHADER_FX_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 01910bffdb0..7169597f100 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -38,6 +38,8 @@ set(INC ../makesrna ../bmesh ../modifiers + ../gpencil_modifiers + ../shader_fx ../nodes ../physics ../render/extern/include @@ -115,6 +117,7 @@ set(SRC intern/font.c intern/freestyle.c intern/gpencil.c + intern/gpencil_modifier.c intern/icons.c intern/icons_rasterize.c intern/idcode.c @@ -180,6 +183,7 @@ set(SRC intern/seqeffects.c intern/seqmodifier.c intern/sequencer.c + intern/shader_fx.c intern/shrinkwrap.c intern/smoke.c intern/softbody.c @@ -259,6 +263,7 @@ set(SRC BKE_freestyle.h BKE_global.h BKE_gpencil.h + BKE_gpencil_modifier.h BKE_icons.h BKE_idcode.h BKE_idprop.h @@ -306,6 +311,7 @@ set(SRC BKE_scene.h BKE_screen.h BKE_sequencer.h + BKE_shader_fx.h BKE_shrinkwrap.h BKE_smoke.h BKE_softbody.h diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index fd7497f9ba1..7dfedfe6c06 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -104,6 +104,7 @@ bool id_type_can_have_animdata(const short id_type) case ID_MSK: case ID_GD: case ID_CF: + case ID_PAL: return true; /* no AnimData */ @@ -1150,6 +1151,9 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use /* grease pencil */ ANIMDATA_IDS_CB(bmain->gpencil.first); + /* palettes */ + ANIMDATA_IDS_CB(bmain->palettes.first); + /* cache files */ ANIMDATA_IDS_CB(bmain->cachefiles.first); } @@ -2925,6 +2929,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene /* grease pencil */ EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM); + /* palettes */ + EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM); + /* cache files */ EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 42cd7968321..598eb9b5b54 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -29,6 +29,7 @@ #include "DNA_brush_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_gpencil_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -36,6 +37,7 @@ #include "BKE_brush.h" #include "BKE_colortools.h" +#include "BKE_context.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_library_query.h" @@ -129,6 +131,7 @@ static void brush_defaults(Brush *brush) brush->stencil_dimension[0] = 256; brush->stencil_dimension[1] = 256; + } /* Datablock add/copy/free/make_local */ @@ -164,6 +167,368 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode) return brush; } +/* add a new gp-brush */ +Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name) +{ + Brush *brush; + Paint *paint = BKE_brush_get_gpencil_paint(ts); + brush = BKE_brush_add(bmain, name, OB_MODE_GPENCIL_PAINT); + + BKE_paint_brush_set(paint, brush); + id_us_min(&brush->id); + + /* grease pencil basic settings */ + brush->size = 3; + + brush->gpencil_settings = MEM_callocN(sizeof(BrushGpencilSettings), "BrushGpencilSettings"); + + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->flag = 0; + brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE; + brush->gpencil_settings->draw_sensitivity = 1.0f; + brush->gpencil_settings->draw_strength = 1.0f; + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN; + + /* curves */ + brush->gpencil_settings->curve_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + brush->gpencil_settings->curve_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + + /* return brush */ + return brush; +} + +Paint *BKE_brush_get_gpencil_paint(ToolSettings *ts) +{ + /* alloc paint session */ + if (ts->gp_paint == NULL) { + ts->gp_paint = MEM_callocN(sizeof(GpPaint), "GpPaint"); + } + + return &ts->gp_paint->paint; +} + +/* grease pencil cumapping->preset */ +typedef enum eGPCurveMappingPreset { + GPCURVE_PRESET_PENCIL = 0, + GPCURVE_PRESET_INK = 1, + GPCURVE_PRESET_INKNOISE = 2, +} eGPCurveMappingPreset; + +static void brush_gpencil_curvemap_reset(CurveMap *cuma, int preset) +{ + if (cuma->curve) + MEM_freeN(cuma->curve); + + cuma->totpoint = 3; + cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), __func__); + + switch (preset) { + case GPCURVE_PRESET_PENCIL: + cuma->curve[0].x = 0.0f; + cuma->curve[0].y = 0.0f; + cuma->curve[1].x = 0.75115f; + cuma->curve[1].y = 0.25f; + cuma->curve[2].x = 1.0f; + cuma->curve[2].y = 1.0f; + break; + case GPCURVE_PRESET_INK: + cuma->curve[0].x = 0.0f; + cuma->curve[0].y = 0.0f; + cuma->curve[1].x = 0.63448f; + cuma->curve[1].y = 0.375f; + cuma->curve[2].x = 1.0f; + cuma->curve[2].y = 1.0f; + break; + case GPCURVE_PRESET_INKNOISE: + cuma->curve[0].x = 0.0f; + cuma->curve[0].y = 0.0f; + cuma->curve[1].x = 0.63134f; + cuma->curve[1].y = 0.3625f; + cuma->curve[2].x = 1.0f; + cuma->curve[2].y = 1.0f; + break; + } + + if (cuma->table) { + MEM_freeN(cuma->table); + cuma->table = NULL; + } +} + +/* create a set of grease pencil presets */ +void BKE_brush_gpencil_presets(bContext *C) +{ +#define SMOOTH_STROKE_RADIUS 40 +#define SMOOTH_STROKE_FACTOR 0.9f + + ToolSettings *ts = CTX_data_tool_settings(C); + Paint *paint = BKE_brush_get_gpencil_paint(ts); + Main *bmain = CTX_data_main(C); + + Brush *brush, *deft; + CurveMapping *custom_curve; + + /* Pencil brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pencil"); + brush->size = 25.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 0.6f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + + brush->gpencil_settings->draw_random_press = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PENCIL; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Pen brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pen"); + deft = brush; /* save default brush */ + brush->size = 30.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 1.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + + brush->gpencil_settings->draw_random_press = 0.0f; + brush->gpencil_settings->draw_random_strength = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Ink brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Ink"); + brush->size = 60.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.6f; + + brush->gpencil_settings->draw_strength = 1.0f; + + brush->gpencil_settings->draw_random_press = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Curve */ + custom_curve = brush->gpencil_settings->curve_sensitivity; + curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); + curvemapping_initialize(custom_curve); + brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INK); + + /* Ink Noise brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Noise"); + brush->size = 60.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 1.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM; + brush->gpencil_settings->draw_random_press = 0.7f; + brush->gpencil_settings->draw_random_strength = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 1.0f; + brush->gpencil_settings->draw_smoothlvl = 2; + brush->gpencil_settings->thick_smoothfac = 0.5f; + brush->gpencil_settings->thick_smoothlvl = 2; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Curve */ + custom_curve = brush->gpencil_settings->curve_sensitivity; + curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f); + curvemapping_initialize(custom_curve); + brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INKNOISE); + + /* Block Basic brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Block"); + brush->size = 150.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 0.7f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + + brush->gpencil_settings->draw_random_press = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = 0.0f; + brush->gpencil_settings->draw_angle_factor = 0.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 0.0f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_subdivide = 0; + brush->gpencil_settings->draw_random_sub = 0; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_BLOCK; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Marker brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Draw Marker"); + brush->size = 80.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR); + brush->gpencil_settings->draw_sensitivity = 1.0f; + + brush->gpencil_settings->draw_strength = 1.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM; + brush->gpencil_settings->draw_random_press = 0.374f; + brush->gpencil_settings->draw_random_strength = 0.0f; + + brush->gpencil_settings->draw_jitter = 0.0f; + brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + + brush->gpencil_settings->draw_angle = M_PI_4; /* 45 degrees */ + brush->gpencil_settings->draw_angle_factor = 1.0f; + + brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; + brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_subdivide = 1; + brush->gpencil_settings->draw_random_sub = 0.0f; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + /* Fill brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Fill Area"); + brush->size = 1.0f; + brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR; + brush->gpencil_settings->draw_sensitivity = 1.0f; + brush->gpencil_settings->fill_leak = 3; + brush->gpencil_settings->fill_threshold = 0.1f; + brush->gpencil_settings->fill_simplylvl = 1; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_FILL; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_FILL; + + brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothlvl = 1; + brush->gpencil_settings->thick_smoothfac = 1.0f; + brush->gpencil_settings->thick_smoothlvl = 3; + brush->gpencil_settings->draw_subdivide = 1; + + brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS; + brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR; + + brush->gpencil_settings->draw_strength = 1.0f; + + /* Soft Eraser brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Soft"); + brush->size = 30.0f; + brush->gpencil_settings->flag |= (GP_BRUSH_ENABLE_CURSOR | GP_BRUSH_DEFAULT_ERASER); + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE; + brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT; + + /* Hard Eraser brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Hard"); + brush->size = 30.0f; + brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_HARD; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE; + brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_HARD; + + /* Stroke Eraser brush */ + brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Stroke"); + brush->size = 30.0f; + brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR; + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_STROKE; + brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE; + brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_STROKE; + + /* set defaut brush */ + BKE_paint_brush_set(paint, deft); + +} + +/* get the active gp-brush for editing */ +Brush *BKE_brush_getactive_gpencil(ToolSettings *ts) +{ + /* error checking */ + if (ELEM(NULL, ts, ts->gp_paint)) { + return NULL; + } + Paint *paint = &ts->gp_paint->paint; + + return paint->brush; +} + struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) { Brush *brush; @@ -197,6 +562,12 @@ void BKE_brush_copy_data(Main *UNUSED(bmain), Brush *brush_dst, const Brush *bru } brush_dst->curve = curvemapping_copy(brush_src->curve); + if (brush_src->gpencil_settings != NULL) { + brush_dst->gpencil_settings = MEM_dupallocN(brush_src->gpencil_settings); + brush_dst->gpencil_settings->curve_sensitivity = curvemapping_copy(brush_src->gpencil_settings->curve_sensitivity); + brush_dst->gpencil_settings->curve_strength = curvemapping_copy(brush_src->gpencil_settings->curve_strength); + brush_dst->gpencil_settings->curve_jitter = curvemapping_copy(brush_src->gpencil_settings->curve_jitter); + } /* enable fake user by default */ id_fake_user_set(&brush_dst->id); @@ -215,11 +586,18 @@ void BKE_brush_free(Brush *brush) if (brush->icon_imbuf) { IMB_freeImBuf(brush->icon_imbuf); } - curvemapping_free(brush->curve); + if (brush->gpencil_settings != NULL) { + curvemapping_free(brush->gpencil_settings->curve_sensitivity); + curvemapping_free(brush->gpencil_settings->curve_strength); + curvemapping_free(brush->gpencil_settings->curve_jitter); + MEM_SAFE_FREE(brush->gpencil_settings); + } + MEM_SAFE_FREE(brush->gradient); + BKE_previewimg_free(&(brush->preview)); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index ff4795afe87..d18572a57f6 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -282,6 +282,7 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) case CURVE_PRESET_MID9: cuma->totpoint = 9; break; case CURVE_PRESET_ROUND: cuma->totpoint = 4; break; case CURVE_PRESET_ROOT: cuma->totpoint = 4; break; + case CURVE_PRESET_GAUSS: cuma->totpoint = 7; break; } cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points"); @@ -352,6 +353,24 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) cuma->curve[3].x = 1; cuma->curve[3].y = 0; break; + case CURVE_PRESET_GAUSS: + cuma->curve[0].x = 0; + cuma->curve[0].y = 0.025f; + cuma->curve[1].x = 0.16f; + cuma->curve[1].y = 0.135f; + cuma->curve[2].x = 0.298f; + cuma->curve[2].y = 0.36f; + + cuma->curve[3].x = 0.50f; + cuma->curve[3].y = 1.0f; + + cuma->curve[4].x = 0.70f; + cuma->curve[4].y = 0.36f; + cuma->curve[5].x = 0.84f; + cuma->curve[5].y = 0.135f; + cuma->curve[6].x = 1.0f; + cuma->curve[6].y = 0.025f; + break; } /* mirror curve in x direction to have positive slope diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 3dfe9732062..84ca143dc55 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -1014,6 +1014,10 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, const eObjectM else if (object_mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX; else if (object_mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE; else if (object_mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE; + else if (object_mode & OB_MODE_GPENCIL_PAINT) return CTX_MODE_GPENCIL_PAINT; + else if (object_mode & OB_MODE_GPENCIL_EDIT) return CTX_MODE_GPENCIL_EDIT; + else if (object_mode & OB_MODE_GPENCIL_SCULPT) return CTX_MODE_GPENCIL_SCULPT; + else if (object_mode & OB_MODE_GPENCIL_WEIGHT) return CTX_MODE_GPENCIL_WEIGHT; } } @@ -1044,6 +1048,10 @@ static const char *data_mode_strings[] = { "imagepaint", "particlemode", "objectmode", + "greasepencil_paint", + "greasepencil_edit", + "greasepencil_sculpt", + "greasepencil_weight", NULL }; BLI_STATIC_ASSERT(ARRAY_SIZE(data_mode_strings) == CTX_MODE_NUM + 1, "Must have a string for each context mode") @@ -1212,17 +1220,7 @@ bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C) return ctx_data_pointer_get(C, "active_gpencil_layer"); } -bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C) -{ - return ctx_data_pointer_get(C, "active_gpencil_palette"); -} - -bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C) -{ - return ctx_data_pointer_get(C, "active_gpencil_palettecolor"); -} - -bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C) +Brush *CTX_data_active_gpencil_brush(const bContext *C) { return ctx_data_pointer_get(C, "active_gpencil_brush"); } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index d08e3643ca7..ddf9840a32e 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -74,7 +74,9 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name) BLI_addtail(&ob->defbase, defgroup); defgroup_unique_name(defgroup, ob); - BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + if (ob->type != OB_GPENCIL) { + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + } return defgroup; } diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index e89508fd6c0..de3f891f9f9 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -39,26 +39,83 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" +#include "BLI_math_color.h" #include "BLI_string_utils.h" +#include "BLI_rand.h" +#include "BLI_ghash.h" #include "BLT_translation.h" +#include "DNA_anim_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_material_types.h" #include "DNA_gpencil_types.h" #include "DNA_userdef_types.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "BKE_context.h" +#include "BKE_action.h" #include "BKE_animsys.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_colortools.h" +#include "BKE_icons.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_material.h" +#include "DEG_depsgraph.h" /* ************************************************** */ -/* GENERAL STUFF */ +/* Draw Engine */ -/* --------- Memory Management ------------ */ +void(*BKE_gpencil_batch_cache_dirty_cb)(bGPdata *gpd) = NULL; +void(*BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd) = NULL; + +void BKE_gpencil_batch_cache_dirty(bGPdata *gpd) +{ + if (gpd) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + BKE_gpencil_batch_cache_dirty_cb(gpd); + } +} + +void BKE_gpencil_batch_cache_free(bGPdata *gpd) +{ + if (gpd) { + BKE_gpencil_batch_cache_free_cb(gpd); + } +} + +/* ************************************************** */ +/* Memory Management */ + +/* clean vertex groups weights */ +void BKE_gpencil_free_point_weights(MDeformVert *dvert) +{ + if (dvert == NULL) { + return; + } + MEM_SAFE_FREE(dvert->dw); +} + +void BKE_gpencil_free_stroke_weights(bGPDstroke *gps) +{ + if (gps == NULL) { + return; + } + + if (gps->dvert == NULL) { + return; + } + + for (int i = 0; i < gps->totpoints; i++) { + MDeformVert *dvert = &gps->dvert[i]; + BKE_gpencil_free_point_weights(dvert); + } +} /* free stroke, doesn't unlink from any listbase */ void BKE_gpencil_free_stroke(bGPDstroke *gps) @@ -66,10 +123,14 @@ void BKE_gpencil_free_stroke(bGPDstroke *gps) if (gps == NULL) { return; } - /* free stroke memory arrays, then stroke itself */ - if (gps->points) + if (gps->points) { MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } if (gps->triangles) MEM_freeN(gps->triangles); @@ -92,6 +153,26 @@ bool BKE_gpencil_free_strokes(bGPDframe *gpf) return changed; } +/* Free strokes and colors belonging to a gp-frame */ +bool BKE_gpencil_free_frame_runtime_data(bGPDframe *derived_gpf) +{ + bGPDstroke *gps_next; + if (!derived_gpf) { + return false; + } + + /* free strokes */ + for (bGPDstroke *gps = derived_gpf->strokes.first; gps; gps = gps_next) { + gps_next = gps->next; + BKE_gpencil_free_stroke(gps); + } + BLI_listbase_clear(&derived_gpf->strokes); + + MEM_SAFE_FREE(derived_gpf); + + return true; +} + /* Free all of a gp-layer's frames */ void BKE_gpencil_free_frames(bGPDlayer *gpl) { @@ -111,101 +192,101 @@ void BKE_gpencil_free_frames(bGPDlayer *gpl) gpl->actframe = NULL; } -/* Free all of a gp-colors */ -static void free_gpencil_colors(bGPDpalette *palette) -{ - /* error checking */ - if (palette == NULL) { - return; - } - /* free colors */ - BLI_freelistN(&palette->colors); -} -/* Free all of the gp-palettes and colors */ -void BKE_gpencil_free_palettes(ListBase *list) +/* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ +void BKE_gpencil_free_layers(ListBase *list) { - bGPDpalette *palette_next; + bGPDlayer *gpl_next; /* error checking */ - if (list == NULL) { - return; - } + if (list == NULL) return; - /* delete palettes */ - for (bGPDpalette *palette = list->first; palette; palette = palette_next) { - palette_next = palette->next; - /* free palette colors */ - free_gpencil_colors(palette); + /* delete layers */ + for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) { + gpl_next = gpl->next; - MEM_freeN(palette); + /* free layers and their data */ + BKE_gpencil_free_frames(gpl); + BLI_freelinkN(list, gpl); } - BLI_listbase_clear(list); } -/* Free all of the gp-brushes for a viewport (list should be &gpd->brushes or so) */ -void BKE_gpencil_free_brushes(ListBase *list) +/* clear all runtime derived data */ +static void BKE_gpencil_clear_derived(bGPDlayer *gpl) { - bGPDbrush *brush_next; + GHashIterator gh_iter; - /* error checking */ - if (list == NULL) { + if (gpl->runtime.derived_data == NULL) { return; } - /* delete brushes */ - for (bGPDbrush *brush = list->first; brush; brush = brush_next) { - brush_next = brush->next; - /* free curves */ - if (brush->cur_sensitivity) { - curvemapping_free(brush->cur_sensitivity); - } - if (brush->cur_strength) { - curvemapping_free(brush->cur_strength); + GHASH_ITER(gh_iter, gpl->runtime.derived_data) { + bGPDframe *gpf = (bGPDframe *)BLI_ghashIterator_getValue(&gh_iter); + if (gpf) { + BKE_gpencil_free_frame_runtime_data(gpf); } - if (brush->cur_jitter) { - curvemapping_free(brush->cur_jitter); - } - - MEM_freeN(brush); } - BLI_listbase_clear(list); } -/* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ -void BKE_gpencil_free_layers(ListBase *list) +/* Free all of the gp-layers temp data*/ +static void BKE_gpencil_free_layers_temp_data(ListBase *list) { bGPDlayer *gpl_next; /* error checking */ if (list == NULL) return; - /* delete layers */ for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) { gpl_next = gpl->next; + BKE_gpencil_clear_derived(gpl); - /* free layers and their data */ - BKE_gpencil_free_frames(gpl); - BLI_freelinkN(list, gpl); + if (gpl->runtime.derived_data) { + BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL); + gpl->runtime.derived_data = NULL; + } + } +} + +/* Free temp gpf derived frames */ +void BKE_gpencil_free_derived_frames(bGPdata *gpd) +{ + /* error checking */ + if (gpd == NULL) return; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + BKE_gpencil_clear_derived(gpl); + + if (gpl->runtime.derived_data) { + BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL); + gpl->runtime.derived_data = NULL; + } } } /** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */ -void BKE_gpencil_free(bGPdata *gpd, bool free_palettes) +void BKE_gpencil_free(bGPdata *gpd, bool free_all) { + /* clear animation data */ BKE_animdata_free(&gpd->id, false); /* free layers */ + if (free_all) { + BKE_gpencil_free_layers_temp_data(&gpd->layers); + } BKE_gpencil_free_layers(&gpd->layers); - /* free palettes */ - if (free_palettes) { - BKE_gpencil_free_palettes(&gpd->palettes); + /* materials */ + MEM_SAFE_FREE(gpd->mat); + + /* free all data */ + if (free_all) { + /* clear cache */ + BKE_gpencil_batch_cache_free(gpd); } } -/* -------- Container Creation ---------- */ +/* ************************************************** */ +/* Container Creation */ /* add a new gp-frame to the given layer */ bGPDframe *BKE_gpencil_frame_addnew(bGPDlayer *gpl, int cframe) @@ -329,28 +410,31 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti /* add to datablock */ BLI_addtail(&gpd->layers, gpl); - /* set basic settings */ - copy_v4_v4(gpl->color, U.gpencil_new_layer_col); - /* Since GPv2 thickness must be 0 */ - gpl->thickness = 0; - - gpl->opacity = 1.0f; + /* annotation vs GP Object behaviour is slightly different */ + if (gpd->flag & GP_DATA_ANNOTATIONS) { + /* set default color of new strokes for this layer */ + copy_v4_v4(gpl->color, U.gpencil_new_layer_col); + gpl->opacity = 1.0f; - /* onion-skinning settings */ - if (gpd->flag & GP_DATA_SHOW_ONIONSKINS) - gpl->flag |= GP_LAYER_ONIONSKIN; + /* set default thickness of new strokes for this layer */ + gpl->thickness = 3; - gpl->flag |= (GP_LAYER_GHOST_PREVCOL | GP_LAYER_GHOST_NEXTCOL); - - ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */ - ARRAY_SET_ITEMS(gpl->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */ - - /* high quality fill by default */ - gpl->flag |= GP_LAYER_HQ_FILL; + /* onion-skinning settings */ + gpl->onion_flag |= GP_LAYER_ONIONSKIN; + } + else { + /* thickness parameter represents "thickness change", not absolute thickness */ + gpl->thickness = 0; + gpl->opacity = 1.0f; + } /* auto-name */ BLI_strncpy(gpl->info, name, sizeof(gpl->info)); - BLI_uniquename(&gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); + BLI_uniquename(&gpd->layers, gpl, + (gpd->flag & GP_DATA_ANNOTATIONS) ? DATA_("Note") : DATA_("GP_Layer"), + '.', + offsetof(bGPDlayer, info), + sizeof(gpl->info)); /* make this one the active one */ if (setactive) @@ -360,292 +444,153 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti return gpl; } -/* add a new gp-palette and make it the active */ -bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name, bool setactive) -{ - bGPDpalette *palette; - - /* check that list is ok */ - if (gpd == NULL) { - return NULL; - } - - /* allocate memory and add to end of list */ - palette = MEM_callocN(sizeof(bGPDpalette), "bGPDpalette"); - - /* add to datablock */ - BLI_addtail(&gpd->palettes, palette); - - /* set basic settings */ - /* auto-name */ - BLI_strncpy(palette->info, name, sizeof(palette->info)); - BLI_uniquename(&gpd->palettes, palette, DATA_("GP_Palette"), '.', offsetof(bGPDpalette, info), - sizeof(palette->info)); - - /* make this one the active one */ - /* NOTE: Always make this active if there's nothing else yet (T50123) */ - if ((setactive) || (gpd->palettes.first == gpd->palettes.last)) { - BKE_gpencil_palette_setactive(gpd, palette); - } - - /* return palette */ - return palette; -} - -/* create a set of default drawing brushes with predefined presets */ -void BKE_gpencil_brush_init_presets(ToolSettings *ts) +/* add a new gp-datablock */ +bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[]) { - bGPDbrush *brush; - /* Basic brush */ - brush = BKE_gpencil_brush_addnew(ts, "Basic", true); - brush->thickness = 3.0f; - brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 1.0f; - brush->flag |= GP_BRUSH_USE_PRESSURE; - - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 1.0f; - brush->flag |= ~GP_BRUSH_USE_STENGTH_PRESSURE; - - brush->draw_random_press = 0.0f; - - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; - - brush->draw_angle = 0.0f; - brush->draw_angle_factor = 0.0f; - - brush->draw_smoothfac = 0.0f; - brush->draw_smoothlvl = 1; - brush->sublevel = 0; - brush->draw_random_sub = 0.0f; - - /* Pencil brush */ - brush = BKE_gpencil_brush_addnew(ts, "Pencil", false); - brush->thickness = 7.0f; - brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 1.0f; - brush->flag |= GP_BRUSH_USE_PRESSURE; - - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 0.7f; - brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; - - brush->draw_random_press = 0.0f; - - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; - - brush->draw_angle = 0.0f; - brush->draw_angle_factor = 0.0f; - - brush->draw_smoothfac = 1.0f; - brush->draw_smoothlvl = 2; - brush->sublevel = 2; - brush->draw_random_sub = 0.0f; - - /* Ink brush */ - brush = BKE_gpencil_brush_addnew(ts, "Ink", false); - brush->thickness = 7.0f; - brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 1.6f; - brush->flag |= GP_BRUSH_USE_PRESSURE; - - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 1.0f; - brush->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE; - - brush->draw_random_press = 0.0f; - - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; - - brush->draw_angle = 0.0f; - brush->draw_angle_factor = 0.0f; + bGPdata *gpd; - brush->draw_smoothfac = 1.1f; - brush->draw_smoothlvl = 2; - brush->sublevel = 2; - brush->draw_random_sub = 0.0f; + /* allocate memory for a new block */ + gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0); - /* Ink Noise brush */ - brush = BKE_gpencil_brush_addnew(ts, "Ink noise", false); - brush->thickness = 6.0f; - brush->flag |= GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 1.611f; - brush->flag |= GP_BRUSH_USE_PRESSURE; + /* initial settings */ + gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND); - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 1.0f; - brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + /* general flags */ + gpd->flag |= GP_DATA_VIEWALIGN; - brush->draw_random_press = 1.0f; + /* GP object specific settings */ + ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f); - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + gpd->xray_mode = GP_XRAY_3DSPACE; + gpd->runtime.batch_cache_data = NULL; + gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; - brush->draw_angle = 0.0f; - brush->draw_angle_factor = 0.0f; + /* onion-skinning settings (datablock level) */ + gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL); + gpd->onion_flag |= GP_ONION_FADE; + gpd->onion_mode = GP_ONION_MODE_RELATIVE; + gpd->onion_factor = 0.5f; + ARRAY_SET_ITEMS(gpd->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */ + ARRAY_SET_ITEMS(gpd->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */ + gpd->gstep = 1; + gpd->gstep_next = 1; - brush->draw_smoothfac = 1.1f; - brush->draw_smoothlvl = 2; - brush->sublevel = 2; - brush->draw_random_sub = 0.0f; + return gpd; +} - /* Marker brush */ - brush = BKE_gpencil_brush_addnew(ts, "Marker", false); - brush->thickness = 10.0f; - brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 2.0f; - brush->flag &= ~GP_BRUSH_USE_PRESSURE; - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 1.0f; - brush->flag &= ~GP_BRUSH_USE_STENGTH_PRESSURE; +/* ************************************************** */ +/* Primitive Creation */ +/* Utilities for easier bulk-creation of geometry */ - brush->draw_random_press = 0.0f; +/** + * Populate stroke with point data from data buffers + * + * \param array Flat array of point data values. Each entry has GP_PRIM_DATABUF_SIZE values + * \param mat 4x4 transform matrix to transform points into the right coordinate space + */ +void BKE_gpencil_stroke_add_points(bGPDstroke *gps, const float *array, const int totpoints, const float mat[4][4]) +{ + for (int i = 0; i < totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + const int x = GP_PRIM_DATABUF_SIZE * i; - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + pt->x = array[x]; + pt->y = array[x + 1]; + pt->z = array[x + 2]; + mul_m4_v3(mat, &pt->x); - brush->draw_angle = M_PI_4; /* 45 degrees */ - brush->draw_angle_factor = 1.0f; + pt->pressure = array[x + 3]; + pt->strength = array[x + 4]; + } +} - brush->draw_smoothfac = 1.0f; - brush->draw_smoothlvl = 2; - brush->sublevel = 2; - brush->draw_random_sub = 0.0f; +/* Create a new stroke, with pre-allocated data buffers */ +bGPDstroke *BKE_gpencil_add_stroke(bGPDframe *gpf, int mat_idx, int totpoints, short thickness) +{ + /* allocate memory for a new stroke */ + bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); - /* Crayon brush */ - brush = BKE_gpencil_brush_addnew(ts, "Crayon", false); - brush->thickness = 10.0f; - brush->flag &= ~GP_BRUSH_USE_RANDOM_PRESSURE; - brush->draw_sensitivity = 3.0f; - brush->flag &= ~GP_BRUSH_USE_PRESSURE; + gps->thickness = thickness * 25; + gps->inittime = 0; - brush->flag &= ~GP_BRUSH_USE_RANDOM_STRENGTH; - brush->draw_strength = 0.140f; - brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; + /* enable recalculation flag by default */ + gps->flag = GP_STROKE_RECALC_CACHES | GP_STROKE_3DSPACE; - brush->draw_random_press = 0.0f; + gps->totpoints = totpoints; + gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; + /* initialize triangle memory to dummy data */ + gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation"); + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; - brush->draw_angle = 0.0f; - brush->draw_angle_factor = 0.0f; + gps->mat_nr = mat_idx; - brush->draw_smoothfac = 0.0f; - brush->draw_smoothlvl = 1; - brush->sublevel = 2; - brush->draw_random_sub = 0.5f; + /* add to frame */ + BLI_addtail(&gpf->strokes, gps); + return gps; } -/* add a new gp-brush and make it the active */ -bGPDbrush *BKE_gpencil_brush_addnew(ToolSettings *ts, const char *name, bool setactive) -{ - bGPDbrush *brush; - - /* check that list is ok */ - if (ts == NULL) { - return NULL; - } - - /* allocate memory and add to end of list */ - brush = MEM_callocN(sizeof(bGPDbrush), "bGPDbrush"); - /* add to datablock */ - BLI_addtail(&ts->gp_brushes, brush); - - /* set basic settings */ - brush->thickness = 3; - brush->draw_smoothlvl = 1; - brush->flag |= GP_BRUSH_USE_PRESSURE; - brush->draw_sensitivity = 1.0f; - brush->draw_strength = 1.0f; - brush->flag |= GP_BRUSH_USE_STENGTH_PRESSURE; - brush->draw_jitter = 0.0f; - brush->flag |= GP_BRUSH_USE_JITTER_PRESSURE; - - /* curves */ - brush->cur_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); - brush->cur_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); - brush->cur_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); - - /* auto-name */ - BLI_strncpy(brush->info, name, sizeof(brush->info)); - BLI_uniquename(&ts->gp_brushes, brush, DATA_("GP_Brush"), '.', offsetof(bGPDbrush, info), sizeof(brush->info)); - - /* make this one the active one */ - if (setactive) { - BKE_gpencil_brush_setactive(ts, brush); - } - - /* return brush */ - return brush; -} +/* ************************************************** */ +/* Data Duplication */ -/* add a new gp-palettecolor and make it the active */ -bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(bGPDpalette *palette, const char *name, bool setactive) +/* make a copy of a given gpencil weights */ +void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_dst) { - bGPDpalettecolor *palcolor; - - /* check that list is ok */ - if (palette == NULL) { - return NULL; + if (gps_src == NULL) { + return; } + BLI_assert(gps_src->totpoints == gps_dst->totpoints); - /* allocate memory and add to end of list */ - palcolor = MEM_callocN(sizeof(bGPDpalettecolor), "bGPDpalettecolor"); - - /* add to datablock */ - BLI_addtail(&palette->colors, palcolor); - - /* set basic settings */ - palcolor->flag |= PC_COLOR_HQ_FILL; - copy_v4_v4(palcolor->color, U.gpencil_new_layer_col); - ARRAY_SET_ITEMS(palcolor->fill, 1.0f, 1.0f, 1.0f); + if ((gps_src->dvert == NULL) || (gps_dst->dvert == NULL)){ + return; + } - /* auto-name */ - BLI_strncpy(palcolor->info, name, sizeof(palcolor->info)); - BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info), - sizeof(palcolor->info)); + for (int i = 0; i < gps_src->totpoints; i++) { + MDeformVert *dvert_src = &gps_src->dvert[i]; + MDeformVert *dvert_dst = &gps_dst->dvert[i]; + if (dvert_src->totweight > 0) { + dvert_dst->dw = MEM_dupallocN(dvert_src->dw); + } + else { + dvert_dst->dw = NULL; + } - /* make this one the active one */ - if (setactive) { - BKE_gpencil_palettecolor_setactive(palette, palcolor); } - - /* return palette color */ - return palcolor; } -/* add a new gp-datablock */ -bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[]) +/* make a copy of a given gpencil stroke */ +bGPDstroke *BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src) { - bGPdata *gpd; + bGPDstroke *gps_dst = NULL; - /* allocate memory for a new block */ - gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0); + gps_dst = MEM_dupallocN(gps_src); + gps_dst->prev = gps_dst->next = NULL; - /* initial settings */ - gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND); + gps_dst->points = MEM_dupallocN(gps_src->points); - /* for now, stick to view is also enabled by default - * since this is more useful... + gps_dst->dvert = MEM_dupallocN(gps_src->dvert); + BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); + + /* Don't clear triangles, so that modifier evaluation can just use + * this without extra work first. Most places that need to force + * this data to get recalculated will destroy the data anyway though. */ - gpd->flag |= GP_DATA_VIEWALIGN; + gps_dst->triangles = MEM_dupallocN(gps_dst->triangles); + /* gps_dst->flag |= GP_STROKE_RECALC_CACHES; */ - return gpd; + /* return new stroke */ + return gps_dst; } -/* -------- Data Duplication ---------- */ - /* make a copy of a given gpencil frame */ bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src) { - bGPDstroke *gps_dst; + bGPDstroke *gps_dst = NULL; bGPDframe *gpf_dst; /* error checking */ @@ -660,11 +605,8 @@ bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src) /* copy strokes */ BLI_listbase_clear(&gpf_dst->strokes); for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { - /* make copy of source stroke, then adjust pointer to points too */ - gps_dst = MEM_dupallocN(gps_src); - gps_dst->points = MEM_dupallocN(gps_src->points); - gps_dst->triangles = MEM_dupallocN(gps_src->triangles); - gps_dst->flag |= GP_STROKE_RECALC_CACHES; + /* make copy of source stroke */ + gps_dst = BKE_gpencil_stroke_duplicate(gps_src); BLI_addtail(&gpf_dst->strokes, gps_dst); } @@ -672,55 +614,24 @@ bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src) return gpf_dst; } -/* make a copy of a given gpencil brush */ -bGPDbrush *BKE_gpencil_brush_duplicate(const bGPDbrush *brush_src) +/* make a copy of strokes between gpencil frames */ +void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_dst) { - bGPDbrush *brush_dst; - + bGPDstroke *gps_dst = NULL; /* error checking */ - if (brush_src == NULL) { - return NULL; - } - - /* make a copy of source brush */ - brush_dst = MEM_dupallocN(brush_src); - brush_dst->prev = brush_dst->next = NULL; - /* make a copy of curves */ - brush_dst->cur_sensitivity = curvemapping_copy(brush_src->cur_sensitivity); - brush_dst->cur_strength = curvemapping_copy(brush_src->cur_strength); - brush_dst->cur_jitter = curvemapping_copy(brush_src->cur_jitter); - - /* return new brush */ - return brush_dst; -} - -/* make a copy of a given gpencil palette */ -bGPDpalette *BKE_gpencil_palette_duplicate(const bGPDpalette *palette_src) -{ - bGPDpalette *palette_dst; - const bGPDpalettecolor *palcolor_src; - bGPDpalettecolor *palcolord_dst; - - /* error checking */ - if (palette_src == NULL) { - return NULL; + if ((gpf_src == NULL) || (gpf_dst == NULL)) { + return; } - /* make a copy of source palette */ - palette_dst = MEM_dupallocN(palette_src); - palette_dst->prev = palette_dst->next = NULL; - - /* copy colors */ - BLI_listbase_clear(&palette_dst->colors); - for (palcolor_src = palette_src->colors.first; palcolor_src; palcolor_src = palcolor_src->next) { - /* make a copy of source */ - palcolord_dst = MEM_dupallocN(palcolor_src); - BLI_addtail(&palette_dst->colors, palcolord_dst); + /* copy strokes */ + BLI_listbase_clear(&gpf_dst->strokes); + for (bGPDstroke *gps_src = gpf_src->strokes.first; gps_src; gps_src = gps_src->next) { + /* make copy of source stroke */ + gps_dst = BKE_gpencil_stroke_duplicate(gps_src); + BLI_addtail(&gpf_dst->strokes, gps_dst); } - - /* return new palette */ - return palette_dst; } + /* make a copy of a given gpencil layer */ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) { @@ -736,6 +647,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) /* make a copy of source layer */ gpl_dst = MEM_dupallocN(gpl_src); gpl_dst->prev = gpl_dst->next = NULL; + gpl_dst->runtime.derived_data = NULL; /* copy frames */ BLI_listbase_clear(&gpl_dst->frames); @@ -755,7 +667,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) /** * Only copy internal data of GreasePencil ID from source to already allocated/initialized destination. - * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs. + * You probably never want to use that directly, use id_copy or BKE_id_copy_ex for typical needs. * * WARNING! This function will not handle ID user count! * @@ -763,6 +675,14 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) */ void BKE_gpencil_copy_data(Main *UNUSED(bmain), bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag)) { + /* cache data is not duplicated */ + gpd_dst->runtime.batch_cache_data = NULL; + + /* duplicate material array */ + if (gpd_src->mat) { + gpd_dst->mat = MEM_dupallocN(gpd_src->mat); + } + /* copy layers */ BLI_listbase_clear(&gpd_dst->layers); for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) { @@ -771,45 +691,46 @@ void BKE_gpencil_copy_data(Main *UNUSED(bmain), bGPdata *gpd_dst, const bGPdata BLI_addtail(&gpd_dst->layers, gpl_dst); } - /* copy palettes */ - BLI_listbase_clear(&gpd_dst->palettes); - for (const bGPDpalette *palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) { - bGPDpalette *palette_dst = BKE_gpencil_palette_duplicate(palette_src); /* TODO here too could add unused flags... */ - BLI_addtail(&gpd_dst->palettes, palette_dst); - } +} + +/* Standard API to make a copy of GP datablock, separate from copying its data */ +bGPdata *BKE_gpencil_copy(Main *bmain, const bGPdata *gpd) +{ + bGPdata *gpd_copy; + BKE_id_copy_ex(bmain, &gpd->id, (ID **)&gpd_copy, 0, false); + return gpd_copy; } /* make a copy of a given gpencil datablock */ +// XXX: Should this be deprecated? bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy) { + bGPdata *gpd_dst; + /* Yuck and super-uber-hyper yuck!!! * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it, * so for now keep old code for that one. */ - if (internal_copy) { - const bGPDlayer *gpl_src; - bGPDlayer *gpl_dst; - bGPdata *gpd_dst; + /* error checking */ + if (gpd_src == NULL) { + return NULL; + } + + if (internal_copy) { /* make a straight copy for undo buffers used during stroke drawing */ gpd_dst = MEM_dupallocN(gpd_src); - - /* copy layers */ - BLI_listbase_clear(&gpd_dst->layers); - for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) { - /* make a copy of source layer and its data */ - gpl_dst = BKE_gpencil_layer_duplicate(gpl_src); - BLI_addtail(&gpd_dst->layers, gpl_dst); - } - - /* return new */ - return gpd_dst; } else { BLI_assert(bmain != NULL); - bGPdata *gpd_copy; - BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_copy, 0, false); - return gpd_copy; + BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_dst, 0, false); + gpd_dst->runtime.batch_cache_data = NULL; } + + /* Copy internal data (layers, etc.) */ + BKE_gpencil_copy_data(bmain, gpd_dst, gpd_src, 0); + + /* return new */ + return gpd_dst; } void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local) @@ -817,7 +738,8 @@ void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local) BKE_id_make_local_generic(bmain, &gpd->id, true, lib_local); } -/* -------- GP-Stroke API --------- */ +/* ************************************************** */ +/* GP Stroke API */ /* ensure selection status of stroke is in sync with its points */ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps) @@ -842,7 +764,8 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps) } } -/* -------- GP-Frame API ---------- */ +/* ************************************************** */ +/* GP Frame API */ /* delete the last stroke of the given frame */ void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) @@ -855,7 +778,13 @@ void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) return; /* free the stroke and its data */ - MEM_freeN(gps->points); + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } MEM_freeN(gps->triangles); BLI_freelinkN(&gpf->strokes, gps); @@ -866,7 +795,8 @@ void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) } } -/* -------- GP-Layer API ---------- */ +/* ************************************************** */ +/* GP Layer API */ /* Check if the given layer is able to be edited or not */ bool gpencil_layer_is_editable(const bGPDlayer *gpl) @@ -1048,8 +978,6 @@ bool BKE_gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf) */ if (gpl->actframe == gpf) gpl->actframe = gpf->prev; - else - gpl->actframe = NULL; /* free the frame and its data */ changed = BKE_gpencil_free_strokes(gpf); @@ -1103,255 +1031,602 @@ void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl) /* free layer */ BKE_gpencil_free_frames(gpl); + + /* free icon providing preview of icon color */ + BKE_icon_delete(gpl->runtime.icon_id); + + /* free derived data */ + BKE_gpencil_clear_derived(gpl); + if (gpl->runtime.derived_data) { + BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL); + gpl->runtime.derived_data = NULL; + } + BLI_freelinkN(&gpd->layers, gpl); } -/* ************************************************** */ -/* get the active gp-brush for editing */ -bGPDbrush *BKE_gpencil_brush_getactive(ToolSettings *ts) +Material *BKE_gpencil_get_material_from_brush(Brush *brush) { - bGPDbrush *brush; + Material *ma = NULL; - /* error checking */ - if (ELEM(NULL, ts, ts->gp_brushes.first)) { - return NULL; + if ((brush != NULL) && (brush->gpencil_settings != NULL) && + (brush->gpencil_settings->material != NULL)) + { + ma = brush->gpencil_settings->material; } - /* loop over brushes until found (assume only one active) */ - for (brush = ts->gp_brushes.first; brush; brush = brush->next) { - if (brush->flag & GP_BRUSH_ACTIVE) { - return brush; + return ma; +} + +/* Get active color, and add all default settings if we don't find anything */ +Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob) +{ + Material *ma = NULL; + + /* sanity checks */ + if (ELEM(NULL, bmain, ob)) + return NULL; + + ma = give_current_material(ob, ob->actcol); + if (ma == NULL) { + if (ob->totcol == 0) { + BKE_object_material_slot_add(bmain, ob); } + ma = BKE_material_add_gpencil(bmain, DATA_("Material")); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + } + else if (ma->gp_style == NULL) { + BKE_material_init_gpencil_settings(ma); } - /* no active brush found */ - return NULL; + return ma; } -/* set the active gp-brush */ -void BKE_gpencil_brush_setactive(ToolSettings *ts, bGPDbrush *active) +/* ************************************************** */ +/* GP Object - Boundbox Support */ + +/** + * Get min/max coordinate bounds for single stroke + * \return Returns whether we found any selected points + */ +bool BKE_gpencil_stroke_minmax( + const bGPDstroke *gps, const bool use_select, + float r_min[3], float r_max[3]) { - bGPDbrush *brush; + const bGPDspoint *pt; + int i; + bool changed = false; - /* error checking */ - if (ELEM(NULL, ts, ts->gp_brushes.first, active)) { - return; - } + if (ELEM(NULL, gps, r_min, r_max)) + return false; - /* loop over brushes deactivating all */ - for (brush = ts->gp_brushes.first; brush; brush = brush->next) { - brush->flag &= ~GP_BRUSH_ACTIVE; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) { + minmax_v3v3_v3(r_min, r_max, &pt->x); + changed = true; + } } - - /* set as active one */ - active->flag |= GP_BRUSH_ACTIVE; + return changed; } -/* delete the active gp-brush */ -void BKE_gpencil_brush_delete(ToolSettings *ts, bGPDbrush *brush) +/* get min/max bounds of all strokes in GP datablock */ +static void gpencil_minmax(bGPdata *gpd, float r_min[3], float r_max[3]) { - /* error checking */ - if (ELEM(NULL, ts, brush)) { + INIT_MINMAX(r_min, r_max); + + if (gpd == NULL) return; - } - /* free curves */ - if (brush->cur_sensitivity) { - curvemapping_free(brush->cur_sensitivity); - } - if (brush->cur_strength) { - curvemapping_free(brush->cur_strength); + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + bGPDframe *gpf = gpl->actframe; + + if (gpf != NULL) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + BKE_gpencil_stroke_minmax(gps, false, r_min, r_max); + } + } } - if (brush->cur_jitter) { - curvemapping_free(brush->cur_jitter); +} + +/* compute center of bounding box */ +void BKE_gpencil_centroid_3D(bGPdata *gpd, float r_centroid[3]) +{ + float min[3], max[3], tot[3]; + + gpencil_minmax(gpd, min, max); + + add_v3_v3v3(tot, min, max); + mul_v3_v3fl(r_centroid, tot, 0.5f); +} + + +/* create bounding box values */ +static void boundbox_gpencil(Object *ob) +{ + BoundBox *bb; + bGPdata *gpd; + float min[3], max[3]; + + if (ob->bb == NULL) { + ob->bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox"); } - /* free */ - BLI_freelinkN(&ts->gp_brushes, brush); + bb = ob->bb; + gpd = ob->data; + + gpencil_minmax(gpd, min, max); + BKE_boundbox_init_from_minmax(bb, min, max); + + bb->flag &= ~BOUNDBOX_DIRTY; } -/* ************************************************** */ -/* get the active gp-palette for editing */ -bGPDpalette *BKE_gpencil_palette_getactive(bGPdata *gpd) +/* get bounding box */ +BoundBox *BKE_gpencil_boundbox_get(Object *ob) { - bGPDpalette *palette; + bGPdata *gpd; - /* error checking */ - if (ELEM(NULL, gpd, gpd->palettes.first)) { + if (ELEM(NULL, ob, ob->data)) return NULL; - } - /* loop over palettes until found (assume only one active) */ - for (palette = gpd->palettes.first; palette; palette = palette->next) { - if (palette->flag & PL_PALETTE_ACTIVE) - return palette; + gpd = ob->data; + if ((ob->bb) && ((ob->bb->flag & BOUNDBOX_DIRTY) == 0) && + ((gpd->flag & GP_DATA_CACHE_IS_DIRTY) == 0)) + { + return ob->bb; } - /* no active palette found */ - return NULL; + boundbox_gpencil(ob); + + return ob->bb; } -/* set the active gp-palette */ -void BKE_gpencil_palette_setactive(bGPdata *gpd, bGPDpalette *active) -{ - bGPDpalette *palette; +/* ************************************************** */ +/* Apply Transforms */ - /* error checking */ - if (ELEM(NULL, gpd, gpd->palettes.first, active)) { +void BKE_gpencil_transform(bGPdata *gpd, float mat[4][4]) +{ + if (gpd == NULL) return; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* FIXME: For now, we just skip parented layers. + * Otherwise, we have to update each frame to find + * the current parent position/effects. + */ + if (gpl->parent) { + continue; + } + + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *pt; + int i; + + for (pt = gps->points, i = 0; i < gps->totpoints; pt++, i++) { + mul_m4_v3(mat, &pt->x); + } + + /* TODO: Do we need to do this? distortion may mean we need to re-triangulate */ + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; + } + } } - /* loop over palettes deactivating all */ - for (palette = gpd->palettes.first; palette; palette = palette->next) { - palette->flag &= ~PL_PALETTE_ACTIVE; +} + +/* ************************************************** */ +/* GP Object - Vertex Groups */ + +/* remove a vertex group */ +void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup) +{ + bGPdata *gpd = ob->data; + MDeformVert *dvert = NULL; + MDeformWeight *gpw = NULL; + const int def_nr = BLI_findindex(&ob->defbase, defgroup); + + /* Remove points data */ + if (gpd) { + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + for (int i = 0; i < gps->totpoints; i++) { + dvert = &gps->dvert[i]; + for (int i2 = 0; i2 < dvert->totweight; i2++) { + gpw = &dvert->dw[i2]; + if (gpw->def_nr == def_nr) { + BKE_gpencil_vgroup_remove_point_weight(dvert, def_nr); + } + /* if index is greater, must be moved one back */ + if (gpw->def_nr > def_nr) { + gpw->def_nr--; + } + } + } + } + } + } } - /* set as active one */ - active->flag |= PL_PALETTE_ACTIVE; - /* force color recalc */ - BKE_gpencil_palette_change_strokes(gpd); + /* Remove the group */ + BLI_freelinkN(&ob->defbase, defgroup); } -/* delete the active gp-palette */ -void BKE_gpencil_palette_delete(bGPdata *gpd, bGPDpalette *palette) +/* add a new weight */ +MDeformWeight *BKE_gpencil_vgroup_add_point_weight(MDeformVert *dvert, int index, float weight) { - /* error checking */ - if (ELEM(NULL, gpd, palette)) { - return; + MDeformWeight *new_gpw = NULL; + MDeformWeight *tmp_gpw; + + /* need to verify if was used before to update */ + for (int i = 0; i < dvert->totweight; i++) { + tmp_gpw = &dvert->dw[i]; + if (tmp_gpw->def_nr == index) { + tmp_gpw->weight = weight; + return tmp_gpw; + } + } + + dvert->totweight++; + if (dvert->totweight == 1) { + dvert->dw = MEM_callocN(sizeof(MDeformWeight), "gp_weight"); + } + else { + dvert->dw = MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight); } + new_gpw = &dvert->dw[dvert->totweight - 1]; + new_gpw->def_nr = index; + new_gpw->weight = weight; - /* free colors */ - free_gpencil_colors(palette); - BLI_freelinkN(&gpd->palettes, palette); - /* force color recalc */ - BKE_gpencil_palette_change_strokes(gpd); + return new_gpw; } -/* Set all strokes to recalc the palette color */ -void BKE_gpencil_palette_change_strokes(bGPdata *gpd) +/* return the weight if use index or -1*/ +float BKE_gpencil_vgroup_use_index(MDeformVert *dvert, int index) { - bGPDlayer *gpl; - bGPDframe *gpf; - bGPDstroke *gps; + MDeformWeight *gpw; + for (int i = 0; i < dvert->totweight; i++) { + gpw = &dvert->dw[i]; + if (gpw->def_nr == index) { + return gpw->weight; + } + } + return -1.0f; +} - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (gps = gpf->strokes.first; gps; gps = gps->next) { - gps->flag |= GP_STROKE_RECALC_COLOR; - } +/* add a new weight */ +bool BKE_gpencil_vgroup_remove_point_weight(MDeformVert *dvert, int index) +{ + int e = 0; + + if (BKE_gpencil_vgroup_use_index(dvert, index) < 0.0f) { + return false; + } + + /* if the array get empty, exit */ + if (dvert->totweight == 1) { + dvert->totweight = 0; + MEM_SAFE_FREE(dvert->dw); + return true; + } + + /* realloc weights */ + MDeformWeight *tmp = MEM_dupallocN(dvert->dw); + MEM_SAFE_FREE(dvert->dw); + dvert->dw = MEM_callocN(sizeof(MDeformWeight) * dvert->totweight - 1, "gp_weights"); + + for (int x = 0; x < dvert->totweight; x++) { + MDeformWeight *gpw = &tmp[e]; + MDeformWeight *final_gpw = &dvert->dw[e]; + if (gpw->def_nr != index) { + final_gpw->def_nr = gpw->def_nr; + final_gpw->weight = gpw->weight; + e++; } } + MEM_SAFE_FREE(tmp); + dvert->totweight--; + + return true; } -/* get the active gp-palettecolor for editing */ -bGPDpalettecolor *BKE_gpencil_palettecolor_getactive(bGPDpalette *palette) +/* ************************************************** */ + +/** + * Apply smooth to stroke point + * \param gps Stroke to smooth + * \param i Point index + * \param inf Amount of smoothing to apply + */ +bool BKE_gpencil_smooth_stroke(bGPDstroke *gps, int i, float inf) { - bGPDpalettecolor *palcolor; + bGPDspoint *pt = &gps->points[i]; + // float pressure = 0.0f; + float sco[3] = { 0.0f }; - /* error checking */ - if (ELEM(NULL, palette, palette->colors.first)) { - return NULL; + /* Do nothing if not enough points to smooth out */ + if (gps->totpoints <= 2) { + return false; + } + + /* Only affect endpoints by a fraction of the normal strength, + * to prevent the stroke from shrinking too much + */ + if ((i == 0) || (i == gps->totpoints - 1)) { + inf *= 0.1f; } - /* loop over colors until found (assume only one active) */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - if (palcolor->flag & PC_COLOR_ACTIVE) { - return palcolor; + /* Compute smoothed coordinate by taking the ones nearby */ + /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */ + { + // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total) + const int steps = 2; + const float average_fac = 1.0f / (float)(steps * 2 + 1); + int step; + + /* add the point itself */ + madd_v3_v3fl(sco, &pt->x, average_fac); + + /* n-steps before/after current point */ + // XXX: review how the endpoints are treated by this algorithm + // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight + for (step = 1; step <= steps; step++) { + bGPDspoint *pt1, *pt2; + int before = i - step; + int after = i + step; + + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); + + pt1 = &gps->points[before]; + pt2 = &gps->points[after]; + + /* add both these points to the average-sum (s += p[i]/n) */ + madd_v3_v3fl(sco, &pt1->x, average_fac); + madd_v3_v3fl(sco, &pt2->x, average_fac); + } } - /* no active color found */ - return NULL; + /* Based on influence factor, blend between original and optimal smoothed coordinate */ + interp_v3_v3v3(&pt->x, &pt->x, sco, inf); + + return true; } -/* get the gp-palettecolor looking for name */ -bGPDpalettecolor *BKE_gpencil_palettecolor_getbyname(bGPDpalette *palette, char *name) + +/** + * Apply smooth for strength to stroke point */ +bool BKE_gpencil_smooth_stroke_strength(bGPDstroke *gps, int point_index, float influence) { - /* error checking */ - if (ELEM(NULL, palette, name)) { - return NULL; + bGPDspoint *ptb = &gps->points[point_index]; + + /* Do nothing if not enough points */ + if (gps->totpoints <= 2) { + return false; } - return BLI_findstring(&palette->colors, name, offsetof(bGPDpalettecolor, info)); + /* Compute theoretical optimal value using distances */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; + + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); + + pta = &gps->points[before]; + ptc = &gps->points[after]; + + /* the optimal value is the corresponding to the interpolation of the strength + * at the distance of point b + */ + const float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength; + + /* Based on influence factor, blend between original and optimal */ + ptb->strength = (1.0f - influence) * ptb->strength + influence * optimal; + + return true; } -/* Change color name in all strokes */ -void BKE_gpencil_palettecolor_changename(bGPdata *gpd, char *oldname, const char *newname) +/** + * Apply smooth for thickness to stroke point (use pressure) */ +bool BKE_gpencil_smooth_stroke_thickness(bGPDstroke *gps, int point_index, float influence) { - bGPDlayer *gpl; - bGPDframe *gpf; - bGPDstroke *gps; + bGPDspoint *ptb = &gps->points[point_index]; - /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */ - if (ELEM(NULL, gpd, oldname, newname)) - return; + /* Do nothing if not enough points */ + if (gps->totpoints <= 2) { + return false; + } - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (gps = gpf->strokes.first; gps; gps = gps->next) { - if (STREQ(gps->colorname, oldname)) { - BLI_strncpy(gps->colorname, newname, sizeof(gps->colorname)); - } + /* Compute theoretical optimal value using distances */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; + + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); + + pta = &gps->points[before]; + ptc = &gps->points[after]; + + /* the optimal value is the corresponding to the interpolation of the pressure + * at the distance of point b + */ + float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + float optimal = interpf(ptc->pressure, pta->pressure, fac); + + /* Based on influence factor, blend between original and optimal */ + ptb->pressure = interpf(optimal, ptb->pressure, influence); + + return true; +} + +/** +* Apply smooth for UV rotation to stroke point (use pressure) */ +bool BKE_gpencil_smooth_stroke_uv(bGPDstroke *gps, int point_index, float influence) +{ + bGPDspoint *ptb = &gps->points[point_index]; + + /* Do nothing if not enough points */ + if (gps->totpoints <= 2) { + return false; + } + + /* Compute theoretical optimal value */ + bGPDspoint *pta, *ptc; + int before = point_index - 1; + int after = point_index + 1; + + CLAMP_MIN(before, 0); + CLAMP_MAX(after, gps->totpoints - 1); + + pta = &gps->points[before]; + ptc = &gps->points[after]; + + /* the optimal value is the corresponding to the interpolation of the pressure + * at the distance of point b + */ + float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac); + + /* Based on influence factor, blend between original and optimal */ + ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence); + CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2); + + return true; +} + +/** + * Get range of selected frames in layer. + * Always the active frame is considered as selected, so if no more selected the range + * will be equal to the current active frame. + * \param gpl Layer + * \param r_initframe Number of first selected frame + * \param r_endframe Number of last selected frame + */ +void BKE_gpencil_get_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe) +{ + *r_initframe = gpl->actframe->framenum; + *r_endframe = gpl->actframe->framenum; + + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if (gpf->flag & GP_FRAME_SELECT) { + if (gpf->framenum < *r_initframe) { + *r_initframe = gpf->framenum; + } + if (gpf->framenum > *r_endframe) { + *r_endframe = gpf->framenum; } } } +} + +/** + * Get Falloff factor base on frame range + * \param gpf Frame + * \param actnum Number of active frame in layer + * \param f_init Number of first selected frame + * \param f_end Number of last selected frame + * \param cur_falloff Curve with falloff factors + */ +float BKE_gpencil_multiframe_falloff_calc(bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff) +{ + float fnum = 0.5f; /* default mid curve */ + float value; + + /* frames to the right of the active frame */ + if (gpf->framenum < actnum) { + fnum = (float)(gpf->framenum - f_init) / (actnum - f_init); + fnum *= 0.5f; + value = curvemapping_evaluateF(cur_falloff, 0, fnum); + } + /* frames to the left of the active frame */ + else if (gpf->framenum > actnum) { + fnum = (float)(gpf->framenum - actnum) / (f_end - actnum); + fnum *= 0.5f; + value = curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f); + } + else { + value = 1.0f; + } + return value; } -/* Delete all strokes of the color */ -void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name) +/* remove strokes using a material */ +void BKE_gpencil_material_index_remove(bGPdata *gpd, int index) { - bGPDlayer *gpl; - bGPDframe *gpf; bGPDstroke *gps, *gpsn; - /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */ - if (ELEM(NULL, gpd, name)) - return; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; - - if (STREQ(gps->colorname, name)) { - if (gps->points) MEM_freeN(gps->points); - if (gps->triangles) MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + if (gps->mat_nr == index) { + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + if (gps->triangles) MEM_freeN(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); + } + else { + /* reassign strokes */ + if (gps->mat_nr > index) { + gps->mat_nr--; + } + } } } } - } - } -/* set the active gp-palettecolor */ -void BKE_gpencil_palettecolor_setactive(bGPDpalette *palette, bGPDpalettecolor *active) +void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len) { - bGPDpalettecolor *palcolor; - - /* error checking */ - if (ELEM(NULL, palette, palette->colors.first, active)) { - return; + const short remap_len_short = (short)remap_len; + +#define MAT_NR_REMAP(n) \ + if (n < remap_len_short) { \ + BLI_assert(n >= 0 && remap[n] < remap_len_short); \ + n = remap[n]; \ + } ((void)0) + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* reassign strokes */ + MAT_NR_REMAP(gps->mat_nr); + } + } } - /* loop over colors deactivating all */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag &= ~PC_COLOR_ACTIVE; - } +#undef MAT_NR_REMAP - /* set as active one */ - active->flag |= PC_COLOR_ACTIVE; } -/* delete the active gp-palettecolor */ -void BKE_gpencil_palettecolor_delete(bGPDpalette *palette, bGPDpalettecolor *palcolor) +/* statistics functions */ +void BKE_gpencil_stats_update(bGPdata *gpd) { - /* error checking */ - if (ELEM(NULL, palette, palcolor)) { - return; + gpd->totlayer = 0; + gpd->totframe = 0; + gpd->totstroke = 0; + gpd->totpoint = 0; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + gpd->totlayer++; + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + gpd->totframe++; + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + gpd->totstroke++; + gpd->totpoint += gps->totpoints; + } + } } - /* free */ - BLI_freelinkN(&palette->colors, palcolor); } diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c new file mode 100644 index 00000000000..2ba738902a0 --- /dev/null +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -0,0 +1,679 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/gpencil_modifier.c + * \ingroup bke + */ + + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" +#include "BLI_string_utils.h" + +#include "BLT_translation.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_gpencil.h" +#include "BKE_lattice.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_object.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_gpencil_modifiertypes.h" + +static GpencilModifierTypeInfo *modifier_gpencil_types[NUM_GREASEPENCIL_MODIFIER_TYPES] = { NULL }; + +/* *************************************************** */ +/* Geometry Utilities */ + +/* calculate stroke normal using some points */ +void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3]) +{ + if (gps->totpoints < 3) { + zero_v3(r_normal); + return; + } + + bGPDspoint *points = gps->points; + int totpoints = gps->totpoints; + + const bGPDspoint *pt0 = &points[0]; + const bGPDspoint *pt1 = &points[1]; + const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; + + float vec1[3]; + float vec2[3]; + + /* initial vector (p0 -> p1) */ + sub_v3_v3v3(vec1, &pt1->x, &pt0->x); + + /* point vector at 3/4 */ + sub_v3_v3v3(vec2, &pt3->x, &pt0->x); + + /* vector orthogonal to polygon plane */ + cross_v3_v3v3(r_normal, vec1, vec2); + + /* Normalize vector */ + normalize_v3(r_normal); +} + +/* Get points of stroke always flat to view not affected by camera view or view position */ +static void gpencil_stroke_project_2d(const bGPDspoint *points, int totpoints, vec2f *points2d) +{ + const bGPDspoint *pt0 = &points[0]; + const bGPDspoint *pt1 = &points[1]; + const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; + + float locx[3]; + float locy[3]; + float loc3[3]; + float normal[3]; + + /* local X axis (p0 -> p1) */ + sub_v3_v3v3(locx, &pt1->x, &pt0->x); + + /* point vector at 3/4 */ + sub_v3_v3v3(loc3, &pt3->x, &pt0->x); + + /* vector orthogonal to polygon plane */ + cross_v3_v3v3(normal, locx, loc3); + + /* local Y axis (cross to normal/x axis) */ + cross_v3_v3v3(locy, normal, locx); + + /* Normalize vectors */ + normalize_v3(locx); + normalize_v3(locy); + + /* Get all points in local space */ + for (int i = 0; i < totpoints; i++) { + const bGPDspoint *pt = &points[i]; + float loc[3]; + + /* Get local space using first point as origin */ + sub_v3_v3v3(loc, &pt->x, &pt0->x); + + vec2f *point = &points2d[i]; + point->x = dot_v3v3(loc, locx); + point->y = dot_v3v3(loc, locy); + } + +} + +/* Stroke Simplify ------------------------------------- */ + +/* Reduce a series of points to a simplified version, but + * maintains the general shape of the series + * + * Ramer - Douglas - Peucker algorithm + * by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm + */ +static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon) +{ + vec2f *old_points2d = points2d; + int totpoints = gps->totpoints; + char *marked = NULL; + char work; + + int start = 1; + int end = gps->totpoints - 2; + + marked = MEM_callocN(totpoints, "GP marked array"); + marked[start] = 1; + marked[end] = 1; + + work = 1; + int totmarked = 0; + /* while still reducing */ + while (work) { + int ls, le; + work = 0; + + ls = start; + le = start + 1; + + /* while not over interval */ + while (ls < end) { + int max_i = 0; + float v1[2]; + /* divided to get more control */ + float max_dist = epsilon / 10.0f; + + /* find the next marked point */ + while (marked[le] == 0) { + le++; + } + + /* perpendicular vector to ls-le */ + v1[1] = old_points2d[le].x - old_points2d[ls].x; + v1[0] = old_points2d[ls].y - old_points2d[le].y; + + for (int i = ls + 1; i < le; i++) { + float mul; + float dist; + float v2[2]; + + v2[0] = old_points2d[i].x - old_points2d[ls].x; + v2[1] = old_points2d[i].y - old_points2d[ls].y; + + if (v2[0] == 0 && v2[1] == 0) { + continue; + } + + mul = (float)(v1[0] * v2[0] + v1[1] * v2[1]) / (float)(v2[0] * v2[0] + v2[1] * v2[1]); + + dist = mul * mul * (v2[0] * v2[0] + v2[1] * v2[1]); + + if (dist > max_dist) { + max_dist = dist; + max_i = i; + } + } + + if (max_i != 0) { + work = 1; + marked[max_i] = 1; + totmarked++; + } + + ls = le; + le = ls + 1; + } + } + + /* adding points marked */ + bGPDspoint *old_points = MEM_dupallocN(gps->points); + MDeformVert *old_dvert = MEM_dupallocN(gps->dvert); + + /* resize gps */ + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; + + int j = 0; + for (int i = 0; i < totpoints; i++) { + bGPDspoint *pt_src = &old_points[i]; + bGPDspoint *pt = &gps->points[j]; + + MDeformVert *dvert_src = &old_dvert[i]; + MDeformVert *dvert = &gps->dvert[j]; + + if ((marked[i]) || (i == 0) || (i == totpoints - 1)) { + memcpy(pt, pt_src, sizeof(bGPDspoint)); + memcpy(dvert, dvert_src, sizeof(MDeformVert)); + j++; + } + else { + BKE_gpencil_free_point_weights(dvert_src); + } + } + + gps->totpoints = j; + + MEM_SAFE_FREE(old_points); + MEM_SAFE_FREE(old_dvert); + MEM_SAFE_FREE(marked); +} + +/* Simplify stroke using Ramer-Douglas-Peucker algorithm */ +void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float factor) +{ + /* first create temp data and convert points to 2D */ + vec2f *points2d = MEM_mallocN(sizeof(vec2f) * gps->totpoints, "GP Stroke temp 2d points"); + + gpencil_stroke_project_2d(gps->points, gps->totpoints, points2d); + + gpencil_rdp_stroke(gps, points2d, factor); + + MEM_SAFE_FREE(points2d); +} + +/* Simplify alternate vertex of stroke except extrems */ +void BKE_gpencil_simplify_fixed(bGPDstroke *gps) +{ + if (gps->totpoints < 5) { + return; + } + + /* save points */ + bGPDspoint *old_points = MEM_dupallocN(gps->points); + MDeformVert *old_dvert = MEM_dupallocN(gps->dvert); + + /* resize gps */ + int newtot = (gps->totpoints - 2) / 2; + if (((gps->totpoints - 2) % 2) > 0) { + newtot++; + } + newtot += 2; + + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot); + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot); + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; + + int j = 0; + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt_src = &old_points[i]; + bGPDspoint *pt = &gps->points[j]; + + MDeformVert *dvert_src = &old_dvert[i]; + MDeformVert *dvert = &gps->dvert[j]; + + if ((i == 0) || (i == gps->totpoints - 1) || ((i % 2) > 0.0)) { + memcpy(pt, pt_src, sizeof(bGPDspoint)); + memcpy(dvert, dvert_src, sizeof(MDeformVert)); + j++; + } + else { + BKE_gpencil_free_point_weights(dvert_src); + } + } + + gps->totpoints = j; + + MEM_SAFE_FREE(old_points); + MEM_SAFE_FREE(old_dvert); +} + +/* *************************************************** */ +/* Modifier Utilities */ + +/* Lattice Modifier ---------------------------------- */ +/* Usually, evaluation of the lattice modifier is self-contained. + * However, since GP's modifiers operate on a per-stroke basis, + * we need to these two extra functions that called before/after + * each loop over all the geometry being evaluated. + */ + +/* init lattice deform data */ +void BKE_gpencil_lattice_init(Object *ob) +{ + GpencilModifierData *md; + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + if (md->type == eGpencilModifierType_Lattice) { + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + Object *latob = NULL; + + latob = mmd->object; + if ((!latob) || (latob->type != OB_LATTICE)) { + return; + } + if (mmd->cache_data) { + end_latt_deform((struct LatticeDeformData *)mmd->cache_data); + } + + /* init deform data */ + mmd->cache_data = (struct LatticeDeformData *)init_latt_deform(latob, ob); + } + } +} + +/* clear lattice deform data */ +void BKE_gpencil_lattice_clear(Object *ob) +{ + GpencilModifierData *md; + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + if (md->type == eGpencilModifierType_Lattice) { + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + if ((mmd) && (mmd->cache_data)) { + end_latt_deform((struct LatticeDeformData *)mmd->cache_data); + mmd->cache_data = NULL; + } + } + } +} + +/* *************************************************** */ +/* Modifier Methods - Evaluation Loops, etc. */ + +/* check if exist geometry modifiers */ +bool BKE_gpencil_has_geometry_modifiers(Object *ob) +{ + GpencilModifierData *md; + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (mti && mti->generateStrokes) { + return true; + } + } + return false; +} + +/* apply stroke modifiers */ +void BKE_gpencil_stroke_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps, bool is_render) +{ + GpencilModifierData *md; + bGPdata *gpd = ob->data; + const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd); + + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) + { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (GPENCIL_MODIFIER_EDIT(md, is_edit)) { + continue; + } + + if (mti && mti->deformStroke) { + mti->deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +/* apply stroke geometry modifiers */ +void BKE_gpencil_geometry_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bool is_render) +{ + GpencilModifierData *md; + bGPdata *gpd = ob->data; + const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd); + + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) + { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (GPENCIL_MODIFIER_EDIT(md, is_edit)) { + continue; + } + + if (mti->generateStrokes) { + mti->generateStrokes(md, depsgraph, ob, gpl, gpf); + } + } + } +} + +/* *************************************************** */ + +void BKE_gpencil_eval_geometry(Depsgraph *depsgraph, + bGPdata *gpd) +{ + DEG_debug_print_eval(depsgraph, __func__, gpd->id.name, gpd); + int ctime = (int)DEG_get_ctime(depsgraph); + + /* update active frame */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV); + } + + /* TODO: Move "derived_gpf" logic here from DRW_gpencil_populate_datablock()? + * This would be better than inventing our own logic for this stuff... + */ + + /* TODO: Move the following code to "BKE_gpencil_eval_done()" (marked as an exit node) + * later when there's more happening here. For now, let's just keep this in here to avoid + * needing to have one more node slowing down evaluation... + */ + if (DEG_is_active(depsgraph)) { + bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id); + + /* sync "actframe" changes back to main-db too, + * so that editing tools work with copy-on-write + * when the current frame changes + */ + for (bGPDlayer *gpl = gpd_orig->layers.first; gpl; gpl = gpl->next) { + gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV); + } + } +} + +void BKE_gpencil_modifier_init(void) +{ + /* Initialize modifier types */ + gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */ +} + +GpencilModifierData *BKE_gpencil_modifier_new(int type) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(type); + GpencilModifierData *md = MEM_callocN(mti->struct_size, mti->struct_name); + + /* note, this name must be made unique later */ + BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name)); + + md->type = type; + md->mode = eGpencilModifierMode_Realtime | eGpencilModifierMode_Render | eGpencilModifierMode_Expanded; + md->flag = eGpencilModifierFlag_StaticOverride_Local; + + if (mti->flags & eGpencilModifierTypeFlag_EnableInEditmode) + md->mode |= eGpencilModifierMode_Editmode; + + if (mti->initData) mti->initData(md); + + return md; +} + +static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag) +{ + ID *id = *idpoin; + if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) { + id_us_min(id); + } +} + +void BKE_gpencil_modifier_free_ex(GpencilModifierData *md, const int flag) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (mti->foreachIDLink) { + mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL); + } + else if (mti->foreachObjectLink) { + mti->foreachObjectLink(md, NULL, (GreasePencilObjectWalkFunc)modifier_free_data_id_us_cb, NULL); + } + } + + if (mti->freeData) mti->freeData(md); + if (md->error) MEM_freeN(md->error); + + MEM_freeN(md); +} + +void BKE_gpencil_modifier_free(GpencilModifierData *md) +{ + BKE_gpencil_modifier_free_ex(md, 0); +} + +/* check unique name */ +bool BKE_gpencil_modifier_unique_name(ListBase *modifiers, GpencilModifierData *gmd) +{ + if (modifiers && gmd) { + const GpencilModifierTypeInfo *gmti = BKE_gpencil_modifierType_getInfo(gmd->type); + return BLI_uniquename(modifiers, gmd, DATA_(gmti->name), '.', offsetof(GpencilModifierData, name), sizeof(gmd->name)); + } + return false; +} + +bool BKE_gpencil_modifier_dependsOnTime(GpencilModifierData *md) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + return mti->dependsOnTime && mti->dependsOnTime(md); +} + +const GpencilModifierTypeInfo *BKE_gpencil_modifierType_getInfo(GpencilModifierType type) +{ + /* type unsigned, no need to check < 0 */ + if (type < NUM_GREASEPENCIL_MODIFIER_TYPES && modifier_gpencil_types[type]->name[0] != '\0') { + return modifier_gpencil_types[type]; + } + else { + return NULL; + } +} + +void BKE_gpencil_modifier_copyData_generic(const GpencilModifierData *md_src, GpencilModifierData *md_dst) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md_src->type); + + /* md_dst may have alredy be fully initialized with some extra allocated data, + * we need to free it now to avoid memleak. */ + if (mti->freeData) { + mti->freeData(md_dst); + } + + const size_t data_size = sizeof(GpencilModifierData); + const char *md_src_data = ((const char *)md_src) + data_size; + char *md_dst_data = ((char *)md_dst) + data_size; + BLI_assert(data_size <= (size_t)mti->struct_size); + memcpy(md_dst_data, md_src_data, (size_t)mti->struct_size - data_size); +} + +static void gpencil_modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag) +{ + ID *id = *idpoin; + if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) { + id_us_plus(id); + } +} + +void BKE_gpencil_modifier_copyData_ex(GpencilModifierData *md, GpencilModifierData *target, const int flag) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + target->mode = md->mode; + target->flag = md->flag; + + if (mti->copyData) { + mti->copyData(md, target); + } + + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (mti->foreachIDLink) { + mti->foreachIDLink(target, NULL, gpencil_modifier_copy_data_id_us_cb, NULL); + } + else if (mti->foreachObjectLink) { + mti->foreachObjectLink(target, NULL, (GreasePencilObjectWalkFunc)gpencil_modifier_copy_data_id_us_cb, NULL); + } + } +} + +void BKE_gpencil_modifier_copyData(GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_ex(md, target, 0); +} + +GpencilModifierData *BKE_gpencil_modifiers_findByType(Object *ob, GpencilModifierType type) +{ + GpencilModifierData *md = ob->greasepencil_modifiers.first; + + for (; md; md = md->next) + if (md->type == type) + break; + + return md; +} + +void BKE_gpencil_modifiers_foreachIDLink(Object *ob, GreasePencilIDWalkFunc walk, void *userData) +{ + GpencilModifierData *md = ob->greasepencil_modifiers.first; + + for (; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData); + else if (mti->foreachObjectLink) { + /* each Object can masquerade as an ID, so this should be OK */ + GreasePencilObjectWalkFunc fp = (GreasePencilObjectWalkFunc)walk; + mti->foreachObjectLink(md, ob, fp, userData); + } + } +} + +void BKE_gpencil_modifiers_foreachTexLink(Object *ob, GreasePencilTexWalkFunc walk, void *userData) +{ + GpencilModifierData *md = ob->greasepencil_modifiers.first; + + for (; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (mti->foreachTexLink) + mti->foreachTexLink(md, ob, walk, userData); + } +} + +GpencilModifierData *BKE_gpencil_modifiers_findByName(Object *ob, const char *name) +{ + return BLI_findstring(&(ob->greasepencil_modifiers), name, offsetof(GpencilModifierData, name)); +} + +/* helper function for per-instance positioning */ +void BKE_gpencil_instance_modifier_instance_tfm(InstanceGpencilModifierData *mmd, const int elem_idx[3], float r_mat[4][4]) +{ + float offset[3], rot[3], scale[3]; + int ri = mmd->rnd[0]; + float factor; + + offset[0] = mmd->offset[0] * elem_idx[0]; + offset[1] = mmd->offset[1] * elem_idx[1]; + offset[2] = mmd->offset[2] * elem_idx[2]; + + /* rotation */ + if (mmd->flag & GP_INSTANCE_RANDOM_ROT) { + factor = mmd->rnd_rot * mmd->rnd[ri]; + mul_v3_v3fl(rot, mmd->rot, factor); + add_v3_v3(rot, mmd->rot); + } + else { + copy_v3_v3(rot, mmd->rot); + } + + /* scale */ + if (mmd->flag & GP_INSTANCE_RANDOM_SIZE) { + factor = mmd->rnd_size * mmd->rnd[ri]; + mul_v3_v3fl(scale, mmd->scale, factor); + add_v3_v3(scale, mmd->scale); + } + else { + copy_v3_v3(scale, mmd->scale); + } + + /* advance random index */ + mmd->rnd[0]++; + if (mmd->rnd[0] > 19) { + mmd->rnd[0] = 1; + } + + /* calculate matrix */ + loc_eul_size_to_mat4(r_mat, offset, rot, scale); +} diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 1c2575dfa52..3a4bf53e22d 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -37,6 +37,8 @@ #include "MEM_guardedalloc.h" +#include "DNA_brush_types.h" +#include "DNA_gpencil_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -45,7 +47,6 @@ #include "DNA_screen_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" -#include "DNA_brush_types.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -127,6 +128,9 @@ static void icon_free_data(int icon_id, Icon *icon) else if (icon->obj_type == ICON_DATA_PREVIEW) { ((PreviewImage *)(icon->obj))->icon_id = 0; } + else if (icon->obj_type == ICON_DATA_GPLAYER) { + ((bGPDlayer *)(icon->obj))->runtime.icon_id = 0; + } else if (icon->obj_type == ICON_DATA_GEOM) { ((struct Icon_Geom *)(icon->obj))->icon_id = 0; } @@ -598,6 +602,44 @@ int BKE_icon_id_ensure(struct ID *id) return icon_id_ensure_create_icon(id); } + +static int icon_gplayer_color_ensure_create_icon(bGPDlayer *gpl) +{ + BLI_assert(BLI_thread_is_main()); + + /* NOTE: The color previews for GP Layers don't really need + * to be "rendered" to image per se (as it will just be a plain + * colored rectangle), we need to define icon data here so that + * we can store a pointer to the layer data in icon->obj. + */ + Icon *icon = icon_create(gpl->runtime.icon_id, ICON_DATA_GPLAYER, gpl); + icon->flag = ICON_FLAG_MANAGED; + + return gpl->runtime.icon_id; +} + +int BKE_icon_gplayer_color_ensure(bGPDlayer *gpl) +{ + /* Never handle icons in non-main thread! */ + BLI_assert(BLI_thread_is_main()); + + if (!gpl || G.background) { + return 0; + } + + if (gpl->runtime.icon_id) + return gpl->runtime.icon_id; + + gpl->runtime.icon_id = get_next_free_id(); + + if (!gpl->runtime.icon_id) { + printf("%s: Internal error - not enough IDs\n", __func__); + return 0; + } + + return icon_gplayer_color_ensure_create_icon(gpl); +} + /** * Return icon id of given preview, or create new icon if not found. */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 351214ed72b..1d70d9db1e9 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1073,6 +1073,7 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[INDEX_ID_IP] = &(main->ipo); lb[INDEX_ID_AC] = &(main->action); /* moved here to avoid problems when freeing with animato (aligorith) */ lb[INDEX_ID_KE] = &(main->key); + lb[INDEX_ID_PAL] = &(main->palettes); /* referenced by gpencil, so needs to be before that to avoid crashes */ lb[INDEX_ID_GD] = &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */ lb[INDEX_ID_NT] = &(main->nodetree); lb[INDEX_ID_IM] = &(main->image); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 93fdd3349bf..473dd787a69 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -417,7 +417,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call SEQ_END } - CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER); for (CollectionObject *cob = scene->master_collection->gobject.first; cob; cob = cob->next) { CALLBACK_INVOKE(cob->ob, IDWALK_CB_USER); @@ -478,6 +477,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call if (toolsett->uvsculpt) { library_foreach_paint(&data, &toolsett->uvsculpt->paint); } + if (toolsett->gp_paint) { + library_foreach_paint(&data, &toolsett->gp_paint->paint); + } } if (scene->rigidbody_world) { @@ -641,6 +643,10 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call if (material->texpaintslot != NULL) { CALLBACK_INVOKE(material->texpaintslot->ima, IDWALK_CB_NOP); } + if (material->gp_style != NULL) { + CALLBACK_INVOKE(material->gp_style->sima, IDWALK_CB_USER); + CALLBACK_INVOKE(material->gp_style->ima, IDWALK_CB_USER); + } break; } @@ -758,6 +764,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call CALLBACK_INVOKE(brush->toggle_brush, IDWALK_CB_NOP); CALLBACK_INVOKE(brush->clone.image, IDWALK_CB_NOP); CALLBACK_INVOKE(brush->paint_curve, IDWALK_CB_USER); + if (brush->gpencil_settings) { + CALLBACK_INVOKE(brush->gpencil_settings->material, IDWALK_CB_USER); + } library_foreach_mtex(&data, &brush->mtex); library_foreach_mtex(&data, &brush->mask_mtex); break; @@ -941,10 +950,15 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call case ID_GD: { bGPdata *gpencil = (bGPdata *) id; + /* materials */ + for (i = 0; i < gpencil->totcol; i++) { + CALLBACK_INVOKE(gpencil->mat[i], IDWALK_CB_USER); + } - for (bGPDlayer *gp_layer = gpencil->layers.first; gp_layer; gp_layer = gp_layer->next) { - CALLBACK_INVOKE(gp_layer->parent, IDWALK_CB_NOP); + for (bGPDlayer *gplayer = gpencil->layers.first; gplayer != NULL; gplayer = gplayer->next) { + CALLBACK_INVOKE(gplayer->parent, IDWALK_CB_NOP); } + break; } @@ -1072,7 +1086,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) return true; #endif case ID_BR: - return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE); + return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE, ID_MA); case ID_PA: return ELEM(id_type_used, ID_OB, ID_GR, ID_TE); case ID_MC: @@ -1083,6 +1097,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) return (ELEM(id_type_used, ID_TE, ID_OB)); case ID_LP: return ELEM(id_type_used, ID_IM); + case ID_GD: + return ELEM(id_type_used, ID_MA); case ID_WS: return ELEM(id_type_used, ID_SCR, ID_SCE); case ID_IM: @@ -1091,7 +1107,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used) case ID_SO: case ID_AR: case ID_AC: - case ID_GD: case ID_WM: case ID_PAL: case ID_PC: diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 28d75811185..03ec26c07d0 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -43,6 +43,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_customdata_types.h" +#include "DNA_gpencil_types.h" #include "DNA_ID.h" #include "DNA_meta_types.h" #include "DNA_node_types.h" @@ -58,6 +59,7 @@ #include "BKE_animsys.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_gpencil.h" #include "BKE_icons.h" #include "BKE_image.h" #include "BKE_library.h" @@ -103,10 +105,30 @@ void BKE_material_free(Material *ma) MEM_SAFE_FREE(ma->texpaintslot); + MEM_SAFE_FREE(ma->gp_style); + BKE_icon_id_delete((ID *)ma); BKE_previewimg_free(&ma->preview); } +void BKE_material_init_gpencil_settings(Material *ma) +{ + if ((ma) && (ma->gp_style == NULL)) { + ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings"); + + MaterialGPencilStyle *gp_style = ma->gp_style; + /* set basic settings */ + gp_style->stroke_rgba[3] = 1.0f; + gp_style->pattern_gridsize = 0.1f; + gp_style->gradient_radius = 0.5f; + ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f); + ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f); + ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f); + gp_style->texture_opacity = 1.0f; + gp_style->texture_pixsize = 100.0f; + } +} + void BKE_material_init(Material *ma) { BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ma, id)); @@ -124,6 +146,7 @@ void BKE_material_init(Material *ma) ma->preview = NULL; ma->alpha_threshold = 0.5f; + } Material *BKE_material_add(Main *bmain, const char *name) @@ -137,6 +160,19 @@ Material *BKE_material_add(Main *bmain, const char *name) return ma; } +Material *BKE_material_add_gpencil(Main *bmain, const char *name) +{ + Material *ma; + + ma = BKE_material_add(bmain, name); + + /* grease pencil settings */ + BKE_material_init_gpencil_settings(ma); + + return ma; +} + + /** * Only copy internal data of Material ID from source to already allocated/initialized destination. * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs. @@ -164,6 +200,10 @@ void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_sr ma_dst->texpaintslot = MEM_dupallocN(ma_src->texpaintslot); } + if (ma_src->gp_style != NULL) { + ma_dst->gp_style = MEM_dupallocN(ma_src->gp_style); + } + BLI_listbase_clear(&ma_dst->gpumaterial); /* TODO Duplicate Engine Settings and set runtime to NULL */ @@ -199,6 +239,7 @@ Material *BKE_material_localize(Material *ma) man->texpaintslot = NULL; man->preview = NULL; + /* man->gp_style = NULL; */ /* XXX: We probably don't want to clear here, or else we may get problems with COW later? */ BLI_listbase_clear(&man->gpumaterial); /* TODO Duplicate Engine Settings and set runtime to NULL */ @@ -218,6 +259,7 @@ Material ***give_matarar(Object *ob) Mesh *me; Curve *cu; MetaBall *mb; + bGPdata *gpd; if (ob->type == OB_MESH) { me = ob->data; @@ -231,6 +273,10 @@ Material ***give_matarar(Object *ob) mb = ob->data; return &(mb->mat); } + else if (ob->type == OB_GPENCIL) { + gpd = ob->data; + return &(gpd->mat); + } return NULL; } @@ -239,6 +285,7 @@ short *give_totcolp(Object *ob) Mesh *me; Curve *cu; MetaBall *mb; + bGPdata *gpd; if (ob->type == OB_MESH) { me = ob->data; @@ -252,6 +299,10 @@ short *give_totcolp(Object *ob) mb = ob->data; return &(mb->totcol); } + else if (ob->type == OB_GPENCIL) { + gpd = ob->data; + return &(gpd->totcol); + } return NULL; } @@ -286,6 +337,8 @@ short *give_totcolp_id(ID *id) return &(((Curve *)id)->totcol); case ID_MB: return &(((MetaBall *)id)->totcol); + case ID_GD: + return &(((bGPdata *)id)->totcol); default: break; } @@ -307,6 +360,9 @@ static void material_data_index_remove_id(ID *id, short index) case ID_MB: /* meta-elems don't have materials atm */ break; + case ID_GD: + BKE_gpencil_material_index_remove((bGPdata *)id, index); + break; default: break; } @@ -487,6 +543,21 @@ Material *give_current_material(Object *ob, short act) return ma; } +MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act) +{ + Material *ma = give_current_material(ob, act); + if (ma != NULL) { + if (ma->gp_style == NULL) { + BKE_material_init_gpencil_settings(ma); + } + + return ma->gp_style; + } + else { + return NULL; + } +} + Material *give_node_material(Material *ma) { if (ma && ma->use_nodes && ma->nodetree) { @@ -727,6 +798,9 @@ void BKE_material_remap_object(Object *ob, const unsigned int *remap) else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { BKE_curve_material_remap(ob->data, remap, ob->totcol); } + if (ob->type == OB_GPENCIL) { + BKE_gpencil_material_remap(ob->data, remap, ob->totcol); + } else { /* add support for this object data! */ BLI_assert(matar == NULL); @@ -924,7 +998,7 @@ bool BKE_object_material_slot_remove(Main *bmain, Object *ob) } /* check indices from mesh */ - if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) { material_data_index_remove_id((ID *)ob->data, actcol - 1); if (ob->runtime.curve_cache) { BKE_displist_free(&ob->runtime.curve_cache->disp); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 21b5bb89f19..c88de006eba 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -41,6 +41,7 @@ #include "DNA_camera_types.h" #include "DNA_constraint_types.h" #include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" #include "DNA_group_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" @@ -53,6 +54,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_sequence_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_smoke_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" @@ -86,6 +88,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_fcurve.h" +#include "BKE_gpencil_modifier.h" #include "BKE_icons.h" #include "BKE_key.h" #include "BKE_lamp.h" @@ -110,12 +113,14 @@ #include "BKE_rigidbody.h" #include "BKE_scene.h" #include "BKE_sequencer.h" +#include "BKE_shader_fx.h" #include "BKE_speaker.h" #include "BKE_softbody.h" #include "BKE_subsurf.h" #include "BKE_material.h" #include "BKE_camera.h" #include "BKE_image.h" +#include "BKE_gpencil.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -185,11 +190,15 @@ void BKE_object_free_curve_cache(Object *ob) void BKE_object_free_modifiers(Object *ob, const int flag) { ModifierData *md; + GpencilModifierData *gp_md; while ((md = BLI_pophead(&ob->modifiers))) { modifier_free_ex(md, flag); } + while ((gp_md = BLI_pophead(&ob->greasepencil_modifiers))) { + BKE_gpencil_modifier_free_ex(gp_md, flag); + } /* particle modifiers were freed, so free the particlesystems as well */ BKE_object_free_particlesystems(ob); @@ -200,6 +209,15 @@ void BKE_object_free_modifiers(Object *ob, const int flag) BKE_object_free_derived_caches(ob); } +void BKE_object_free_shaderfx(Object *ob, const int flag) +{ + ShaderFxData *fx; + + while ((fx = BLI_pophead(&ob->shader_fx))) { + BKE_shaderfx_free_ex(fx, flag); + } +} + void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd) { /* reset functionality */ @@ -222,6 +240,29 @@ void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd) } } +void BKE_object_modifier_gpencil_hook_reset(Object *ob, HookGpencilModifierData *hmd) +{ + if (hmd->object == NULL) { + return; + } + /* reset functionality */ + bPoseChannel *pchan = BKE_pose_channel_find_name(hmd->object->pose, hmd->subtarget); + + if (hmd->subtarget[0] && pchan) { + float imat[4][4], mat[4][4]; + + /* calculate the world-space matrix for the pose-channel target first, then carry on as usual */ + mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat); + + invert_m4_m4(imat, mat); + mul_m4_m4m4(hmd->parentinv, imat, ob->obmat); + } + else { + invert_m4_m4(hmd->object->imat, hmd->object->obmat); + mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat); + } +} + bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) { const ModifierTypeInfo *mti; @@ -428,6 +469,7 @@ void BKE_object_free(Object *ob) /* BKE__free shall never touch to ID->us. Never ever. */ BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT); + BKE_object_free_shaderfx(ob, LIB_ID_CREATE_NO_USER_REFCOUNT); MEM_SAFE_FREE(ob->mat); MEM_SAFE_FREE(ob->matbits); @@ -653,6 +695,7 @@ static const char *get_obdata_defname(int type) case OB_ARMATURE: return DATA_("Armature"); case OB_SPEAKER: return DATA_("Speaker"); case OB_EMPTY: return DATA_("Empty"); + case OB_GPENCIL: return DATA_("GPencil"); default: printf("get_obdata_defname: Internal error, bad type: %d\n", type); return DATA_("Empty"); @@ -677,6 +720,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name) case OB_ARMATURE: return BKE_armature_add(bmain, name); case OB_SPEAKER: return BKE_speaker_add(bmain, name); case OB_LIGHTPROBE:return BKE_lightprobe_add(bmain, name); + case OB_GPENCIL: return BKE_gpencil_data_addnew(bmain, name); case OB_EMPTY: return NULL; default: printf("%s: Internal error, bad type: %d\n", __func__, type); @@ -810,7 +854,7 @@ Object *BKE_object_add( /** * Add a new object, using another one as a reference * - * /param ob_src object to use to determine the collections of the new object. + * \param ob_src object to use to determine the collections of the new object. */ Object *BKE_object_add_from( Main *bmain, Scene *scene, ViewLayer *view_layer, @@ -828,6 +872,41 @@ Object *BKE_object_add_from( return ob; } +/** + * Add a new object, but assign the given datablock as the ob->data + * for the newly created object. + * + * \param data The datablock to assign as ob->data for the new object. + * This is assumed to be of the correct type. + * \param do_id_user If true, id_us_plus() will be called on data when + * assigning it to the object. + */ +Object *BKE_object_add_for_data( + Main *bmain, ViewLayer *view_layer, + int type, const char *name, ID *data, bool do_id_user) +{ + Object *ob; + Base *base; + LayerCollection *layer_collection; + + /* same as object_add_common, except we don't create new ob->data */ + ob = BKE_object_add_only_object(bmain, type, name); + ob->data = data; + if (do_id_user) id_us_plus(data); + + BKE_view_layer_base_deselect_all(view_layer); + DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + + layer_collection = BKE_layer_collection_get_active(view_layer); + BKE_collection_object_add(bmain, layer_collection->collection, ob); + + base = BKE_view_layer_base_find(view_layer, ob); + BKE_view_layer_base_select(view_layer, base); + + return ob; +} + + void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src, const int flag) { SoftBody *sb = ob_src->soft; @@ -1153,6 +1232,8 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src) void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag) { ModifierData *md; + GpencilModifierData *gmd; + ShaderFxData *fx; /* Do not copy runtime data. */ BKE_object_runtime_reset(ob_dst); @@ -1179,6 +1260,24 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con BLI_addtail(&ob_dst->modifiers, nmd); } + BLI_listbase_clear(&ob_dst->greasepencil_modifiers); + + for (gmd = ob_src->greasepencil_modifiers.first; gmd; gmd = gmd->next) { + GpencilModifierData *nmd = BKE_gpencil_modifier_new(gmd->type); + BLI_strncpy(nmd->name, gmd->name, sizeof(nmd->name)); + BKE_gpencil_modifier_copyData_ex(gmd, nmd, flag_subdata); + BLI_addtail(&ob_dst->greasepencil_modifiers, nmd); + } + + BLI_listbase_clear(&ob_dst->shader_fx); + + for (fx = ob_src->shader_fx.first; fx; fx = fx->next) { + ShaderFxData *nfx = BKE_shaderfx_new(fx->type); + BLI_strncpy(nfx->name, fx->name, sizeof(nfx->name)); + BKE_shaderfx_copyData_ex(fx, nfx, flag_subdata); + BLI_addtail(&ob_dst->shader_fx, nfx); + } + if (ob_src->pose) { copy_object_pose(ob_dst, ob_src, flag_subdata); /* backwards compat... non-armatures can get poses in older files? */ @@ -1210,6 +1309,10 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con BLI_listbase_clear((ListBase *)&ob_dst->drawdata); BLI_listbase_clear(&ob_dst->pc_ids); + /* grease pencil: clean derived data */ + if (ob_dst->type == OB_GPENCIL) + BKE_gpencil_free_derived_frames(ob_dst->data); + ob_dst->avs = ob_src->avs; ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath); @@ -1469,6 +1572,11 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size) ob->empty_drawsize *= size; break; } + case OB_GPENCIL: + { + ob->empty_drawsize *= size; + break; + } case OB_FONT: { Curve *cu = ob->data; @@ -2452,7 +2560,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us float size[3]; copy_v3_v3(size, ob->size); - if (ob->type == OB_EMPTY) { + if ((ob->type == OB_EMPTY) || (ob->type == OB_GPENCIL)) { mul_v3_fl(size, ob->empty_drawsize); } @@ -3694,6 +3802,88 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md) return false; } +bool BKE_object_modifier_gpencil_use_time(Object *ob, GpencilModifierData *md) +{ + if (BKE_gpencil_modifier_dependsOnTime(md)) { + return true; + } + + /* Check whether modifier is animated. */ + /* TODO (Aligorith): this should be handled as part of build_animdata() */ + if (ob->adt) { + AnimData *adt = ob->adt; + FCurve *fcu; + + char pattern[MAX_NAME + 32]; + BLI_snprintf(pattern, sizeof(pattern), "grease_pencil_modifiers[\"%s\"]", md->name); + + /* action - check for F-Curves with paths containing 'grease_pencil_modifiers[' */ + if (adt->action) { + for (fcu = (FCurve *)adt->action->curves.first; + fcu != NULL; + fcu = (FCurve *)fcu->next) + { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + return true; + } + } + + /* This here allows modifier properties to get driven and still update properly + * + */ + for (fcu = (FCurve *)adt->drivers.first; + fcu != NULL; + fcu = (FCurve *)fcu->next) + { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + return true; + } + } + + return false; +} + +bool BKE_object_shaderfx_use_time(Object *ob, ShaderFxData *fx) +{ + if (BKE_shaderfx_dependsOnTime(fx)) { + return true; + } + + /* Check whether effect is animated. */ + /* TODO (Aligorith): this should be handled as part of build_animdata() */ + if (ob->adt) { + AnimData *adt = ob->adt; + FCurve *fcu; + + char pattern[MAX_NAME + 32]; + BLI_snprintf(pattern, sizeof(pattern), "shader_effects[\"%s\"]", fx->name); + + /* action - check for F-Curves with paths containing string[' */ + if (adt->action) { + for (fcu = (FCurve *)adt->action->curves.first; + fcu != NULL; + fcu = (FCurve *)fcu->next) + { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + return true; + } + } + + /* This here allows properties to get driven and still update properly + * + */ + for (fcu = (FCurve *)adt->drivers.first; + fcu != NULL; + fcu = (FCurve *)fcu->next) + { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + return true; + } + } + + return false; +} + /* set "ignore cache" flag for all caches on this object */ static void object_cacheIgnoreClear(Object *ob, int state) { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 5c9e53aaa56..a6b0e57e55c 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -53,6 +53,7 @@ #include "BKE_object.h" #include "BKE_mesh.h" #include "BKE_modifier.h" +#include "BKE_gpencil.h" /** \name Misc helpers * \{ */ @@ -402,12 +403,17 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg) */ void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup) { - if (BKE_object_is_in_editmode_vgroup(ob)) - object_defgroup_remove_edit_mode(ob, defgroup); - else - object_defgroup_remove_object_mode(ob, defgroup); + if ((ob) && (ob->type == OB_GPENCIL)) { + BKE_gpencil_vgroup_remove(ob, defgroup); + } + else { + if (BKE_object_is_in_editmode_vgroup(ob)) + object_defgroup_remove_edit_mode(ob, defgroup); + else + object_defgroup_remove_object_mode(ob, defgroup); - BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + } } /** diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 3e72de3909f..3641df26496 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -62,6 +62,7 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_scene.h" +#include "BKE_gpencil.h" #include "MEM_guardedalloc.h" @@ -324,6 +325,9 @@ void BKE_object_eval_uber_data(Depsgraph *depsgraph, case OB_MBALL: BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL); break; + case OB_GPENCIL: + BKE_gpencil_batch_cache_dirty(ob->data); + break; } } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 07aa21f44ff..cb26f7e9f3e 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -41,13 +41,19 @@ #include "DNA_scene_types.h" #include "DNA_brush_types.h" #include "DNA_space_types.h" +#include "DNA_gpencil_types.h" #include "DNA_workspace_types.h" #include "BLI_bitmap.h" +#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_string_utils.h" #include "BLI_math_vector.h" #include "BLI_listbase.h" +#include "BLT_translation.h" + +#include "BKE_animsys.h" #include "BKE_brush.h" #include "BKE_colortools.h" #include "BKE_deform.h" @@ -55,6 +61,7 @@ #include "BKE_context.h" #include "BKE_crazyspace.h" #include "BKE_global.h" +#include "BKE_gpencil.h" #include "BKE_image.h" #include "BKE_key.h" #include "BKE_library.h" @@ -151,6 +158,8 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode) return &ts->imapaint.paint; case ePaintSculptUV: return &ts->uvsculpt->paint; + case ePaintGpencil: + return &ts->gp_paint->paint; case ePaintInvalid: return NULL; default: @@ -176,6 +185,8 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer) return &ts->wpaint->paint; case OB_MODE_TEXTURE_PAINT: return &ts->imapaint.paint; + case OB_MODE_GPENCIL_PAINT: + return &ts->gp_paint->paint; case OB_MODE_EDIT: if (ts->use_uv_sculpt) return &ts->uvsculpt->paint; @@ -430,13 +441,11 @@ PaletteColor *BKE_palette_color_add(Palette *palette) return color; } - bool BKE_palette_is_empty(const struct Palette *palette) { return BLI_listbase_is_empty(&palette->colors); } - /* are we in vertex paint or weight pain face select mode? */ bool BKE_paint_select_face_test(Object *ob) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b50dc37af81..7085b515ec1 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -173,6 +173,10 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag) ts->uvsculpt = MEM_dupallocN(ts->uvsculpt); BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag); } + if (ts->gp_paint) { + ts->gp_paint = MEM_dupallocN(ts->gp_paint); + BKE_paint_copy(&ts->gp_paint->paint, &ts->gp_paint->paint, flag); + } BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag); ts->imapaint.paintcursor = NULL; @@ -180,15 +184,10 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag) ts->particle.scene = NULL; ts->particle.object = NULL; - /* duplicate Grease Pencil Drawing Brushes */ - BLI_listbase_clear(&ts->gp_brushes); - for (bGPDbrush *brush = toolsettings->gp_brushes.first; brush; brush = brush->next) { - bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush); - BLI_addtail(&ts->gp_brushes, newbrush); - } - /* duplicate Grease Pencil interpolation curve */ ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo); + /* duplicate Grease Pencil multiframe fallof */ + ts->gp_sculpt.cur_falloff = curvemapping_copy(ts->gp_sculpt.cur_falloff); return ts; } @@ -213,16 +212,20 @@ void BKE_toolsettings_free(ToolSettings *toolsettings) BKE_paint_free(&toolsettings->uvsculpt->paint); MEM_freeN(toolsettings->uvsculpt); } + if (toolsettings->gp_paint) { + BKE_paint_free(&toolsettings->gp_paint->paint); + MEM_freeN(toolsettings->gp_paint); + } BKE_paint_free(&toolsettings->imapaint.paint); - /* free Grease Pencil Drawing Brushes */ - BKE_gpencil_free_brushes(&toolsettings->gp_brushes); - BLI_freelistN(&toolsettings->gp_brushes); - /* free Grease Pencil interpolation curve */ if (toolsettings->gp_interpolate.custom_ipo) { curvemapping_free(toolsettings->gp_interpolate.custom_ipo); } + /* free Grease Pencil multiframe falloff curve */ + if (toolsettings->gp_sculpt.cur_falloff) { + curvemapping_free(toolsettings->gp_sculpt.cur_falloff); + } MEM_freeN(toolsettings); } @@ -428,9 +431,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type) } /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations - * are done outside of blenkernel with ED_objects_single_users! */ + * are done outside of blenkernel with ED_object_single_users! */ - /* camera */ + /* camera */ if (ELEM(type, SCE_COPY_LINK_DATA, SCE_COPY_FULL)) { ID_NEW_REMAP(sce_copy->camera); } @@ -683,6 +686,19 @@ void BKE_scene_init(Scene *sce) sce->toolsettings->imapaint.normal_angle = 80; sce->toolsettings->imapaint.seam_bleed = 2; + /* alloc grease pencil drawing brushes */ + sce->toolsettings->gp_paint = MEM_callocN(sizeof(GpPaint), "GpPaint"); + + /* grease pencil multiframe falloff curve */ + sce->toolsettings->gp_sculpt.cur_falloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + CurveMapping *gp_falloff_curve = sce->toolsettings->gp_sculpt.cur_falloff; + curvemapping_set_defaults(gp_falloff_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f); + curvemapping_initialize(gp_falloff_curve); + curvemap_reset(gp_falloff_curve->cm, + &gp_falloff_curve->clipr, + CURVE_PRESET_GAUSS, + CURVEMAP_SLOPE_POSITIVE); + sce->physics_settings.gravity[0] = 0.0f; sce->physics_settings.gravity[1] = 0.0f; sce->physics_settings.gravity[2] = -9.81f; @@ -760,46 +776,65 @@ void BKE_scene_init(Scene *sce) { GP_BrushEdit_Settings *gset = &sce->toolsettings->gp_sculpt; GP_EditBrush_Data *gp_brush; + float curcolor_add[3], curcolor_sub[3]; + ARRAY_SET_ITEMS(curcolor_add, 1.0f, 0.6f, 0.6f); + ARRAY_SET_ITEMS(curcolor_sub, 0.6f, 0.6f, 1.0f); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_SMOOTH]; gp_brush->size = 25; gp_brush->strength = 0.3f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_THICKNESS]; gp_brush->size = 25; gp_brush->strength = 0.5f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH]; gp_brush->size = 25; gp_brush->strength = 0.5f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB]; gp_brush->size = 50; gp_brush->strength = 0.3f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_PUSH]; gp_brush->size = 25; gp_brush->strength = 0.3f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_TWIST]; gp_brush->size = 50; gp_brush->strength = 0.3f; // XXX? - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_PINCH]; gp_brush->size = 50; gp_brush->strength = 0.5f; // XXX? - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE]; gp_brush->size = 25; gp_brush->strength = 0.5f; - gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); } /* GP Stroke Placement */ @@ -808,6 +843,10 @@ void BKE_scene_init(Scene *sce) sce->toolsettings->gpencil_seq_align = GP_PROJECT_VIEWSPACE; sce->toolsettings->gpencil_ima_align = GP_PROJECT_VIEWSPACE; + /* Annotations */ + sce->toolsettings->annotate_v3d_align = GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR; + sce->toolsettings->annotate_thickness = 3; + sce->orientation_index_custom = -1; /* Master Collection */ diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c new file mode 100644 index 00000000000..c028c2184fd --- /dev/null +++ b/source/blender/blenkernel/intern/shader_fx.c @@ -0,0 +1,245 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/shader_fx.c + * \ingroup bke + */ + + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" +#include "BLI_string_utils.h" + +#include "BLT_translation.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_shader_fx_types.h" + +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_gpencil.h" +#include "BKE_shader_fx.h" +#include "BKE_object.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "FX_shader_types.h" + +static ShaderFxTypeInfo *shader_fx_types[NUM_SHADER_FX_TYPES] = { NULL }; + +/* *************************************************** */ +/* Methods - Evaluation Loops, etc. */ + +/* check if exist grease pencil effects */ +bool BKE_shaderfx_has_gpencil(Object *ob) +{ + ShaderFxData *fx; + for (fx = ob->shader_fx.first; fx; fx = fx->next) { + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + if (fxi->type == eShaderFxType_GpencilType) { + return true; + } + } + return false; +} + +void BKE_shaderfx_init(void) +{ + /* Initialize shaders */ + shaderfx_type_init(shader_fx_types); /* FX_shader_util.c */ +} + +ShaderFxData *BKE_shaderfx_new(int type) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(type); + ShaderFxData *fx = MEM_callocN(fxi->struct_size, fxi->struct_name); + + /* note, this name must be made unique later */ + BLI_strncpy(fx->name, DATA_(fxi->name), sizeof(fx->name)); + + fx->type = type; + fx->mode = eShaderFxMode_Realtime | eShaderFxMode_Render | eShaderFxMode_Expanded; + fx->flag = eShaderFxFlag_StaticOverride_Local; + + if (fxi->flags & eShaderFxTypeFlag_EnableInEditmode) + fx->mode |= eShaderFxMode_Editmode; + + if (fxi->initData) fxi->initData(fx); + + return fx; +} + +static void shaderfx_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag) +{ + ID *id = *idpoin; + if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) { + id_us_min(id); + } +} + +void BKE_shaderfx_free_ex(ShaderFxData *fx, const int flag) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (fxi->foreachIDLink) { + fxi->foreachIDLink(fx, NULL, shaderfx_free_data_id_us_cb, NULL); + } + else if (fxi->foreachObjectLink) { + fxi->foreachObjectLink(fx, NULL, (ShaderFxObjectWalkFunc)shaderfx_free_data_id_us_cb, NULL); + } + } + + if (fxi->freeData) fxi->freeData(fx); + if (fx->error) MEM_freeN(fx->error); + + MEM_freeN(fx); +} + +void BKE_shaderfx_free(ShaderFxData *fx) +{ + BKE_shaderfx_free_ex(fx, 0); +} + +/* check unique name */ +bool BKE_shaderfx_unique_name(ListBase *shaders, ShaderFxData *fx) +{ + if (shaders && fx) { + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + return BLI_uniquename(shaders, fx, DATA_(fxi->name), '.', offsetof(ShaderFxData, name), sizeof(fx->name)); + } + return false; +} + +bool BKE_shaderfx_dependsOnTime(ShaderFxData *fx) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + + return fxi->dependsOnTime && fxi->dependsOnTime(fx); +} + +const ShaderFxTypeInfo *BKE_shaderfxType_getInfo(ShaderFxType type) +{ + /* type unsigned, no need to check < 0 */ + if (type < NUM_SHADER_FX_TYPES && shader_fx_types[type]->name[0] != '\0') { + return shader_fx_types[type]; + } + else { + return NULL; + } +} + +void BKE_shaderfx_copyData_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx_src->type); + + /* fx_dst may have alredy be fully initialized with some extra allocated data, + * we need to free it now to avoid memleak. */ + if (fxi->freeData) { + fxi->freeData(fx_dst); + } + + const size_t data_size = sizeof(ShaderFxData); + const char *fx_src_data = ((const char *)fx_src) + data_size; + char *fx_dst_data = ((char *)fx_dst) + data_size; + BLI_assert(data_size <= (size_t)fxi->struct_size); + memcpy(fx_dst_data, fx_src_data, (size_t)fxi->struct_size - data_size); +} + +static void shaderfx_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag) +{ + ID *id = *idpoin; + if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) { + id_us_plus(id); + } +} + +void BKE_shaderfx_copyData_ex(ShaderFxData *fx, ShaderFxData *target, const int flag) +{ + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + + target->mode = fx->mode; + target->flag = fx->flag; + + if (fxi->copyData) { + fxi->copyData(fx, target); + } + + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + if (fxi->foreachIDLink) { + fxi->foreachIDLink(target, NULL, shaderfx_copy_data_id_us_cb, NULL); + } + else if (fxi->foreachObjectLink) { + fxi->foreachObjectLink(target, NULL, (ShaderFxObjectWalkFunc)shaderfx_copy_data_id_us_cb, NULL); + } + } +} + +void BKE_shaderfx_copyData(ShaderFxData *fx, ShaderFxData *target) +{ + BKE_shaderfx_copyData_ex(fx, target, 0); +} + +ShaderFxData *BKE_shaderfx_findByType(Object *ob, ShaderFxType type) +{ + ShaderFxData *fx = ob->shader_fx.first; + + for (; fx; fx = fx->next) + if (fx->type == type) + break; + + return fx; +} + +void BKE_shaderfx_foreachIDLink(Object *ob, ShaderFxIDWalkFunc walk, void *userData) +{ + ShaderFxData *fx = ob->shader_fx.first; + + for (; fx; fx = fx->next) { + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + + if (fxi->foreachIDLink) fxi->foreachIDLink(fx, ob, walk, userData); + else if (fxi->foreachObjectLink) { + /* each Object can masquerade as an ID, so this should be OK */ + ShaderFxObjectWalkFunc fp = (ShaderFxObjectWalkFunc)walk; + fxi->foreachObjectLink(fx, ob, fp, userData); + } + } +} + +ShaderFxData *BKE_shaderfx_findByName(Object *ob, const char *name) +{ + return BLI_findstring(&(ob->shader_fx), name, offsetof(ShaderFxData, name)); +} diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index ec16a6854c4..ef2ff10b5c6 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -78,6 +78,9 @@ MINLINE void zero_v3_int(int r[3]); MINLINE void copy_v2_v2_int(int r[2], const int a[2]); MINLINE void copy_v3_v3_int(int r[3], const int a[3]); MINLINE void copy_v4_v4_int(int r[4], const int a[4]); +/* int <-> float */ +MINLINE void copy_v2fl_v2i(float r[2], const int a[2]); +MINLINE void round_v2i_v2fl(int r[2], const float a[2]); /* double -> float */ MINLINE void copy_v2fl_v2db(float r[2], const double a[2]); MINLINE void copy_v3fl_v3db(float r[3], const double a[3]); diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index 612151b7ea2..f7dea562393 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -64,6 +64,9 @@ void BLI_rng_shuffle_array(struct RNG *rng, void *data, unsigned int elem /** Note that skipping is as slow as generating n numbers! */ void BLI_rng_skip(struct RNG *rng, int n) ATTR_NONNULL(1); +/* fill an array with random numbers */ +void BLI_array_frand(float *ar, int count, unsigned int seed); + /** Return a pseudo-random (hash) float from an integer value */ float BLI_hash_frand(unsigned int seed) ATTR_WARN_UNUSED_RESULT; diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 568448327bd..80b8a8d041c 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -578,6 +578,9 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) Link *link = NULL; const char *id_iter; + if (id == NULL) + return NULL; + for (link = listbase->first; link; link = link->next) { id_iter = ((const char *)link) + offset; diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 189b94a6f13..c4535eacefa 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -192,6 +192,19 @@ MINLINE void copy_v4_v4_int(int r[4], const int a[4]) r[3] = a[3]; } +/* int <-> float */ +MINLINE void round_v2i_v2fl(int r[2], const float a[2]) +{ + r[0] = (int)roundf(a[0]); + r[1] = (int)roundf(a[1]); +} + +MINLINE void copy_v2fl_v2i(float r[2], const int a[2]) +{ + r[0] = (float)a[0]; + r[1] = (float)a[1]; +} + /* double -> float */ MINLINE void copy_v2fl_v2db(float r[2], const double a[2]) { diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 9e56ce6b2cf..8613a0ea6dd 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -265,6 +265,18 @@ void BLI_rng_skip(RNG *rng, int n) /***/ +/* fill an array with random numbers */ +void BLI_array_frand(float *ar, int count, unsigned int seed) +{ + RNG rng; + + BLI_rng_srandom(&rng, seed); + + for (int i = 0; i < count; i++) { + ar[i] = BLI_rng_get_float(&rng); + } +} + float BLI_hash_frand(unsigned int seed) { RNG rng; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 816a527d829..293114c4b79 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -72,6 +72,8 @@ #include "DNA_genfile.h" #include "DNA_group_types.h" #include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" @@ -130,6 +132,8 @@ #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_global.h" // for G +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" #include "BKE_layer.h" #include "BKE_library.h" // for which_libbase #include "BKE_library_idmap.h" @@ -153,6 +157,7 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_sequencer.h" +#include "BKE_shader_fx.h" #include "BKE_outliner_treehash.h" #include "BKE_sound.h" #include "BKE_colortools.h" @@ -266,6 +271,8 @@ static BHead *find_bhead_from_idname(FileData *fd, const char *idname); #ifdef USE_COLLECTION_COMPAT_28 static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc); #endif +static void direct_link_animdata(FileData *fd, AnimData *adt); +static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt); /* this function ensures that reports are printed, * in the case of libraray linking errors this is important! @@ -2368,6 +2375,7 @@ static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap) } /* ************ READ Brush *************** */ + /* library brush linking after fileread */ static void lib_link_brush(FileData *fd, Main *main) { @@ -2383,6 +2391,11 @@ static void lib_link_brush(FileData *fd, Main *main) brush->toggle_brush = newlibadr(fd, brush->id.lib, brush->toggle_brush); brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve); + /* link default grease pencil palette */ + if (brush->gpencil_settings != NULL) { + brush->gpencil_settings->material = newlibadr_us(fd, brush->id.lib, brush->gpencil_settings->material); + } + brush->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -2394,6 +2407,7 @@ static void direct_link_brush(FileData *fd, Brush *brush) /* fallof curve */ brush->curve = newdataadr(fd, brush->curve); + brush->gradient = newdataadr(fd, brush->gradient); if (brush->curve) @@ -2401,11 +2415,29 @@ static void direct_link_brush(FileData *fd, Brush *brush) else BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP); + /* grease pencil */ + brush->gpencil_settings = newdataadr(fd, brush->gpencil_settings); + if (brush->gpencil_settings != NULL) { + brush->gpencil_settings->curve_sensitivity = newdataadr(fd, brush->gpencil_settings->curve_sensitivity); + brush->gpencil_settings->curve_strength = newdataadr(fd, brush->gpencil_settings->curve_strength); + brush->gpencil_settings->curve_jitter = newdataadr(fd, brush->gpencil_settings->curve_jitter); + + if (brush->gpencil_settings->curve_sensitivity) + direct_link_curvemapping(fd, brush->gpencil_settings->curve_sensitivity); + + if (brush->gpencil_settings->curve_strength) + direct_link_curvemapping(fd, brush->gpencil_settings->curve_strength); + + if (brush->gpencil_settings->curve_jitter) + direct_link_curvemapping(fd, brush->gpencil_settings->curve_jitter); + } + brush->preview = NULL; brush->icon_imbuf = NULL; } /* ************ READ Palette *************** */ + static void lib_link_palette(FileData *fd, Main *main) { /* only link ID pointers */ @@ -2420,6 +2452,7 @@ static void lib_link_palette(FileData *fd, Main *main) static void direct_link_palette(FileData *fd, Palette *palette) { + /* palette itself has been read */ link_list(fd, &palette->colors); } @@ -4147,6 +4180,17 @@ static void lib_link_material(FileData *fd, Main *main) ma->nodetree->id.lib = ma->id.lib; } + /* relink grease pencil settings */ + if (ma->gp_style != NULL) { + MaterialGPencilStyle *gp_style = ma->gp_style; + if (gp_style->sima != NULL) { + gp_style->sima = newlibadr_us(fd, ma->id.lib, gp_style->sima); + } + if (gp_style->ima != NULL) { + gp_style->ima = newlibadr_us(fd, ma->id.lib, gp_style->ima); + } + } + ma->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -4167,6 +4211,8 @@ static void direct_link_material(FileData *fd, Material *ma) ma->preview = direct_link_preview_image(fd, ma->preview); BLI_listbase_clear(&ma->gpumaterial); + + ma->gp_style = newdataadr(fd, ma->gp_style); } /* ************ READ PARTICLE SETTINGS ***************** */ @@ -4802,7 +4848,7 @@ static void direct_link_latt(FileData *fd, Lattice *lt) /* ************ READ OBJECT ***************** */ -static void lib_link_modifiers__linkModifiers( +static void lib_link_modifiers_common( void *userData, Object *ob, ID **idpoin, int cb_flag) { FileData *fd = userData; @@ -4812,9 +4858,10 @@ static void lib_link_modifiers__linkModifiers( id_us_plus_no_lib(*idpoin); } } + static void lib_link_modifiers(FileData *fd, Object *ob) { - modifiers_foreachIDLink(ob, lib_link_modifiers__linkModifiers, fd); + modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd); /* If linking from a library, clear 'local' static override flag. */ if (ob->id.lib != NULL) { @@ -4825,6 +4872,30 @@ static void lib_link_modifiers(FileData *fd, Object *ob) } +static void lib_link_gpencil_modifiers(FileData *fd, Object *ob) +{ + BKE_gpencil_modifiers_foreachIDLink(ob, lib_link_modifiers_common, fd); + + /* If linking from a library, clear 'local' static override flag. */ + if (ob->id.lib != NULL) { + for (GpencilModifierData *mod = ob->greasepencil_modifiers.first; mod != NULL; mod = mod->next) { + mod->flag &= ~eGpencilModifierFlag_StaticOverride_Local; + } + } +} + +static void lib_link_shaderfxs(FileData *fd, Object *ob) +{ + BKE_shaderfx_foreachIDLink(ob, lib_link_modifiers_common, fd); + + /* If linking from a library, clear 'local' static override flag. */ + if (ob->id.lib != NULL) { + for (ShaderFxData *fx = ob->shader_fx.first; fx != NULL; fx = fx->next) { + fx->flag &= ~eShaderFxFlag_StaticOverride_Local; + } + } +} + static void lib_link_object(FileData *fd, Main *main) { bool warn = false; @@ -4961,6 +5032,8 @@ static void lib_link_object(FileData *fd, Main *main) lib_link_particlesystems(fd, ob, &ob->id, &ob->particlesystem); lib_link_modifiers(fd, ob); + lib_link_gpencil_modifiers(fd, ob); + lib_link_shaderfxs(fd, ob); if (ob->rigidbody_constraint) { ob->rigidbody_constraint->ob1 = newlibadr(fd, ob->id.lib, ob->rigidbody_constraint->ob1); @@ -5356,6 +5429,61 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) } } +static void direct_link_gpencil_modifiers(FileData *fd, ListBase *lb) +{ + GpencilModifierData *md; + + link_list(fd, lb); + + for (md = lb->first; md; md = md->next) { + md->error = NULL; + + /* if modifiers disappear, or for upward compatibility */ + if (NULL == BKE_gpencil_modifierType_getInfo(md->type)) + md->type = eModifierType_None; + + if (md->type == eGpencilModifierType_Lattice) { + LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData*)md; + gpmd->cache_data = NULL; + } + else if (md->type == eGpencilModifierType_Hook) { + HookGpencilModifierData *hmd = (HookGpencilModifierData *)md; + + hmd->curfalloff = newdataadr(fd, hmd->curfalloff); + if (hmd->curfalloff) { + direct_link_curvemapping(fd, hmd->curfalloff); + } + } + else if (md->type == eGpencilModifierType_Thick) { + ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; + + gpmd->curve_thickness = newdataadr(fd, gpmd->curve_thickness); + if (gpmd->curve_thickness) { + direct_link_curvemapping(fd, gpmd->curve_thickness); + /* initialize the curve. Maybe this could be moved to modififer logic */ + curvemapping_initialize(gpmd->curve_thickness); + } + } + + } +} + +static void direct_link_shaderfxs(FileData *fd, ListBase *lb) +{ + ShaderFxData *fx; + + link_list(fd, lb); + + for (fx = lb->first; fx; fx = fx->next) { + fx->error = NULL; + + /* if shader disappear, or for upward compatibility */ + if (NULL == BKE_shaderfxType_getInfo(fx->type)) + fx->type = eShaderFxType_None; + + } +} + static void direct_link_object(FileData *fd, Object *ob) { PartEff *paf; @@ -5399,6 +5527,8 @@ static void direct_link_object(FileData *fd, Object *ob) /* do it here, below old data gets converted */ direct_link_modifiers(fd, &ob->modifiers); + direct_link_gpencil_modifiers(fd, &ob->greasepencil_modifiers); + direct_link_shaderfxs(fd, &ob->shader_fx); link_list(fd, &ob->effect); paf= ob->effect.first; @@ -5879,6 +6009,7 @@ static void lib_link_scene(FileData *fd, Main *main) link_paint(fd, sce, &sce->toolsettings->wpaint->paint); link_paint(fd, sce, &sce->toolsettings->imapaint.paint); link_paint(fd, sce, &sce->toolsettings->uvsculpt->paint); + link_paint(fd, sce, &sce->toolsettings->gp_paint->paint); if (sce->toolsettings->sculpt) sce->toolsettings->sculpt->gravity_object = @@ -6137,6 +6268,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->vpaint); direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->wpaint); direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->uvsculpt); + direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->gp_paint); direct_link_paint(fd, &sce->toolsettings->imapaint.paint); @@ -6146,28 +6278,16 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->toolsettings->particle.object = NULL; sce->toolsettings->gp_sculpt.paintcursor = NULL; - /* relink grease pencil drawing brushes */ - link_list(fd, &sce->toolsettings->gp_brushes); - for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) { - brush->cur_sensitivity = newdataadr(fd, brush->cur_sensitivity); - if (brush->cur_sensitivity) { - direct_link_curvemapping(fd, brush->cur_sensitivity); - } - brush->cur_strength = newdataadr(fd, brush->cur_strength); - if (brush->cur_strength) { - direct_link_curvemapping(fd, brush->cur_strength); - } - brush->cur_jitter = newdataadr(fd, brush->cur_jitter); - if (brush->cur_jitter) { - direct_link_curvemapping(fd, brush->cur_jitter); - } - } - /* relink grease pencil interpolation curves */ sce->toolsettings->gp_interpolate.custom_ipo = newdataadr(fd, sce->toolsettings->gp_interpolate.custom_ipo); if (sce->toolsettings->gp_interpolate.custom_ipo) { direct_link_curvemapping(fd, sce->toolsettings->gp_interpolate.custom_ipo); } + /* relink grease pencil multiframe falloff curve */ + sce->toolsettings->gp_sculpt.cur_falloff = newdataadr(fd, sce->toolsettings->gp_sculpt.cur_falloff); + if (sce->toolsettings->gp_sculpt.cur_falloff) { + direct_link_curvemapping(fd, sce->toolsettings->gp_sculpt.cur_falloff); + } } if (sce->ed) { @@ -6405,11 +6525,24 @@ static void direct_link_scene(FileData *fd, Scene *sce) /* relink's grease pencil data's refs */ static void lib_link_gpencil(FileData *fd, Main *main) { + /* Relink all datablock linked by GP datablock */ for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) { if (gpd->id.tag & LIB_TAG_NEED_LINK) { + /* Layers */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* Layer -> Parent References */ + gpl->parent = newlibadr(fd, gpd->id.lib, gpl->parent); + } + + /* Datablock Stuff */ IDP_LibLinkProperty(gpd->id.properties, fd); lib_link_animdata(fd, &gpd->id, gpd->adt); + /* materials */ + for (int a = 0; a < gpd->totcol; a++) { + gpd->mat[a] = newlibadr_us(fd, gpd->id.lib, gpd->mat[a]); + } + gpd->id.tag &= ~LIB_TAG_NEED_LINK; } } @@ -6431,36 +6564,49 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) gpd->adt = newdataadr(fd, gpd->adt); direct_link_animdata(fd, gpd->adt); - /* relink palettes */ + /* relink palettes (old palettes deprecated, only to convert old files) */ link_list(fd, &gpd->palettes); - for (palette = gpd->palettes.first; palette; palette = palette->next) { - link_list(fd, &palette->colors); + if (gpd->palettes.first != NULL) { + for (palette = gpd->palettes.first; palette; palette = palette->next) { + link_list(fd, &palette->colors); + } } + /* clear drawing cache */ + gpd->runtime.batch_cache_data = NULL; + + /* materials */ + gpd->mat = newdataadr(fd, gpd->mat); + test_pointer_array(fd, (void **)&gpd->mat); + /* relink layers */ link_list(fd, &gpd->layers); for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* parent */ - gpl->parent = newlibadr(fd, gpd->id.lib, gpl->parent); /* relink frames */ link_list(fd, &gpl->frames); + gpl->actframe = newdataadr(fd, gpl->actframe); + gpl->runtime.derived_data = NULL; + gpl->runtime.icon_id = 0; + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { /* relink strokes (and their points) */ link_list(fd, &gpf->strokes); for (gps = gpf->strokes.first; gps; gps = gps->next) { + /* relink stroke points array */ gps->points = newdataadr(fd, gps->points); + /* relink weight data */ + gps->dvert = newdataadr(fd, gps->dvert); + direct_link_dverts(fd, gps->totpoints, gps->dvert); + /* the triangulation is not saved, so need to be recalculated */ gps->triangles = NULL; gps->tot_triangles = 0; gps->flag |= GP_STROKE_RECALC_CACHES; - /* the color pointer is not saved, so need to be recalculated using the color name */ - gps->palcolor = NULL; - gps->flag |= GP_STROKE_RECALC_COLOR; } } } @@ -8618,6 +8764,11 @@ static void do_versions_userdef(FileData *fd, BlendFileData *bfd) user->walk_navigation.jump_height = 0.4f; /* m */ user->walk_navigation.teleport_time = 0.2f; /* s */ } + + /* grease pencil multisamples */ + if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "gpencil_multisamples")) { + user->gpencil_multisamples = 4; + } } static void do_versions(FileData *fd, Library *lib, Main *main) @@ -8696,8 +8847,8 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_action(fd, main); lib_link_vfont(fd, main); lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */ - lib_link_brush(fd, main); lib_link_palette(fd, main); + lib_link_brush(fd, main); lib_link_paint_curve(fd, main); lib_link_particlesettings(fd, main); lib_link_movieclip(fd, main); @@ -9434,6 +9585,9 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush) expand_doit(fd, mainvar, brush->mask_mtex.tex); expand_doit(fd, mainvar, brush->clone.image); expand_doit(fd, mainvar, brush->paint_curve); + if (brush->gpencil_settings != NULL) { + expand_doit(fd, mainvar, brush->gpencil_settings->material); + } } static void expand_material(FileData *fd, Main *mainvar, Material *ma) @@ -9445,6 +9599,12 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) if (ma->nodetree) expand_nodetree(fd, mainvar, ma->nodetree); + + if (ma->gp_style) { + MaterialGPencilStyle *gp_style = ma->gp_style; + expand_doit(fd, mainvar, gp_style->sima); + expand_doit(fd, mainvar, gp_style->ima); + } } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) @@ -9621,6 +9781,24 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); } + /* expand_object_expandModifier() */ + if (ob->greasepencil_modifiers.first) { + struct { FileData *fd; Main *mainvar; } data; + data.fd = fd; + data.mainvar = mainvar; + + BKE_gpencil_modifiers_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); + } + + /* expand_object_expandShaderFx() */ + if (ob->shader_fx.first) { + struct { FileData *fd; Main *mainvar; } data; + data.fd = fd; + data.mainvar = mainvar; + + BKE_shaderfx_foreachIDLink(ob, expand_object_expandModifiers, (void *)&data); + } + expand_pose(fd, mainvar, ob->pose); expand_doit(fd, mainvar, ob->poselib); expand_constraints(fd, mainvar, &ob->constraints); @@ -9899,8 +10077,18 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd) { - if (gpd->adt) + if (gpd->adt) { expand_animdata(fd, mainvar, gpd->adt); + } + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + expand_doit(fd, mainvar, gpl->parent); + } + + for (int a = 0; a < gpd->totcol; a++) { + expand_doit(fd, mainvar, gpd->mat[a]); + } + } static void expand_workspace(FileData *fd, Main *mainvar, WorkSpace *workspace) diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 7a032dc3c90..f2f2e7d7881 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -1685,7 +1685,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) case SPACE_VIEW3D: { View3D *v3d = (View3D *)sl; - v3d->flag2 |= V3D_SHOW_GPENCIL; + v3d->flag2 |= V3D_SHOW_ANNOTATION; break; } case SPACE_SEQ: @@ -1709,7 +1709,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) case SPACE_CLIP: { SpaceClip *sclip = (SpaceClip *)sl; - sclip->flag |= SC_SHOW_GPENCIL; + sclip->flag |= SC_SHOW_ANNOTATION; break; } } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 7a106611e64..fadf332c850 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -76,6 +76,9 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLI_string_utils.h" + +#include "BLT_translation.h" #include "BLO_readfile.h" @@ -87,6 +90,64 @@ #include "MEM_guardedalloc.h" +/* ************************************************** */ +/* GP Palettes API (Deprecated) */ + +/* add a new gp-palette */ +static bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name) +{ + bGPDpalette *palette; + + /* check that list is ok */ + if (gpd == NULL) { + return NULL; + } + + /* allocate memory and add to end of list */ + palette = MEM_callocN(sizeof(bGPDpalette), "bGPDpalette"); + + /* add to datablock */ + BLI_addtail(&gpd->palettes, palette); + + /* set basic settings */ + /* auto-name */ + BLI_strncpy(palette->info, name, sizeof(palette->info)); + BLI_uniquename(&gpd->palettes, palette, DATA_("GP_Palette"), '.', offsetof(bGPDpalette, info), + sizeof(palette->info)); + + /* return palette */ + return palette; +} + +/* add a new gp-palettecolor */ +static bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(bGPDpalette *palette, const char *name) +{ + bGPDpalettecolor *palcolor; + + /* check that list is ok */ + if (palette == NULL) { + return NULL; + } + + /* allocate memory and add to end of list */ + palcolor = MEM_callocN(sizeof(bGPDpalettecolor), "bGPDpalettecolor"); + + /* add to datablock */ + BLI_addtail(&palette->colors, palcolor); + + /* set basic settings */ + copy_v4_v4(palcolor->color, U.gpencil_new_layer_col); + ARRAY_SET_ITEMS(palcolor->fill, 1.0f, 1.0f, 1.0f); + + /* auto-name */ + BLI_strncpy(palcolor->info, name, sizeof(palcolor->info)); + BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info), + sizeof(palcolor->info)); + + /* return palette color */ + return palcolor; +} + /** * Setup rotation stabilization from ancient single track spec. * Former Version of 2D stabilization used a single tracking marker to determine the rotation @@ -1344,8 +1405,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) ToolSettings *ts = scene->toolsettings; /* initialize use position for sculpt brushes */ ts->gp_sculpt.flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION; - /* initialize selected vertices alpha factor */ - ts->gp_sculpt.alpha = 1.0f; /* new strength sculpt brush */ if (ts->gp_sculpt.brush[0].size >= 11) { @@ -1358,25 +1417,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; } } - /* create a default grease pencil drawing brushes set */ - if (!BLI_listbase_is_empty(&bmain->gpencil)) { - for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { - ToolSettings *ts = scene->toolsettings; - if (BLI_listbase_is_empty(&ts->gp_brushes)) { - BKE_gpencil_brush_init_presets(ts); - } - } - } /* Convert Grease Pencil to new palettes/brushes * Loop all strokes and create the palette and all colors */ for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { if (BLI_listbase_is_empty(&gpd->palettes)) { /* create palette */ - bGPDpalette *palette = BKE_gpencil_palette_addnew(gpd, "GP_Palette", true); + bGPDpalette *palette = BKE_gpencil_palette_addnew(gpd, "GP_Palette"); for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* create color using layer name */ - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_addnew(palette, gpl->info, true); + bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_addnew(palette, gpl->info); if (palcolor != NULL) { /* set color attributes */ copy_v4_v4(palcolor->color, gpl->color); @@ -1386,7 +1436,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (gpl->flag & GP_LAYER_LOCKED) palcolor->flag |= PC_COLOR_LOCKED; if (gpl->flag & GP_LAYER_ONIONSKIN) palcolor->flag |= PC_COLOR_ONIONSKIN; if (gpl->flag & GP_LAYER_VOLUMETRIC) palcolor->flag |= PC_COLOR_VOLUMETRIC; - if (gpl->flag & GP_LAYER_HQ_FILL) palcolor->flag |= PC_COLOR_HQ_FILL; /* set layer opacity to 1 */ gpl->opacity = 1.0f; @@ -1399,8 +1448,6 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { /* set stroke to palette and force recalculation */ BLI_strncpy(gps->colorname, gpl->info, sizeof(gps->colorname)); - gps->palcolor = NULL; - gps->flag |= GP_STROKE_RECALC_COLOR; gps->thickness = gpl->thickness; /* set alpha strength to 1 */ @@ -1410,13 +1457,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } - - /* set thickness to 0 (now it is a factor to override stroke thickness) */ - gpl->thickness = 0.0f; } - /* set first color as active */ - if (palette->colors.first) - BKE_gpencil_palettecolor_setactive(palette, palette->colors.first); } } } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 5b0a12a0b4c..7339f1977ff 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -54,16 +54,19 @@ #include "DNA_screen_types.h" #include "DNA_view3d_types.h" #include "DNA_genfile.h" +#include "DNA_gpencil_types.h" #include "DNA_workspace_types.h" #include "BKE_collection.h" #include "BKE_constraint.h" #include "BKE_customdata.h" +#include "BKE_colortools.h" #include "BKE_freestyle.h" #include "BKE_idprop.h" #include "BKE_image.h" #include "BKE_layer.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_node.h" #include "BKE_pointcache.h" @@ -73,6 +76,9 @@ #include "BKE_sequencer.h" #include "BKE_studiolight.h" #include "BKE_workspace.h" +#include "BKE_gpencil.h" +#include "BKE_paint.h" +#include "BKE_object.h" #include "BLO_readfile.h" #include "readfile.h" @@ -743,6 +749,7 @@ void do_versions_after_linking_280(Main *bmain) } } #endif + } /* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already. @@ -839,7 +846,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (ntree->type == NTREE_SHADER) { for (bNode *node = ntree->nodes.first; node; node = node->next) { if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && - STREQ(node->idname, "ShaderNodeOutputMetallic")) + STREQ(node->idname, "ShaderNodeOutputMetallic")) { BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname)); error |= NTREE_DOVERSION_NEED_OUTPUT; @@ -851,14 +858,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } else if (node->type == 196 /* SH_NODE_OUTPUT_EEVEE_MATERIAL */ && - STREQ(node->idname, "ShaderNodeOutputEeveeMaterial")) + STREQ(node->idname, "ShaderNodeOutputEeveeMaterial")) { node->type = SH_NODE_OUTPUT_MATERIAL; BLI_strncpy(node->idname, "ShaderNodeOutputMaterial", sizeof(node->idname)); } else if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && - STREQ(node->idname, "ShaderNodeEeveeMetallic")) + STREQ(node->idname, "ShaderNodeEeveeMetallic")) { node->type = SH_NODE_BSDF_PRINCIPLED; BLI_strncpy(node->idname, "ShaderNodeBsdfPrincipled", sizeof(node->idname)); @@ -869,10 +876,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } FOREACH_NODETREE_END - if (error & NTREE_DOVERSION_NEED_OUTPUT) { - BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console"); - printf("You need to connect Principled and Eevee Specular shader nodes to new material output nodes.\n"); - } + if (error & NTREE_DOVERSION_NEED_OUTPUT) { + BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console"); + printf("You need to connect Principled and Eevee Specular shader nodes to new material output nodes.\n"); + } if (error & NTREE_DOVERSION_TRANSPARENCY_EMISSION) { BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console"); @@ -896,6 +903,68 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } #endif + + { + /* Grease pencil sculpt and paint cursors */ + if (!DNA_struct_elem_find(fd->filesdna, "GP_BrushEdit_Settings", "int", "weighttype")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + /* sculpt brushes */ + GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; + if (gset) { + gset->weighttype = GP_EDITBRUSH_TYPE_WEIGHT; + } + } + } + + { + float curcolor_add[3], curcolor_sub[3]; + ARRAY_SET_ITEMS(curcolor_add, 1.0f, 0.6f, 0.6f); + ARRAY_SET_ITEMS(curcolor_sub, 0.6f, 0.6f, 1.0f); + GP_EditBrush_Data *gp_brush; + + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + ToolSettings *ts = scene->toolsettings; + /* sculpt brushes */ + GP_BrushEdit_Settings *gset = &ts->gp_sculpt; + for (int i = 0; i < TOT_GP_EDITBRUSH_TYPES; ++i) { + gp_brush = &gset->brush[i]; + gp_brush->flag |= GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(gp_brush->curcolor_add, curcolor_add); + copy_v3_v3(gp_brush->curcolor_sub, curcolor_sub); + } + } + } + + /* Init grease pencil edit line color */ + if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "float", "line_color[4]")) { + for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { + ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f); + } + } + + /* Init grease pencil pixel size factor */ + if (!DNA_struct_elem_find(fd->filesdna, "bGPDdata", "int", "pixfactor")) { + for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { + gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; + } + } + + /* Grease pencil multiframe falloff curve */ + if (!DNA_struct_elem_find(fd->filesdna, "GP_BrushEdit_Settings", "CurveMapping", "cur_falloff")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + /* sculpt brushes */ + GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; + if ((gset) && (gset->cur_falloff == NULL)) { + gset->cur_falloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + curvemapping_initialize(gset->cur_falloff); + curvemap_reset(gset->cur_falloff->cm, + &gset->cur_falloff->clipr, + CURVE_PRESET_GAUSS, + CURVEMAP_SLOPE_POSITIVE); + } + } + } + } } #ifdef USE_COLLECTION_COMPAT_28 @@ -915,6 +984,26 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } #endif + if (!MAIN_VERSION_ATLEAST(bmain, 280, 3)) { + /* init grease pencil grids and paper */ + if (!DNA_struct_elem_find(fd->filesdna, "gp_paper_opacity", "float", "gpencil_paper_color[3]")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *area = screen->areabase.first; area; area = area->next) { + for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_grid_scale = 1.0f; // Scale + v3d->overlay.gpencil_grid_lines = GP_DEFAULT_GRID_LINES; // NUmber of lines + v3d->overlay.gpencil_paper_opacity = 0.5f; + v3d->overlay.gpencil_grid_axis = V3D_GP_GRID_AXIS_Y; + v3d->overlay.gpencil_grid_opacity = 0.9f; + } + } + } + } + } + } + if (!MAIN_VERSION_ATLEAST(bmain, 280, 6)) { if (DNA_struct_elem_find(fd->filesdna, "SpaceOops", "int", "filter") == false) { bScreen *sc; @@ -1017,6 +1106,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) tex->type = 0; } } + } if (!MAIN_VERSION_ATLEAST(bmain, 280, 11)) { @@ -1643,6 +1733,101 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) BKE_screen_view3d_shading_init(&scene->display.shading); } } + /* initialize grease pencil view data */ + if (!DNA_struct_elem_find(fd->filesdna, "SpaceView3D", "float", "vertex_opacity")) { + for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->vertex_opacity = 1.0f; + v3d->flag3 |= V3D_GP_SHOW_EDIT_LINES; + } + } + } + } + } + + } + + if (!MAIN_VERSION_ATLEAST(bmain, 280, 22)) { + if (!DNA_struct_elem_find(fd->filesdna, "ToolSettings", "char", "annotate_v3d_align")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + scene->toolsettings->annotate_v3d_align = GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR; + scene->toolsettings->annotate_thickness = 3; + } + } + if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "short", "line_change")) { + for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + gpl->line_change = gpl->thickness; + if ((gpl->thickness < 1) || (gpl->thickness > 10)) { + gpl->thickness = 3; + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_grid_scale")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_grid_scale = 1.0f; + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_paper_opacity")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_paper_opacity = 0.5f; + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_grid_opacity")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_grid_opacity = 0.5f; + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "int", "gpencil_grid_axis")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_grid_axis = V3D_GP_GRID_AXIS_Y; + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "int", "gpencil_grid_lines")) { + for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.gpencil_grid_lines = GP_DEFAULT_GRID_LINES; + } + } + } + } + } + } } diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index bd7334516ca..a86986e2e09 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -170,46 +170,77 @@ void BLO_update_defaults_startup_blend(Main *bmain) if (ts->gp_sculpt.brush[0].size == 0) { GP_BrushEdit_Settings *gset = &ts->gp_sculpt; GP_EditBrush_Data *brush; + float curcolor_add[3], curcolor_sub[3]; + ARRAY_SET_ITEMS(curcolor_add, 1.0f, 0.6f, 0.6f); + ARRAY_SET_ITEMS(curcolor_sub, 0.6f, 0.6f, 1.0f); + + /* default sculpt brush */ + gset->brushtype = GP_EDITBRUSH_TYPE_PUSH; + /* default weight paint brush */ + gset->weighttype = GP_EDITBRUSH_TYPE_WEIGHT; brush = &gset->brush[GP_EDITBRUSH_TYPE_SMOOTH]; brush->size = 25; brush->strength = 0.3f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_THICKNESS]; brush->size = 25; brush->strength = 0.5f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_STRENGTH]; brush->size = 25; brush->strength = 0.5f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_GRAB]; brush->size = 50; brush->strength = 0.3f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_PUSH]; brush->size = 25; brush->strength = 0.3f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_TWIST]; brush->size = 50; brush->strength = 0.3f; // XXX? - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_PINCH]; brush->size = 50; brush->strength = 0.5f; // XXX? - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE]; brush->size = 25; brush->strength = 0.5f; - brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); + + brush = &gset->brush[GP_EDITBRUSH_TYPE_WEIGHT]; + brush->size = 25; + brush->strength = 0.5f; + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF | GP_EDITBRUSH_FLAG_ENABLE_CURSOR; + copy_v3_v3(brush->curcolor_add, curcolor_add); + copy_v3_v3(brush->curcolor_sub, curcolor_sub); } ts->gpencil_v3d_align = GP_PROJECT_VIEWSPACE; @@ -217,6 +248,9 @@ void BLO_update_defaults_startup_blend(Main *bmain) ts->gpencil_seq_align = GP_PROJECT_VIEWSPACE; ts->gpencil_ima_align = GP_PROJECT_VIEWSPACE; + ts->annotate_v3d_align = GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR; + ts->annotate_thickness = 3; + ParticleEditSettings *pset = &ts->particle; for (int a = 0; a < ARRAY_SIZE(pset->brush); a++) { pset->brush[a].strength = 0.5f; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 503f8b44ec3..3883e024ab7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -118,6 +118,8 @@ #include "DNA_genfile.h" #include "DNA_group_types.h" #include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_fileglobal_types.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" @@ -165,6 +167,7 @@ #include "BKE_collection.h" #include "BKE_constraint.h" #include "BKE_global.h" // for G +#include "BKE_gpencil_modifier.h" #include "BKE_idcode.h" #include "BKE_layer.h" #include "BKE_library.h" // for set_listbasepointers @@ -173,6 +176,7 @@ #include "BKE_node.h" #include "BKE_report.h" #include "BKE_sequencer.h" +#include "BKE_shader_fx.h" #include "BKE_subsurf.h" #include "BKE_modifier.h" #include "BKE_fcurve.h" @@ -1788,6 +1792,57 @@ static void write_modifiers(WriteData *wd, ListBase *modbase) } } +static void write_gpencil_modifiers(WriteData *wd, ListBase *modbase) +{ + GpencilModifierData *md; + + if (modbase == NULL) { + return; + } + + for (md = modbase->first; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + if (mti == NULL) { + return; + } + + writestruct_id(wd, DATA, mti->struct_name, 1, md); + + if (md->type == eGpencilModifierType_Thick) { + ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; + + if (gpmd->curve_thickness) { + write_curvemapping(wd, gpmd->curve_thickness); + } + } + else if (md->type == eGpencilModifierType_Hook) { + HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md; + + if (gpmd->curfalloff) { + write_curvemapping(wd, gpmd->curfalloff); + } + } + } +} + +static void write_shaderfxs(WriteData *wd, ListBase *fxbase) +{ + ShaderFxData *fx; + + if (fxbase == NULL) { + return; + } + + for (fx = fxbase->first; fx; fx = fx->next) { + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(fx->type); + if (fxi == NULL) { + return; + } + + writestruct_id(wd, DATA, fxi->struct_name, 1, fx); + } +} + static void write_object(WriteData *wd, Object *ob) { if (ob->id.us > 0 || wd->use_memfile) { @@ -1842,6 +1897,8 @@ static void write_object(WriteData *wd, Object *ob) write_particlesystems(wd, &ob->particlesystem); write_modifiers(wd, &ob->modifiers); + write_gpencil_modifiers(wd, &ob->greasepencil_modifiers); + write_shaderfxs(wd, &ob->shader_fx); writelist(wd, DATA, LinkData, &ob->pc_ids); writelist(wd, DATA, LodLevel, &ob->lodlevels); @@ -2260,6 +2317,11 @@ static void write_material(WriteData *wd, Material *ma) } write_previews(wd, ma->preview); + + /* grease pencil settings */ + if (ma->gp_style) { + writestruct(wd, DATA, MaterialGPencilStyle, 1, ma->gp_style); + } } } @@ -2463,24 +2525,18 @@ static void write_scene(WriteData *wd, Scene *sce) writestruct(wd, DATA, UvSculpt, 1, tos->uvsculpt); write_paint(wd, &tos->uvsculpt->paint); } - /* write grease-pencil drawing brushes to file */ - writelist(wd, DATA, bGPDbrush, &tos->gp_brushes); - for (bGPDbrush *brush = tos->gp_brushes.first; brush; brush = brush->next) { - if (brush->cur_sensitivity) { - write_curvemapping(wd, brush->cur_sensitivity); - } - if (brush->cur_strength) { - write_curvemapping(wd, brush->cur_strength); - } - if (brush->cur_jitter) { - write_curvemapping(wd, brush->cur_jitter); - } + if (tos->gp_paint) { + writestruct(wd, DATA, GpPaint, 1, tos->gp_paint); + write_paint(wd, &tos->gp_paint->paint); } /* write grease-pencil custom ipo curve to file */ if (tos->gp_interpolate.custom_ipo) { write_curvemapping(wd, tos->gp_interpolate.custom_ipo); } - + /* write grease-pencil multiframe falloff curve to file */ + if (tos->gp_sculpt.cur_falloff) { + write_curvemapping(wd, tos->gp_sculpt.cur_falloff); + } write_paint(wd, &tos->imapaint.paint); @@ -2654,6 +2710,8 @@ static void write_gpencil(WriteData *wd, bGPdata *gpd) write_animdata(wd, gpd->adt); } + writedata(wd, DATA, sizeof(void *) * gpd->totcol, gpd->mat); + /* write grease-pencil layers to file */ writelist(wd, DATA, bGPDlayer, &gpd->layers); for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { @@ -2664,15 +2722,10 @@ static void write_gpencil(WriteData *wd, bGPdata *gpd) writelist(wd, DATA, bGPDstroke, &gpf->strokes); for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { writestruct(wd, DATA, bGPDspoint, gps->totpoints, gps->points); + write_dverts(wd, gps->totpoints, gps->dvert); } } } - - /* write grease-pencil palettes */ - writelist(wd, DATA, bGPDpalette, &gpd->palettes); - for (bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) { - writelist(wd, DATA, bGPDpalettecolor, &palette->colors); - } } } @@ -3159,6 +3212,20 @@ static void write_brush(WriteData *wd, Brush *brush) if (brush->curve) { write_curvemapping(wd, brush->curve); } + + if (brush->gpencil_settings) { + writestruct(wd, DATA, BrushGpencilSettings, 1, brush->gpencil_settings); + + if (brush->gpencil_settings->curve_sensitivity) { + write_curvemapping(wd, brush->gpencil_settings->curve_sensitivity); + } + if (brush->gpencil_settings->curve_strength) { + write_curvemapping(wd, brush->gpencil_settings->curve_strength); + } + if (brush->gpencil_settings->curve_jitter) { + write_curvemapping(wd, brush->gpencil_settings->curve_jitter); + } + } if (brush->gradient) { writestruct(wd, DATA, ColorBand, 1, brush->gradient); } diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 47d8f4f52bb..248c780102c 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -69,6 +69,7 @@ void SceneExporter::exportHierarchy(bContext *C, Depsgraph *depsgraph, Scene *sc case OB_CAMERA: case OB_LAMP: case OB_EMPTY: + case OB_GPENCIL: case OB_ARMATURE: base_objects.push_back(ob); break; @@ -122,6 +123,7 @@ void SceneExporter::writeNodes(bContext *C, Depsgraph *depsgraph, Object *ob, Sc case OB_CAMERA: case OB_LAMP: case OB_EMPTY: + case OB_GPENCIL: case OB_ARMATURE: if (bc_is_marked(cob)) child_objects.push_back(cob); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 1b68a73bbd7..e20b589bf22 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -77,6 +77,8 @@ extern "C" { #include "BKE_curve.h" #include "BKE_effect.h" #include "BKE_fcurve.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" #include "BKE_idcode.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -93,6 +95,7 @@ extern "C" { #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_rigidbody.h" +#include "BKE_shader_fx.h" #include "BKE_sound.h" #include "BKE_tracking.h" #include "BKE_world.h" @@ -514,6 +517,18 @@ void DepsgraphNodeBuilder::build_object(int base_index, data.builder = this; modifiers_foreachIDLink(object, modifier_walk, &data); } + /* Grease Pencil Modifiers. */ + if (object->greasepencil_modifiers.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data); + } + /* Shadr FX. */ + if (object->shader_fx.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + BKE_shaderfx_foreachIDLink(object, modifier_walk, &data); + } /* Constraints. */ if (object->constraints.first != NULL) { BuilderWalkUserData data; @@ -538,10 +553,6 @@ void DepsgraphNodeBuilder::build_object(int base_index, if (object->particlesystem.first != NULL) { build_particles(object); } - /* Grease pencil. */ - if (object->gpd != NULL) { - build_gpencil(object->gpd); - } /* Proxy object to copy from. */ if (object->proxy_from != NULL) { build_object(-1, object->proxy_from, DEG_ID_LINKED_INDIRECTLY); @@ -592,6 +603,7 @@ void DepsgraphNodeBuilder::build_object_data(Object *object) case OB_SURF: case OB_MBALL: case OB_LATTICE: + case OB_GPENCIL: build_object_data_geometry(object); /* TODO(sergey): Only for until we support granular * update of curves. @@ -1213,6 +1225,20 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata) op_node->set_as_entry(); break; } + + case ID_GD: + { + /* GPencil evaluation operations. */ + op_node = add_operation_node(obdata, + DEG_NODE_TYPE_GEOMETRY, + function_bind(BKE_gpencil_eval_geometry, + _1, + (bGPdata *)obdata_cow), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); + op_node->set_as_entry(); + break; + } default: BLI_assert(!"Should not happen"); break; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index f1db05b7220..3d7b2d6d232 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -134,10 +134,6 @@ void DepsgraphNodeBuilder::build_view_layer( if (scene->nodetree != NULL) { build_compositor(scene); } - /* Grease pencil. */ - if (scene->gpd != NULL) { - build_gpencil(scene->gpd); - } /* Cache file. */ LISTBASE_FOREACH (CacheFile *, cachefile, &bmain_->cachefiles) { build_cachefile(cachefile); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 1a0c621ab43..c9a00b0bf0f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -85,10 +85,12 @@ extern "C" { #include "BKE_material.h" #include "BKE_mball.h" #include "BKE_modifier.h" +#include "BKE_gpencil_modifier.h" #include "BKE_node.h" #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_rigidbody.h" +#include "BKE_shader_fx.h" #include "BKE_sound.h" #include "BKE_tracking.h" #include "BKE_world.h" @@ -525,6 +527,18 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) data.builder = this; modifiers_foreachIDLink(object, modifier_walk, &data); } + /* Grease Pencil Modifiers. */ + if (object->greasepencil_modifiers.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + BKE_gpencil_modifiers_foreachIDLink(object, modifier_walk, &data); + } + /* Shader FX. */ + if (object->shader_fx.first != NULL) { + BuilderWalkUserData data; + data.builder = this; + BKE_shaderfx_foreachIDLink(object, modifier_walk, &data); + } /* Constraints. */ if (object->constraints.first != NULL) { BuilderWalkUserData data; @@ -570,10 +584,6 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) if (object->particlesystem.first != NULL) { build_particles(object); } - /* Grease pencil. */ - if (object->gpd != NULL) { - build_gpencil(object->gpd); - } /* Proxy object to copy from. */ if (object->proxy_from != NULL) { build_object(NULL, object->proxy_from); @@ -630,6 +640,7 @@ void DepsgraphRelationBuilder::build_object_data(Object *object) case OB_SURF: case OB_MBALL: case OB_LATTICE: + case OB_GPENCIL: { build_object_data_geometry(object); break; @@ -1798,6 +1809,42 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object) } } } + /* Grease Pencil Modifiers */ + if (object->greasepencil_modifiers.first != NULL) { + ModifierUpdateDepsgraphContext ctx = {}; + ctx.scene = scene_; + ctx.object = object; + LISTBASE_FOREACH(GpencilModifierData *, md, &object->greasepencil_modifiers) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo((GpencilModifierType)md->type); + if (mti->updateDepsgraph) { + DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); + ctx.node = reinterpret_cast< ::DepsNodeHandle* >(&handle); + mti->updateDepsgraph(md, &ctx); + } + if (BKE_object_modifier_gpencil_use_time(object, md)) { + TimeSourceKey time_src_key; + add_relation(time_src_key, obdata_ubereval_key, "Time Source"); + } + } + } + /* Shader FX */ + if (object->shader_fx.first != NULL) { + ModifierUpdateDepsgraphContext ctx = {}; + ctx.scene = scene_; + ctx.object = object; + LISTBASE_FOREACH(ShaderFxData *, fx, &object->shader_fx) { + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo((ShaderFxType)fx->type); + if (fxi->updateDepsgraph) { + DepsNodeHandle handle = create_node_handle(obdata_ubereval_key); + ctx.node = reinterpret_cast< ::DepsNodeHandle* >(&handle); + fxi->updateDepsgraph(fx, &ctx); + } + if (BKE_object_shaderfx_use_time(object, fx)) { + TimeSourceKey time_src_key; + add_relation(time_src_key, obdata_ubereval_key, "Time Source"); + } + } + } /* Materials. */ if (object->totcol) { for (int a = 1; a <= object->totcol; a++) { @@ -1895,13 +1942,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) } /* Link object data evaluation node to exit operation. */ OperationKey obdata_geom_eval_key(obdata, - DEG_NODE_TYPE_GEOMETRY, - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); OperationKey obdata_geom_done_key(obdata, - DEG_NODE_TYPE_GEOMETRY, - DEG_OPCODE_PLACEHOLDER, - "Eval Done"); + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_PLACEHOLDER, + "Eval Done"); add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done"); @@ -1917,35 +1964,67 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) Curve *cu = (Curve *)obdata; if (cu->bevobj != NULL) { ComponentKey bevob_geom_key(&cu->bevobj->id, - DEG_NODE_TYPE_GEOMETRY); + DEG_NODE_TYPE_GEOMETRY); add_relation(bevob_geom_key, - obdata_geom_eval_key, - "Curve Bevel Geometry"); + obdata_geom_eval_key, + "Curve Bevel Geometry"); ComponentKey bevob_key(&cu->bevobj->id, - DEG_NODE_TYPE_TRANSFORM); + DEG_NODE_TYPE_TRANSFORM); add_relation(bevob_key, - obdata_geom_eval_key, - "Curve Bevel Transform"); + obdata_geom_eval_key, + "Curve Bevel Transform"); build_object(NULL, cu->bevobj); } if (cu->taperobj != NULL) { ComponentKey taperob_key(&cu->taperobj->id, - DEG_NODE_TYPE_GEOMETRY); + DEG_NODE_TYPE_GEOMETRY); add_relation(taperob_key, obdata_geom_eval_key, "Curve Taper"); build_object(NULL, cu->taperobj); } if (cu->textoncurve != NULL) { ComponentKey textoncurve_key(&cu->textoncurve->id, - DEG_NODE_TYPE_GEOMETRY); + DEG_NODE_TYPE_GEOMETRY); add_relation(textoncurve_key, - obdata_geom_eval_key, - "Text on Curve"); + obdata_geom_eval_key, + "Text on Curve"); build_object(NULL, cu->textoncurve); } break; } case ID_LT: break; + case ID_GD: /* Grease Pencil */ + { + bGPdata *gpd = (bGPdata *)obdata; + + /* Geometry cache needs to be recalculated on frame change + * (e.g. to fix crashes after scrubbing the timeline when + * onion skinning is enabled, since the ghosts need to be + * re-added to the cache once scrubbing ends) + */ + TimeSourceKey time_key; + ComponentKey geometry_key(obdata, DEG_NODE_TYPE_GEOMETRY); + add_relation(time_key, + geometry_key, + "GP Frame Change"); + + /* Geometry cache also needs to be recalculated when Material + * settings change (e.g. when fill.opacity changes on/off, + * we need to rebuild the bGPDstroke->triangles caches) + */ + for (int i = 0; i < gpd->totcol; i++) { + Material *ma = gpd->mat[i]; + if ((ma != NULL) && (ma->gp_style != NULL)) { + OperationKey material_key(&ma->id, + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); + add_relation(material_key, + geometry_key, + "Material -> GP Data"); + } + } + break; + } default: BLI_assert(!"Should not happen"); break; @@ -2228,6 +2307,11 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDDepsNode *id_node if (id_type == ID_ME && comp_node->type == DEG_NODE_TYPE_GEOMETRY) { rel_flag &= ~DEPSREL_FLAG_NO_FLUSH; } + /* materials need update grease pencil objects */ + if (id_type == ID_MA) { + rel_flag &= ~DEPSREL_FLAG_NO_FLUSH; + } + /* Notes on exceptions: * - Parameters component is where drivers are living. Changing any * of the (custom) properties in the original datablock (even the diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index f069c63f138..78d1a930eb7 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -123,10 +123,6 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la if (scene->nodetree != NULL) { build_compositor(scene); } - /* Grease pencil. */ - if (scene->gpd != NULL) { - build_gpencil(scene->gpd); - } /* Masks. */ LISTBASE_FOREACH (Mask *, mask, &bmain_->mask) { build_mask(mask); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 4229f8bf9a2..e4659a7a94d 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -100,6 +100,7 @@ void depsgraph_geometry_tag_to_component(const ID *id, case OB_FONT: case OB_LATTICE: case OB_MBALL: + case OB_GPENCIL: *component_type = DEG_NODE_TYPE_GEOMETRY; break; case OB_ARMATURE: @@ -112,11 +113,17 @@ void depsgraph_geometry_tag_to_component(const ID *id, case ID_ME: *component_type = DEG_NODE_TYPE_GEOMETRY; break; - case ID_PA: + case ID_PA: /* Particles */ return; case ID_LP: *component_type = DEG_NODE_TYPE_PARAMETERS; break; + case ID_GD: + *component_type = DEG_NODE_TYPE_GEOMETRY; + break; + case ID_PAL: /* Palettes */ + *component_type = DEG_NODE_TYPE_PARAMETERS; + break; default: break; } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 6ec7b03501b..d672645dea0 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -123,6 +123,13 @@ set(SRC engines/workbench/solid_mode.c engines/workbench/transparent_mode.c engines/external/external_engine.c + engines/gpencil/gpencil_engine.h + engines/gpencil/gpencil_engine.c + engines/gpencil/gpencil_render.c + engines/gpencil/gpencil_cache_utils.c + engines/gpencil/gpencil_draw_utils.c + engines/gpencil/gpencil_draw_cache_impl.c + engines/gpencil/gpencil_shader_fx.c DRW_engine.h intern/DRW_render.h @@ -303,6 +310,33 @@ data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC) data_to_c_simple(modes/shaders/volume_velocity_vert.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_fill_vert.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_fill_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_vert.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_geom.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_simple_mix_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_point_vert.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_point_geom.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_point_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_background_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_paper_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_edit_point_vert.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_edit_point_geom.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/gpencil_edit_point_frag.glsl SRC) + +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl SRC) +data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC) + + list(APPEND INC ) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 4d4b486d247..6d8e8a69e29 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -126,6 +126,9 @@ void DRW_draw_depth_loop( struct Depsgraph *depsgraph, struct ARegion *ar, struct View3D *v3d); +/* grease pencil render */ +void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph); + /* This is here because GPUViewport needs it */ void DRW_pass_free(struct DRWPass *pass); struct DRWInstanceDataList *DRW_instance_data_list_create(void); diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c new file mode 100644 index 00000000000..4e01c42d33d --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c @@ -0,0 +1,296 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_cache_utils.c + * \ingroup draw + */ + +#include "DRW_render.h" + +#include "BKE_global.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#include "DNA_gpencil_types.h" +#include "DNA_view3d_types.h" + +#include "gpencil_engine.h" + +#include "draw_cache_impl.h" + + /* add a gpencil object to cache to defer drawing */ +tGPencilObjectCache *gpencil_object_cache_add(tGPencilObjectCache *cache_array, Object *ob, bool is_temp, + int *gp_cache_size, int *gp_cache_used) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + tGPencilObjectCache *cache_elem = NULL; + RegionView3D *rv3d = draw_ctx->rv3d; + tGPencilObjectCache *p = NULL; + + /* By default a cache is created with one block with a predefined number of free slots, + if the size is not enough, the cache is reallocated adding a new block of free slots. + This is done in order to keep cache small */ + if (*gp_cache_used + 1 > *gp_cache_size) { + if ((*gp_cache_size == 0) || (cache_array == NULL)) { + p = MEM_callocN(sizeof(struct tGPencilObjectCache) * GP_CACHE_BLOCK_SIZE, "tGPencilObjectCache"); + *gp_cache_size = GP_CACHE_BLOCK_SIZE; + } + else { + *gp_cache_size += GP_CACHE_BLOCK_SIZE; + p = MEM_recallocN(cache_array, sizeof(struct tGPencilObjectCache) * *gp_cache_size); + } + cache_array = p; + } + + /* zero out all pointers */ + cache_elem = &cache_array[*gp_cache_used]; + memset(cache_elem, 0, sizeof(*cache_elem)); + + /* save object */ + cache_elem->ob = ob; + cache_elem->temp_ob = is_temp; + cache_elem->idx = *gp_cache_used; + + cache_elem->init_grp = 0; + cache_elem->end_grp = -1; + + /* calculate zdepth from point of view */ + float zdepth = 0.0; + if (rv3d) { + if (rv3d->is_persp) { + zdepth = ED_view3d_calc_zfac(rv3d, ob->loc, NULL); + } + else { + zdepth = -dot_v3v3(rv3d->viewinv[2], ob->loc); + } + } + else { + /* In render mode, rv3d is not available, so use the distance to camera. + * The real distance is not important, but the relative distance to the camera plane + * in order to sort by z_depth of the objects + */ + float vn[3] = { 0.0f, 0.0f, -1.0f }; /* always face down */ + float plane_cam[4]; + struct Object *camera = draw_ctx->scene->camera; + if (camera) { + mul_m4_v3(camera->obmat, vn); + normalize_v3(vn); + plane_from_point_normal_v3(plane_cam, camera->loc, vn); + zdepth = dist_squared_to_plane_v3(ob->loc, plane_cam); + } + } + cache_elem->zdepth = zdepth; + /* increase slots used in cache */ + (*gp_cache_used)++; + + return cache_array; +} + +/* get current cache data */ +static GpencilBatchCache *gpencil_batch_get_element(Object *ob) +{ + bGPdata *gpd = ob->data; + if (gpd->runtime.batch_cache_data == NULL) { + gpd->runtime.batch_cache_data = BLI_ghash_str_new("GP batch cache data"); + return NULL; + } + + return (GpencilBatchCache *) BLI_ghash_lookup(gpd->runtime.batch_cache_data, ob->id.name); +} + +/* verify if cache is valid */ +static bool gpencil_batch_cache_valid(Object *ob, bGPdata *gpd, int cfra) +{ + GpencilBatchCache *cache = gpencil_batch_get_element(ob); + + if (cache == NULL) { + return false; + } + + cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd); + + if (cfra != cache->cache_frame) { + return false; + } + + if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) { + return false; + } + + if (cache->is_editmode) { + return false; + } + + if (cache->is_dirty) { + return false; + } + + return true; +} + +/* resize the cache to the number of slots */ +static void gpencil_batch_cache_resize(GpencilBatchCache *cache, int slots) +{ + cache->cache_size = slots; + cache->batch_stroke = MEM_recallocN(cache->batch_stroke, sizeof(struct Gwn_Batch *) * slots); + cache->batch_fill = MEM_recallocN(cache->batch_fill, sizeof(struct Gwn_Batch *) * slots); + cache->batch_edit = MEM_recallocN(cache->batch_edit, sizeof(struct Gwn_Batch *) * slots); + cache->batch_edlin = MEM_recallocN(cache->batch_edlin, sizeof(struct Gwn_Batch *) * slots); +} + +/* check size and increase if no free slots */ +void gpencil_batch_cache_check_free_slots(Object *ob) +{ + GpencilBatchCache *cache = gpencil_batch_get_element(ob); + + /* the memory is reallocated by chunks, not for one slot only to improve speed */ + if (cache->cache_idx >= cache->cache_size) { + cache->cache_size += GPENCIL_MIN_BATCH_SLOTS_CHUNK; + gpencil_batch_cache_resize(cache, cache->cache_size); + } +} + +/* cache init */ +static void gpencil_batch_cache_init(Object *ob, int cfra) +{ + GpencilBatchCache *cache = gpencil_batch_get_element(ob); + bGPdata *gpd = ob->data; + + if (G.debug_value >= 664) { + printf("gpencil_batch_cache_init: %s\n", ob->id.name); + } + + if (!cache) { + cache = MEM_callocN(sizeof(*cache), __func__); + BLI_ghash_insert(gpd->runtime.batch_cache_data, ob->id.name, cache); + } + else { + memset(cache, 0, sizeof(*cache)); + } + + cache->cache_size = GPENCIL_MIN_BATCH_SLOTS_CHUNK; + cache->batch_stroke = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Stroke"); + cache->batch_fill = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Fill"); + cache->batch_edit = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Edit"); + cache->batch_edlin = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Edlin"); + + cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd); + gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY; + + cache->cache_idx = 0; + cache->is_dirty = true; + cache->cache_frame = cfra; +} + +/* clear cache */ +static void gpencil_batch_cache_clear(GpencilBatchCache *cache, bGPdata *gpd) +{ + if (!cache) { + return; + } + + if (cache->cache_size == 0) { + return; + } + + if (G.debug_value >= 664) { + printf("gpencil_batch_cache_clear: %s\n", gpd->id.name); + } + + if (cache->cache_size > 0) { + for (int i = 0; i < cache->cache_size; i++) { + GPU_BATCH_DISCARD_SAFE(cache->batch_stroke[i]); + GPU_BATCH_DISCARD_SAFE(cache->batch_fill[i]); + GPU_BATCH_DISCARD_SAFE(cache->batch_edit[i]); + GPU_BATCH_DISCARD_SAFE(cache->batch_edlin[i]); + } + MEM_SAFE_FREE(cache->batch_stroke); + MEM_SAFE_FREE(cache->batch_fill); + MEM_SAFE_FREE(cache->batch_edit); + MEM_SAFE_FREE(cache->batch_edlin); + } + + MEM_SAFE_FREE(cache); +} + +/* get cache */ +GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra) +{ + bGPdata *gpd = ob->data; + + if (!gpencil_batch_cache_valid(ob, gpd, cfra)) { + if (G.debug_value >= 664) { + printf("gpencil_batch_cache: %s\n", gpd->id.name); + } + + GpencilBatchCache *cache = gpencil_batch_get_element(ob); + if (cache) { + gpencil_batch_cache_clear(cache, gpd); + BLI_ghash_remove(gpd->runtime.batch_cache_data, ob->id.name, NULL, NULL); + } + gpencil_batch_cache_init(ob, cfra); + } + + return gpencil_batch_get_element(ob); +} + +/* set cache as dirty */ +void DRW_gpencil_batch_cache_dirty(bGPdata *gpd) +{ + if (gpd->runtime.batch_cache_data == NULL) { + return; + } + + GHashIterator *ihash = BLI_ghashIterator_new(gpd->runtime.batch_cache_data); + while (!BLI_ghashIterator_done(ihash)) { + GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash); + if (cache) { + cache->is_dirty = true; + } + BLI_ghashIterator_step(ihash); + } + BLI_ghashIterator_free(ihash); +} + +/* free batch cache */ +void DRW_gpencil_batch_cache_free(bGPdata *gpd) +{ + if (gpd->runtime.batch_cache_data == NULL) { + return; + } + + GHashIterator *ihash = BLI_ghashIterator_new(gpd->runtime.batch_cache_data); + while (!BLI_ghashIterator_done(ihash)) { + GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash); + if (cache) { + gpencil_batch_cache_clear(cache, gpd); + } + BLI_ghashIterator_step(ihash); + } + BLI_ghashIterator_free(ihash); + + /* free hash */ + if (gpd->runtime.batch_cache_data) { + BLI_ghash_free(gpd->runtime.batch_cache_data, NULL, NULL); + gpd->runtime.batch_cache_data = NULL; + } +} diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c new file mode 100644 index 00000000000..dd5db85f3f4 --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c @@ -0,0 +1,739 @@ +/* + * ***** 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) 2008, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file draw/engines/gpencil/gpencil_draw_cache_impl.c + * \ingroup draw + */ + +#include "BLI_polyfill_2d.h" +#include "BLI_math_color.h" + +#include "DNA_meshdata_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_gpencil.h" +#include "BKE_action.h" + +#include "DRW_render.h" + +#include "GPU_immediate.h" +#include "GPU_draw.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#include "UI_resources.h" + +#include "gpencil_engine.h" + +/* Helper to add stroke point to vbo */ +static void gpencil_set_stroke_point( + GPUVertBuf *vbo, float matrix[4][4], const bGPDspoint *pt, int idx, + uint pos_id, uint color_id, + uint thickness_id, uint uvdata_id, short thickness, + const float ink[4]) +{ + float viewfpt[3]; + + float alpha = ink[3] * pt->strength; + CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); + float col[4]; + ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha); + + GPU_vertbuf_attr_set(vbo, color_id, idx, col); + + /* transfer both values using the same shader variable */ + float uvdata[2] = { pt->uv_fac, pt->uv_rot }; + GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata); + + /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */ + mul_v3_m4v3(viewfpt, matrix, &pt->x); + float thick = max_ff(pt->pressure * thickness, 1.0f); + GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick); + + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); +} + +/* Helper to add a new fill point and texture coordinates to vertex buffer */ +static void gpencil_set_fill_point( + GPUVertBuf *vbo, int idx, bGPDspoint *pt, const float fcolor[4], float uv[2], + uint pos_id, uint color_id, uint text_id) +{ + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); + GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor); + GPU_vertbuf_attr_set(vbo, text_id, idx, uv); +} + +/* create batch geometry data for points stroke shader */ +GPUBatch *DRW_gpencil_get_point_geom(bGPDstroke *gps, short thickness, const float ink[4]) +{ + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, size_id, uvdata_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + size_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, gps->totpoints); + + /* draw stroke curve */ + const bGPDspoint *pt = gps->points; + int idx = 0; + float alpha; + float col[4]; + + for (int i = 0; i < gps->totpoints; i++, pt++) { + /* set point */ + alpha = ink[3] * pt->strength; + CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); + ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha); + + float thick = max_ff(pt->pressure * thickness, 1.0f); + + GPU_vertbuf_attr_set(vbo, color_id, idx, col); + GPU_vertbuf_attr_set(vbo, size_id, idx, &thick); + + /* transfer both values using the same shader variable */ + float uvdata[2] = { pt->uv_fac, pt->uv_rot }; + GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata); + + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); + idx++; + } + + return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* create batch geometry data for stroke shader */ +GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thickness, const float ink[4]) +{ + bGPDspoint *points = gps->points; + int totpoints = gps->totpoints; + /* if cyclic needs more vertex */ + int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 1 : 0; + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, thickness_id, uvdata_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, totpoints + cyclic_add + 2); + + /* draw stroke curve */ + const bGPDspoint *pt = points; + int idx = 0; + for (int i = 0; i < totpoints; i++, pt++) { + /* first point for adjacency (not drawn) */ + if (i == 0) { + if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[totpoints - 1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + idx++; + } + else { + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + idx++; + } + } + /* set point */ + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + idx++; + } + + if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { + /* draw line to first point to complete the cycle */ + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[0], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + idx++; + /* now add adjacency point (not drawn) */ + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + idx++; + } + /* last adjacency point (not drawn) */ + else { + gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[totpoints - 2], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + } + + return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* create batch geometry data for current buffer stroke shader */ +GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], short thickness) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; + ARegion *ar = draw_ctx->ar; + RegionView3D *rv3d = draw_ctx->rv3d; + ToolSettings *ts = scene->toolsettings; + Object *ob = draw_ctx->obact; + + tGPspoint *points = gpd->runtime.sbuffer; + int totpoints = gpd->runtime.sbuffer_size; + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, thickness_id, uvdata_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, totpoints + 2); + + /* draw stroke curve */ + const tGPspoint *tpt = points; + bGPDspoint pt, pt2; + int idx = 0; + + /* get origin to reproject point */ + float origin[3]; + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + ED_gp_get_drawing_reference(v3d, scene, ob, gpl, ts->gpencil_v3d_align, origin); + + for (int i = 0; i < totpoints; i++, tpt++) { + ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt); + ED_gp_project_point_to_plane(ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt); + + /* first point for adjacency (not drawn) */ + if (i == 0) { + if (totpoints > 1) { + ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2); + gpencil_set_stroke_point(vbo, matrix, &pt2, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + } + else { + gpencil_set_stroke_point(vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + } + idx++; + } + /* set point */ + gpencil_set_stroke_point(vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + idx++; + } + + /* last adjacency point (not drawn) */ + if (totpoints > 2) { + ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2); + gpencil_set_stroke_point(vbo, matrix, &pt2, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + } + else { + gpencil_set_stroke_point(vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + } + + return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* create batch geometry data for current buffer point shader */ +GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, float matrix[4][4], short thickness) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; + ARegion *ar = draw_ctx->ar; + RegionView3D *rv3d = draw_ctx->rv3d; + ToolSettings *ts = scene->toolsettings; + Object *ob = draw_ctx->obact; + + tGPspoint *points = gpd->runtime.sbuffer; + int totpoints = gpd->runtime.sbuffer_size; + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, thickness_id, uvdata_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, totpoints); + + /* draw stroke curve */ + const tGPspoint *tpt = points; + bGPDspoint pt; + int idx = 0; + + /* get origin to reproject point */ + float origin[3]; + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + ED_gp_get_drawing_reference(v3d, scene, ob, gpl, ts->gpencil_v3d_align, origin); + + for (int i = 0; i < totpoints; i++, tpt++) { + ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt); + ED_gp_project_point_to_plane(ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt); + + /* set point */ + gpencil_set_stroke_point(vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, + thickness, gpd->runtime.scolor); + idx++; + } + + return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* create batch geometry data for current buffer fill shader */ +GPUBatch *DRW_gpencil_get_buffer_fill_geom(bGPdata *gpd) +{ + if (gpd == NULL) { + return NULL; + } + + const tGPspoint *points = gpd->runtime.sbuffer; + int totpoints = gpd->runtime.sbuffer_size; + if (totpoints < 3) { + return NULL; + } + + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; + ARegion *ar = draw_ctx->ar; + ToolSettings *ts = scene->toolsettings; + Object *ob = draw_ctx->obact; + + /* get origin to reproject point */ + float origin[3]; + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + ED_gp_get_drawing_reference(v3d, scene, ob, gpl, ts->gpencil_v3d_align, origin); + + int tot_triangles = totpoints - 2; + /* allocate memory for temporary areas */ + uint (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, __func__); + float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__); + + /* Convert points to array and triangulate + * Here a cache is not used because while drawing the information changes all the time, so the cache + * would be recalculated constantly, so it is better to do direct calculation for each function call + */ + for (int i = 0; i < totpoints; i++) { + const tGPspoint *pt = &points[i]; + points2d[i][0] = pt->x; + points2d[i][1] = pt->y; + } + BLI_polyfill_calc(points2d, (uint)totpoints, 0, tmp_triangles); + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + + /* draw triangulation data */ + if (tot_triangles > 0) { + GPU_vertbuf_data_alloc(vbo, tot_triangles * 3); + + const tGPspoint *tpt; + bGPDspoint pt; + + int idx = 0; + for (int i = 0; i < tot_triangles; i++) { + for (int j = 0; j < 3; j++) { + tpt = &points[tmp_triangles[i][j]]; + ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt); + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt.x); + GPU_vertbuf_attr_set(vbo, color_id, idx, gpd->runtime.sfill); + idx++; + } + } + } + + /* clear memory */ + if (tmp_triangles) { + MEM_freeN(tmp_triangles); + } + if (points2d) { + MEM_freeN(points2d); + } + + return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* create batch geometry data for stroke shader */ +GPUBatch *DRW_gpencil_get_fill_geom(Object *ob, bGPDstroke *gps, const float color[4]) +{ + BLI_assert(gps->totpoints >= 3); + + /* Calculate triangles cache for filling area (must be done only after changes) */ + if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) { + DRW_gpencil_triangulate_stroke_fill(gps); + ED_gpencil_calc_stroke_uv(ob, gps); + } + + BLI_assert(gps->tot_triangles >= 1); + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, text_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + text_id = GPU_vertformat_attr_add(&format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, gps->tot_triangles * 3); + + /* Draw all triangles for filling the polygon (cache must be calculated before) */ + bGPDtriangle *stroke_triangle = gps->triangles; + int idx = 0; + for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { + for (int j = 0; j < 3; j++) { + gpencil_set_fill_point( + vbo, idx, &gps->points[stroke_triangle->verts[j]], color, stroke_triangle->uv[j], + pos_id, color_id, text_id); + idx++; + } + } + + return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* Draw selected verts for strokes being edited */ +GPUBatch *DRW_gpencil_get_edit_geom(bGPDstroke *gps, float alpha, short dflag) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Object *ob = draw_ctx->obact; + bGPdata *gpd = ob->data; + bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); + + int vgindex = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, vgindex)) { + vgindex = -1; + } + + /* Get size of verts: + * - The selected state needs to be larger than the unselected state so that + * they stand out more. + * - We use the theme setting for size of the unselected verts + */ + float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); + float vsize; + if ((int)bsize > 8) { + vsize = 10.0f; + bsize = 8.0f; + } + else { + vsize = bsize + 2; + } + + /* for now, we assume that the base color of the points is not too close to the real color */ + float selectColor[4]; + UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); + selectColor[3] = alpha; + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id, size_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, gps->totpoints); + + /* Draw start and end point differently if enabled stroke direction hint */ + bool show_direction_hint = (dflag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1); + + /* Draw all the stroke points (selected or not) */ + bGPDspoint *pt = gps->points; + MDeformVert *dvert = gps->dvert; + + int idx = 0; + float fcolor[4]; + float fsize = 0; + for (int i = 0; i < gps->totpoints; i++, pt++, dvert++) { + /* weight paint */ + if (is_weight_paint) { + float weight = BKE_gpencil_vgroup_use_index(dvert, vgindex); + CLAMP(weight, 0.0f, 1.0f); + float hue = 2.0f * (1.0f - weight) / 3.0f; + hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]); + selectColor[3] = 1.0f; + copy_v4_v4(fcolor, selectColor); + fsize = vsize; + } + else { + if (show_direction_hint && i == 0) { + /* start point in green bigger */ + ARRAY_SET_ITEMS(fcolor, 0.0f, 1.0f, 0.0f, 1.0f); + fsize = vsize + 4; + } + else if (show_direction_hint && (i == gps->totpoints - 1)) { + /* end point in red smaller */ + ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f); + fsize = vsize + 1; + } + else if (pt->flag & GP_SPOINT_SELECT) { + copy_v4_v4(fcolor, selectColor); + fsize = vsize; + } + else { + copy_v4_v4(fcolor, gps->runtime.tmp_stroke_rgba); + fsize = bsize; + } + } + + GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor); + GPU_vertbuf_attr_set(vbo, size_id, idx, &fsize); + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); + idx++; + } + + return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +/* Draw lines for strokes being edited */ +GPUBatch *DRW_gpencil_get_edlin_geom(bGPDstroke *gps, float alpha, short UNUSED(dflag)) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Object *ob = draw_ctx->obact; + bGPdata *gpd = ob->data; + bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); + + int vgindex = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, vgindex)) { + vgindex = -1; + } + + float selectColor[4]; + UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); + selectColor[3] = alpha; + float linecolor[4]; + copy_v4_v4(linecolor, gpd->line_color); + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, gps->totpoints); + + /* Draw all the stroke lines (selected or not) */ + bGPDspoint *pt = gps->points; + + /* GPXX: for some converted files, this struct could be null + * maybe we can remove this and move to versioning code after + * merge */ + if (gps->dvert == NULL) { + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); + } + + MDeformVert *dvert = gps->dvert; + + int idx = 0; + float fcolor[4]; + for (int i = 0; i < gps->totpoints; i++, pt++, dvert++) { + /* weight paint */ + if (is_weight_paint) { + float weight = BKE_gpencil_vgroup_use_index(dvert, vgindex); + CLAMP(weight, 0.0f, 1.0f); + float hue = 2.0f * (1.0f - weight) / 3.0f; + hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]); + selectColor[3] = 1.0f; + copy_v4_v4(fcolor, selectColor); + } + else { + if (pt->flag & GP_SPOINT_SELECT) { + copy_v4_v4(fcolor, selectColor); + } + else { + copy_v4_v4(fcolor, linecolor); + } + } + + GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor); + GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); + idx++; + } + + return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); +} + +static void set_grid_point(GPUVertBuf *vbo, int idx, float col_grid[4], + uint pos_id, uint color_id, + float v1, float v2, int axis) +{ + GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid); + + float pos[3]; + /* Set the grid in the selected axis (default is always Y axis) */ + if (axis & V3D_GP_GRID_AXIS_X) { + pos[0] = 0.0f; + pos[1] = v1; + pos[2] = v2; + } + else if (axis & V3D_GP_GRID_AXIS_Z) { + pos[0] = v1; + pos[1] = v2; + pos[2] = 0.0f; + } + else + { + pos[0] = v1; + pos[1] = 0.0f; + pos[2] = v2; + } + + + + GPU_vertbuf_attr_set(vbo, pos_id, idx, pos); +} + +/* Draw grid lines */ +GPUBatch *DRW_gpencil_get_grid(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + ToolSettings *ts = scene->toolsettings; + View3D *v3d = draw_ctx->v3d; + + float col_grid[4]; + + /* verify we have something to draw and valid values */ + if (v3d->overlay.gpencil_grid_lines < 1) { + v3d->overlay.gpencil_grid_lines = GP_DEFAULT_GRID_LINES; + } + + if (v3d->overlay.gpencil_grid_scale == 0.0f) { + v3d->overlay.gpencil_grid_scale = 1.0f; + } + + if (v3d->overlay.gpencil_grid_opacity < 0.1f) { + v3d->overlay.gpencil_grid_opacity = 0.1f; + } + + UI_GetThemeColor3fv(TH_GRID, col_grid); + col_grid[3] = v3d->overlay.gpencil_grid_opacity; + + /* if use locked axis, copy value */ + int axis = v3d->overlay.gpencil_grid_axis; + if ((v3d->overlay.gpencil_grid_axis & V3D_GP_GRID_AXIS_LOCK) == 0) { + + axis = v3d->overlay.gpencil_grid_axis; + } + else { + switch (ts->gp_sculpt.lock_axis) { + case GP_LOCKAXIS_X: + { + axis = V3D_GP_GRID_AXIS_X; + break; + } + case GP_LOCKAXIS_NONE: + case GP_LOCKAXIS_Y: + { + axis = V3D_GP_GRID_AXIS_Y; + break; + } + case GP_LOCKAXIS_Z: + { + axis = V3D_GP_GRID_AXIS_Z; + break; + } + } + } + + const char *grid_unit = NULL; + const int gridlines = v3d->overlay.gpencil_grid_lines; + const float grid_scale = v3d->overlay.gpencil_grid_scale * ED_scene_grid_scale(scene, &grid_unit); + const float grid = grid_scale; + const float space = (grid_scale / gridlines); + + const uint vertex_len = 2 * (gridlines * 4 + 2); + + static GPUVertFormat format = { 0 }; + static uint pos_id, color_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, vertex_len); + + int idx = 0; + + for (int a = 1; a <= gridlines; a++) { + const float line = a * space; + + set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid, -line, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid, -line, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid, +line, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid, +line, axis); + idx++; + + set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line, -grid, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line, +grid, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line, -grid, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line, +grid, axis); + idx++; + } + /* center lines */ + set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid, 0.0f, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid, 0.0f, axis); + idx++; + + set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f, -grid, axis); + idx++; + set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f, +grid, axis); + idx++; + + return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); +} diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c new file mode 100644 index 00000000000..76cb1405a71 --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -0,0 +1,1336 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_draw_utils.c + * \ingroup draw + */ + +#include "BLI_polyfill_2d.h" + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "BKE_brush.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_image.h" +#include "BKE_material.h" + +#include "ED_gpencil.h" +#include "ED_view3d.h" + +#include "DNA_gpencil_types.h" +#include "DNA_material_types.h" +#include "DNA_view3d_types.h" +#include "DNA_gpencil_modifier_types.h" + + /* If builtin shaders are needed */ +#include "GPU_shader.h" +#include "GPU_texture.h" + +/* For EvaluationContext... */ +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "IMB_imbuf_types.h" + +#include "gpencil_engine.h" + +/* fill type to communicate to shader */ +#define SOLID 0 +#define GRADIENT 1 +#define RADIAL 2 +#define CHESS 3 +#define TEXTURE 4 +#define PATTERN 5 + +/* Helper for doing all the checks on whether a stroke can be drawn */ +static bool gpencil_can_draw_stroke(struct MaterialGPencilStyle *gp_style, const bGPDstroke *gps, + const bool onion, const bool is_mat_preview) +{ + /* skip stroke if it doesn't have any valid data */ + if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) + return false; + + /* if mat preview render always visible */ + if (is_mat_preview) { + return true; + } + + /* check if the color is visible */ + if ((gp_style == NULL) || + (gp_style->flag & GP_STYLE_COLOR_HIDE) || + (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) + { + return false; + } + + /* stroke can be drawn */ + return true; +} + +/* calc bounding box in 2d using flat projection data */ +static void gpencil_calc_2d_bounding_box( + const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], bool expand) +{ + minv[0] = points2d[0][0]; + minv[1] = points2d[0][1]; + maxv[0] = points2d[0][0]; + maxv[1] = points2d[0][1]; + + for (int i = 1; i < totpoints; i++) { + /* min */ + if (points2d[i][0] < minv[0]) { + minv[0] = points2d[i][0]; + } + if (points2d[i][1] < minv[1]) { + minv[1] = points2d[i][1]; + } + /* max */ + if (points2d[i][0] > maxv[0]) { + maxv[0] = points2d[i][0]; + } + if (points2d[i][1] > maxv[1]) { + maxv[1] = points2d[i][1]; + } + } + /* If not expanded, use a perfect square */ + if (expand == false) { + if (maxv[0] > maxv[1]) { + maxv[1] = maxv[0]; + } + else { + maxv[0] = maxv[1]; + } + } +} + +/* calc texture coordinates using flat projected points */ +static void gpencil_calc_stroke_fill_uv( + const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], float(*r_uv)[2]) +{ + float d[2]; + d[0] = maxv[0] - minv[0]; + d[1] = maxv[1] - minv[1]; + for (int i = 0; i < totpoints; i++) { + r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0]; + r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1]; + } +} + +/* Get points of stroke always flat to view not affected by camera view or view position */ +static void gpencil_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction) +{ + const bGPDspoint *pt0 = &points[0]; + const bGPDspoint *pt1 = &points[1]; + const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; + + float locx[3]; + float locy[3]; + float loc3[3]; + float normal[3]; + + /* local X axis (p0 -> p1) */ + sub_v3_v3v3(locx, &pt1->x, &pt0->x); + + /* point vector at 3/4 */ + sub_v3_v3v3(loc3, &pt3->x, &pt0->x); + + /* vector orthogonal to polygon plane */ + cross_v3_v3v3(normal, locx, loc3); + + /* local Y axis (cross to normal/x axis) */ + cross_v3_v3v3(locy, normal, locx); + + /* Normalize vectors */ + normalize_v3(locx); + normalize_v3(locy); + + /* Get all points in local space */ + for (int i = 0; i < totpoints; i++) { + const bGPDspoint *pt = &points[i]; + float loc[3]; + + /* Get local space using first point as origin */ + sub_v3_v3v3(loc, &pt->x, &pt0->x); + + points2d[i][0] = dot_v3v3(loc, locx); + points2d[i][1] = dot_v3v3(loc, locy); + } + + /* Concave (-1), Convex (1), or Autodetect (0)? */ + *r_direction = (int)locy[2]; +} + +/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */ +void DRW_gpencil_triangulate_stroke_fill(bGPDstroke *gps) +{ + BLI_assert(gps->totpoints >= 3); + + /* allocate memory for temporary areas */ + gps->tot_triangles = gps->totpoints - 2; + uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation"); + float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points"); + float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data"); + + int direction = 0; + + /* convert to 2d and triangulate */ + gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction); + BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles); + + /* calc texture coordinates automatically */ + float minv[2]; + float maxv[2]; + /* first needs bounding box data */ + gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv, false); + /* calc uv data */ + gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv); + + /* Number of triangles */ + gps->tot_triangles = gps->totpoints - 2; + /* save triangulation data in stroke cache */ + if (gps->tot_triangles > 0) { + if (gps->triangles == NULL) { + gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles, "GP Stroke triangulation"); + } + else { + gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles); + } + + for (int i = 0; i < gps->tot_triangles; i++) { + bGPDtriangle *stroke_triangle = &gps->triangles[i]; + memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3])); + /* copy texture coordinates */ + copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]); + copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]); + copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]); + } + } + else { + /* No triangles needed - Free anything allocated previously */ + if (gps->triangles) + MEM_freeN(gps->triangles); + + gps->triangles = NULL; + } + + /* disable recalculation flag */ + if (gps->flag & GP_STROKE_RECALC_CACHES) { + gps->flag &= ~GP_STROKE_RECALC_CACHES; + } + + /* clear memory */ + MEM_SAFE_FREE(tmp_triangles); + MEM_SAFE_FREE(points2d); + MEM_SAFE_FREE(uv); +} + +/* recalc the internal geometry caches for fill and uvs */ +static void DRW_gpencil_recalc_geometry_caches(Object *ob, MaterialGPencilStyle *gp_style, bGPDstroke *gps) +{ + if (gps->flag & GP_STROKE_RECALC_CACHES) { + /* Calculate triangles cache for filling area (must be done only after changes) */ + if ((gps->tot_triangles == 0) || (gps->triangles == NULL)) { + if ((gps->totpoints > 2) && + ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0))) + { + DRW_gpencil_triangulate_stroke_fill(gps); + } + } + + /* calc uv data along the stroke */ + ED_gpencil_calc_stroke_uv(ob, gps); + + /* clear flag */ + gps->flag &= ~GP_STROKE_RECALC_CACHES; + } +} + +/* create shading group for filling */ +static DRWShadingGroup *DRW_gpencil_shgroup_fill_create( + GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, + GPUShader *shader, bGPdata *gpd, MaterialGPencilStyle *gp_style, int id) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + + /* e_data.gpencil_fill_sh */ + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1); + + /* set style type */ + switch (gp_style->fill_style) { + case GP_STYLE_FILL_STYLE_SOLID: + stl->shgroups[id].fill_style = SOLID; + break; + case GP_STYLE_FILL_STYLE_GRADIENT: + if (gp_style->gradient_type == GP_STYLE_GRADIENT_LINEAR) { + stl->shgroups[id].fill_style = GRADIENT; + } + else { + stl->shgroups[id].fill_style = RADIAL; + } + break; + case GP_STYLE_FILL_STYLE_CHESSBOARD: + stl->shgroups[id].fill_style = CHESS; + break; + case GP_STYLE_FILL_STYLE_TEXTURE: + if (gp_style->flag & GP_STYLE_FILL_PATTERN) { + stl->shgroups[id].fill_style = PATTERN; + } + else { + stl->shgroups[id].fill_style = TEXTURE; + } + break; + default: + stl->shgroups[id].fill_style = GP_STYLE_FILL_STYLE_SOLID; + break; + } + DRW_shgroup_uniform_int(grp, "fill_type", &stl->shgroups[id].fill_style, 1); + + DRW_shgroup_uniform_float(grp, "mix_factor", &gp_style->mix_factor, 1); + + DRW_shgroup_uniform_float(grp, "gradient_angle", &gp_style->gradient_angle, 1); + DRW_shgroup_uniform_float(grp, "gradient_radius", &gp_style->gradient_radius, 1); + DRW_shgroup_uniform_float(grp, "pattern_gridsize", &gp_style->pattern_gridsize, 1); + DRW_shgroup_uniform_vec2(grp, "gradient_scale", gp_style->gradient_scale, 1); + DRW_shgroup_uniform_vec2(grp, "gradient_shift", gp_style->gradient_shift, 1); + + DRW_shgroup_uniform_float(grp, "texture_angle", &gp_style->texture_angle, 1); + DRW_shgroup_uniform_vec2(grp, "texture_scale", gp_style->texture_scale, 1); + DRW_shgroup_uniform_vec2(grp, "texture_offset", gp_style->texture_offset, 1); + DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1); + + stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0; + DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1); + + stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0; + DRW_shgroup_uniform_int(grp, "texture_flip", &stl->shgroups[id].texture_flip, 1); + + DRW_shgroup_uniform_int(grp, "xraymode", (const int *) &gpd->xray_mode, 1); + /* image texture */ + if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) || + (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE)) + { + ImBuf *ibuf; + Image *image = gp_style->ima; + ImageUser iuser = { NULL }; + void *lock; + + iuser.ok = true; + + ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); + + if (ibuf == NULL || ibuf->rect == NULL) { + BKE_image_release_ibuf(image, ibuf, NULL); + } + else { + GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true, 0.0); + DRW_shgroup_uniform_texture(grp, "myTexture", texture); + + stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0; + DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1); + + BKE_image_release_ibuf(image, ibuf, NULL); + } + } + else { + /* if no texture defined, need a blank texture to avoid errors in draw manager */ + DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture); + stl->shgroups[id].texture_clamp = 0; + DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1); + } + + return grp; +} + +/* create shading group for strokes */ +DRWShadingGroup *DRW_gpencil_shgroup_stroke_create( + GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob, + bGPdata *gpd, MaterialGPencilStyle *gp_style, int id, bool onion) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const float *viewport_size = DRW_viewport_size_get(); + + /* e_data.gpencil_stroke_sh */ + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1); + + DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(grp, "pixelsize", &U.pixelsize, 1); + + /* avoid wrong values */ + if ((gpd) && (gpd->pixfactor == 0)) { + gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; + } + + /* object scale and depth */ + if ((ob) && (id > -1)) { + stl->shgroups[id].obj_scale = (ob->size[0] + ob->size[1] + ob->size[2]) / 3.0f; + DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1); + stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS)); + DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1); + + stl->shgroups[id].stroke_style = gp_style->stroke_style; + stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID; + if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) { + stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE; + if (gp_style->flag & GP_STYLE_STROKE_PATTERN) { + stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN; + } + } + DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1); + DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1); + } + else { + stl->storage->obj_scale = 1.0f; + stl->storage->keep_size = 0; + stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR; + DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1); + DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1); + DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1); + if (gpd) { + DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1); + } + else { + DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1); + } + } + + if ((gpd) && (id > -1)) { + DRW_shgroup_uniform_int(grp, "xraymode", (const int *) &gpd->xray_mode, 1); + } + else { + /* for drawing always on front */ + DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1); + } + + /* image texture for pattern */ + if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) { + ImBuf *ibuf; + Image *image = gp_style->sima; + ImageUser iuser = { NULL }; + void *lock; + + iuser.ok = true; + + ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); + + if (ibuf == NULL || ibuf->rect == NULL) { + BKE_image_release_ibuf(image, ibuf, NULL); + } + else { + GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f); + DRW_shgroup_uniform_texture(grp, "myTexture", texture); + + BKE_image_release_ibuf(image, ibuf, NULL); + } + } + else { + /* if no texture defined, need a blank texture to avoid errors in draw manager */ + DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture); + } + + return grp; +} + +/* create shading group for volumetrics */ +static DRWShadingGroup *DRW_gpencil_shgroup_point_create( + GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob, + bGPdata *gpd, MaterialGPencilStyle *gp_style, int id, bool onion) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const float *viewport_size = DRW_viewport_size_get(); + + /* e_data.gpencil_stroke_sh */ + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1); + DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(grp, "pixelsize", &U.pixelsize, 1); + + /* avoid wrong values */ + if ((gpd) && (gpd->pixfactor == 0)) { + gpd->pixfactor = GP_DEFAULT_PIX_FACTOR; + } + + /* object scale and depth */ + if ((ob) && (id > -1)) { + stl->shgroups[id].obj_scale = (ob->size[0] + ob->size[1] + ob->size[2]) / 3.0f; + DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1); + stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS)); + DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1); + + stl->shgroups[id].mode = gp_style->mode; + stl->shgroups[id].stroke_style = gp_style->stroke_style; + stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID; + if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) { + stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE; + if (gp_style->flag & GP_STYLE_STROKE_PATTERN) { + stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN; + } + } + DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1); + DRW_shgroup_uniform_int(grp, "mode", &stl->shgroups[id].mode, 1); + DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1); + } + else { + stl->storage->obj_scale = 1.0f; + stl->storage->keep_size = 0; + stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR; + stl->storage->mode = gp_style->mode; + DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1); + DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1); + DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1); + DRW_shgroup_uniform_int(grp, "mode", &stl->storage->mode, 1); + if (gpd) { + DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1); + } + else { + DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1); + } + } + + if (gpd) { + DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&gpd->xray_mode, 1); + } + else { + /* for drawing always on front */ + DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1); + } + + /* image texture */ + if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) { + ImBuf *ibuf; + Image *image = gp_style->sima; + ImageUser iuser = { NULL }; + void *lock; + + iuser.ok = true; + + ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); + + if (ibuf == NULL || ibuf->rect == NULL) { + BKE_image_release_ibuf(image, ibuf, NULL); + } + else { + GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true, 0.0f); + DRW_shgroup_uniform_texture(grp, "myTexture", texture); + + BKE_image_release_ibuf(image, ibuf, NULL); + } + } + else { + /* if no texture defined, need a blank texture to avoid errors in draw manager */ + DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture); + } + + return grp; +} + +/* add fill shading group to pass */ +static void gpencil_add_fill_shgroup( + GpencilBatchCache *cache, DRWShadingGroup *fillgrp, + Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, + const float tintcolor[4], const bool onion, const bool custonion) +{ + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + if (gps->totpoints >= 3) { + float tfill[4]; + /* set color using material, tint color and opacity */ + interp_v3_v3v3(tfill, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]); + tfill[3] = gps->runtime.tmp_fill_rgba[3] * gpl->opacity; + if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) { + const float *color; + if (!onion) { + color = tfill; + } + else { + if (custonion) { + color = tintcolor; + } + else { + ARRAY_SET_ITEMS(tfill, UNPACK3(gps->runtime.tmp_fill_rgba), tintcolor[3]); + color = tfill; + } + } + if (cache->is_dirty) { + gpencil_batch_cache_check_free_slots(ob); + cache->batch_fill[cache->cache_idx] = DRW_gpencil_get_fill_geom(ob, gps, color); + } + DRW_shgroup_call_add(fillgrp, cache->batch_fill[cache->cache_idx], gpf->runtime.viewmatrix); + } + } +} + +/* add stroke shading group to pass */ +static void gpencil_add_stroke_shgroup(GpencilBatchCache *cache, DRWShadingGroup *strokegrp, + Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps, + const float opacity, const float tintcolor[4], const bool onion, const bool custonion) +{ + float tcolor[4]; + float ink[4]; + short sthickness; + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + + /* set color using base color, tint color and opacity */ + if (!onion) { + /* if special stroke, use fill color as stroke color */ + if (gps->flag & GP_STROKE_NOFILL) { + interp_v3_v3v3(tcolor, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]); + tcolor[3] = gps->runtime.tmp_fill_rgba[3] * opacity; + } + else { + interp_v3_v3v3(tcolor, gps->runtime.tmp_stroke_rgba, tintcolor, tintcolor[3]); + tcolor[3] = gps->runtime.tmp_stroke_rgba[3] * opacity; + } + copy_v4_v4(ink, tcolor); + } + else { + if (custonion) { + copy_v4_v4(ink, tintcolor); + } + else { + ARRAY_SET_ITEMS(tcolor, UNPACK3(gps->runtime.tmp_stroke_rgba), opacity); + copy_v4_v4(ink, tcolor); + } + } + + sthickness = gps->thickness + gpl->line_change; + CLAMP_MIN(sthickness, 1); + if (cache->is_dirty) { + gpencil_batch_cache_check_free_slots(ob); + if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) { + cache->batch_stroke[cache->cache_idx] = DRW_gpencil_get_stroke_geom(gpf, gps, sthickness, ink); + } + else { + cache->batch_stroke[cache->cache_idx] = DRW_gpencil_get_point_geom(gps, sthickness, ink); + } + } + DRW_shgroup_call_add(strokegrp, cache->batch_stroke[cache->cache_idx], gpf->runtime.viewmatrix); +} + +/* add edit points shading group to pass */ +static void gpencil_add_editpoints_shgroup( + GPENCIL_StorageList *stl, GpencilBatchCache *cache, ToolSettings *UNUSED(ts), Object *ob, + bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + + /* alpha factor for edit points/line to make them more subtle */ + float edit_alpha = v3d->vertex_opacity; + + if (GPENCIL_ANY_EDIT_MODE(gpd)) { + Object *obact = DRW_context_state_get()->obact; + if ((!obact) || (obact->type != OB_GPENCIL)) { + return; + } + const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); + + /* line of the original stroke */ + if (cache->is_dirty) { + gpencil_batch_cache_check_free_slots(ob); + cache->batch_edlin[cache->cache_idx] = DRW_gpencil_get_edlin_geom(gps, edit_alpha, gpd->flag); + } + if (cache->batch_edlin[cache->cache_idx]) { + if ((obact) && (obact == ob) && + ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_EDIT_LINES)) + { + DRW_shgroup_call_add( + stl->g_data->shgrps_edit_line, + cache->batch_edlin[cache->cache_idx], + gpf->runtime.viewmatrix); + } + } + /* edit points */ + if ((gps->flag & GP_STROKE_SELECT) || (is_weight_paint)) { + if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) || ((gp_style->flag & GP_STYLE_COLOR_LOCKED) == 0)) { + if (cache->is_dirty) { + gpencil_batch_cache_check_free_slots(ob); + cache->batch_edit[cache->cache_idx] = DRW_gpencil_get_edit_geom(gps, edit_alpha, gpd->flag); + } + if (cache->batch_edit[cache->cache_idx]) { + if ((obact) && (obact == ob)) { + /* edit pass */ + DRW_shgroup_call_add( + stl->g_data->shgrps_edit_point, + cache->batch_edit[cache->cache_idx], + gpf->runtime.viewmatrix); + } + } + } + } + } +} + +/* function to draw strokes for onion only */ +static void gpencil_draw_onion_strokes( + GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, Object *ob, + bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, + const float opacity, const float tintcolor[4], const bool custonion) +{ + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + Depsgraph *depsgraph = DRW_context_state_get()->depsgraph; + + float viewmatrix[4][4]; + + /* get parent matrix and save as static data */ + ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix); + copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix); + + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); + copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + + int id = stl->storage->shgroup_id; + /* check if stroke can be drawn */ + if (gpencil_can_draw_stroke(gp_style, gps, true, false) == false) { + continue; + } + /* limit the number of shading groups */ + if (id >= GPENCIL_MAX_SHGROUPS) { + continue; + } + + stl->shgroups[id].shgrps_fill = NULL; + if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) { + stl->shgroups[id].shgrps_stroke = DRW_gpencil_shgroup_stroke_create( + e_data, vedata, psl->stroke_pass, e_data->gpencil_stroke_sh, ob, gpd, gp_style, id, true); + } + else { + stl->shgroups[id].shgrps_stroke = DRW_gpencil_shgroup_point_create( + e_data, vedata, psl->stroke_pass, e_data->gpencil_point_sh, ob, gpd, gp_style, id, true); + } + + /* stroke */ + gpencil_add_stroke_shgroup( + cache, stl->shgroups[id].shgrps_stroke, ob, gpl, gpf, gps, opacity, tintcolor, true, custonion); + + stl->storage->shgroup_id++; + cache->cache_idx++; + } +} + + +/* main function to draw strokes */ +static void gpencil_draw_strokes( + GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob, + bGPdata *gpd, bGPDlayer *gpl, bGPDframe *src_gpf, bGPDframe *derived_gpf, + const float opacity, const float tintcolor[4], const bool custonion) +{ + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; + bGPDstroke *gps, *src_gps; + DRWShadingGroup *fillgrp; + DRWShadingGroup *strokegrp; + float viewmatrix[4][4]; + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + const bool playing = (bool)stl->storage->playing; + const bool is_render = (bool)stl->storage->is_render; + const bool is_mat_preview = (bool)stl->storage->is_mat_preview; + const bool overlay_multiedit = v3d != NULL ? (v3d->flag3 & V3D_GP_SHOW_MULTIEDIT_LINES) : true; + + /* Get evaluation context */ + /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files + * (i.e. the thumbnail offscreen rendering fails) + */ + Depsgraph *depsgraph = DRW_context_state_get()->depsgraph; + + /* get parent matrix and save as static data */ + ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix); + copy_m4_m4(derived_gpf->runtime.viewmatrix, viewmatrix); + + /* apply geometry modifiers */ + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) { + if (!stl->storage->simplify_modif) { + if (BKE_gpencil_has_geometry_modifiers(ob)) { + BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, derived_gpf, stl->storage->is_render); + } + } + } + + if (src_gpf) { + src_gps = src_gpf->strokes.first; + } + else { + src_gps = NULL; + } + + for (gps = derived_gpf->strokes.first; gps; gps = gps->next) { + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + + /* check if stroke can be drawn */ + if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) { + continue; + } + /* limit the number of shading groups */ + if (stl->storage->shgroup_id >= GPENCIL_MAX_SHGROUPS) { + continue; + } + + /* be sure recalc all chache in source stroke to avoid recalculation when frame change + * and improve fps */ + if (src_gps) { + DRW_gpencil_recalc_geometry_caches(ob, gp_style, src_gps); + } + + /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is enabled */ + if ((stl->storage->simplify_fill) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) { + if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || + (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID)) + { + continue; + } + } + + if ((gpl->actframe->framenum == derived_gpf->framenum) || + (!is_multiedit) || (overlay_multiedit)) + { + int id = stl->storage->shgroup_id; + if (gps->totpoints > 0) { + if ((gps->totpoints > 2) && (!stl->storage->simplify_fill) && + ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) && + ((gps->flag & GP_STROKE_NOFILL) == 0)) + { + stl->shgroups[id].shgrps_fill = DRW_gpencil_shgroup_fill_create( + e_data, vedata, psl->stroke_pass, e_data->gpencil_fill_sh, gpd, gp_style, id); + } + else { + stl->shgroups[id].shgrps_fill = NULL; + } + if ((gp_style->mode == GP_STYLE_MODE_LINE) && (gps->totpoints > 1)) { + stl->shgroups[id].shgrps_stroke = DRW_gpencil_shgroup_stroke_create( + e_data, vedata, psl->stroke_pass, e_data->gpencil_stroke_sh, ob, gpd, gp_style, id, false); + } + else { + stl->shgroups[id].shgrps_stroke = DRW_gpencil_shgroup_point_create( + e_data, vedata, psl->stroke_pass, e_data->gpencil_point_sh, ob, gpd, gp_style, id, false); + } + } + else { + stl->shgroups[id].shgrps_fill = NULL; + stl->shgroups[id].shgrps_stroke = NULL; + } + stl->storage->shgroup_id++; + + fillgrp = stl->shgroups[id].shgrps_fill; + strokegrp = stl->shgroups[id].shgrps_stroke; + + /* copy color to temp fields to apply temporal changes in the stroke */ + copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); + copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + + /* apply modifiers (only modify geometry, but not create ) */ + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) { + if (!stl->storage->simplify_modif) { + BKE_gpencil_stroke_modifiers(depsgraph, ob, gpl, derived_gpf, gps, stl->storage->is_render); + } + } + + /* fill */ + if ((fillgrp) && (!stl->storage->simplify_fill)) { + gpencil_add_fill_shgroup( + cache, fillgrp, ob, gpl, derived_gpf, gps, tintcolor, false, custonion); + } + /* stroke */ + if (strokegrp) { + gpencil_add_stroke_shgroup( + cache, strokegrp, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion); + } + } + + /* edit points (only in edit mode and not play animation not render) */ + if ((src_gps) && (!playing) && (!is_render)) { + if (!stl->g_data->shgrps_edit_line) { + stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, psl->edit_pass); + } + if (!stl->g_data->shgrps_edit_point) { + stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->edit_pass); + const float *viewport_size = DRW_viewport_size_get(); + DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1); + } + + gpencil_add_editpoints_shgroup(stl, cache, ts, ob, gpd, gpl, derived_gpf, src_gps); + } + + if (src_gps) { + src_gps = src_gps->next; + } + + cache->cache_idx++; + } +} + + /* draw stroke in drawing buffer */ +void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob) +{ + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + Brush *brush = BKE_brush_getactive_gpencil(ts); + bGPdata *gpd = ob->data; + MaterialGPencilStyle *gp_style = NULL; + + float obscale = (ob->size[0] + ob->size[1] + ob->size[2]) / 3.0f; + + /* use the brush material */ + Material *ma = BKE_gpencil_get_material_from_brush(brush); + if (ma != NULL) { + gp_style = ma->gp_style; + } + /* this is not common, but avoid any special situations when brush could be without material */ + if (gp_style == NULL) { + gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol); + } + + /* drawing strokes */ + /* Check if may need to draw the active stroke cache, only if this layer is the active layer + * that is being edited. (Stroke buffer is currently stored in gp-data) + */ + if (ED_gpencil_session_active() && (gpd->runtime.sbuffer_size > 0)) { + if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) { + /* It should also be noted that sbuffer contains temporary point types + * i.e. tGPspoints NOT bGPDspoints + */ + short lthick = brush->size * obscale; + /* if only one point, don't need to draw buffer because the user has no time to see it */ + if (gpd->runtime.sbuffer_size > 1) { + if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) { + stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create( + e_data, vedata, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL, gpd, gp_style, -1, false); + } + else { + stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create( + e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false); + } + + /* use unit matrix because the buffer is in screen space and does not need conversion */ + if (gpd->runtime.mode == GP_STYLE_MODE_LINE) { + stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom( + gpd, stl->storage->unit_matrix, lthick); + } + else { + stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom( + gpd, stl->storage->unit_matrix, lthick); + } + + DRW_shgroup_call_add( + stl->g_data->shgrps_drawing_stroke, + stl->g_data->batch_buffer_stroke, + stl->storage->unit_matrix); + + if ((gpd->runtime.sbuffer_size >= 3) && (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) && + ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0)) + { + /* if not solid, fill is simulated with solid color */ + if (gpd->runtime.bfill_style > 0) { + gpd->runtime.sfill[3] = 0.5f; + } + stl->g_data->shgrps_drawing_fill = DRW_shgroup_create( + e_data->gpencil_drawing_fill_sh, psl->drawing_pass); + stl->g_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd); + DRW_shgroup_call_add( + stl->g_data->shgrps_drawing_fill, + stl->g_data->batch_buffer_fill, + stl->storage->unit_matrix); + } + } + } + } +} + +/* get alpha factor for onion strokes */ +static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd) +{ +#define MIN_ALPHA_VALUE 0.01f + + /* if fade is disabled, opacity is equal in all frames */ + if ((gpd->onion_flag & GP_ONION_FADE) == 0) { + color[3] = gpd->onion_factor; + } + else { + /* add override opacity factor */ + color[3] += gpd->onion_factor - 0.5f; + } + + CLAMP(color[3], MIN_ALPHA_VALUE, 1.0f); +} + +/* draw onion-skinning for a layer */ +static void gpencil_draw_onionskins( + GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, + Object *ob, bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf) +{ + + const float default_color[3] = { UNPACK3(U.gpencil_new_layer_col) }; + const float alpha = 1.0f; + float color[4]; + int idx; + float fac = 1.0f; + int step = 0; + int mode = 0; + bool colflag = false; + bGPDframe *gpf_loop = NULL; + int last = gpf->framenum; + + colflag = (bool)gpd->onion_flag & GP_ONION_GHOST_PREVCOL; + + + /* ------------------------------- + * 1) Draw Previous Frames First + * ------------------------------- */ + step = gpd->gstep; + mode = gpd->onion_mode; + + if (gpd->onion_flag & GP_ONION_GHOST_PREVCOL) { + copy_v3_v3(color, gpd->gcolor_prev); + } + else { + copy_v3_v3(color, default_color); + } + + idx = 0; + for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) { + /* only selected frames */ + if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) { + continue; + } + /* absolute range */ + if (mode == GP_ONION_MODE_ABSOLUTE) { + if ((gpf->framenum - gf->framenum) > step) { + break; + } + } + /* relative range */ + if (mode == GP_ONION_MODE_RELATIVE) { + idx++; + if (idx > step) { + break; + } + + } + /* alpha decreases with distance from curframe index */ + if (mode != GP_ONION_MODE_SELECTED) { + if (mode == GP_ONION_MODE_ABSOLUTE) { + fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(step + 1)); + } + else { + fac = 1.0f - ((float)idx / (float)(step + 1)); + } + color[3] = alpha * fac * 0.66f; + } + else { + idx++; + fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f); + color[3] = fac; + } + + /* if loop option, save the frame to use later */ + if ((mode != GP_ONION_MODE_ABSOLUTE) && (gpd->onion_flag & GP_ONION_LOOP)) { + gpf_loop = gf; + } + + gpencil_get_onion_alpha(color, gpd); + gpencil_draw_onion_strokes(cache, e_data, vedata, ob, gpd, gpl, gf, color[3], color, colflag); + } + /* ------------------------------- + * 2) Now draw next frames + * ------------------------------- */ + step = gpd->gstep_next; + mode = gpd->onion_mode; + + if (gpd->onion_flag & GP_ONION_GHOST_NEXTCOL) { + copy_v3_v3(color, gpd->gcolor_next); + } + else { + copy_v3_v3(color, default_color); + } + + idx = 0; + for (bGPDframe *gf = gpf->next; gf; gf = gf->next) { + /* only selected frames */ + if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) { + continue; + } + /* absolute range */ + if (mode == GP_ONION_MODE_ABSOLUTE) { + if ((gf->framenum - gpf->framenum) > step) { + break; + } + } + /* relative range */ + if (mode == GP_ONION_MODE_RELATIVE) { + idx++; + if (idx > step) { + break; + } + + } + /* alpha decreases with distance from curframe index */ + if (mode != GP_ONION_MODE_SELECTED) { + if (mode == GP_ONION_MODE_ABSOLUTE) { + fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(step + 1)); + } + else { + fac = 1.0f - ((float)idx / (float)(step + 1)); + } + color[3] = alpha * fac * 0.66f; + } + else { + idx++; + fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f); + color[3] = fac; + } + + gpencil_get_onion_alpha(color, gpd); + gpencil_draw_onion_strokes(cache, e_data, vedata, ob, gpd, gpl, gf, color[3], color, colflag); + if (last < gf->framenum) { + last = gf->framenum; + } + } + + /* Draw first frame in blue for loop mode */ + if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) { + if ((last == gpf->framenum) || (gpf->next == NULL)) { + gpencil_get_onion_alpha(color, gpd); + gpencil_draw_onion_strokes( + cache, e_data, vedata, ob, gpd, gpl, + gpf_loop, color[3], color, colflag); + } + } +} + +/* populate a datablock for multiedit (no onions, no modifiers) */ +void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene *scene, Object *ob, bGPdata *gpd) +{ + bGPDframe *gpf = NULL; + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); + GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); + ToolSettings *ts = scene->toolsettings; + cache->cache_idx = 0; + + /* check if playing animation */ + bool playing = (bool)stl->storage->playing; + + /* draw strokes */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* don't draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; + + /* list of frames to draw */ + if (!playing) { + for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) { + gpencil_draw_strokes( + cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf, + gpl->opacity, gpl->tintcolor, false); + } + } + } + else { + gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); + if (gpf) { + gpencil_draw_strokes( + cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf, + gpl->opacity, gpl->tintcolor, false); + } + } + + } + + cache->is_dirty = false; +} + +/* helper for populate a complete grease pencil datablock */ +void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene *scene, Object *ob, bGPdata *gpd) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; + int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); + ToolSettings *ts = scene->toolsettings; + bGPDframe *derived_gpf = NULL; + const bool main_onion = v3d != NULL ? ((v3d->flag3 & V3D_GP_SHOW_ONION_SKIN) == 0) : true; + const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion; + const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; + + /* check if playing animation */ + bool playing = (bool)stl->storage->playing; + + GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); + cache->cache_idx = 0; + + /* init general modifiers data */ + if (!stl->storage->simplify_modif) { + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_init(ob); + } + } + /* draw normal strokes */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* don't draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; + + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); + if (gpf == NULL) + continue; + + /* create GHash if need */ + if (gpl->runtime.derived_data == NULL) { + gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); + } + + derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); + if (derived_gpf == NULL) { + cache->is_dirty = true; + } + if (cache->is_dirty) { + if (derived_gpf != NULL) { + /* first clear temp data */ + BKE_gpencil_free_frame_runtime_data(derived_gpf); + BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); + } + /* create new data */ + derived_gpf = BKE_gpencil_frame_duplicate(gpf); + BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); + } + + /* draw onion skins */ + if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && + (!no_onion) && (overlay) && + (gpl->onion_flag & GP_LAYER_ONIONSKIN) && + ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + { + if ((!stl->storage->is_render) || + ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + { + gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); + } + } + + /* draw normal strokes */ + gpencil_draw_strokes( + cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf, + gpl->opacity, gpl->tintcolor, false); + + } + + /* clear any lattice data */ + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_clear(ob); + } + + cache->is_dirty = false; +} + +/* Helper for gpencil_instance_modifiers() + * See also MOD_gpencilinstance.c -> bakeModifier() + */ +static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object *ob, InstanceGpencilModifierData *mmd) +{ + /* reset random */ + mmd->rnd[0] = 1; + + /* Generate instances */ + for (int x = 0; x < mmd->count[0]; x++) { + for (int y = 0; y < mmd->count[1]; y++) { + for (int z = 0; z < mmd->count[2]; z++) { + Object *newob; + + const int elem_idx[3] = {x, y, z}; + float mat[4][4]; + int sh; + + /* original strokes are at index = 0,0,0 */ + if ((x == 0) && (y == 0) && (z == 0)) { + continue; + } + + /* compute transform for instance */ + BKE_gpencil_instance_modifier_instance_tfm(mmd, elem_idx, mat); + + /* add object to cache */ + newob = MEM_dupallocN(ob); + mul_m4_m4m4(newob->obmat, ob->obmat, mat); + + /* apply scale */ + ARRAY_SET_ITEMS(newob->size, mat[0][0], mat[1][1], mat[2][2]); + + /* apply shift */ + sh = x; + if (mmd->lock_axis == GP_LOCKAXIS_Y) { + sh = y; + } + if (mmd->lock_axis == GP_LOCKAXIS_Z) { + sh = z; + } + madd_v3_v3fl(newob->obmat[3], mmd->shift, sh); + + /* add temp object to cache */ + stl->g_data->gp_object_cache = gpencil_object_cache_add( + stl->g_data->gp_object_cache, newob, true, + &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used); + } + } + } +} + +/* create instances using instance modifiers */ +void gpencil_instance_modifiers(GPENCIL_StorageList *stl, Object *ob) +{ + if ((ob) && (ob->data)) { + bGPdata *gpd = ob->data; + if (GPENCIL_ANY_EDIT_MODE(gpd)) { + return; + } + } + + for (GpencilModifierData *md = ob->greasepencil_modifiers.first; md; md = md->next) { + if (((md->mode & eGpencilModifierMode_Realtime) && (stl->storage->is_render == false)) || + ((md->mode & eGpencilModifierMode_Render) && (stl->storage->is_render == true))) + { + if (md->type == eGpencilModifierType_Instance) { + InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; + + /* Only add instances if the "Make Objects" flag is set + * FIXME: This is a workaround for z-ordering weirdness when all instances are in the same object + */ + if (mmd->flag & GP_INSTANCE_MAKE_OBJECTS) { + gp_instance_modifier_make_instances(stl, ob, mmd); + } + } + } + } +} diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c new file mode 100644 index 00000000000..71c99b2bcdf --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -0,0 +1,794 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_engine.c + * \ingroup draw + */ +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "BKE_camera.h" +#include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_gpencil.h" +#include "BKE_shader_fx.h" + +#include "DNA_gpencil_types.h" +#include "DNA_view3d_types.h" + +#include "draw_mode_engines.h" + +#include "UI_resources.h" + +#include "GPU_texture.h" + +#include "gpencil_engine.h" + +#include "ED_screen.h" +#include "ED_gpencil.h" + +extern char datatoc_gpencil_fill_vert_glsl[]; +extern char datatoc_gpencil_fill_frag_glsl[]; +extern char datatoc_gpencil_stroke_vert_glsl[]; +extern char datatoc_gpencil_stroke_geom_glsl[]; +extern char datatoc_gpencil_stroke_frag_glsl[]; +extern char datatoc_gpencil_zdepth_mix_frag_glsl[]; +extern char datatoc_gpencil_simple_mix_frag_glsl[]; +extern char datatoc_gpencil_point_vert_glsl[]; +extern char datatoc_gpencil_point_geom_glsl[]; +extern char datatoc_gpencil_point_frag_glsl[]; +extern char datatoc_gpencil_background_frag_glsl[]; +extern char datatoc_gpencil_paper_frag_glsl[]; +extern char datatoc_gpencil_edit_point_vert_glsl[]; +extern char datatoc_gpencil_edit_point_geom_glsl[]; +extern char datatoc_gpencil_edit_point_frag_glsl[]; + +/* *********** STATIC *********** */ +static GPENCIL_e_data e_data = {NULL}; /* Engine data */ + +/* *********** FUNCTIONS *********** */ + +/* create a multisample buffer if not present */ +void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h) +{ + GPENCIL_FramebufferList *fbl = vedata->fbl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl; + + short samples = stl->storage->multisamples; + + if (samples > 0) { + if (!fbl->multisample_fb) { + fbl->multisample_fb = GPU_framebuffer_create(); + if (fbl->multisample_fb) { + if (txl->multisample_color == NULL) { + txl->multisample_color = GPU_texture_create_2D_multisample( + rect_w, rect_h, GPU_RGBA16F, NULL, samples, NULL); + } + if (txl->multisample_depth == NULL) { + txl->multisample_depth = GPU_texture_create_2D_multisample( + rect_w, rect_h, GPU_DEPTH24_STENCIL8, NULL, samples, NULL); + } + GPU_framebuffer_ensure_config(&fbl->multisample_fb, { + GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), + GPU_ATTACHMENT_TEXTURE(txl->multisample_color) + }); + if (!GPU_framebuffer_check_valid(fbl->multisample_fb, NULL)) { + GPU_framebuffer_free(fbl->multisample_fb); + } + } + } + } +} + +static void GPENCIL_create_framebuffers(void *vedata) +{ + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + + /* Go full 32bits for rendering */ + GPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F; + + if (DRW_state_is_fbo()) { + const float *viewport_size = DRW_viewport_size_get(); + const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] }; + + /* create multiframe framebuffer for AA */ + if (stl->storage->multisamples > 0) { + DRW_gpencil_multisample_ensure(vedata, size[0], size[1]); + } + + /* temp textures */ + e_data.temp_depth_tx_a = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.temp_color_tx_a = DRW_texture_pool_query_2D(size[0], size[1], fb_format, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config(&fbl->temp_fb_a, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a) + }); + + e_data.temp_depth_tx_b = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.temp_color_tx_b = DRW_texture_pool_query_2D(size[0], size[1], fb_format, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config(&fbl->temp_fb_b, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b) + }); + + /* used for rim FX effect */ + e_data.temp_depth_tx_rim = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.temp_color_tx_rim = DRW_texture_pool_query_2D(size[0], size[1], fb_format, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config(&fbl->temp_fb_rim, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_rim), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_rim), + }); + + /* background framebuffer to speed up drawing process (always 16 bits) */ + e_data.background_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.background_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config(&fbl->background_fb, { + GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx), + GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx) + }); + } +} + +static void GPENCIL_create_shaders(void) +{ + /* normal fill shader */ + if (!e_data.gpencil_fill_sh) { + e_data.gpencil_fill_sh = DRW_shader_create( + datatoc_gpencil_fill_vert_glsl, NULL, + datatoc_gpencil_fill_frag_glsl, NULL); + } + + /* normal stroke shader using geometry to display lines (line mode) */ + if (!e_data.gpencil_stroke_sh) { + e_data.gpencil_stroke_sh = DRW_shader_create( + datatoc_gpencil_stroke_vert_glsl, + datatoc_gpencil_stroke_geom_glsl, + datatoc_gpencil_stroke_frag_glsl, + NULL); + } + + /* dot/rectangle mode for normal strokes using geometry */ + if (!e_data.gpencil_point_sh) { + e_data.gpencil_point_sh = DRW_shader_create( + datatoc_gpencil_point_vert_glsl, + datatoc_gpencil_point_geom_glsl, + datatoc_gpencil_point_frag_glsl, + NULL); + } + /* used for edit points or strokes with one point only */ + if (!e_data.gpencil_edit_point_sh) { + e_data.gpencil_edit_point_sh = DRW_shader_create( + datatoc_gpencil_edit_point_vert_glsl, + datatoc_gpencil_edit_point_geom_glsl, + datatoc_gpencil_edit_point_frag_glsl, NULL); + } + + /* used for edit lines for edit modes */ + if (!e_data.gpencil_line_sh) { + e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR); + } + + /* used to filling during drawing */ + if (!e_data.gpencil_drawing_fill_sh) { + e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR); + } + + /* full screen for mix zdepth*/ + if (!e_data.gpencil_fullscreen_sh) { + e_data.gpencil_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_zdepth_mix_frag_glsl, NULL); + } + if (!e_data.gpencil_simple_fullscreen_sh) { + e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_simple_mix_frag_glsl, NULL); + } + + /* shaders for use when drawing */ + if (!e_data.gpencil_background_sh) { + e_data.gpencil_background_sh = DRW_shader_create_fullscreen(datatoc_gpencil_background_frag_glsl, NULL); + } + if (!e_data.gpencil_paper_sh) { + e_data.gpencil_paper_sh = DRW_shader_create_fullscreen(datatoc_gpencil_paper_frag_glsl, NULL); + } +} + +void GPENCIL_engine_init(void *vedata) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + /* init storage */ + if (!stl->storage) { + stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage"); + + /* unit matrix */ + unit_m4(stl->storage->unit_matrix); + } + + stl->storage->multisamples = U.gpencil_multisamples; + + /* create framebuffers */ + GPENCIL_create_framebuffers(vedata); + + /* create shaders */ + GPENCIL_create_shaders(); + GPENCIL_create_fx_shaders(&e_data); + + /* blank texture used if no texture defined for fill shader */ + if (!e_data.gpencil_blank_texture) { + float rect[16][16][4] = {{{0.0f}}}; + e_data.gpencil_blank_texture = DRW_texture_create_2D(16, 16, GPU_RGBA8, DRW_TEX_FILTER, (float *)rect); + } +} + +static void GPENCIL_engine_free(void) +{ + /* only free custom shaders, builtin shaders are freed in blender close */ + DRW_SHADER_FREE_SAFE(e_data.gpencil_fill_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_point_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh); + DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh); + + DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture); + + /* effects */ + GPENCIL_delete_fx_shaders(&e_data); +} + +void GPENCIL_cache_init(void *vedata) +{ + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + View3D *v3d = draw_ctx->v3d; + + /* Special handling for when active object is GP object (e.g. for draw mode) */ + Object *obact = draw_ctx->obact; + bGPdata *obact_gpd = NULL; + MaterialGPencilStyle *gp_style = NULL; + + if (obact && (obact->type == OB_GPENCIL) && (obact->data)) { + obact_gpd = (bGPdata *)obact->data; + gp_style = BKE_material_gpencil_settings_get(obact, obact->actcol); + } + + if (!stl->g_data) { + /* Alloc transient pointers */ + stl->g_data = MEM_mallocN(sizeof(g_data), "g_data"); + stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */ + stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; /* used for drawing */ + } + stl->storage->tonemapping = 0; + + stl->g_data->shgrps_edit_line = NULL; + stl->g_data->shgrps_edit_point = NULL; + + if (!stl->shgroups) { + /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning. + I tried to allocate only one block and using realloc, increasing the size when read a new strokes + in cache_finish, but the realloc produce weird things on screen, so we keep as is while we found + a better solution + */ + stl->shgroups = MEM_mallocN(sizeof(GPENCIL_shgroup) * GPENCIL_MAX_SHGROUPS, "GPENCIL_shgroup"); + } + + /* init gp objects cache */ + stl->g_data->gp_cache_used = 0; + stl->g_data->gp_cache_size = 0; + stl->g_data->gp_object_cache = NULL; + + { + /* Stroke pass */ + psl->stroke_pass = DRW_pass_create( + "GPencil Stroke Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND); + stl->storage->shgroup_id = 0; + + /* edit pass */ + psl->edit_pass = DRW_pass_create( + "GPencil Edit Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND); + + /* detect if playing animation */ + stl->storage->playing = 0; + if (draw_ctx->evil_C) { + stl->storage->playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL ? 1 : 0; + } + + if (obact_gpd) { + /* for some reason, when press play there is a delay in the animation flag check + * and this produces errors. To be sure, we set cache as dirty because the frame + * is changing. + */ + if (stl->storage->playing == 1) { + obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + } + /* if render, set as dirty to update all data */ + else if (stl->storage->is_render == true) { + obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + } + } + + /* save render state */ + stl->storage->is_render = DRW_state_is_image_render(); + stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview"); + + /* save simplify flags (can change while drawing, so it's better to save) */ + stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->playing); + stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->playing); + + /* save pixsize */ + stl->storage->pixsize = DRW_viewport_pixelsize_get(); + if ((!DRW_state_is_opengl_render()) && (stl->storage->is_render)) { + stl->storage->pixsize = &stl->storage->render_pixsize; + } + + /* detect if painting session */ + if ((obact_gpd) && + (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) && + (stl->storage->playing == 0)) + { + if (((obact_gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) && + (obact_gpd->runtime.sbuffer_size > 1)) + { + stl->g_data->session_flag = GP_DRW_PAINT_PAINTING; + } + else { + stl->g_data->session_flag = GP_DRW_PAINT_IDLE; + } + } + else { + /* if not drawing mode */ + stl->g_data->session_flag = GP_DRW_PAINT_HOLD; + } + + if (gp_style) { + stl->storage->stroke_style = gp_style->stroke_style; + stl->storage->color_type = GPENCIL_COLOR_SOLID; + if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) { + stl->storage->color_type = GPENCIL_COLOR_TEXTURE; + if (gp_style->flag & GP_STYLE_STROKE_PATTERN) { + stl->storage->color_type = GPENCIL_COLOR_PATTERN; + } + } + } + else { + stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; + stl->storage->color_type = GPENCIL_COLOR_SOLID; + } + + /* drawing buffer pass for drawing the stroke that is beeing drawing by the user. The data + * is stored in sbuffer + */ + psl->drawing_pass = DRW_pass_create( + "GPencil Drawing Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + + /* full screen pass to combine the result with default framebuffer */ + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); + psl->mix_pass = DRW_pass_create( + "GPencil Mix Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass); + DRW_shgroup_call_add(mix_shgrp, quad, NULL); + DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx); + DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx); + DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1); + + /* mix pass no blend used to copy between passes. A separated pass is required + * because if mix_pass is used, the acumulation of blend degrade the colors. + * + * This pass is used too to take the snapshot used for background_pass. This image + * will be used as the background while the user is drawing. + */ + psl->mix_pass_noblend = DRW_pass_create( + "GPencil Mix Pass no blend", + DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass_noblend); + DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL); + DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx); + DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx); + DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1); + + /* Painting session pass (used only to speedup while the user is drawing ) + * This pass is used to show the snapshot of the current grease pencil strokes captured + * when the user starts to draw (see comments above). + * In this way, the previous strokes don't need to be redraw and the drawing process + * is far to agile. + */ + psl->background_pass = DRW_pass_create( + "GPencil Background Painting Session Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh, psl->background_pass); + DRW_shgroup_call_add(background_shgrp, quad, NULL); + DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx); + DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx); + + /* pass for drawing paper (only if viewport) + * In render, the v3d is null so the paper is disabled + * The paper is way to isolate the drawing in complex scene and to have a cleaner + * drawing area. + */ + if (v3d) { + psl->paper_pass = DRW_pass_create( + "GPencil Paper Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND); + DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass); + DRW_shgroup_call_add(paper_shgrp, quad, NULL); + DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1); + DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1); + } + + /* grid pass */ + if (v3d) { + psl->grid_pass = DRW_pass_create( + "GPencil Grid Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); + stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass); + } + + /* create effects passes */ + GPENCIL_create_fx_passes(psl); + } +} + +void GPENCIL_cache_populate(void *vedata, Object *ob) +{ + /* object must be visible */ + if (!DRW_check_object_visible_within_active_context(ob)) { + return; + } + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + ToolSettings *ts = scene->toolsettings; + View3D *v3d = draw_ctx->v3d; + + /* object datablock (this is not draw now) */ + if (ob->type == OB_GPENCIL && ob->data) { + bGPdata *gpd = (bGPdata *)ob->data; + if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) { + + /* if render set as dirty */ + if (stl->storage->is_render == true) { + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + } + + /* allocate memory for saving gp objects for drawing later */ + stl->g_data->gp_object_cache = gpencil_object_cache_add(stl->g_data->gp_object_cache, ob, false, + &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used); + + /* generate instances as separate cache objects for instance modifiers + * with the "Make as Objects" option enabled + */ + if (!stl->storage->simplify_modif) { + gpencil_instance_modifiers(stl, ob); + } + } + /* draw current painting strokes */ + DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob); + + /* grid */ + if ((v3d) && + ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_GRID) && + (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact)) + { + stl->g_data->batch_grid = DRW_gpencil_get_grid(); + DRW_shgroup_call_add(stl->g_data->shgrps_grid, + stl->g_data->batch_grid, + ob->obmat); + } + } +} + +void GPENCIL_cache_finish(void *vedata) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + bool is_multiedit = false; + + /* if painting session, don't need to do more */ + if (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING) { + return; + } + + /* Draw all pending objects */ + if (stl->g_data->gp_cache_used > 0) { + for (int i = 0; i < stl->g_data->gp_cache_used; i++) { + Object *ob = stl->g_data->gp_object_cache[i].ob; + bGPdata *gpd = ob->data; + + /* save init shading group */ + stl->g_data->gp_object_cache[i].init_grp = stl->storage->shgroup_id; + + /* fill shading groups */ + is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + if (!is_multiedit) { + DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, gpd); + } + else { + DRW_gpencil_populate_multiedit(&e_data, vedata, scene, ob, gpd); + } + + /* save end shading group */ + stl->g_data->gp_object_cache[i].end_grp = stl->storage->shgroup_id - 1; + /* if render set to dirty to refresh viewport */ + if (stl->storage->is_render == true) { + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + } + /* FX passses */ + tGPencilObjectCache *cache = &stl->g_data->gp_object_cache[i]; + if (!is_multiedit) { + DRW_gpencil_fx_prepare(&e_data, vedata, cache); + } + } + } +} + +/* helper function to sort inverse gpencil objects using qsort */ +static int gpencil_object_cache_compare_zdepth(const void *a1, const void *a2) +{ + const tGPencilObjectCache *ps1 = a1, *ps2 = a2; + + if (ps1->zdepth < ps2->zdepth) return 1; + else if (ps1->zdepth > ps2->zdepth) return -1; + + return 0; +} + +/* prepare a texture with full viewport screenshot for fast drawing */ +static void gpencil_prepare_fast_drawing( + GPENCIL_StorageList *stl, DefaultFramebufferList *dfbl, + GPENCIL_FramebufferList *fbl, DRWPass *pass, + const float clearcol[4]) +{ + if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) { + GPU_framebuffer_bind(fbl->background_fb); + /* clean only in first loop cycle */ + if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) { + GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f); + stl->g_data->session_flag = GP_DRW_PAINT_FILLING; + } + /* repeat pass to fill temp texture */ + DRW_draw_pass(pass); + /* set default framebuffer again */ + GPU_framebuffer_bind(dfbl->default_fb); + } +} + +static void gpencil_free_obj_list(GPENCIL_StorageList *stl) +{ + /* Clear temp objects created for display instances only. These objects are created + * while the draw manager draw the scene, but only to hold the strokes data. + * see: gp_instance_modifier_make_instances() + * + * the normal objects are not freed because they are not tagged as temp objects + */ + for (int i = 0; i < stl->g_data->gp_cache_used; i++) { + Object *ob = stl->g_data->gp_object_cache[i].ob; + if (stl->g_data->gp_object_cache[i].temp_ob) { + MEM_SAFE_FREE(ob); + } + } + + /* free the cache itself */ + MEM_SAFE_FREE(stl->g_data->gp_object_cache); +} + +/* draw scene */ +void GPENCIL_draw_scene(void *ved) +{ + GPENCIL_Data *vedata = (GPENCIL_Data *)ved; + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl; + + int init_grp, end_grp; + tGPencilObjectCache *cache; + const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; + Object *obact = draw_ctx->obact; + const bool playing = (bool)stl->storage->playing; + const bool is_render = stl->storage->is_render; + + /* paper pass to display a confortable area to draw over complex scenes with geometry */ + if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_PAPER) && + (stl->g_data->gp_cache_used > 0)) + { + DRW_draw_pass(psl->paper_pass); + } + } + + /* if we have a painting session, we use fast viewport drawing method */ + if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) { + GPU_framebuffer_bind(dfbl->default_fb); + + MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl); + + DRW_draw_pass(psl->background_pass); + DRW_draw_pass(psl->drawing_pass); + + MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl); + + /* free memory */ + gpencil_free_obj_list(stl); + + /* grid pass */ + if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_GRID)) + { + DRW_draw_pass(psl->grid_pass); + } + } + + return; + } + + if (DRW_state_is_fbo()) { + /* attach temp textures */ + GPU_framebuffer_texture_attach(fbl->temp_fb_a, e_data.temp_depth_tx_a, 0, 0); + GPU_framebuffer_texture_attach(fbl->temp_fb_a, e_data.temp_color_tx_a, 0, 0); + GPU_framebuffer_texture_attach(fbl->temp_fb_b, e_data.temp_depth_tx_b, 0, 0); + GPU_framebuffer_texture_attach(fbl->temp_fb_b, e_data.temp_color_tx_b, 0, 0); + + GPU_framebuffer_texture_attach(fbl->background_fb, e_data.background_depth_tx, 0, 0); + GPU_framebuffer_texture_attach(fbl->background_fb, e_data.background_color_tx, 0, 0); + + /* Draw all pending objects */ + if (stl->g_data->gp_cache_used > 0) { + + /* sort by zdepth */ + qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used, + sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth); + + for (int i = 0; i < stl->g_data->gp_cache_used; i++) { + cache = &stl->g_data->gp_object_cache[i]; + Object *ob = cache->ob; + bGPdata *gpd = ob->data; + init_grp = cache->init_grp; + end_grp = cache->end_grp; + /* Render stroke in separated framebuffer */ + GPU_framebuffer_bind(fbl->temp_fb_a); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); + + /* Stroke Pass: DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH + * draw only a subset that usually start with a fill and end with stroke because the + * shading groups are created by pairs */ + if (end_grp >= init_grp) { + MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl); + + DRW_draw_pass_subset( + psl->stroke_pass, + stl->shgroups[init_grp].shgrps_fill != NULL ? + stl->shgroups[init_grp].shgrps_fill : stl->shgroups[init_grp].shgrps_stroke, + stl->shgroups[end_grp].shgrps_stroke); + + MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fbl->temp_fb_a, txl); + } + + /* Current buffer drawing */ + if ((!is_render) && (gpd->runtime.sbuffer_size > 0)) { + DRW_draw_pass(psl->drawing_pass); + } + /* fx passes */ + if (BKE_shaderfx_has_gpencil(ob)) { + stl->storage->tonemapping = 0; + DRW_gpencil_fx_draw(&e_data, vedata, cache); + } + + e_data.input_depth_tx = e_data.temp_depth_tx_a; + e_data.input_color_tx = e_data.temp_color_tx_a; + + /* Combine with scene buffer */ + if ((!is_render) || (fbl->main == NULL)) { + GPU_framebuffer_bind(dfbl->default_fb); + } + else { + GPU_framebuffer_bind(fbl->main); + } + /* tonemapping */ + stl->storage->tonemapping = stl->storage->is_render ? 1 : 0; + + DRW_draw_pass(psl->mix_pass); + + /* prepare for fast drawing */ + if (!is_render) { + gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol); + } + } + /* edit points */ + if ((!is_render) && (!playing)) { + DRW_draw_pass(psl->edit_pass); + } + } + /* grid pass */ + if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_GRID)) + { + DRW_draw_pass(psl->grid_pass); + } + } + } + /* free memory */ + gpencil_free_obj_list(stl); + + /* detach temp textures */ + if (DRW_state_is_fbo()) { + GPU_framebuffer_texture_detach(fbl->temp_fb_a, e_data.temp_depth_tx_a); + GPU_framebuffer_texture_detach(fbl->temp_fb_a, e_data.temp_color_tx_a); + GPU_framebuffer_texture_detach(fbl->temp_fb_b, e_data.temp_depth_tx_b); + GPU_framebuffer_texture_detach(fbl->temp_fb_b, e_data.temp_color_tx_b); + + GPU_framebuffer_texture_detach(fbl->background_fb, e_data.background_depth_tx); + GPU_framebuffer_texture_detach(fbl->background_fb, e_data.background_color_tx); + + /* attach again default framebuffer after detach textures */ + if (!is_render) { + GPU_framebuffer_bind(dfbl->default_fb); + } + + /* the temp texture is ready. Now we can use fast screen drawing */ + if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) { + stl->g_data->session_flag = GP_DRW_PAINT_READY; + } + } +} + +static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data); + +DrawEngineType draw_engine_gpencil_type = { + NULL, NULL, + N_("GpencilMode"), + &GPENCIL_data_size, + &GPENCIL_engine_init, + &GPENCIL_engine_free, + &GPENCIL_cache_init, + &GPENCIL_cache_populate, + &GPENCIL_cache_finish, + NULL, + &GPENCIL_draw_scene, + NULL, + NULL, + &GPENCIL_render_to_image, +}; diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h new file mode 100644 index 00000000000..24a627f1012 --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -0,0 +1,355 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_engine.h + * \ingroup draw + */ + +#ifndef __GPENCIL_ENGINE_H__ +#define __GPENCIL_ENGINE_H__ + +#include "GPU_batch.h" + +struct tGPspoint; +struct bGPDstroke; +struct ModifierData; +struct GPENCIL_Data; +struct GPENCIL_StorageList; +struct Object; +struct MaterialGPencilStyle; +struct RenderEngine; +struct RenderLayer; + + /* TODO: these could be system parameter in userprefs screen */ +#define GPENCIL_MAX_GP_OBJ 256 + +#define GPENCIL_CACHE_BLOCK_SIZE 8 +#define GPENCIL_MAX_SHGROUPS 65536 +#define GPENCIL_MIN_BATCH_SLOTS_CHUNK 16 + +#define GPENCIL_COLOR_SOLID 0 +#define GPENCIL_COLOR_TEXTURE 1 +#define GPENCIL_COLOR_PATTERN 2 + +#define GP_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE)) +#define GP_SIMPLIFY_ONPLAY(playing) (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0)) +#define GP_SIMPLIFY_FILL(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL))) +#define GP_SIMPLIFY_MODIF(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER))) + +#define GP_IS_CAMERAVIEW ((rv3d != NULL) && (rv3d->persp == RV3D_CAMOB && v3d->camera)) + + /* *********** OBJECTS CACHE *********** */ + + /* used to save gpencil objects */ +typedef struct tGPencilObjectCache { + struct Object *ob; + int init_grp, end_grp; + int idx; /*original index, can change after sort */ + + /* effects */ + DRWShadingGroup *fx_wave_sh; + DRWShadingGroup *fx_blur_sh; + DRWShadingGroup *fx_colorize_sh; + DRWShadingGroup *fx_pixel_sh; + DRWShadingGroup *fx_rim_sh; + DRWShadingGroup *fx_swirl_sh; + DRWShadingGroup *fx_flip_sh; + DRWShadingGroup *fx_light_sh; + + float zdepth; /* z-depth value to sort gp object */ + bool temp_ob; /* flag to tag temporary objects that must be removed after drawing loop */ +} tGPencilObjectCache; + + /* *********** LISTS *********** */ +typedef struct GPENCIL_shgroup { + int s_clamp; + int stroke_style; + int color_type; + int mode; + int texture_mix; + int texture_flip; + int texture_clamp; + int fill_style; + int keep_size; + float obj_scale; + struct DRWShadingGroup *shgrps_fill; + struct DRWShadingGroup *shgrps_stroke; +} GPENCIL_shgroup; + +typedef struct GPENCIL_Storage { + int shgroup_id; /* total elements */ + float unit_matrix[4][4]; + int stroke_style; + int color_type; + int mode; + int xray; + int keep_size; + float obj_scale; + float pixfactor; + int playing; + bool is_render; + bool is_mat_preview; + const float *pixsize; + float render_pixsize; + int tonemapping; + short multisamples; + + /* simplify settings*/ + bool simplify_fill; + bool simplify_modif; + bool simplify_fx; + + /* Render Matrices and data */ + float persmat[4][4], persinv[4][4]; + float viewmat[4][4], viewinv[4][4]; + float winmat[4][4], wininv[4][4]; + float view_vecs[2][4]; /* vec4[2] */ + + Object *camera; /* camera pointer for render mode */ +} GPENCIL_Storage; + +typedef struct GPENCIL_StorageList { + struct GPENCIL_Storage *storage; + struct g_data *g_data; + struct GPENCIL_shgroup *shgroups; +} GPENCIL_StorageList; + +typedef struct GPENCIL_PassList { + struct DRWPass *stroke_pass; + struct DRWPass *edit_pass; + struct DRWPass *drawing_pass; + struct DRWPass *mix_pass; + struct DRWPass *mix_pass_noblend; + struct DRWPass *background_pass; + struct DRWPass *paper_pass; + struct DRWPass *grid_pass; + + /* effects */ + struct DRWPass *fx_shader_pass; + struct DRWPass *fx_shader_pass_blend; + +} GPENCIL_PassList; + +typedef struct GPENCIL_FramebufferList { + struct GPUFrameBuffer *main; + struct GPUFrameBuffer *temp_fb_a; + struct GPUFrameBuffer *temp_fb_b; + struct GPUFrameBuffer *temp_fb_rim; + struct GPUFrameBuffer *background_fb; + + struct GPUFrameBuffer *multisample_fb; +} GPENCIL_FramebufferList; + +typedef struct GPENCIL_TextureList { + struct GPUTexture *texture; + + /* multisample textures */ + struct GPUTexture *multisample_color; + struct GPUTexture *multisample_depth; + +} GPENCIL_TextureList; + +typedef struct GPENCIL_Data { + void *engine_type; /* Required */ + struct GPENCIL_FramebufferList *fbl; + struct GPENCIL_TextureList *txl; + struct GPENCIL_PassList *psl; + struct GPENCIL_StorageList *stl; + + /* render textures */ + struct GPUTexture *render_depth_tx; + struct GPUTexture *render_color_tx; + +} GPENCIL_Data; + +/* *********** STATIC *********** */ +typedef struct g_data { + struct DRWShadingGroup *shgrps_edit_point; + struct DRWShadingGroup *shgrps_edit_line; + struct DRWShadingGroup *shgrps_drawing_stroke; + struct DRWShadingGroup *shgrps_drawing_fill; + struct DRWShadingGroup *shgrps_grid; + + /* for buffer only one batch is nedeed because the drawing is only of one stroke */ + GPUBatch *batch_buffer_stroke; + GPUBatch *batch_buffer_fill; + + /* grid geometry */ + GPUBatch *batch_grid; + + int gp_cache_used; /* total objects in cache */ + int gp_cache_size; /* size of the cache */ + struct tGPencilObjectCache *gp_object_cache; + + int session_flag; + +} g_data; /* Transient data */ + +/* flags for fast drawing support */ +typedef enum eGPsession_Flag { + GP_DRW_PAINT_HOLD = (1 << 0), + GP_DRW_PAINT_IDLE = (1 << 1), + GP_DRW_PAINT_FILLING = (1 << 2), + GP_DRW_PAINT_READY = (1 << 3), + GP_DRW_PAINT_PAINTING = (1 << 4), +} eGPsession_Flag; + +typedef struct GPENCIL_e_data { + /* general drawing shaders */ + struct GPUShader *gpencil_fill_sh; + struct GPUShader *gpencil_stroke_sh; + struct GPUShader *gpencil_point_sh; + struct GPUShader *gpencil_edit_point_sh; + struct GPUShader *gpencil_line_sh; + struct GPUShader *gpencil_drawing_fill_sh; + struct GPUShader *gpencil_fullscreen_sh; + struct GPUShader *gpencil_simple_fullscreen_sh; + struct GPUShader *gpencil_background_sh; + struct GPUShader *gpencil_paper_sh; + + /* effects */ + struct GPUShader *gpencil_fx_blur_sh; + struct GPUShader *gpencil_fx_colorize_sh; + struct GPUShader *gpencil_fx_flip_sh; + struct GPUShader *gpencil_fx_light_sh; + struct GPUShader *gpencil_fx_pixel_sh; + struct GPUShader *gpencil_fx_rim_prepare_sh; + struct GPUShader *gpencil_fx_rim_resolve_sh; + struct GPUShader *gpencil_fx_swirl_sh; + struct GPUShader *gpencil_fx_wave_sh; + + /* textures */ + struct GPUTexture *background_depth_tx; + struct GPUTexture *background_color_tx; + + struct GPUTexture *gpencil_blank_texture; + + /* runtime pointers texture */ + struct GPUTexture *input_depth_tx; + struct GPUTexture *input_color_tx; + + /* working textures */ + struct GPUTexture *temp_color_tx_a; + struct GPUTexture *temp_depth_tx_a; + + struct GPUTexture *temp_color_tx_b; + struct GPUTexture *temp_depth_tx_b; + + struct GPUTexture *temp_color_tx_rim; + struct GPUTexture *temp_depth_tx_rim; +} GPENCIL_e_data; /* Engine data */ + +/* GPUBatch Cache */ +typedef struct GpencilBatchCache { + /* For normal strokes, a variable number of batch can be needed depending of number of strokes. + It could use the stroke number as total size, but when activate the onion skining, the number + can change, so the size is changed dinamically. + */ + GPUBatch **batch_stroke; + GPUBatch **batch_fill; + GPUBatch **batch_edit; + GPUBatch **batch_edlin; + + /* settings to determine if cache is invalid */ + bool is_dirty; + bool is_editmode; + int cache_frame; + + /* keep information about the size of the cache */ + int cache_size; /* total batch slots available */ + int cache_idx; /* current slot index */ +} GpencilBatchCache; + +/* general drawing functions */ +struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, struct DRWPass *pass, struct GPUShader *shader, + struct Object *ob, struct bGPdata *gpd, struct MaterialGPencilStyle *gp_style, int id, bool onion); +void DRW_gpencil_populate_datablock(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd); +void DRW_gpencil_populate_buffer_strokes(struct GPENCIL_e_data *e_data, void *vedata, struct ToolSettings *ts, struct Object *ob); +void DRW_gpencil_populate_multiedit(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd); +void DRW_gpencil_triangulate_stroke_fill(struct bGPDstroke *gps); + +void DRW_gpencil_multisample_ensure(struct GPENCIL_Data *vedata, int rect_w, int rect_h); + +/* create geometry functions */ +struct GPUBatch *DRW_gpencil_get_point_geom(struct bGPDstroke *gps, short thickness, const float ink[4]); +struct GPUBatch *DRW_gpencil_get_stroke_geom(struct bGPDframe *gpf, struct bGPDstroke *gps, short thickness, const float ink[4]); +struct GPUBatch *DRW_gpencil_get_fill_geom(struct Object *ob, struct bGPDstroke *gps, const float color[4]); +struct GPUBatch *DRW_gpencil_get_edit_geom(struct bGPDstroke *gps, float alpha, short dflag); +struct GPUBatch *DRW_gpencil_get_edlin_geom(struct bGPDstroke *gps, float alpha, short dflag); +struct GPUBatch *DRW_gpencil_get_buffer_stroke_geom(struct bGPdata *gpd, float matrix[4][4], short thickness); +struct GPUBatch *DRW_gpencil_get_buffer_fill_geom(struct bGPdata *gpd); +struct GPUBatch *DRW_gpencil_get_buffer_point_geom(struct bGPdata *gpd, float matrix[4][4], short thickness); +struct GPUBatch *DRW_gpencil_get_grid(void); + +/* object cache functions */ +struct tGPencilObjectCache *gpencil_object_cache_add(struct tGPencilObjectCache *cache_array, struct Object *ob, + bool is_temp, int *gp_cache_size, int *gp_cache_used); + +/* geometry batch cache functions */ +void gpencil_batch_cache_check_free_slots(struct Object *ob); +struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra); + +/* modifier functions */ +void gpencil_instance_modifiers(struct GPENCIL_StorageList *stl, struct Object *ob); + +/* effects */ +void GPENCIL_create_fx_shaders(struct GPENCIL_e_data *e_data); +void GPENCIL_delete_fx_shaders(struct GPENCIL_e_data *e_data); +void GPENCIL_create_fx_passes(struct GPENCIL_PassList *psl); + +void DRW_gpencil_fx_prepare( + struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, + struct tGPencilObjectCache *cache); +void DRW_gpencil_fx_draw( + struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, + struct tGPencilObjectCache *cache); + +/* main functions */ +void GPENCIL_engine_init(void *vedata); +void GPENCIL_cache_init(void *vedata); +void GPENCIL_cache_populate(void *vedata, struct Object *ob); +void GPENCIL_cache_finish(void *vedata); +void GPENCIL_draw_scene(void *vedata); + +/* render */ +void GPENCIL_render_init(struct GPENCIL_Data *ved, struct RenderEngine *engine, struct Depsgraph *depsgraph); +void GPENCIL_render_to_image(void *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect); + +/* Use of multisample framebuffers. */ +#define MULTISAMPLE_GP_SYNC_ENABLE(lvl, fbl) { \ + if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \ + DRW_stats_query_start("GP Multisample Blit"); \ + GPU_framebuffer_bind(fbl->multisample_fb); \ + GPU_framebuffer_clear_color_depth(fbl->multisample_fb, (const float[4]){0.0f}, 1.0f); \ + DRW_stats_query_end(); \ + } \ +} + +#define MULTISAMPLE_GP_SYNC_DISABLE(lvl, fbl, fb, txl) { \ + if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \ + DRW_stats_query_start("GP Multisample Resolve"); \ + GPU_framebuffer_bind(fb); \ + DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \ + DRW_stats_query_end(); \ + } \ +} + +#endif /* __GPENCIL_ENGINE_H__ */ diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c new file mode 100644 index 00000000000..d76ea56894f --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_render.c @@ -0,0 +1,353 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_render.c + * \ingroup draw + */ +#include "BLI_rect.h" + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "BKE_camera.h" + +#include "DNA_gpencil_types.h" + +#include "DEG_depsgraph_query.h" + +#include "draw_mode_engines.h" + +#include "RE_pipeline.h" + +#include "gpencil_engine.h" + +/* Get pixel size for render +* This function uses the same calculation used for viewport, because if use +* camera pixelsize, the result is not correct. +*/ +static float get_render_pixelsize(float persmat[4][4], int winx, int winy) +{ + float v1[3], v2[3]; + float len_px, len_sc; + + v1[0] = persmat[0][0]; + v1[1] = persmat[1][0]; + v1[2] = persmat[2][0]; + + v2[0] = persmat[0][1]; + v2[1] = persmat[1][1]; + v2[2] = persmat[2][1]; + + len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2))); + len_sc = (float)MAX2(winx, winy); + + return len_px / len_sc; +} + +/* init render data */ +void GPENCIL_render_init(GPENCIL_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph) +{ + GPENCIL_Data *vedata = (GPENCIL_Data *)ved; + GPENCIL_StorageList *stl = vedata->stl; + GPENCIL_FramebufferList *fbl = vedata->fbl; + + Scene *scene = DEG_get_evaluated_scene(depsgraph); + const float *viewport_size = DRW_viewport_size_get(); + const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] }; + + /* In render mode the default framebuffer is not generated + * because there is no viewport. So we need to manually create one + * NOTE : use 32 bit format for precision in render mode. + */ + /* create multiframe framebuffer for AA */ + if (U.gpencil_multisamples > 0) { + int rect_w = (int)viewport_size[0]; + int rect_h = (int)viewport_size[1]; + DRW_gpencil_multisample_ensure(vedata, rect_w, rect_h); + } + + vedata->render_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + vedata->render_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config(&fbl->main, { + GPU_ATTACHMENT_TEXTURE(vedata->render_depth_tx), + GPU_ATTACHMENT_TEXTURE(vedata->render_color_tx) + }); + + /* Alloc transient data. */ + if (!stl->g_data) { + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); + } + + /* Set the pers & view matrix. */ + struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); + float frame = BKE_scene_frame_get(scene); + RE_GetCameraWindow(engine->re, camera, frame, stl->storage->winmat); + RE_GetCameraModelMatrix(engine->re, camera, stl->storage->viewinv); + + invert_m4_m4(stl->storage->viewmat, stl->storage->viewinv); + mul_m4_m4m4(stl->storage->persmat, stl->storage->winmat, stl->storage->viewmat); + invert_m4_m4(stl->storage->persinv, stl->storage->persmat); + invert_m4_m4(stl->storage->wininv, stl->storage->winmat); + + DRW_viewport_matrix_override_set(stl->storage->persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(stl->storage->persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(stl->storage->winmat, DRW_MAT_WIN); + DRW_viewport_matrix_override_set(stl->storage->wininv, DRW_MAT_WININV); + DRW_viewport_matrix_override_set(stl->storage->viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(stl->storage->viewinv, DRW_MAT_VIEWINV); + + /* calculate pixel size for render */ + stl->storage->render_pixsize = get_render_pixelsize(stl->storage->persmat, viewport_size[0], viewport_size[1]); + /* INIT CACHE */ + GPENCIL_cache_init(vedata); +} + +/* render all objects and select only grease pencil */ +static void GPENCIL_render_cache( + void *vedata, struct Object *ob, + struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +{ + if ((ob == NULL) || (DRW_check_object_visible_within_active_context(ob) == false)) { + return; + } + + if (ob->type == OB_GPENCIL) { + GPENCIL_cache_populate(vedata, ob); + } +} + +/* TODO: Reuse Eevee code in shared module instead to duplicate here */ +static void GPENCIL_render_update_viewvecs(float invproj[4][4], float winmat[4][4], float(*r_viewvecs)[4]) +{ + /* view vectors for the corners of the view frustum. + * Can be used to recreate the world space position easily */ + float view_vecs[4][4] = { + { -1.0f, -1.0f, -1.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, 1.0f }, + { -1.0f, 1.0f, -1.0f, 1.0f }, + { -1.0f, -1.0f, 1.0f, 1.0f } + }; + + /* convert the view vectors to view space */ + const bool is_persp = (winmat[3][3] == 0.0f); + for (int i = 0; i < 4; i++) { + mul_project_m4_v3(invproj, view_vecs[i]); + /* normalized trick see: + * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ + if (is_persp) { + /* Divide XY by Z. */ + mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]); + } + } + + /** + * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and + * view_vecs[1] is the vector going from the near-bottom-left corner to + * the far-top-right corner. + * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner + * when Z = 1, and top-left corner if Z = 1. + * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed) + * distance from the near plane to the far clip plane. + **/ + copy_v4_v4(r_viewvecs[0], view_vecs[0]); + + /* we need to store the differences */ + r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0]; + r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1]; + r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2]; +} + +/* Update view_vecs */ +static void GPENCIL_render_update_vecs(GPENCIL_Data *vedata) +{ + GPENCIL_StorageList *stl = vedata->stl; + + float invproj[4][4], winmat[4][4]; + DRW_viewport_matrix_get(winmat, DRW_MAT_WIN); + DRW_viewport_matrix_get(invproj, DRW_MAT_WININV); + + /* this is separated to keep function equal to Eevee for future reuse of same code */ + GPENCIL_render_update_viewvecs(invproj, winmat, stl->storage->view_vecs); +} + +/* read z-depth render result */ +static void GPENCIL_render_result_z(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + GPENCIL_StorageList *stl = vedata->stl; + + if ((view_layer->passflag & SCE_PASS_Z) != 0) { + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname); + + GPU_framebuffer_read_depth(vedata->fbl->main, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), rp->rect); + + bool is_persp = DRW_viewport_is_persp_get(); + + GPENCIL_render_update_vecs(vedata); + + /* Convert ogl depth [0..1] to view Z [near..far] */ + for (int i = 0; i < BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); i++) { + if (rp->rect[i] == 1.0f) { + rp->rect[i] = 1e10f; /* Background */ + } + else { + if (is_persp) { + rp->rect[i] = rp->rect[i] * 2.0f - 1.0f; + rp->rect[i] = stl->storage->winmat[3][2] / (rp->rect[i] + stl->storage->winmat[2][2]); + } + else { + rp->rect[i] = -stl->storage->view_vecs[0][2] + rp->rect[i] * -stl->storage->view_vecs[1][2]; + } + } + } + } +} + +/* read combined render result */ +static void GPENCIL_render_result_combined(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect) +{ + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + + GPU_framebuffer_bind(fbl->main); + GPU_framebuffer_read_color(vedata->fbl->main, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 4, 0, rp->rect); +} + +/* helper to blend pixels */ +static void blend_pixel(float src[4], float dst[4]) +{ + float alpha = src[3]; + + /* use blend: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA */ + dst[0] = (src[0] * alpha) + (dst[0] * (1.0f - alpha)); + dst[1] = (src[1] * alpha) + (dst[1] * (1.0f - alpha)); + dst[2] = (src[2] * alpha) + (dst[2] * (1.0f - alpha)); +} + +/* render grease pencil to image */ +void GPENCIL_render_to_image(void *vedata, RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect) +{ + const char *viewname = RE_GetActiveRenderView(engine->re); + const DRWContextState *draw_ctx = DRW_context_state_get(); + int imgsize = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); + + /* save previous render data */ + RenderPass *rpass_color_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname); + RenderPass *rpass_depth_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname); + float *src_rect_color_data = NULL; + float *src_rect_depth_data = NULL; + if ((rpass_color_src) && (rpass_depth_src) && (rpass_color_src->rect) && (rpass_depth_src->rect)) { + src_rect_color_data = MEM_dupallocN(rpass_color_src->rect); + src_rect_depth_data = MEM_dupallocN(rpass_depth_src->rect); + } + else { + /* TODO: put this message in a better place */ + printf("Warning: To render grease pencil, enable Combined and Z passes.\n"); + } + + GPENCIL_engine_init(vedata); + GPENCIL_render_init(vedata, engine, draw_ctx->depsgraph); + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + Object *camera = DEG_get_evaluated_object(draw_ctx->depsgraph, RE_GetCamera(engine->re)); + stl->storage->camera = camera; /* save current camera */ + + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + if (fbl->main) { + GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx, 0, 0); + GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx, 0, 0); + /* clean first time the buffer */ + float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + GPU_framebuffer_bind(fbl->main); + GPU_framebuffer_clear_color_depth(fbl->main, clearcol, 1.0f); + } + + /* loop all objects and draw */ + DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, GPENCIL_render_cache); + + GPENCIL_cache_finish(vedata); + GPENCIL_draw_scene(vedata); + + /* combined data */ + GPENCIL_render_result_combined(render_layer, viewname, vedata, rect); + /* z-depth data */ + GPENCIL_render_result_z(render_layer, viewname, vedata, rect); + + /* detach textures */ + if (fbl->main) { + GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx); + GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx); + } + + /* merge previous render image with new GP image */ + if (src_rect_color_data) { + RenderPass *rpass_color_gp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname); + RenderPass *rpass_depth_gp = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname); + float *gp_rect_color_data = rpass_color_gp->rect; + float *gp_rect_depth_data = rpass_depth_gp->rect; + float *gp_pixel_rgba; + float *gp_pixel_depth; + float *src_pixel_rgba; + float *src_pixel_depth; + float tmp[4]; + + for (int i = 0; i < imgsize; i++) { + gp_pixel_rgba = &gp_rect_color_data[i * 4]; + gp_pixel_depth = &gp_rect_depth_data[i]; + + src_pixel_rgba = &src_rect_color_data[i * 4]; + src_pixel_depth = &src_rect_depth_data[i]; + + /* check grease pencil render transparency */ + if (gp_pixel_rgba[3] > 0.0f) { + copy_v4_v4(tmp, gp_pixel_rgba); + if (src_pixel_rgba[3] > 0.0f) { + /* copy source color on back */ + copy_v4_v4(gp_pixel_rgba, src_pixel_rgba); + /* check z-depth */ + if (gp_pixel_depth[0] > src_pixel_depth[0]) { + /* copy source z-depth */ + gp_pixel_depth[0] = src_pixel_depth[0]; + /* blend gp render */ + blend_pixel(tmp, gp_pixel_rgba); + /* blend object on top */ + blend_pixel(src_pixel_rgba, gp_pixel_rgba); + } + else { + /* blend gp render */ + blend_pixel(tmp, gp_pixel_rgba); + } + } + } + else { + copy_v4_v4(gp_pixel_rgba, src_pixel_rgba); + gp_pixel_depth[0] = src_pixel_depth[0]; + } + } + + /* free memory */ + MEM_SAFE_FREE(src_rect_color_data); + MEM_SAFE_FREE(src_rect_depth_data); + } +} diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c new file mode 100644 index 00000000000..e453224020d --- /dev/null +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c @@ -0,0 +1,848 @@ +/* + * Copyright 2017, Blender Foundation. + * + * 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. + * + * Contributor(s): Antonio Vazquez + * + */ + +/** \file blender/draw/engines/gpencil/gpencil_shader_fx.c + * \ingroup draw + */ +#include "DNA_gpencil_types.h" +#include "DNA_shader_fx_types.h" +#include "DNA_screen_types.h" +#include "DNA_view3d_types.h" +#include "DNA_camera_types.h" + +#include "BKE_gpencil.h" +#include "BKE_shader_fx.h" + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "BKE_camera.h" + +#include "ED_view3d.h" +#include "ED_gpencil.h" + +#include "gpencil_engine.h" + +extern char datatoc_gpencil_fx_blur_frag_glsl[]; +extern char datatoc_gpencil_fx_colorize_frag_glsl[]; +extern char datatoc_gpencil_fx_flip_frag_glsl[]; +extern char datatoc_gpencil_fx_light_frag_glsl[]; +extern char datatoc_gpencil_fx_pixel_frag_glsl[]; +extern char datatoc_gpencil_fx_rim_prepare_frag_glsl[]; +extern char datatoc_gpencil_fx_rim_resolve_frag_glsl[]; +extern char datatoc_gpencil_fx_swirl_frag_glsl[]; +extern char datatoc_gpencil_fx_wave_frag_glsl[]; + +/* verify if this fx is active */ +static bool effect_is_active(Object *ob, ShaderFxData *fx, bool is_render) +{ + if (fx == NULL) { + return false; + } + + bGPdata *gpd = ob->data; + if (gpd == NULL) { + return false; + } + + bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd); + if (((fx->mode & eShaderFxMode_Editmode) == 0) && (is_edit)) { + return false; + } + + if (((fx->mode & eShaderFxMode_Realtime) && (is_render == false)) || + ((fx->mode & eShaderFxMode_Render) && (is_render == true))) + { + return true; + } + + return false; +} + +/* get normal of draw using one stroke of visible layer +* /param gpd GP datablock +* /param r_point Point on plane +* /param r_normal Normal vector +*/ +static bool get_normal_vector(bGPdata *gpd, float r_point[3], float r_normal[3]) +{ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpl->flag & GP_LAYER_HIDE) + continue; + + /* get frame */ + bGPDframe *gpf = gpl->actframe; + if (gpf == NULL) + continue; + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + if (gps->totpoints >= 3) { + bGPDspoint *pt = &gps->points[0]; + BKE_gpencil_stroke_normal(gps, r_normal); + /* in some weird situations, the normal cannot be calculated, so try next stroke */ + if ((r_normal[0] != 0.0f) || (r_normal[1] != 0.0f) || (r_normal[2] != 0.0f)) { + copy_v3_v3(r_point, &pt->x); + return true; + } + } + } + } + + return false; +} + +/* helper to get near and far depth of field values */ +static void GPENCIL_dof_nearfar(Object *camera, float coc, float nearfar[2]) +{ + if (camera == NULL) { + return; + } + + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + Camera *cam = (Camera *)camera->data; + + float fstop = cam->gpu_dof.fstop; + float focus_dist = BKE_camera_object_dof_distance(camera); + float focal_len = cam->lens; + + /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm + * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though + * because the shader reads coordinates in world space, which is in blender units. + * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */ + float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f; + float scale_camera = 0.001f / scale; + /* we want radius here for the aperture number */ + float aperture_scaled = 0.5f * scale_camera * focal_len / fstop; + float focal_len_scaled = scale_camera * focal_len; + + float hyperfocal = (focal_len_scaled * focal_len_scaled) / (aperture_scaled * coc); + nearfar[0] = (hyperfocal * focus_dist) / (hyperfocal + focal_len); + nearfar[1] = (hyperfocal * focus_dist) / (hyperfocal - focal_len); +} + +/* **************** Shader Effects ***************************** */ + +/* Gaussian Blur FX + * The effect is done using two shading groups because is faster to apply horizontal + * and vertical in different operations. + */ +static void DRW_gpencil_fx_blur( + ShaderFxData *fx, int ob_idx, GPENCIL_e_data *e_data, + GPENCIL_Data *vedata, tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + + BlurShaderFxData *fxd = (BlurShaderFxData *)fx; + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; + RegionView3D *rv3d = draw_ctx->rv3d; + DRWShadingGroup *fx_shgrp; + + Object *ob = cache->ob; + bGPdata *gpd = (bGPdata *)ob->data; + + fxd->blur[0] = fxd->radius[0]; + fxd->blur[1] = fxd->radius[1]; + + /* init weight */ + if (fxd->flag & FX_BLUR_DOF_MODE) { + /* viewport and opengl render */ + Object *camera = NULL; + if (rv3d) { + if (rv3d->persp == RV3D_CAMOB) { + camera = v3d->camera; + } + } + else { + camera = stl->storage->camera; + } + + if (camera) { + float nearfar[2]; + GPENCIL_dof_nearfar(camera, fxd->coc, nearfar); + float zdepth = stl->g_data->gp_object_cache[ob_idx].zdepth; + /* the object is on focus area */ + if ((zdepth >= nearfar[0]) && (zdepth <= nearfar[1])) { + fxd->blur[0] = 0; + fxd->blur[1] = 0; + } + else { + float f; + if (zdepth < nearfar[0]) { + f = nearfar[0] - zdepth; + } + else { + f = zdepth - nearfar[1]; + } + fxd->blur[0] = f; + fxd->blur[1] = f; + CLAMP2(&fxd->blur[0], 0, fxd->radius[0]); + } + } + else { + /* if not camera view, the blur is disabled */ + fxd->blur[0] = 0; + fxd->blur[1] = 0; + } + } + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Colorize FX */ +static void DRW_gpencil_fx_colorize( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata) +{ + if (fx == NULL) { + return; + } + ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_vec4(fx_shgrp, "low_color", &fxd->low_color[0], 1); + DRW_shgroup_uniform_vec4(fx_shgrp, "high_color", &fxd->high_color[0], 1); + DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1); + DRW_shgroup_uniform_float(fx_shgrp, "factor", &fxd->factor, 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Flip FX */ +static void DRW_gpencil_fx_flip( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata) +{ + if (fx == NULL) { + return; + } + FlipShaderFxData *fxd = (FlipShaderFxData *)fx; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + + fxd->flipmode = 100; + /* the number works as bit flag */ + if (fxd->flag & FX_FLIP_HORIZONTAL) { + fxd->flipmode += 10; + } + if (fxd->flag & FX_FLIP_VERTICAL) { + fxd->flipmode += 1; + } + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_int(fx_shgrp, "flipmode", &fxd->flipmode, 1); + + DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Light FX */ +static void DRW_gpencil_fx_light( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + Object *ob = cache->ob; + LightShaderFxData *fxd = (LightShaderFxData *)fx; + + if (fxd->object == NULL) { + return; + } + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + + DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1); + + /* location of the light using obj location as origin */ + copy_v3_v3(fxd->loc, &fxd->object->loc[0]); + + /* Calc distance to strokes plane + * The w component of location is used to transfer the distance to drawing plane + */ + float r_point[3], r_normal[3]; + float r_plane[4]; + bGPdata *gpd = (bGPdata *)ob->data; + if (!get_normal_vector(gpd, r_point, r_normal)) { + return; + } + mul_mat3_m4_v3(ob->obmat, r_normal); /* only rotation component */ + plane_from_point_normal_v3(r_plane, r_point, r_normal); + float dt = dist_to_plane_v3(fxd->object->loc, r_plane); + fxd->loc[3] = dt; /* use last element to save it */ + + DRW_shgroup_uniform_vec4(fx_shgrp, "loc", &fxd->loc[0], 1); + + DRW_shgroup_uniform_float(fx_shgrp, "energy", &fxd->energy, 1); + DRW_shgroup_uniform_float(fx_shgrp, "ambient", &fxd->ambient, 1); + + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Pixelate FX */ +static void DRW_gpencil_fx_pixel( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + Object *ob = cache->ob; + PixelShaderFxData *fxd = (PixelShaderFxData *)fx; + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + bGPdata *gpd = (bGPdata *)ob->data; + + fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES; + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3); + DRW_shgroup_uniform_vec4(fx_shgrp, "color", &fxd->rgba[0], 1); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Rim FX */ +static void DRW_gpencil_fx_rim( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + Object *ob = cache->ob; + RimShaderFxData *fxd = (RimShaderFxData *)fx; + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + bGPdata *gpd = (bGPdata *)ob->data; + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + /* prepare pass */ + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_prepare_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1); + + DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2); + DRW_shgroup_uniform_vec3(fx_shgrp, "rim_color", &fxd->rim_rgb[0], 1); + DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh = fx_shgrp; + + /* blur pass */ + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_rim); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_rim); + DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh_b = fx_shgrp; + + /* resolve pass */ + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_resolve_sh, + psl->fx_shader_pass_blend); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_rim); + DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1); + DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1); + + fxd->runtime.fx_sh_c = fx_shgrp; +} + +/* Swirl FX */ +static void DRW_gpencil_fx_swirl( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata, + tGPencilObjectCache *cache) +{ + if (fx == NULL) { + return; + } + Object *ob = cache->ob; + SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; + if (fxd->object == NULL) { + return; + } + + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + DRWShadingGroup *fx_shgrp; + bGPdata *gpd = (bGPdata *)ob->data; + + fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT; + + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + + DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1); + + DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &fxd->object->loc[0], 1); + + DRW_shgroup_uniform_int(fx_shgrp, "radius", &fxd->radius, 1); + DRW_shgroup_uniform_float(fx_shgrp, "angle", &fxd->angle, 1); + DRW_shgroup_uniform_int(fx_shgrp, "transparent", &fxd->transparent, 1); + + DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1); + DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* Wave Distorsion FX */ +static void DRW_gpencil_fx_wave( + ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata) +{ + if (fx == NULL) { + return; + } + + WaveShaderFxData *fxd = (WaveShaderFxData *)fx; + + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); + + DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass); + DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); + DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); + DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1); + DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1); + DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1); + DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1); + DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1); + + fxd->runtime.fx_sh = fx_shgrp; +} + +/* ************************************************************** */ + +/* create all FX shaders */ +void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data) +{ + /* fx shaders (all in screen space) */ + if (!e_data->gpencil_fx_blur_sh) { + e_data->gpencil_fx_blur_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_blur_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_colorize_sh) { + e_data->gpencil_fx_colorize_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_colorize_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_flip_sh) { + e_data->gpencil_fx_flip_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_flip_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_light_sh) { + e_data->gpencil_fx_light_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_light_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_pixel_sh) { + e_data->gpencil_fx_pixel_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_pixel_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_rim_prepare_sh) { + e_data->gpencil_fx_rim_prepare_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_rim_prepare_frag_glsl, NULL); + + e_data->gpencil_fx_rim_resolve_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_rim_resolve_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_swirl_sh) { + e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_swirl_frag_glsl, NULL); + } + if (!e_data->gpencil_fx_wave_sh) { + e_data->gpencil_fx_wave_sh = DRW_shader_create_fullscreen( + datatoc_gpencil_fx_wave_frag_glsl, NULL); + } +} + +/* free FX shaders */ +void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data) +{ + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_blur_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_colorize_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_flip_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_light_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_pixel_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_prepare_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh); + DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh); +} + +/* create all passes used by FX */ +void GPENCIL_create_fx_passes(GPENCIL_PassList *psl) +{ + psl->fx_shader_pass = DRW_pass_create( + "GPencil Shader FX Pass", + DRW_STATE_WRITE_COLOR | + DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); + psl->fx_shader_pass_blend = DRW_pass_create( + "GPencil Shader FX Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | + DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS); +} + + +/* prepare fx shading groups */ +void DRW_gpencil_fx_prepare( + struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, + struct tGPencilObjectCache *cache) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + Object *ob = cache->ob; + int ob_idx = cache->idx; + + if (ob->shader_fx.first == NULL) { + return; + } + /* loop FX */ + for (ShaderFxData *fx = ob->shader_fx.first; fx; fx = fx->next) { + if (effect_is_active(ob, fx, stl->storage->is_render)) { + switch (fx->type) { + case eShaderFxType_Blur: + DRW_gpencil_fx_blur(fx, ob_idx, e_data, vedata, cache); + break; + case eShaderFxType_Colorize: + DRW_gpencil_fx_colorize(fx, e_data, vedata); + break; + case eShaderFxType_Flip: + DRW_gpencil_fx_flip(fx, e_data, vedata); + break; + case eShaderFxType_Light: + DRW_gpencil_fx_light(fx, e_data, vedata, cache); + break; + case eShaderFxType_Pixel: + DRW_gpencil_fx_pixel(fx, e_data, vedata, cache); + break; + case eShaderFxType_Rim: + DRW_gpencil_fx_rim(fx, e_data, vedata, cache); + break; + case eShaderFxType_Swirl: + DRW_gpencil_fx_swirl(fx, e_data, vedata, cache); + break; + case eShaderFxType_Wave: + DRW_gpencil_fx_wave(fx, e_data, vedata); + break; + default: + break; + } + } + } + +} + +/* helper to draw one FX pass and do ping-pong copy */ +static void gpencil_draw_fx_pass( + GPENCIL_e_data *e_data, + GPENCIL_PassList *psl, + GPENCIL_FramebufferList *fbl, + DRWShadingGroup *shgrp, bool blend) +{ + if (shgrp == NULL) { + return; + } + + static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + GPU_framebuffer_bind(fbl->temp_fb_b); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); + + /* draw effect pass in temp texture (B) using as source the previous image + * existing in the other temp texture (A) */ + if (!blend) { + DRW_draw_pass_subset(psl->fx_shader_pass, shgrp, shgrp); + } + else { + DRW_draw_pass_subset(psl->fx_shader_pass_blend, shgrp, shgrp); + } + + /* copy pass from b to a for ping-pong frame buffers */ + e_data->input_depth_tx = e_data->temp_depth_tx_b; + e_data->input_color_tx = e_data->temp_color_tx_b; + + GPU_framebuffer_bind(fbl->temp_fb_a); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); + DRW_draw_pass(psl->mix_pass_noblend); +} + +/* helper to manage gaussian blur passes */ +static void draw_gpencil_blur_passes( + struct GPENCIL_e_data *e_data, + struct GPENCIL_Data *vedata, + struct BlurShaderFxData *fxd) +{ + if (fxd->runtime.fx_sh == NULL) { + return; + } + + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + DRWShadingGroup *shgrp = fxd->runtime.fx_sh; + int samples = fxd->samples; + + float bx = fxd->blur[0]; + float by = fxd->blur[1]; + + /* the blur is done in two steps (Hor/Ver) because is faster and + * gets better result + * + * samples could be 0 and disable de blur effects because sometimes + * is easier animate the number of samples only, instead to animate the + * hide/unhide and the number of samples to make some effects. + */ + for (int b = 0; b < samples; b++) { + /* horizontal */ + if (bx > 0) { + fxd->blur[0] = bx; + fxd->blur[1] = 0; + gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true); + } + /* vertical */ + if (by > 0) { + fxd->blur[0] = 0; + fxd->blur[1] = by; + gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true); + } + } +} + +static void draw_gpencil_rim_blur( + struct GPENCIL_e_data *UNUSED(e_data), + struct GPENCIL_Data *vedata, + struct RimShaderFxData *fxd) +{ + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + GPU_framebuffer_bind(fbl->temp_fb_b); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); + DRW_draw_pass_subset(psl->fx_shader_pass_blend, + fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b); + + /* copy pass from b for ping-pong frame buffers */ + GPU_framebuffer_bind(fbl->temp_fb_rim); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_rim, clearcol, 1.0f); + DRW_draw_pass(psl->mix_pass_noblend); +} + +/* helper to draw RIM passes */ +static void draw_gpencil_rim_passes( + struct GPENCIL_e_data *e_data, + struct GPENCIL_Data *vedata, + struct RimShaderFxData *fxd) +{ + if (fxd->runtime.fx_sh_b == NULL) { + return; + } + + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + + static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + int bx = fxd->blur[0]; + int by = fxd->blur[1]; + + /* prepare mask */ + GPU_framebuffer_bind(fbl->temp_fb_rim); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_rim, clearcol, 1.0f); + DRW_draw_pass_subset( + psl->fx_shader_pass_blend, + fxd->runtime.fx_sh, fxd->runtime.fx_sh); + + /* blur rim */ + e_data->input_depth_tx = e_data->temp_depth_tx_b; + e_data->input_color_tx = e_data->temp_color_tx_b; + + if ((fxd->samples > 0) && ((bx > 0) || (by > 0))) { + for (int x = 0; x < fxd->samples; x++) { + + /* horizontal */ + fxd->blur[0] = bx; + fxd->blur[1] = 0; + draw_gpencil_rim_blur(e_data, vedata, fxd); + + /* Vertical */ + fxd->blur[0] = 0; + fxd->blur[1] = by; + draw_gpencil_rim_blur(e_data, vedata, fxd); + + fxd->blur[0] = bx; + fxd->blur[1] = by; + } + } + /* resolve */ + GPU_framebuffer_bind(fbl->temp_fb_b); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); + DRW_draw_pass_subset( + psl->fx_shader_pass_blend, + fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c); + + /* copy pass from b to a for ping-pong frame buffers */ + e_data->input_depth_tx = e_data->temp_depth_tx_b; + e_data->input_color_tx = e_data->temp_color_tx_b; + + GPU_framebuffer_bind(fbl->temp_fb_a); + GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); + DRW_draw_pass(psl->mix_pass_noblend); +} + +/* apply all object fx effects */ +void DRW_gpencil_fx_draw( + struct GPENCIL_e_data *e_data, + struct GPENCIL_Data *vedata, struct tGPencilObjectCache *cache) +{ + GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; + GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; + GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl; + Object *ob = cache->ob; + + /* loop FX modifiers */ + for (ShaderFxData *fx = ob->shader_fx.first; fx; fx = fx->next) { + if (effect_is_active(ob, fx, stl->storage->is_render)) { + switch (fx->type) { + case eShaderFxType_Blur: + { + BlurShaderFxData *fxd = (BlurShaderFxData *)fx; + draw_gpencil_blur_passes(e_data, vedata, fxd); + break; + } + case eShaderFxType_Colorize: + { + ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + case eShaderFxType_Flip: + { + FlipShaderFxData *fxd = (FlipShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + case eShaderFxType_Light: + { + LightShaderFxData *fxd = (LightShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + case eShaderFxType_Pixel: + { + PixelShaderFxData *fxd = (PixelShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + case eShaderFxType_Rim: + { + RimShaderFxData *fxd = (RimShaderFxData *)fx; + draw_gpencil_rim_passes(e_data, vedata, fxd); + break; + } + case eShaderFxType_Swirl: + { + SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + case eShaderFxType_Wave: + { + WaveShaderFxData *fxd = (WaveShaderFxData *)fx; + gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false); + break; + } + default: + break; + } + } + } +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl new file mode 100644 index 00000000000..1d66ba3d4d4 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl @@ -0,0 +1,60 @@ +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +uniform int blur[2]; + +uniform vec3 loc; +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform float pixfactor; + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); +vec2 noffset = vec2(blur[0], blur[1]); + +out vec4 FragColor; + +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + + vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + + float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize); + float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize); + + /* apply blurring, using a 9-tap filter with predefined gaussian weights */ + /* depth */ + float outdepth = 0; + outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0).r * 0.0947416; + outdepth += texelFetch(strokeDepth, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0).r * 0.118318; + outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0).r * 0.0947416; + outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0).r * 0.118318; + + outdepth += texelFetch(strokeDepth, ivec2(uv.x, uv.y), 0).r * 0.147761; + + outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0).r * 0.118318; + outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0).r * 0.0947416; + outdepth += texelFetch(strokeDepth, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0).r * 0.118318; + outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0).r * 0.0947416; + + gl_FragDepth = outdepth; + + /* color */ + vec4 outcolor = vec4(0.0); + outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416; + outcolor += texelFetch(strokeColor, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0) * 0.118318; + outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416; + outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318; + + outcolor += texelFetch(strokeColor, ivec2(uv.x, uv.y), 0) * 0.147761; + + outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318; + outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416; + outcolor += texelFetch(strokeColor, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0) * 0.118318; + outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416; + + FragColor = clamp(outcolor, 0, 1.0); +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl new file mode 100644 index 00000000000..7d0ce4a804e --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl @@ -0,0 +1,86 @@ +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +uniform vec4 low_color; +uniform vec4 high_color; +uniform int mode; +uniform float factor; + +out vec4 FragColor; + +#define MODE_GRAYSCALE 0 +#define MODE_SEPIA 1 +#define MODE_BITONE 2 +#define MODE_CUSTOM 3 +#define MODE_TRANSPARENT 4 + +float get_luminance(vec4 color) +{ + float lum = (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.723); + return lum; +} + +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + + float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r; + vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0); + float luminance = get_luminance(src_pixel); + vec4 outcolor; + + /* is transparent */ + if (src_pixel.a == 0.0f) { + discard; + } + + switch(mode) { + case MODE_GRAYSCALE: + { + outcolor = vec4(luminance, luminance, luminance, src_pixel.a); + break; + } + case MODE_SEPIA: + { + float Red = (src_pixel.r * 0.393) + (src_pixel.g * 0.769) + (src_pixel.b * 0.189); + float Green = (src_pixel.r * 0.349) + (src_pixel.g * 0.686) + (src_pixel.b * 0.168); + float Blue = (src_pixel.r * 0.272) + (src_pixel.g * 0.534) + (src_pixel.b * 0.131); + outcolor = vec4(Red, Green, Blue, src_pixel.a); + break; + } + case MODE_BITONE: + { + if (luminance <= factor) { + outcolor = low_color; + } + else { + outcolor = high_color; + } + break; + } + case MODE_CUSTOM: + { + /* if below umbral, force custom color */ + if (luminance <= factor) { + outcolor = low_color; + } + else { + outcolor = vec4(luminance * low_color.r, luminance * low_color.b, luminance * low_color.b, src_pixel.a); + } + break; + } + case MODE_TRANSPARENT: + { + outcolor = vec4(src_pixel.rgb, src_pixel.a * factor); + break; + } + default: + { + outcolor = src_pixel; + } + + } + + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl new file mode 100644 index 00000000000..94fb3405c79 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl @@ -0,0 +1,37 @@ +out vec4 FragColor; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +uniform vec2 wsize; +uniform int flipmode; + +void main() +{ + vec2 mode = vec2(0,0); + /* horz. */ + if (flipmode >= 110) { + mode[0] = 1; + } + /* vert. */ + if ((flipmode == 101) || (flipmode == 111)) { + mode[1] = 1; + } + + vec2 uv = vec2(gl_FragCoord.xy); + float stroke_depth; + vec4 outcolor; + + if (mode[0] > 0) { + uv.x = wsize.x - uv.x; + } + if (mode[1] > 0) { + uv.y = wsize.y - uv.y; + } + + ivec2 iuv = ivec2(uv.x, uv.y); + stroke_depth = texelFetch(strokeDepth, iuv, 0).r; + outcolor = texelFetch(strokeColor, iuv, 0); + + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl new file mode 100644 index 00000000000..f3026c32fc8 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl @@ -0,0 +1,70 @@ +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +uniform vec2 Viewport; +uniform vec4 loc; +uniform float energy; +uniform float ambient; + +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform float pixfactor; + +out vec4 FragColor; + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); + +#define height loc.w + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + /* need to calculate ndc because this is not done by vertex shader */ + vec3 ndc = vec3(vertex).xyz / vertex.w; + + vec2 sc; + sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x; + sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y; + + return sc; +} + +void main() +{ + float stroke_depth; + vec4 objcolor; + + vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + vec2 light2d = toScreenSpace(light_loc); + + /* calc pixel scale */ + float pxscale = (ProjectionMatrix[3][3] == 0.0) ? (10.0 / (light_loc.z * defaultpixsize)) : (10.0 / defaultpixsize); + pxscale = max(pxscale, 0.000001); + + /* the height over plane is received in the w component of the loc + * and needs a factor to adapt to pixels + */ + float peak = height * 10.0 * pxscale; + vec3 light3d = vec3(light2d.x, light2d.y, peak); + + vec2 uv = vec2(gl_FragCoord.xy); + vec3 frag_loc = vec3(uv.x, uv.y, 0); + vec3 norm = vec3(0, 0, 1.0); /* always z-up */ + + ivec2 iuv = ivec2(uv.x, uv.y); + stroke_depth = texelFetch(strokeDepth, iuv, 0).r; + objcolor = texelFetch(strokeColor, iuv, 0); + + /* diffuse light */ + vec3 lightdir = normalize(light3d - frag_loc); + float diff = max(dot(norm, lightdir), 0.0); + float dist = length(light3d - frag_loc) / pxscale; + float factor = diff * ((energy * 100.0) / (dist * dist)); + + vec3 result = factor * max(ambient, 0.1) * vec3(objcolor); + + gl_FragDepth = stroke_depth; + FragColor = vec4(result.r, result.g, result.b, objcolor.a); +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl new file mode 100644 index 00000000000..d1a57a9a1b6 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl @@ -0,0 +1,50 @@ +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +uniform int size[3]; +uniform vec4 color; + +uniform vec3 loc; +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform float pixfactor; + +out vec4 FragColor; + +int uselines = size[2]; +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); +vec2 nsize = max(vec2(size[0], size[1]), 3.0); + +/* This pixelation shader is a modified version of original Geeks3d.com code */ +void main() +{ + vec2 uv = vec2(gl_FragCoord.xy); + vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + + float dx = (ProjectionMatrix[3][3] == 0.0) ? (nsize[0] / (nloc.z * defaultpixsize)) : (nsize[0] / defaultpixsize); + float dy = (ProjectionMatrix[3][3] == 0.0) ? (nsize[1] / (nloc.z * defaultpixsize)) : (nsize[1] / defaultpixsize); + + dx = max(abs(dx), 3.0); + dy = max(abs(dy), 3.0); + + vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy)); + + float stroke_depth = texelFetch(strokeDepth, ivec2(coord), 0).r; + vec4 outcolor = texelFetch(strokeColor, ivec2(coord), 0); + + if (uselines == 1) { + float difx = uv.x - (floor(uv.x / nsize[0]) * nsize[0]); + if ((difx == 0.5) && (outcolor.a > 0)) { + outcolor = color; + } + float dify = uv.y - (floor(uv.y / nsize[1]) * nsize[1]); + if ((dify == 0.5) && (outcolor.a > 0)) { + outcolor = color; + } + } + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl new file mode 100644 index 00000000000..fe35d3832e1 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl @@ -0,0 +1,64 @@ +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +/* ******************************************************************* */ +/* create rim and mask */ +/* ******************************************************************* */ +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +uniform vec2 Viewport; + +uniform int offset[2]; +uniform vec3 rim_color; +uniform vec3 mask_color; + +uniform vec3 loc; +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform float pixfactor; + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); +vec2 noffset = vec2(offset[0], offset[1]); + +out vec4 FragColor; + +void main() +{ + vec2 uv = vec2(gl_FragCoord.xy); + vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + + float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize); + float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize); + + float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r; + vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0); + vec4 offset_pixel= texelFetch(strokeColor, ivec2(uv.x - dx, uv.y - dy), 0); + vec4 outcolor; + + /* is transparent */ + if (src_pixel.a == 0.0f) { + discard; + } + /* check inside viewport */ + else if ((uv.x - dx < 0) || (uv.x - dx > Viewport[0])) { + discard; + } + else if ((uv.y - dy < 0) || (uv.y - dy > Viewport[1])) { + discard; + } + /* pixel is equal to mask color, keep */ + else if (src_pixel.rgb == mask_color.rgb) { + discard; + } + else { + if ((src_pixel.a > 0) && (offset_pixel.a > 0)) { + discard; + } + else { + outcolor = vec4(rim_color, 1.0); + } + } + + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl new file mode 100644 index 00000000000..5e5edbd8325 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl @@ -0,0 +1,101 @@ +/* ******************************************************************* */ +/* Resolve RIM pass and add blur if needed */ +/* ******************************************************************* */ +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +uniform sampler2D strokeRim; + +uniform vec3 mask_color; +uniform int mode; + +out vec4 FragColor; + +#define MODE_NORMAL 0 +#define MODE_OVERLAY 1 +#define MODE_ADD 2 +#define MODE_SUB 3 +#define MODE_MULTIPLY 4 +#define MODE_DIVIDE 5 + +float overlay_color(float a, float b) +{ + float rtn; + if (a < 0.5) { + rtn = 2.0 * a * b; + } + else { + rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b); + } + + return rtn; +} + +vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color) +{ + vec4 outcolor; + if (mode == MODE_NORMAL) { + outcolor = mix_color; + } + else if (mode == MODE_OVERLAY) { + outcolor.r = overlay_color(src_color.r, mix_color.r); + outcolor.g = overlay_color(src_color.g, mix_color.g); + outcolor.b = overlay_color(src_color.b, mix_color.b); + } + else if (mode == MODE_ADD){ + outcolor = src_color + mix_color; + } + else if (mode == MODE_SUB){ + outcolor = src_color - mix_color; + } + else if (mode == MODE_MULTIPLY) { + outcolor = src_color * mix_color; + } + else if (mode == MODE_DIVIDE) { + outcolor = src_color / mix_color; + } + else { + outcolor = mix_color; + } + + /* use always the alpha of source color */ + + outcolor.a = src_color.a; + /* use alpha to calculate the weight of the mixed color */ + outcolor = mix(src_color, outcolor, mix_color.a); + + return outcolor; +} + +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + + float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r; + vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0); + vec4 rim_pixel= texelFetch(strokeRim, uv.xy, 0); + + vec4 outcolor = src_pixel; + + /* is transparent */ + if (src_pixel.a == 0.0f) { + discard; + } + /* pixel is equal to mask color, keep */ + else if (src_pixel.rgb == mask_color.rgb) { + outcolor = src_pixel; + } + else { + if (rim_pixel.a == 0.0f) { + outcolor = src_pixel; + } + else { + outcolor = get_blend_color(mode, src_pixel, rim_pixel); + } + } + + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} + + + diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl new file mode 100644 index 00000000000..6ce64350b3d --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl @@ -0,0 +1,70 @@ +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +uniform vec2 Viewport; +uniform vec3 loc; +uniform int radius; +uniform float angle; +uniform int transparent; + +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform float pixfactor; + +out vec4 FragColor; + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + /* need to calculate ndc because this is not done by vertex shader */ + vec3 ndc = vec3(vertex).xyz / vertex.w; + + vec2 sc; + sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x; + sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y; + + return sc; +} + +/* This swirl shader is a modified version of original Geeks3d.com code */ +void main() +{ + vec2 uv = vec2(gl_FragCoord.xy); + float stroke_depth; + vec4 outcolor; + + vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + vec2 center = toScreenSpace(center3d); + vec2 tc = uv - center; + + float dist = length(tc); + float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) : (radius / defaultpixsize); + pxradius = max(pxradius, 1); + + if (dist <= pxradius) { + float percent = (pxradius - dist) / pxradius; + float theta = percent * percent * angle * 8.0; + float s = sin(theta); + float c = cos(theta); + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + tc += center; + + stroke_depth = texelFetch(strokeDepth, ivec2(tc), 0).r; + outcolor = texelFetch(strokeColor, ivec2(tc), 0); + } + else { + if (transparent == 1) { + discard; + } + stroke_depth = texelFetch(strokeDepth, ivec2(uv), 0).r; + outcolor = texelFetch(strokeColor, ivec2(uv), 0); + } + + gl_FragDepth = stroke_depth; + FragColor = outcolor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl new file mode 100644 index 00000000000..882b2cf59f1 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl @@ -0,0 +1,40 @@ + +out vec4 FragColor; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +uniform float amplitude; +uniform float period; +uniform float phase; +uniform int orientation; +uniform vec2 wsize; + +#define M_PI 3.1415926535897932384626433832795 + +#define HORIZONTAL 0 +#define VERTICAL 1 + +void main() +{ + vec4 outcolor; + ivec2 uv = ivec2(gl_FragCoord.xy); + float stroke_depth; + + float value; + if (orientation == HORIZONTAL) { + float pval = (uv.x * M_PI) / wsize[0]; + value = amplitude * sin((period * pval) + phase); + outcolor = texelFetch(strokeColor, ivec2(uv.x, uv.y + value), 0); + stroke_depth = texelFetch(strokeDepth, ivec2(uv.x, uv.y + value), 0).r; + } + else { + float pval = (uv.y * M_PI) / wsize[1]; + value = amplitude * sin((period * pval) + phase); + outcolor = texelFetch(strokeColor, ivec2(uv.x + value, uv.y), 0); + stroke_depth = texelFetch(strokeDepth, ivec2(uv.x + value, uv.y), 0).r; + } + + FragColor = outcolor; + gl_FragDepth = stroke_depth; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl new file mode 100644 index 00000000000..cbd7a461dd3 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl @@ -0,0 +1,12 @@ +out vec4 FragColor; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; + +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + + gl_FragDepth = texelFetch(strokeDepth, uv, 0).r; + FragColor = texelFetch(strokeColor, uv, 0); +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl new file mode 100644 index 00000000000..b3bd8e488f2 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl @@ -0,0 +1,17 @@ +in vec4 mColor; +in vec2 mTexCoord; +out vec4 fragColor; + +void main() +{ + vec2 centered = mTexCoord - vec2(0.5); + float dist_squared = dot(centered, centered); + const float rad_squared = 0.25; + + // round point with jaggy edges + if (dist_squared > rad_squared) { + discard; + } + + fragColor = mColor; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl new file mode 100644 index 00000000000..0d2da00db66 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl @@ -0,0 +1,48 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 Viewport; + +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +in vec4 finalColor[1]; +in float finalThickness[1]; + +out vec4 mColor; +out vec2 mTexCoord; + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w) * Viewport; +} + +void main(void) +{ + vec4 P0 = gl_in[0].gl_Position; + vec2 sp0 = toScreenSpace(P0); + + float size = finalThickness[0]; + + /* generate the triangle strip */ + mTexCoord = vec2(0, 1); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, 0, 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, 0, 1.0); + EmitVertex(); + + mTexCoord = vec2(1, 1); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, 0, 1.0); + EmitVertex(); + + mTexCoord = vec2(1, 0); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, 0, 1.0); + EmitVertex(); + + EndPrimitive(); +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl new file mode 100644 index 00000000000..77fdf58bea0 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl @@ -0,0 +1,15 @@ +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec4 color; +in float size; + +out vec4 finalColor; +out float finalThickness; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + finalColor = color; + finalThickness = size; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl new file mode 100644 index 00000000000..35f47d6c418 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl @@ -0,0 +1,140 @@ +uniform vec4 color2; +uniform int fill_type; +uniform float mix_factor; + +uniform float gradient_angle; +uniform float gradient_radius; +uniform float pattern_gridsize; +uniform vec2 gradient_scale; +uniform vec2 gradient_shift; + +uniform float texture_angle; +uniform vec2 texture_scale; +uniform vec2 texture_offset; +uniform int texture_mix; +uniform int texture_flip; +uniform float texture_opacity; +uniform int xraymode; + +uniform sampler2D myTexture; +uniform int texture_clamp; + +/* keep this list synchronized with list in gpencil_draw_utils.c */ +#define SOLID 0 +#define GRADIENT 1 +#define RADIAL 2 +#define CHESS 3 +#define TEXTURE 4 +#define PATTERN 5 + +#define GP_XRAY_FRONT 0 +#define GP_XRAY_3DSPACE 1 +#define GP_XRAY_BACK 2 + +in vec4 finalColor; +in vec2 texCoord_interp; +out vec4 fragColor; +#define texture2D texture + +void set_color(in vec4 color, in vec4 color2, in vec4 tcolor, in float mixv, in float factor, + in int tmix, in int flip, out vec4 ocolor) +{ + /* full color A */ + if (mixv == 1.0) { + if (tmix == 1) { + ocolor = (flip == 0) ? color : tcolor; + } + else { + ocolor = (flip == 0) ? color : color2; + } + } + /* full color B */ + else if (mixv == 0.0) { + if (tmix == 1) { + ocolor = (flip == 0) ? tcolor : color; + } + else { + ocolor = (flip == 0) ? color2 : color; + } + } + /* mix of colors */ + else { + if (tmix == 1) { + ocolor = (flip == 0) ? mix(color, tcolor, factor) : mix(tcolor, color, factor); + } + else { + ocolor = (flip == 0) ? mix(color, color2, factor) : mix(color2, color, factor); + } + } +} + +void main() +{ + vec2 t_center = vec2(0.5, 0.5); + mat2 matrot_tex = mat2(cos(texture_angle), -sin(texture_angle), sin(texture_angle), cos(texture_angle)); + vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset; + vec4 tmp_color; + tmp_color = (texture_clamp == 0) ? texture2D(myTexture, rot_tex * texture_scale) : texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0)); + vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity); + vec4 chesscolor; + + /* solid fill */ + if (fill_type == SOLID) { + fragColor = finalColor; + } + else { + vec2 center = vec2(0.5, 0.5) + gradient_shift; + mat2 matrot = mat2(cos(gradient_angle), -sin(gradient_angle), sin(gradient_angle), cos(gradient_angle)); + vec2 rot = (((matrot * (texCoord_interp - center)) + center) * gradient_scale) + gradient_shift; + /* gradient */ + if (fill_type == GRADIENT) { + set_color(finalColor, color2, text_color, mix_factor, rot.x - mix_factor + 0.5, texture_mix, texture_flip, fragColor); + } + /* radial gradient */ + if (fill_type == RADIAL) { + float in_rad = gradient_radius * mix_factor; + float ex_rad = gradient_radius - in_rad; + float intensity = 0; + float distance = length((center - texCoord_interp) * gradient_scale); + if (distance > gradient_radius) { + discard; + } + if (distance > in_rad) { + intensity = clamp(((distance - in_rad) / ex_rad), 0.0, 1.0); + } + set_color(finalColor, color2, text_color, mix_factor, intensity, texture_mix, texture_flip, fragColor); + } + /* chessboard */ + if (fill_type == CHESS) { + vec2 pos = rot / pattern_gridsize; + if ((fract(pos.x) < 0.5 && fract(pos.y) < 0.5) || (fract(pos.x) > 0.5 && fract(pos.y) > 0.5)) { + chesscolor = (texture_flip == 0) ? finalColor : color2; + } + else { + chesscolor = (texture_flip == 0) ? color2 : finalColor; + } + /* mix with texture */ + fragColor = (texture_mix == 1) ? mix(chesscolor, text_color, mix_factor) : chesscolor; + } + /* texture */ + if (fill_type == TEXTURE) { + fragColor = (texture_mix == 1) ? mix(text_color, finalColor, mix_factor) : text_color; + } + /* pattern */ + if (fill_type == PATTERN) { + fragColor = finalColor; + fragColor.a = min(text_color.a, finalColor.a); + } + } + + /* set zdepth */ + if (xraymode == GP_XRAY_FRONT) { + gl_FragDepth = 0.0; + } + if (xraymode == GP_XRAY_3DSPACE) { + gl_FragDepth = gl_FragCoord.z; + } + if (xraymode == GP_XRAY_BACK) { + gl_FragDepth = 0.999999; + } +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl new file mode 100644 index 00000000000..52da354a562 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl @@ -0,0 +1,14 @@ +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec4 color; +in vec2 texCoord; +out vec4 finalColor; +out vec2 texCoord_interp; + +void main(void) +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + finalColor = color; + texCoord_interp = texCoord; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl new file mode 100644 index 00000000000..c2e3f787bec --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl @@ -0,0 +1,9 @@ +uniform vec3 color; +uniform float opacity; + +out vec4 FragColor; + +void main() +{ + FragColor = vec4(color, opacity); +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl new file mode 100644 index 00000000000..0d6d2b22a55 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl @@ -0,0 +1,49 @@ +uniform int color_type; +uniform int mode; +uniform sampler2D myTexture; + +in vec4 mColor; +in vec2 mTexCoord; +out vec4 fragColor; + +#define texture2D texture + +#define GPENCIL_MODE_LINE 0 +#define GPENCIL_MODE_DOTS 1 +#define GPENCIL_MODE_BOX 2 + +/* keep this list synchronized with list in gpencil_engine.h */ +#define GPENCIL_COLOR_SOLID 0 +#define GPENCIL_COLOR_TEXTURE 1 +#define GPENCIL_COLOR_PATTERN 2 + +void main() +{ + vec2 centered = mTexCoord - vec2(0.5); + float dist_squared = dot(centered, centered); + const float rad_squared = 0.25; + + // round point with jaggy edges + if ((mode != GPENCIL_MODE_BOX) && (dist_squared > rad_squared)) + discard; + + vec4 tmp_color = texture2D(myTexture, mTexCoord); + + /* Solid */ + if (color_type == GPENCIL_COLOR_SOLID) { + fragColor = mColor; + } + /* texture */ + if (color_type == GPENCIL_COLOR_TEXTURE) { + fragColor = texture2D(myTexture, mTexCoord); + /* mult both alpha factor to use strength factor with texture */ + fragColor.a = min(fragColor.a * mColor.a, fragColor.a); + } + /* pattern */ + if (color_type == GPENCIL_COLOR_PATTERN) { + vec4 text_color = texture2D(myTexture, mTexCoord); + fragColor = mColor; + /* mult both alpha factor to use strength factor with color alpha limit */ + fragColor.a = min(text_color.a * mColor.a, mColor.a); + } +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl new file mode 100644 index 00000000000..f092149430c --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl @@ -0,0 +1,82 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 Viewport; +uniform int xraymode; + +layout(points) in; +layout(triangle_strip, max_vertices = 4) out; + +in vec4 finalColor[1]; +in float finalThickness[1]; +in vec2 finaluvdata[1]; + +out vec4 mColor; +out vec2 mTexCoord; + +#define GP_XRAY_FRONT 0 +#define GP_XRAY_3DSPACE 1 +#define GP_XRAY_BACK 2 + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w) * Viewport; +} + +/* get zdepth value */ +float getZdepth(vec4 point) +{ + if (xraymode == GP_XRAY_FRONT) { + return 0.0; + } + if (xraymode == GP_XRAY_3DSPACE) { + return (point.z / point.w); + } + if (xraymode == GP_XRAY_BACK) { + return 0.999999; + } + + /* in front by default */ + return 0.0; +} + +vec2 rotateUV(vec2 uv, float angle) +{ + /* translate center of rotation to the center of texture */ + vec2 new_uv = uv - vec2(0.5f, 0.5f); + vec2 rot_uv; + rot_uv.x = new_uv.x * cos(angle) - new_uv.y * sin(angle); + rot_uv.y = new_uv.y * cos(angle) + new_uv.x * sin(angle); + return rot_uv + vec2(0.5f, 0.5f); +} + +void main(void) +{ + /* receive 4 points */ + vec4 P0 = gl_in[0].gl_Position; + vec2 sp0 = toScreenSpace(P0); + + float size = finalThickness[0]; + float aspect = 1.0; + /* generate the triangle strip */ + mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x - size, sp0.y + size * aspect) / Viewport, getZdepth(P0), 1.0); + EmitVertex(); + + mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x - size, sp0.y - size * aspect) / Viewport, getZdepth(P0), 1.0); + EmitVertex(); + + mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x + size, sp0.y + size * aspect) / Viewport, getZdepth(P0), 1.0); + EmitVertex(); + + mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y); + mColor = finalColor[0]; + gl_Position = vec4(vec2(sp0.x + size, sp0.y - size * aspect) / Viewport, getZdepth(P0), 1.0); + EmitVertex(); + + EndPrimitive(); +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl new file mode 100644 index 00000000000..5e89bf8e5ce --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl @@ -0,0 +1,37 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ProjectionMatrix; + +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform int keep_size; +uniform float objscale; +uniform float pixfactor; + +in vec3 pos; +in vec4 color; +in float thickness; +in vec2 uvdata; + +out vec4 finalColor; +out float finalThickness; +out vec2 finaluvdata; + +#define TRUE 1 + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + finalColor = color; + + if (keep_size == TRUE) { + finalThickness = thickness; + } + else { + float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize); + finalThickness = max(size * objscale, 4.0); /* minimum 4 pixels */ + } + + finaluvdata = uvdata; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl new file mode 100644 index 00000000000..dd54e38c3d0 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl @@ -0,0 +1,15 @@ +in vec4 uvcoordsvar; + +out vec4 FragColor; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + float stroke_depth = texelFetch(strokeDepth, uv, 0).r; + vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba; + + FragColor = stroke_color; + gl_FragDepth = stroke_depth; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl new file mode 100644 index 00000000000..d57921c1629 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl @@ -0,0 +1,46 @@ +uniform int color_type; +uniform sampler2D myTexture; + +in vec4 mColor; +in vec2 mTexCoord; +in float uvfac; + +out vec4 fragColor; + +#define texture2D texture + +/* keep this list synchronized with list in gpencil_engine.h */ +#define GPENCIL_COLOR_SOLID 0 +#define GPENCIL_COLOR_TEXTURE 1 +#define GPENCIL_COLOR_PATTERN 2 + +void main() +{ + vec4 tColor = vec4(mColor); + /* if alpha < 0, then encap (only solid mode ) */ + if ((mColor.a < 0) && (color_type == GPENCIL_COLOR_SOLID)) { + vec2 center = vec2(uvfac, 1.0); + tColor.a = tColor.a * -1.0; + float dist = length(mTexCoord - center); + if (dist > 0.50) { + discard; + } + } + /* Solid */ + if (color_type == GPENCIL_COLOR_SOLID) { + fragColor = tColor; + } + /* texture */ + if (color_type == GPENCIL_COLOR_TEXTURE) { + fragColor = texture2D(myTexture, mTexCoord); + /* mult both alpha factor to use strength factor */ + fragColor.a = min(fragColor.a * tColor.a, fragColor.a); + } + /* pattern */ + if (color_type == GPENCIL_COLOR_PATTERN) { + vec4 text_color = texture2D(myTexture, mTexCoord); + fragColor = tColor; + /* mult both alpha factor to use strength factor with color alpha limit */ + fragColor.a = min(text_color.a * tColor.a, tColor.a); + } +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl new file mode 100644 index 00000000000..0bcfe8cddb7 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl @@ -0,0 +1,208 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 Viewport; +uniform int xraymode; +uniform int color_type; + +layout(lines_adjacency) in; +layout(triangle_strip, max_vertices = 13) out; + +in vec4 finalColor[4]; +in float finalThickness[4]; +in vec2 finaluvdata[4]; + +out vec4 mColor; +out vec2 mTexCoord; +out float uvfac; + +#define GP_XRAY_FRONT 0 +#define GP_XRAY_3DSPACE 1 +#define GP_XRAY_BACK 2 + +/* keep this list synchronized with list in gpencil_engine.h */ +#define GPENCIL_COLOR_SOLID 0 +#define GPENCIL_COLOR_TEXTURE 1 +#define GPENCIL_COLOR_PATTERN 2 + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w) * Viewport; +} + +/* get zdepth value */ +float getZdepth(vec4 point) +{ + if (xraymode == GP_XRAY_FRONT) { + return 0.0; + } + if (xraymode == GP_XRAY_3DSPACE) { + return (point.z / point.w); + } + if (xraymode == GP_XRAY_BACK) { + return 0.999999; + } + + /* in front by default */ + return 0.0; +} +void main(void) +{ + float MiterLimit = 0.75; + uvfac = 0; + + /* receive 4 points */ + vec4 P0 = gl_in[0].gl_Position; + vec4 P1 = gl_in[1].gl_Position; + vec4 P2 = gl_in[2].gl_Position; + vec4 P3 = gl_in[3].gl_Position; + + /* get the four vertices passed to the shader */ + vec2 sp0 = toScreenSpace(P0); // start of previous segment + vec2 sp1 = toScreenSpace(P1); // end of previous segment, start of current segment + vec2 sp2 = toScreenSpace(P2); // end of current segment, start of next segment + vec2 sp3 = toScreenSpace(P3); // end of next segment + + /* culling outside viewport */ + vec2 area = Viewport * 4.0; + if (sp1.x < -area.x || sp1.x > area.x) return; + if (sp1.y < -area.y || sp1.y > area.y) return; + if (sp2.x < -area.x || sp2.x > area.x) return; + if (sp2.y < -area.y || sp2.y > area.y) return; + + /* determine the direction of each of the 3 segments (previous, current, next) */ + vec2 v0 = normalize(sp1 - sp0); + vec2 v1 = normalize(sp2 - sp1); + vec2 v2 = normalize(sp3 - sp2); + + /* determine the normal of each of the 3 segments (previous, current, next) */ + vec2 n0 = vec2(-v0.y, v0.x); + vec2 n1 = vec2(-v1.y, v1.x); + vec2 n2 = vec2(-v2.y, v2.x); + + /* determine miter lines by averaging the normals of the 2 segments */ + vec2 miter_a = normalize(n0 + n1); // miter at start of current segment + vec2 miter_b = normalize(n1 + n2); // miter at end of current segment + + /* determine the length of the miter by projecting it onto normal and then inverse it */ + float an1 = dot(miter_a, n1); + float bn1 = dot(miter_b, n2); + if (an1 == 0) an1 = 1; + if (bn1 == 0) bn1 = 1; + float length_a = finalThickness[1] / an1; + float length_b = finalThickness[2] / bn1; + if (length_a <= 0.0) length_a = 0.01; + if (length_b <= 0.0) length_b = 0.01; + + /* prevent excessively long miters at sharp corners */ + if (dot(v0, v1) < -MiterLimit) { + miter_a = n1; + length_a = finalThickness[1]; + + /* close the gap */ + if (dot(v0, n1) > 0) { + mTexCoord = vec2(0, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0.5); + mColor = finalColor[1]; + gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + EndPrimitive(); + } + else { + mTexCoord = vec2(0, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0.5); + mColor = finalColor[1]; + gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + EndPrimitive(); + } + } + + if (dot(v1, v2) < -MiterLimit) { + miter_b = n1; + length_b = finalThickness[2]; + } + + /* generate the start endcap (alpha < 0 used as endcap flag)*/ + if ((P0 == P2) && (color_type == GPENCIL_COLOR_SOLID)){ + mTexCoord = vec2(2, 1); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + vec2 svn1 = normalize(sp1 - sp2) * length_a * 4.0; + gl_Position = vec4((sp1 + svn1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + gl_Position = vec4((sp1 - (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 2); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + gl_Position = vec4((sp1 + (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + } + + /* generate the triangle strip */ + mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 0) : vec2(finaluvdata[1].x, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 1) : vec2(finaluvdata[1].x, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 0) : vec2(finaluvdata[2].x, 0); + mColor = finalColor[2]; + gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 1) : vec2(finaluvdata[2].x, 1); + mColor = finalColor[2]; + gl_Position = vec4((sp2 - length_b * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + /* generate the end endcap (alpha < 0 used as endcap flag)*/ + if ((P1 == P3) && (color_type == GPENCIL_COLOR_SOLID)){ + mTexCoord = vec2(finaluvdata[2].x, 2); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + uvfac = finaluvdata[2].x; + gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = vec2(finaluvdata[2].x, 0); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + uvfac = finaluvdata[2].x; + gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = vec2(finaluvdata[2].x + 2, 1); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + uvfac = finaluvdata[2].x; + vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0; + gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + } + + EndPrimitive(); +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl new file mode 100644 index 00000000000..2f9a105e911 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl @@ -0,0 +1,37 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ProjectionMatrix; + +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform int keep_size; +uniform float objscale; +uniform float pixfactor; + +in vec3 pos; +in vec4 color; +in float thickness; +in vec2 uvdata; + +out vec4 finalColor; +out float finalThickness; +out vec2 finaluvdata; + +#define TRUE 1 + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); + +void main(void) +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + finalColor = color; + + if (keep_size == TRUE) { + finalThickness = thickness; + } + else { + float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize); + finalThickness = max(size * objscale, 1.0); + } + + finaluvdata = uvdata; +} diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl new file mode 100644 index 00000000000..0983e6c4d87 --- /dev/null +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl @@ -0,0 +1,45 @@ +in vec4 uvcoordsvar; + +out vec4 FragColor; + +uniform sampler2D strokeColor; +uniform sampler2D strokeDepth; +uniform int tonemapping; + +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045) + return (c < 0.0) ? 0.0 : c * (1.0 / 12.92); + else + return pow((c + 0.055) * (1.0 / 1.055), 2.4); +} + +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) + return (c < 0.0) ? 0.0 : c * 12.92; + else + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; +} + +void main() +{ + ivec2 uv = ivec2(gl_FragCoord.xy); + float stroke_depth = texelFetch(strokeDepth, uv, 0).r; + vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba; + + /* premult alpha factor to remove double blend effects */ + if (stroke_color.a > 0) { + stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a); + } + + /* apply color correction for render only */ + if (tonemapping == 1) { + stroke_color.r = srgb_to_linearrgb(stroke_color.r); + stroke_color.g = srgb_to_linearrgb(stroke_color.g); + stroke_color.b = srgb_to_linearrgb(stroke_color.b); + } + + FragColor = stroke_color; + gl_FragDepth = stroke_depth; +} diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 0db16ab5472..abba8d3ce91 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -136,6 +136,7 @@ typedef char DRWViewportEmptyList; + typedef struct DrawEngineDataSize { int fbl_len; int txl_len; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index bdfa3211f7c..ac84a847a1b 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -107,6 +107,7 @@ static struct DRWShapeCache { GPUBatch *drw_particle_cross; GPUBatch *drw_particle_circle; GPUBatch *drw_particle_axis; + GPUBatch *drw_gpencil_axes; } SHC = {NULL}; void DRW_shape_cache_free(void) @@ -551,12 +552,67 @@ GPUBatch *DRW_cache_screenspace_circle_get(void) #undef CIRCLE_RESOL } -/** \} */ +/* Grease Pencil object */ +GPUBatch *DRW_cache_gpencil_axes_get(void) +{ + if (!SHC.drw_gpencil_axes) { + int axis; + float v1[3] = { 0.0f, 0.0f, 0.0f }; + float v2[3] = { 0.0f, 0.0f, 0.0f }; + + /* cube data */ + const GLfloat verts[8][3] = { + { -0.25f, -0.25f, -0.25f }, + { -0.25f, -0.25f, 0.25f }, + { -0.25f, 0.25f, -0.25f }, + { -0.25f, 0.25f, 0.25f }, + { 0.25f, -0.25f, -0.25f }, + { 0.25f, -0.25f, 0.25f }, + { 0.25f, 0.25f, -0.25f }, + { 0.25f, 0.25f, 0.25f } + }; + + 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 }; + + /* Position Only 3D format */ + static GPUVertFormat format = { 0 }; + static uint pos_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + + /* alloc 30 elements for cube and 3 axis */ + GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(indices) + 6); + + /* draw axis */ + for (axis = 0; axis < 3; axis++) { + v1[axis] = 1.0f; + v2[axis] = -1.0f; + + GPU_vertbuf_attr_set(vbo, pos_id, axis * 2, v1); + GPU_vertbuf_attr_set(vbo, pos_id, axis * 2 + 1, v2); + + /* reset v1 & v2 to zero for next axis */ + v1[axis] = v2[axis] = 0.0f; + } + + /* draw cube */ + for (int i = 0; i < 24; ++i) { + GPU_vertbuf_attr_set(vbo, pos_id, i + 6, verts[indices[i]]); + } + + SHC.drw_gpencil_axes = GPU_batch_create(GPU_PRIM_LINES, vbo, NULL); + } + return SHC.drw_gpencil_axes; +} + /* -------------------------------------------------------------------- */ /** \name Common Object API - * \{ */ +* \{ */ GPUBatch *DRW_cache_object_wire_outline_get(Object *ob) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 129c0252f30..7d0996b3059 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -82,6 +82,9 @@ struct GPUBatch *DRW_cache_field_vortex_get(void); struct GPUBatch *DRW_cache_field_tube_limit_get(void); struct GPUBatch *DRW_cache_field_cone_limit_get(void); +/* Grease Pencil */ +struct GPUBatch *DRW_cache_gpencil_axes_get(void); + /* Lamps */ struct GPUBatch *DRW_cache_lamp_get(void); struct GPUBatch *DRW_cache_lamp_shadows_get(void); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index eeb7b1c41ee..d4dbe5db80d 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -41,6 +41,7 @@ struct Curve; struct Lattice; struct Mesh; struct MetaBall; +struct bGPdata; /* Expose via BKE callbacks */ void DRW_mball_batch_cache_dirty(struct MetaBall *mb, int mode); @@ -58,6 +59,9 @@ void DRW_lattice_batch_cache_free(struct Lattice *lt); void DRW_particle_batch_cache_dirty(struct ParticleSystem *psys, int mode); void DRW_particle_batch_cache_free(struct ParticleSystem *psys); +void DRW_gpencil_batch_cache_dirty(struct bGPdata *gpd); +void DRW_gpencil_batch_cache_free(struct bGPdata *gpd); + /* Curve */ struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache); struct GPUBatch *DRW_curve_batch_cache_get_normal_edge( diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 714edc23719..e6e20934283 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -48,6 +48,7 @@ #include "ED_space_api.h" #include "ED_screen.h" +#include "ED_gpencil.h" #include "ED_particle.h" #include "ED_view3d.h" @@ -1222,10 +1223,17 @@ static void drw_engines_enable_from_mode(int mode) break; case CTX_MODE_OBJECT: break; + case CTX_MODE_GPENCIL_PAINT: + case CTX_MODE_GPENCIL_EDIT: + case CTX_MODE_GPENCIL_SCULPT: + case CTX_MODE_GPENCIL_WEIGHT: + break; default: BLI_assert(!"Draw mode invalid"); break; } + /* grease pencil */ + use_drw_engine(&draw_engine_gpencil_type); } static void drw_engines_enable_from_overlays(int overlay_flag) @@ -1258,6 +1266,10 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t drw_engines_enable_from_object_mode(); drw_engines_enable_from_mode(mode); } + else { + /* if gpencil must draw the strokes, but not the object */ + drw_engines_enable_from_mode(mode); + } } static void drw_engines_disable(void) @@ -1377,6 +1389,7 @@ void DRW_draw_render_loop_ex( Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = ar->regiondata; + bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)); DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; @@ -1471,6 +1484,17 @@ void DRW_draw_render_loop_ex( drw_engines_draw_scene(); + /* annotations - temporary drawing buffer (3d space) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (do_annotations)) + { + glDisable(GL_DEPTH_TEST); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true); + glEnable(GL_DEPTH_TEST); + } + DRW_draw_callbacks_post_scene(); if (DST.draw_ctx.evil_C) { ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); @@ -1495,6 +1519,17 @@ void DRW_draw_render_loop_ex( DRW_draw_region_info(); + /* annotations - temporary drawing buffer (screenspace) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (do_annotations)) + { + glDisable(GL_DEPTH_TEST); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false); + glEnable(GL_DEPTH_TEST); + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. * 'DRW_draw_region_info' sets the projection in pixel-space. */ @@ -1583,6 +1618,105 @@ void DRW_draw_render_loop_offscreen( GPU_offscreen_bind(ofs, false); } +/* helper to check if exit object type to render */ +static bool DRW_render_check_object_type(struct Depsgraph *depsgraph, short obtype) +{ + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) + { + if ((ob->type == obtype) && (DRW_check_object_visible_within_active_context(ob))) { + return true; + } + } + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END + + return false; +} + +static void DRW_render_gpencil_to_image(RenderEngine *engine, struct Depsgraph *depsgraph, struct RenderLayer *render_layer, const rcti *rect) +{ + if (draw_engine_gpencil_type.render_to_image) { + if (DRW_render_check_object_type(depsgraph, OB_GPENCIL)) { + ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type); + draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect); + } + } +} + +void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph) +{ + /* This function is only valid for Cycles + * Eevee done all work in the Eevee render directly. + * Maybe it can be done equal for both engines? + */ + if (STREQ(engine->type->name, "Eevee")) { + return; + } + + Scene *scene = DEG_get_evaluated_scene(depsgraph); + ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + RenderEngineType *engine_type = engine->type; + RenderData *r = &scene->r; + Render *render = engine->re; + /* Changing Context */ + /* GPXX Review this context */ + DRW_opengl_context_enable(); + /* Reset before using it. */ + drw_state_prepare_clean_for_draw(&DST); + DST.options.is_image_render = true; + DST.options.is_scene_render = true; + DST.options.draw_background = scene->r.alphamode == R_ADDSKY; + DST.buffer_finish_called = true; + + DST.draw_ctx = (DRWContextState) { + .scene = scene, .view_layer = view_layer, + .engine_type = engine_type, + .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT, + }; + drw_context_state_init(); + + DST.viewport = GPU_viewport_create(); + const int size[2] = { (r->size * r->xsch) / 100, (r->size * r->ysch) / 100 }; + GPU_viewport_size_set(DST.viewport, size); + + drw_viewport_var_init(); + + /* set default viewport */ + gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); + glDisable(GL_SCISSOR_TEST); + glViewport(0, 0, size[0], size[1]); + + /* Main rendering. */ + rctf view_rect; + rcti render_rect; + RE_GetViewPlane(render, &view_rect, &render_rect); + if (BLI_rcti_is_empty(&render_rect)) { + BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]); + } + + RenderResult *render_result = RE_engine_get_result(engine); + RenderLayer *render_layer = render_result->layers.first; + + DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); + + /* Force cache to reset. */ + drw_viewport_cache_resize(); + GPU_viewport_free(DST.viewport); + DRW_state_reset(); + + glDisable(GL_DEPTH_TEST); + + /* Restore Drawing area. */ + gpuPopAttrib(); + glEnable(GL_SCISSOR_TEST); + GPU_framebuffer_restore(); + + /* Changing Context */ + /* GPXX Review this context */ + DRW_opengl_context_disable(); + + DST.buffer_finish_called = false; +} + void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) { Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -1663,6 +1797,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) { RE_SetActiveRenderView(render, render_view->name); engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect); + /* grease pencil: render result is merged in the previous render result. */ + DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); DST.buffer_finish_called = false; } @@ -1671,8 +1807,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) /* Force cache to reset. */ drw_viewport_cache_resize(); - /* TODO grease pencil */ - GPU_viewport_free(DST.viewport); GPU_framebuffer_restore(); @@ -2286,6 +2420,7 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_particle_type); DRW_engine_register(&draw_engine_pose_type); DRW_engine_register(&draw_engine_sculpt_type); + DRW_engine_register(&draw_engine_gpencil_type); /* setup callbacks */ { @@ -2304,6 +2439,9 @@ void DRW_engines_register(void) /* BKE: particle.c */ extern void *BKE_particle_batch_cache_dirty_cb; extern void *BKE_particle_batch_cache_free_cb; + /* BKE: gpencil.c */ + extern void *BKE_gpencil_batch_cache_dirty_cb; + extern void *BKE_gpencil_batch_cache_free_cb; BKE_mball_batch_cache_dirty_cb = DRW_mball_batch_cache_dirty; BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; @@ -2319,6 +2457,9 @@ void DRW_engines_register(void) BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty; BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free; + + BKE_gpencil_batch_cache_dirty_cb = DRW_gpencil_batch_cache_dirty; + BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free; } } diff --git a/source/blender/draw/modes/draw_mode_engines.h b/source/blender/draw/modes/draw_mode_engines.h index f88d49dfa96..8e8ddfef5a4 100644 --- a/source/blender/draw/modes/draw_mode_engines.h +++ b/source/blender/draw/modes/draw_mode_engines.h @@ -42,5 +42,6 @@ extern DrawEngineType draw_engine_particle_type; extern DrawEngineType draw_engine_pose_type; extern DrawEngineType draw_engine_sculpt_type; extern DrawEngineType draw_engine_overlay_type; +extern DrawEngineType draw_engine_gpencil_type; #endif /* __DRAW_MODE_ENGINES_H__ */ diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index db906714dd5..675a2a02db8 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -165,6 +165,9 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *field_tube_limit; DRWShadingGroup *field_cone_limit; + /* Grease Pencil */ + DRWShadingGroup *gpencil_axes; + /* Speaker */ DRWShadingGroup *speaker; @@ -1136,6 +1139,10 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_screenspace_circle_get(); stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom); + /* Grease Pencil */ + geom = DRW_cache_gpencil_axes_get(); + stl->g_data->gpencil_axes = shgroup_instance(psl->non_meshes, geom); + /* Speaker */ geom = DRW_cache_speaker_get(); stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom); @@ -1820,6 +1827,14 @@ static void volumes_free_smoke_textures(void) BLI_freelistN(&e_data.smoke_domains); } +static void DRW_shgroup_gpencil(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) +{ + float *color; + DRW_object_wire_theme_get(ob, view_layer, &color); + + DRW_shgroup_call_dynamic_add(stl->g_data->gpencil_axes, color, &ob->empty_drawsize, ob->obmat); +} + static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) { float *color; @@ -2445,6 +2460,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } DRW_shgroup_empty(stl, psl, ob, view_layer); break; + case OB_GPENCIL: + DRW_shgroup_gpencil(stl, ob, view_layer); + break; case OB_SPEAKER: if (hide_object_extra) { break; diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 3c10cda6456..2431bd50e1b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -64,6 +64,7 @@ #include "BKE_animsys.h" #include "BKE_curve.h" +#include "BKE_gpencil.h" #include "BKE_key.h" #include "BKE_main.h" #include "BKE_nla.h" @@ -83,6 +84,8 @@ #include "BIF_gl.h" +#include "DEG_depsgraph.h" + #include "WM_api.h" #include "WM_types.h" @@ -661,6 +664,8 @@ static int acf_object_icon(bAnimListElem *ale) return ICON_OUTLINER_OB_SURFACE; case OB_EMPTY: return ICON_OUTLINER_OB_EMPTY; + case OB_GPENCIL: + return ICON_OUTLINER_OB_GREASEPENCIL; default: return ICON_OBJECT_DATA; } @@ -4048,8 +4053,16 @@ static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void return; } - if (ale_setting->type == ANIMTYPE_GPLAYER) + if (ale_setting->type == ANIMTYPE_GPLAYER) { + /* draw cache updates for settings that affect the visible strokes */ + if (setting == ACHANNEL_SETTING_VISIBLE) { + bGPdata *gpd = (bGPdata *)ale_setting->id; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + + /* UI updates */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); + } /* tag copy-on-write flushing (so that the settings will have an effect) */ if (ale_setting->id) { diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index d768be49ad4..3f22ac6fa3a 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1727,8 +1727,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) bGPDlayer *gpl = (bGPDlayer *)ale->data; /* try to delete the layer's data and the layer itself */ - BKE_gpencil_free_frames(gpl); - BLI_freelinkN(&gpd->layers, gpl); + BKE_gpencil_layer_delete(gpd, gpl); break; } case ANIMTYPE_MASKLAYER: diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index adb5a10c19d..898c8b6464a 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -435,6 +435,16 @@ void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data) ANIM_list_elem_update(ac->bmain, ac->scene, ale); } } + else if (ale->update) { +#if 0 + if (G.debug & G_DEBUG) { + printf("%s: Unhandled animchannel updates (%d) for type=%d (%p)\n", + __func__, ale->update, ale->type, ale->data); + } +#endif + /* Prevent crashes in cases where it can't be handled */ + ale->update = 0; + } BLI_assert(ale->update == 0); } diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 780e984f870..05ea3fd6314 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -552,11 +552,11 @@ static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prev /* populate tree with keyframe nodes */ scene_to_keylist(&ads, scene, &keys, NULL); - gpencil_to_keylist(&ads, scene->gpd, &keys); + gpencil_to_keylist(&ads, scene->gpd, &keys, false); if (ob) { ob_to_keylist(&ads, ob, &keys, NULL); - gpencil_to_keylist(&ads, ob->gpd, &keys); + gpencil_to_keylist(&ads, ob->data, &keys, false); } if (mask) { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index c59d24bbdf8..1981814eb02 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -72,6 +72,7 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_brush_types.h" #include "DNA_object_types.h" #include "DNA_userdef_types.h" #include "DNA_layer_types.h" @@ -1660,7 +1661,7 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads, */ if (filter_mode & ANIMFILTER_ANIMDATA) { /* just add GPD as a channel - this will add everything needed */ - ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL); + ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, gpd); } else { ListBase tmp_data = {NULL, NULL}; @@ -1711,7 +1712,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi /* Objects in the scene */ for (base = view_layer->object_bases.first; base; base = base->next) { /* Only consider this object if it has got some GP data (saving on all the other tests) */ - if (base->object && base->object->gpd) { + if (base->object && (base->object->type == OB_GPENCIL)) { Object *ob = base->object; /* firstly, check if object can be included, by the following factors: @@ -1748,7 +1749,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi /* finally, include this object's grease pencil datablock */ /* XXX: Should we store these under expanders per item? */ - items += animdata_filter_gpencil_data(anim_data, ads, ob->gpd, filter_mode); + items += animdata_filter_gpencil_data(anim_data, ads, ob->data, filter_mode); } } } @@ -2613,8 +2614,10 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data } /* grease pencil */ - if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) { - tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode); + if ((ob->type == OB_GPENCIL) && + (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) + { + tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode); } } END_ANIMFILTER_SUBCHANNELS; diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 30130ce4dac..a8b63e01ac1 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -48,6 +48,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_gpencil_types.h" +#include "DNA_brush_types.h" #include "DNA_mask_types.h" #include "BKE_fcurve.h" @@ -783,7 +784,7 @@ void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos BLI_dlrbTree_init(&keys); - gpencil_to_keylist(ads, gpd, &keys); + gpencil_to_keylist(ads, gpd, &keys, false); BLI_dlrbTree_linkedlist_sync(&keys); @@ -1019,7 +1020,7 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree } -void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys) +void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active) { bGPDlayer *gpl; @@ -1027,7 +1028,9 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys) /* for now, just aggregate out all the frames, but only for visible layers */ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { if ((gpl->flag & GP_LAYER_HIDE) == 0) { - gpl_to_keylist(ads, gpl, keys); + if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) { + gpl_to_keylist(ads, gpl, keys); + } } } } diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 0e09ef6f583..0698282c4e5 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -536,6 +536,16 @@ set(ICON_NAMES # This section is maintained by the updating script, keep BEGIN/END comments. set_property(GLOBAL PROPERTY ICON_GEOM_NAMES # BEGIN ICON_GEOM_NAMES + brush.gpencil.draw.eraser_hard + brush.gpencil.draw.eraser_soft + brush.gpencil.draw.eraser_stroke + brush.gpencil.draw_block + brush.gpencil.draw_fill + brush.gpencil.draw_ink + brush.gpencil.draw_marker + brush.gpencil.draw_noise + brush.gpencil.draw_pen + brush.gpencil.draw_pencil brush.paint_texture.airbrush brush.paint_texture.clone brush.paint_texture.draw @@ -583,6 +593,24 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES ops.generic.select_border ops.generic.select_circle ops.generic.select_lasso + ops.gpencil.draw + ops.gpencil.draw.eraser + ops.gpencil.draw.line + ops.gpencil.draw.poly + ops.gpencil.edit_bend + ops.gpencil.edit_mirror + ops.gpencil.edit_shear + ops.gpencil.edit_to_sphere + ops.gpencil.sculpt_clone + ops.gpencil.sculpt_grab + ops.gpencil.sculpt_pinch + ops.gpencil.sculpt_push + ops.gpencil.sculpt_randomize + ops.gpencil.sculpt_smooth + ops.gpencil.sculpt_strength + ops.gpencil.sculpt_thickness + ops.gpencil.sculpt_twist + ops.gpencil.sculpt_weight ops.mesh.bevel ops.mesh.bisect ops.mesh.dupli_extrude_cursor @@ -634,6 +662,7 @@ if(WITH_BLENDER) # blends data_to_c_simple(../../../../release/datafiles/preview.blend SRC) data_to_c_simple(../../../../release/datafiles/preview_cycles.blend SRC) + data_to_c_simple(../../../../release/datafiles/preview_grease_pencil.blend SRC) # images data_to_c_simple(../../../../release/datafiles/splash.png SRC) @@ -689,6 +718,29 @@ if(WITH_BLENDER) data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC) + # grease pencil sculpt + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_smooth.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_thickness.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_strength.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_grab.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_push.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_twist.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pinch.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_randomize.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_clone.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_weight.png SRC) + + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pencil.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_pen.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_ink.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_inknoise.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_block.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_marker.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_fill.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_soft.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_hard.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/gp_brush_erase_stroke.png SRC) + endif() data_to_c_simple(../../../../release/datafiles/startup.blend SRC) diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 587c25031ab..f9f196f6634 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -39,18 +39,24 @@ set(INC_SYS ) set(SRC + annotate_draw.c + annotate_paint.c drawgpencil.c editaction_gpencil.c + gpencil_add_monkey.c gpencil_brush.c gpencil_convert.c gpencil_data.c gpencil_edit.c gpencil_interpolate.c + gpencil_primitive.c gpencil_ops.c gpencil_paint.c + gpencil_fill.c gpencil_select.c gpencil_undo.c gpencil_utils.c + gpencil_old.c gpencil_intern.h ) diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c new file mode 100644 index 00000000000..dad5af7379c --- /dev/null +++ b/source/blender/editors/gpencil/annotate_draw.c @@ -0,0 +1,1065 @@ +/* + * ***** 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) 2008, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung, Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/annotate_draw.c + * \ingroup edgpencil + */ + + +#include +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_sys_types.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_polyfill_2d.h" + +#include "BLF_api.h" +#include "BLT_translation.h" + +#include "DNA_gpencil_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" +#include "DNA_userdef_types.h" +#include "DNA_object_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" + +#include "WM_api.h" + +#include "BIF_glutil.h" + +#include "GPU_immediate.h" +#include "GPU_draw.h" +#include "GPU_state.h" + +#include "ED_gpencil.h" +#include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_space_api.h" + +#include "UI_interface_icons.h" +#include "UI_resources.h" + +/* ************************************************** */ +/* GREASE PENCIL DRAWING */ + +/* ----- General Defines ------ */ +/* flags for sflag */ +typedef enum eDrawStrokeFlags { + GP_DRAWDATA_NOSTATUS = (1 << 0), /* don't draw status info */ + GP_DRAWDATA_ONLY3D = (1 << 1), /* only draw 3d-strokes */ + GP_DRAWDATA_ONLYV2D = (1 << 2), /* only draw 'canvas' strokes */ + GP_DRAWDATA_ONLYI2D = (1 << 3), /* only draw 'image' strokes */ + GP_DRAWDATA_IEDITHACK = (1 << 4), /* special hack for drawing strokes in Image Editor (weird coordinates) */ + GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */ + GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */ +} eDrawStrokeFlags; + + +/* ----- Tool Buffer Drawing ------ */ + +/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */ +static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short thickness, + short dflag, short sflag, float ink[4]) +{ + int draw_points = 0; + + /* error checking */ + if ((points == NULL) || (totpoints <= 0)) + return; + + /* check if buffer can be drawn */ + if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D)) + return; + + if (sflag & GP_STROKE_ERASER) { + /* don't draw stroke at all! */ + return; + } + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + + const tGPspoint *pt = points; + + if (totpoints == 1) { + /* if drawing a single point, draw it larger */ + GPU_point_size((float)(thickness + 2) * points->pressure); + immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + immUniformColor3fvAlpha(ink, ink[3]); + immBegin(GPU_PRIM_POINTS, 1); + immVertex2iv(pos, &pt->x); + } + else { + float oldpressure = points[0].pressure; + + /* draw stroke curve */ + GPU_line_width(max_ff(oldpressure * thickness, 1.0)); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3fvAlpha(ink, ink[3]); + + /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints); + + for (int i = 0; i < totpoints; i++, pt++) { + /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, + * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) + */ + if (fabsf(pt->pressure - oldpressure) > 0.2f) { + /* need to have 2 points to avoid immEnd assert error */ + if (draw_points < 2) { + immVertex2iv(pos, &(pt - 1)->x); + } + + immEnd(); + draw_points = 0; + + GPU_line_width(max_ff(pt->pressure * thickness, 1.0f)); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1); + + /* need to roll-back one point to ensure that there are no gaps in the stroke */ + if (i != 0) { + immVertex2iv(pos, &(pt - 1)->x); + draw_points++; + } + + oldpressure = pt->pressure; /* reset our threshold */ + } + + /* now the point we want */ + immVertex2iv(pos, &pt->x); + draw_points++; + } + /* need to have 2 points to avoid immEnd assert error */ + if (draw_points < 2) { + immVertex2iv(pos, &(pt - 1)->x); + } + } + + immEnd(); + immUnbindProgram(); +} + +/* --------- 2D Stroke Drawing Helpers --------- */ +/* change in parameter list */ +static void gp_calc_2d_stroke_fxy(const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2]) +{ + if (sflag & GP_STROKE_2DSPACE) { + r_co[0] = pt[0]; + r_co[1] = pt[1]; + } + else if (sflag & GP_STROKE_2DIMAGE) { + const float x = (float)((pt[0] * winx) + offsx); + const float y = (float)((pt[1] * winy) + offsy); + + r_co[0] = x; + r_co[1] = y; + } + else { + const float x = (float)(pt[0] / 100 * winx) + offsx; + const float y = (float)(pt[1] / 100 * winy) + offsy; + + r_co[0] = x; + r_co[1] = y; + } +} + +/* ----- Existing Strokes Drawing (3D and Point) ------ */ + +/* draw a given stroke - just a single dot (only one point) */ +static void gp_draw_stroke_point( + const bGPDspoint *points, short thickness, short UNUSED(dflag), short sflag, + int offsx, int offsy, int winx, int winy, const float ink[4]) +{ + const bGPDspoint *pt = points; + + /* get final position using parent matrix */ + float fpt[3]; + copy_v3_v3(fpt, &pt->x); + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + if (sflag & GP_STROKE_3DSPACE) { + immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + } + else { + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + + /* get 2D coordinates of point */ + float co[3] = { 0.0f }; + gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co); + copy_v3_v3(fpt, co); + } + + /* set color */ + immUniformColor3fvAlpha(ink, ink[3]); + + /* set point thickness (since there's only one of these) */ + immUniform1f("size", (float)(thickness + 2) * pt->pressure); + + immBegin(GPU_PRIM_POINTS, 1); + immVertex3fv(pos, fpt); + immEnd(); + + immUnbindProgram(); +} + +/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */ +static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug), + short UNUSED(sflag), const float ink[4], bool cyclic) +{ + float curpressure = points[0].pressure; + float cyclic_fpt[3]; + int draw_points = 0; + + /* if cyclic needs one vertex more */ + int cyclic_add = 0; + if (cyclic) { + cyclic_add++; + } + + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor3fvAlpha(ink, ink[3]); + + /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ + + /* draw stroke curve */ + GPU_line_width(max_ff(curpressure * thickness, 1.0f)); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add); + const bGPDspoint *pt = points; + for (int i = 0; i < totpoints; i++, pt++) { + /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, + * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) + * Note: we want more visible levels of pressures when thickness is bigger. + */ + if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) { + /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */ + if (draw_points < 2) { + const bGPDspoint *pt2 = pt - 1; + immVertex3fv(pos, &pt2->x); + } + immEnd(); + draw_points = 0; + + curpressure = pt->pressure; + GPU_line_width(max_ff(curpressure * thickness, 1.0f)); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add); + + /* need to roll-back one point to ensure that there are no gaps in the stroke */ + if (i != 0) { + const bGPDspoint *pt2 = pt - 1; + immVertex3fv(pos, &pt2->x); + draw_points++; + } + } + + /* now the point we want */ + immVertex3fv(pos, &pt->x); + draw_points++; + + if (cyclic && i == 0) { + /* save first point to use in cyclic */ + copy_v3_v3(cyclic_fpt, &pt->x); + } + } + + if (cyclic) { + /* draw line to first point to complete the cycle */ + immVertex3fv(pos, cyclic_fpt); + draw_points++; + } + + /* if less of two points, need to repeat last point to avoid assert in immEnd() */ + if (draw_points < 2) { + const bGPDspoint *pt2 = pt - 1; + immVertex3fv(pos, &pt2->x); + } + + immEnd(); + immUnbindProgram(); +} + +/* ----- Fancy 2D-Stroke Drawing ------ */ + +/* draw a given stroke in 2d */ +static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, + bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float ink[4]) +{ + /* otherwise thickness is twice that of the 3D view */ + float thickness = (float)thickness_s * 0.5f; + + /* strokes in Image Editor need a scale factor, since units there are not pixels! */ + float scalefac = 1.0f; + if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { + scalefac = 0.001f; + } + + /* TODO: fancy++ with the magic of shaders */ + + /* tessellation code - draw stroke as series of connected quads (triangle strips in fact) with connection + * edges rotated to minimize shrinking artifacts, and rounded endcaps + */ + { + const bGPDspoint *pt1, *pt2; + float s0[2], s1[2]; /* segment 'center' points */ + float pm[2]; /* normal from previous segment. */ + int i; + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor3fvAlpha(ink, ink[3]); + immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4); + + /* get x and y coordinates from first point */ + gp_calc_2d_stroke_fxy(&points->x, sflag, offsx, offsy, winx, winy, s0); + + for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) { + float t0[2], t1[2]; /* tessellated coordinates */ + float m1[2], m2[2]; /* gradient and normal */ + float mt[2], sc[2]; /* gradient for thickness, point for end-cap */ + float pthick; /* thickness at segment point */ + + /* get x and y coordinates from point2 (point1 has already been computed in previous iteration). */ + gp_calc_2d_stroke_fxy(&pt2->x, sflag, offsx, offsy, winx, winy, s1); + + /* calculate gradient and normal - 'angle'=(ny/nx) */ + m1[1] = s1[1] - s0[1]; + m1[0] = s1[0] - s0[0]; + normalize_v2(m1); + m2[1] = -m1[0]; + m2[0] = m1[1]; + + /* always use pressure from first point here */ + pthick = (pt1->pressure * thickness * scalefac); + + /* if the first segment, start of segment is segment's normal */ + if (i == 0) { + /* draw start cap first + * - make points slightly closer to center (about halfway across) + */ + mt[0] = m2[0] * pthick * 0.5f; + mt[1] = m2[1] * pthick * 0.5f; + sc[0] = s0[0] - (m1[0] * pthick * 0.75f); + sc[1] = s0[1] - (m1[1] * pthick * 0.75f); + + t0[0] = sc[0] - mt[0]; + t0[1] = sc[1] - mt[1]; + t1[0] = sc[0] + mt[0]; + t1[1] = sc[1] + mt[1]; + + /* First two points of cap. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); + + /* calculate points for start of segment */ + mt[0] = m2[0] * pthick; + mt[1] = m2[1] * pthick; + + t0[0] = s0[0] - mt[0]; + t0[1] = s0[1] - mt[1]; + t1[0] = s0[0] + mt[0]; + t1[1] = s0[1] + mt[1]; + + /* Last two points of start cap (and first two points of first segment). */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); + } + /* if not the first segment, use bisector of angle between segments */ + else { + float mb[2]; /* bisector normal */ + float athick, dfac; /* actual thickness, difference between thicknesses */ + + /* calculate gradient of bisector (as average of normals) */ + mb[0] = (pm[0] + m2[0]) / 2; + mb[1] = (pm[1] + m2[1]) / 2; + normalize_v2(mb); + + /* calculate gradient to apply + * - as basis, use just pthick * bisector gradient + * - if cross-section not as thick as it should be, add extra padding to fix it + */ + mt[0] = mb[0] * pthick; + mt[1] = mb[1] * pthick; + athick = len_v2(mt); + dfac = pthick - (athick * 2); + + if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) { + mt[0] += (mb[0] * dfac); + mt[1] += (mb[1] * dfac); + } + + /* calculate points for start of segment */ + t0[0] = s0[0] - mt[0]; + t0[1] = s0[1] - mt[1]; + t1[0] = s0[0] + mt[0]; + t1[1] = s0[1] + mt[1]; + + /* Last two points of previous segment, and first two points of current segment. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); + } + + /* if last segment, also draw end of segment (defined as segment's normal) */ + if (i == totpoints - 2) { + /* for once, we use second point's pressure (otherwise it won't be drawn) */ + pthick = (pt2->pressure * thickness * scalefac); + + /* calculate points for end of segment */ + mt[0] = m2[0] * pthick; + mt[1] = m2[1] * pthick; + + t0[0] = s1[0] - mt[0]; + t0[1] = s1[1] - mt[1]; + t1[0] = s1[0] + mt[0]; + t1[1] = s1[1] + mt[1]; + + /* Last two points of last segment (and first two points of end cap). */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); + + /* draw end cap as last step + * - make points slightly closer to center (about halfway across) + */ + mt[0] = m2[0] * pthick * 0.5f; + mt[1] = m2[1] * pthick * 0.5f; + sc[0] = s1[0] + (m1[0] * pthick * 0.75f); + sc[1] = s1[1] + (m1[1] * pthick * 0.75f); + + t0[0] = sc[0] - mt[0]; + t0[1] = sc[1] - mt[1]; + t1[0] = sc[0] + mt[0]; + t1[1] = sc[1] + mt[1]; + + /* Last two points of end cap. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); + } + + /* store computed point2 coordinates as point1 ones of next segment. */ + copy_v2_v2(s0, s1); + /* store stroke's 'natural' normal for next stroke to use */ + copy_v2_v2(pm, m2); + } + + immEnd(); + immUnbindProgram(); + } +} + +/* ----- Strokes Drawing ------ */ + +/* Helper for doing all the checks on whether a stroke can be drawn */ +static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) +{ + /* skip stroke if it isn't in the right display space for this drawing context */ + /* 1) 3D Strokes */ + if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE)) + return false; + + /* 2) Screen Space 2D Strokes */ + if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE)) + return false; + + /* 3) Image Space (2D) */ + if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE)) + return false; + if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE)) + return false; + + /* skip stroke if it doesn't have any valid data */ + if ((gps->points == NULL) || (gps->totpoints < 1)) + return false; + + /* stroke can be drawn */ + return true; +} + +/* draw a set of strokes */ +static void gp_draw_strokes( + bGPdata *UNUSED(gpd), bGPDlayer *UNUSED(gpl), const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, + int dflag, bool debug, short lthick, const float color[4]) +{ + GPU_enable_program_point_size(); + + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* check if stroke can be drawn */ + if (gp_can_draw_stroke(gps, dflag) == false) { + continue; + } + + /* check which stroke-drawer to use */ + if (dflag & GP_DRAWDATA_ONLY3D) { + const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); + int mask_orig = 0; + + if (no_xray) { + glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); + glDepthMask(0); + GPU_depth_test(true); + + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ + bglPolygonOffset(1.0f, 1.0f); + } + + /* 3D Lines - OpenGL primitives-based */ + if (gps->totpoints == 1) { + gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color); + } + else { + gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug, gps->flag, + color, gps->flag & GP_STROKE_CYCLIC); + } + + if (no_xray) { + glDepthMask(mask_orig); + GPU_depth_test(false); + + bglPolygonOffset(0.0, 0.0); + } + } + else { + /* 2D Strokes... */ + if (gps->totpoints == 1) { + gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy, color); + } + else { + gp_draw_stroke_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, + offsx, offsy, winx, winy, color); + } + } + } + + GPU_disable_program_point_size(); +} + +/* Draw selected verts for strokes being edited */ +static void gp_draw_strokes_edit( + bGPdata *gpd, bGPDlayer *gpl, const bGPDframe *gpf, + int offsx, int offsy, int winx, int winy, + short dflag, short UNUSED(lflag), float alpha) +{ + /* if alpha 0 do not draw */ + if (alpha == 0.0f) + return; + + const bool no_xray = (dflag & GP_DRAWDATA_NO_XRAY) != 0; + int mask_orig = 0; + + /* set up depth masks... */ + if (dflag & GP_DRAWDATA_ONLY3D) { + if (no_xray) { + glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); + glDepthMask(0); + GPU_depth_test(true); + + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ + bglPolygonOffset(1.0f, 1.0f); + } + } + + GPU_enable_program_point_size(); + + /* draw stroke verts */ + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* check if stroke can be drawn */ + if (gp_can_draw_stroke(gps, dflag) == false) + continue; + + /* Optimisation: only draw points for selected strokes + * We assume that selected points can only occur in + * strokes that are selected too. + */ + if ((gps->flag & GP_STROKE_SELECT) == 0) + continue; + + /* Get size of verts: + * - The selected state needs to be larger than the unselected state so that + * they stand out more. + * - We use the theme setting for size of the unselected verts + */ + float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); + float vsize; + if ((int)bsize > 8) { + vsize = 10.0f; + bsize = 8.0f; + } + else { + vsize = bsize + 2; + } + + float selectColor[4]; + UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); + selectColor[3] = alpha; + + GPUVertFormat *format = immVertexFormat(); + uint pos; /* specified later */ + uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + if (gps->flag & GP_STROKE_3DSPACE) { + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); + } + else { + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR); + } + + immBegin(GPU_PRIM_POINTS, gps->totpoints); + + /* Draw start and end point differently if enabled stroke direction hint */ + bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1); + + /* Draw all the stroke points (selected or not) */ + bGPDspoint *pt = gps->points; + for (int i = 0; i < gps->totpoints; i++, pt++) { + /* size and color first */ + if (show_direction_hint && i == 0) { + /* start point in green bigger */ + immAttrib3f(color, 0.0f, 1.0f, 0.0f); + immAttrib1f(size, vsize + 4); + } + else if (show_direction_hint && (i == gps->totpoints - 1)) { + /* end point in red smaller */ + immAttrib3f(color, 1.0f, 0.0f, 0.0f); + immAttrib1f(size, vsize + 1); + } + else if (pt->flag & GP_SPOINT_SELECT) { + immAttrib3fv(color, selectColor); + immAttrib1f(size, vsize); + } + else { + immAttrib3fv(color, gpl->color); + immAttrib1f(size, bsize); + } + + /* then position */ + if (gps->flag & GP_STROKE_3DSPACE) { + immVertex3fv(pos, &pt->x); + } + else { + float co[2]; + gp_calc_2d_stroke_fxy(&pt->x, gps->flag, offsx, offsy, winx, winy, co); + immVertex2fv(pos, co); + } + } + + immEnd(); + immUnbindProgram(); + } + + GPU_disable_program_point_size(); + + /* clear depth mask */ + if (dflag & GP_DRAWDATA_ONLY3D) { + if (no_xray) { + glDepthMask(mask_orig); + GPU_depth_test(false); + + bglPolygonOffset(0.0, 0.0); +#if 0 + glDisable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(0, 0); +#endif + } + } +} + +/* ----- General Drawing ------ */ + +/* loop over gpencil data layers, drawing them */ +static void gp_draw_data_layers( + bGPdata *gpd, int offsx, int offsy, int winx, int winy, + int cfra, int dflag, float alpha) +{ + float ink[4]; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG); + short lthick = gpl->thickness; + + /* apply layer opacity */ + copy_v3_v3(ink, gpl->color); + ink[3] = gpl->opacity; + + /* don't draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; + + /* get frame to draw */ + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0); + if (gpf == NULL) + continue; + + /* set basic stroke thickness */ + GPU_line_width(lthick); + + /* Add layer drawing settings to the set of "draw flags" + * NOTE: If the setting doesn't apply, it *must* be cleared, + * as dflag's carry over from the previous layer + */ +#define GP_DRAWFLAG_APPLY(condition, draw_flag_value) { \ + if (condition) dflag |= (draw_flag_value); \ + else dflag &= ~(draw_flag_value); \ + } (void)0 + + /* xray... */ + GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_NO_XRAY), GP_DRAWDATA_NO_XRAY); + +#undef GP_DRAWFLAG_APPLY + + + /* draw the strokes already in active frame */ + gp_draw_strokes(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, debug, lthick, ink); + + /* Draw verts of selected strokes + * - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering + * - locked layers can't be edited, so there's no point showing these verts + * as they will have no bearings on what gets edited + * - only show when in editmode, since operators shouldn't work otherwise + * (NOTE: doing it this way means that the toggling editmode shows visible change immediately) + */ + /* XXX: perhaps we don't want to show these when users are drawing... */ + if ((G.f & G_RENDER_OGL) == 0 && + (gpl->flag & GP_LAYER_LOCKED) == 0 && + (gpd->flag & GP_DATA_STROKE_EDITMODE)) + { + gp_draw_strokes_edit(gpd, gpl, gpf, offsx, offsy, winx, winy, dflag, gpl->flag, alpha); + } + + /* Check if may need to draw the active stroke cache, only if this layer is the active layer + * that is being edited. (Stroke buffer is currently stored in gp-data) + */ + if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && + (gpf->flag & GP_FRAME_PAINT)) + { + /* Buffer stroke needs to be drawn with a different linestyle + * to help differentiate them from normal strokes. + * + * It should also be noted that sbuffer contains temporary point types + * i.e. tGPspoints NOT bGPDspoints + */ + gp_draw_stroke_buffer(gpd->runtime.sbuffer, + gpd->runtime.sbuffer_size, lthick, + dflag, gpd->runtime.sbuffer_sflag, ink); + } + } +} + +/* draw a short status message in the top-right corner */ +static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar) +{ + rcti rect; + + /* Cannot draw any status text when drawing OpenGL Renders */ + if (G.f & G_RENDER_OGL) + return; + + /* Get bounds of region - Necessary to avoid problems with region overlap */ + ED_region_visible_rect(ar, &rect); + + /* for now, this should only be used to indicate when we are in stroke editmode */ + if (gpd->flag & GP_DATA_STROKE_EDITMODE) { + const char *printable = IFACE_("GPencil Stroke Editing"); + float printable_size[2]; + + int font_id = BLF_default(); + + BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); + + int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; + int yco = (rect.ymax - U.widget_unit); + + /* text label */ + UI_FontThemeColor(font_id, TH_TEXT_HI); +#ifdef WITH_INTERNATIONAL + BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); +#else + BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); +#endif + + /* grease pencil icon... */ + // XXX: is this too intrusive? + GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(true); + + xco -= U.widget_unit; + yco -= (int)printable_size[1] / 2; + + UI_icon_draw(xco, yco, ICON_GREASEPENCIL); + + GPU_blend(false); + } +} + +/* draw grease-pencil datablock */ +static void gp_draw_data( + bGPdata *gpd, int offsx, int offsy, int winx, int winy, + int cfra, int dflag, float alpha) +{ + /* turn on smooth lines (i.e. anti-aliasing) */ + GPU_line_smooth(true); + + /* turn on alpha-blending */ + GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(true); + + /* draw! */ + gp_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag, alpha); + + /* turn off alpha blending, then smooth lines */ + GPU_blend(false); // alpha blending + GPU_line_smooth(false); // smooth lines +} + +/* if we have strokes for scenes (3d view)/clips (movie clip editor) + * and objects/tracks, multiple data blocks have to be drawn */ +static void gp_draw_data_all( + Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy, + int cfra, int dflag, const char spacetype) +{ + bGPdata *gpd_source = NULL; + float alpha = 1.0f; + + if (scene) { + if (spacetype == SPACE_VIEW3D) { + gpd_source = (scene->gpd ? scene->gpd : NULL); + } + else if (spacetype == SPACE_CLIP && scene->clip) { + /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */ + gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL); + } + + if (gpd_source) { + gp_draw_data(gpd_source, offsx, offsy, winx, winy, cfra, dflag, alpha); + } + } + + /* scene/clip data has already been drawn, only object/track data is drawn here + * if gpd_source == gpd, we don't have any object/track data and we can skip */ + if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) { + gp_draw_data(gpd, offsx, offsy, winx, winy, cfra, dflag, alpha); + } +} + +/* ----- Grease Pencil Sketches Drawing API ------ */ + +/* ............................ + * XXX + * We need to review the calls below, since they may be/are not that suitable for + * the new ways that we intend to be drawing data... + * ............................ */ + +/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ +void ED_gpencil_draw_2dimage(const bContext *C) +{ + wmWindowManager *wm = CTX_wm_manager(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + + int offsx, offsy, sizex, sizey; + int dflag = GP_DRAWDATA_NOSTATUS; + + bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX + if (gpd == NULL) return; + + /* calculate rect */ + switch (sa->spacetype) { + case SPACE_IMAGE: /* image */ + case SPACE_CLIP: /* clip */ + { + /* just draw using standard scaling (settings here are currently ignored anyways) */ + /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ + offsx = 0; + offsy = 0; + sizex = ar->winx; + sizey = ar->winy; + + wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax); + + dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK; + break; + } + case SPACE_SEQ: /* sequence */ + { + /* just draw using standard scaling (settings here are currently ignored anyways) */ + offsx = 0; + offsy = 0; + sizex = ar->winx; + sizey = ar->winy; + + /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated + * and everything moved to standard View2d + */ + dflag |= GP_DRAWDATA_ONLYV2D; + break; + } + default: /* for spacetype not yet handled */ + offsx = 0; + offsy = 0; + sizex = ar->winx; + sizey = ar->winy; + + dflag |= GP_DRAWDATA_ONLYI2D; + break; + } + + if (ED_screen_animation_playing(wm)) { + /* don't show onionskins during animation playback/scrub (i.e. it obscures the poses) + * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes) + */ + dflag |= GP_DRAWDATA_NO_ONIONS; + } + + /* draw it! */ + gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype); +} + +/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly + * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes, + * second time with onlyv2d=false for screen-aligned strokes */ +void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d) +{ + wmWindowManager *wm = CTX_wm_manager(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int dflag = 0; + + /* check that we have grease-pencil stuff to draw */ + if (sa == NULL) return; + bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX + if (gpd == NULL) return; + + /* special hack for Image Editor */ + /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ + if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP)) + dflag |= GP_DRAWDATA_IEDITHACK; + + /* draw it! */ + if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS); + if (ED_screen_animation_playing(wm)) dflag |= GP_DRAWDATA_NO_ONIONS; + + gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype); + + /* draw status text (if in screen/pixel-space) */ + if (!onlyv2d) { + gp_draw_status_text(gpd, ar); + } +} + + +/* draw annotations sketches to specified 3d-view assuming that matrices are already set correctly + * Note: this gets called twice - first time with only3d=true to draw 3d-strokes, + * second time with only3d=false for screen-aligned strokes */ +void ED_gpencil_draw_view3d_annotations( + Scene *scene, struct Depsgraph *depsgraph, + View3D *v3d, ARegion *ar, + bool only3d) +{ + int dflag = 0; + RegionView3D *rv3d = ar->regiondata; + int offsx, offsy, winx, winy; + + /* check that we have grease-pencil stuff to draw */ + /* XXX: Hardcoded reference here may get out of sync if we change how we fetch annotation data */ + bGPdata *gpd = scene->gpd; + if (gpd == NULL) return; + + /* when rendering to the offscreen buffer we don't want to + * deal with the camera border, otherwise map the coords to the camera border. */ + if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) { + rctf rectf; + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */ + + offsx = round_fl_to_int(rectf.xmin); + offsy = round_fl_to_int(rectf.ymin); + winx = round_fl_to_int(rectf.xmax - rectf.xmin); + winy = round_fl_to_int(rectf.ymax - rectf.ymin); + } + else { + offsx = 0; + offsy = 0; + winx = ar->winx; + winy = ar->winy; + } + + /* set flags */ + if (only3d) { + /* 3D strokes/3D space: + * - only 3D space points + * - don't status text either (as it's the wrong space) + */ + dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); + } + + if (v3d->flag2 & V3D_RENDER_OVERRIDE) { + /* don't draw status text when "only render" flag is set */ + dflag |= GP_DRAWDATA_NOSTATUS; + } + + /* draw it! */ + gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype); +} + +#if 0 // XXX: Reinstate, after renaming the functions + +void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype) +{ + int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D; + + gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype); +} + +#endif + +/* ************************************************** */ diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c new file mode 100644 index 00000000000..6325052fccd --- /dev/null +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -0,0 +1,2382 @@ +/* + * ***** 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) 2008/2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/annotate_paint.c + * \ingroup edgpencil + */ + + +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_math_geom.h" + +#include "BLT_translation.h" + +#include "PIL_time.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_screen.h" +#include "BKE_tracking.h" + +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_windowmanager_types.h" + +#include "UI_view2d.h" + +#include "ED_gpencil.h" +#include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_clip.h" + +#include "BIF_glutil.h" + +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_state.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "DEG_depsgraph.h" + +#include "gpencil_intern.h" + +/* ******************************************* */ +/* 'Globals' and Defines */ + +/* values for tGPsdata->status */ +typedef enum eGPencil_PaintStatus { + GP_STATUS_IDLING = 0, /* stroke isn't in progress yet */ + GP_STATUS_PAINTING, /* a stroke is in progress */ + GP_STATUS_ERROR, /* something wasn't correctly set up */ + GP_STATUS_DONE /* painting done */ +} eGPencil_PaintStatus; + +/* Return flags for adding points to stroke buffer */ +typedef enum eGP_StrokeAdd_Result { + GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */ + GP_STROKEADD_OVERFLOW = -1, /* error occurred - cannot fit any more points */ + GP_STROKEADD_NORMAL, /* point was successfully added */ + GP_STROKEADD_FULL /* cannot add any more points to buffer */ +} eGP_StrokeAdd_Result; + +/* Runtime flags */ +typedef enum eGPencil_PaintFlags { + GP_PAINTFLAG_FIRSTRUN = (1 << 0), /* operator just started */ + GP_PAINTFLAG_STROKEADDED = (1 << 1), + GP_PAINTFLAG_V3D_ERASER_DEPTH = (1 << 2), + GP_PAINTFLAG_SELECTMASK = (1 << 3), +} eGPencil_PaintFlags; + + +/* Temporary 'Stroke' Operation data + * "p" = op->customdata + */ +typedef struct tGPsdata { + Main *bmain; + Scene *scene; /* current scene from context */ + struct Depsgraph *depsgraph; + + wmWindow *win; /* window where painting originated */ + ScrArea *sa; /* area where painting originated */ + ARegion *ar; /* region where painting originated */ + View2D *v2d; /* needed for GP_STROKE_2DSPACE */ + rctf *subrect; /* for using the camera rect within the 3d view */ + rctf subrect_data; + + GP_SpaceConversion gsc; /* settings to pass to gp_points_to_xy() */ + + PointerRNA ownerPtr; /* pointer to owner of gp-datablock */ + bGPdata *gpd; /* gp-datablock layer comes from */ + bGPDlayer *gpl; /* layer we're working on */ + bGPDframe *gpf; /* frame we're working on */ + + char *align_flag; /* projection-mode flags (toolsettings - eGPencil_Placement_Flags) */ + + eGPencil_PaintStatus status; /* current status of painting */ + eGPencil_PaintModes paintmode; /* mode for painting */ + eGPencil_PaintFlags flags; /* flags that can get set during runtime (eGPencil_PaintFlags) */ + + short radius; /* radius of influence for eraser */ + + int mval[2]; /* current mouse-position */ + int mvalo[2]; /* previous recorded mouse-position */ + + float pressure; /* current stylus pressure */ + float opressure; /* previous stylus pressure */ + + /* These need to be doubles, as (at least under unix) they are in seconds since epoch, + * float (and its 7 digits precision) is definitively not enough here! + * double, with its 15 digits precision, ensures us millisecond precision for a few centuries at least. + */ + double inittime; /* Used when converting to path */ + double curtime; /* Used when converting to path */ + double ocurtime; /* Used when converting to path */ + + float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space + * to region space */ + float mat[4][4]; + + float custom_color[4]; /* custom color - hack for enforcing a particular color for track/mask editing */ + + void *erasercursor; /* radial cursor data for drawing eraser */ + + short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */ + int lock_axis; /* lock drawing to one axis */ + + short keymodifier; /* key used for invoking the operator */ +} tGPsdata; + +/* ------ */ + +/* Macros for accessing sensitivity thresholds... */ +/* minimum number of pixels mouse should move before new point created */ +#define MIN_MANHATTEN_PX (U.gp_manhattendist) +/* minimum length of new segment before new point can be added */ +#define MIN_EUCLIDEAN_PX (U.gp_euclideandist) + +static bool gp_stroke_added_check(tGPsdata *p) +{ + return (p->gpf && p->gpf->strokes.last && p->flags & GP_PAINTFLAG_STROKEADDED); +} + +static void gp_stroke_added_enable(tGPsdata *p) +{ + BLI_assert(p->gpf->strokes.last != NULL); + p->flags |= GP_PAINTFLAG_STROKEADDED; +} + +/* ------ */ +/* Forward defines for some functions... */ + +static void gp_session_validatebuffer(tGPsdata *p); + +/* ******************************************* */ +/* Context Wrangling... */ + +/* check if context is suitable for drawing */ +static bool gpencil_draw_poll(bContext *C) +{ + if (ED_operator_regionactive(C)) { + /* check if current context can support GPencil data */ + if (ED_gpencil_data_get_pointers(C, NULL) != NULL) { + /* check if Grease Pencil isn't already running */ + if (ED_gpencil_session_active() == 0) + return 1; + else + CTX_wm_operator_poll_msg_set(C, "Annotation operator is already active"); + } + else { + CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into"); + } + } + else { + CTX_wm_operator_poll_msg_set(C, "Active region not set"); + } + + return 0; +} + +/* check if projecting strokes into 3d-geometry in the 3D-View */ +static bool gpencil_project_check(tGPsdata *p) +{ + bGPdata *gpd = p->gpd; + return ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE))); +} + +/* ******************************************* */ +/* Calculations/Conversions */ + +/* Utilities --------------------------------- */ + +/* get the reference point for stroke-point conversions */ +static void gp_get_3d_reference(tGPsdata *p, float vec[3]) +{ + View3D *v3d = p->sa->spacedata.first; + const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location; + + /* use 3D-cursor */ + copy_v3_v3(vec, fp); +} + +/* Stroke Editing ---------------------------- */ + +/* check if the current mouse position is suitable for adding a new point */ +static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2]) +{ + int dx = abs(mval[0] - pmval[0]); + int dy = abs(mval[1] - pmval[1]); + + /* if buffer is empty, just let this go through (i.e. so that dots will work) */ + if (p->gpd->runtime.sbuffer_size == 0) + return true; + + /* check if mouse moved at least certain distance on both axes (best case) + * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand + */ + else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) + return true; + + /* check if the distance since the last point is significant enough + * - prevents points being added too densely + * - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though + */ + else if ((dx * dx + dy * dy) > MIN_EUCLIDEAN_PX * MIN_EUCLIDEAN_PX) + return true; + + /* mouse 'didn't move' */ + else + return false; +} + +/* reproject the points of the stroke to a plane locked to axis to avoid stroke offset */ +static void gp_project_points_to_plane(RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis) +{ + float plane_normal[3]; + float vn[3]; + + float ray[3]; + float rpoint[3]; + + /* normal vector for a plane locked to axis */ + zero_v3(plane_normal); + plane_normal[axis] = 1.0f; + + /* Reproject the points in the plane */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + + /* get a vector from the point with the current view direction of the viewport */ + ED_view3d_global_to_vector(rv3d, &pt->x, vn); + + /* calculate line extrem point to create a ray that cross the plane */ + mul_v3_fl(vn, -50.0f); + add_v3_v3v3(ray, &pt->x, vn); + + /* if the line never intersect, the point is not changed */ + if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) { + copy_v3_v3(&pt->x, rpoint); + } + } +} + +/* reproject stroke to plane locked to axis in 3d cursor location */ +static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps) +{ + bGPdata *gpd = p->gpd; + float origin[3]; + float cursor[3]; + RegionView3D *rv3d = p->ar->regiondata; + + /* verify the stroke mode is CURSOR 3d space mode */ + if ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) == 0) { + return; + } + if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { + return; + } + if ((*p->align_flag & GP_PROJECT_DEPTH_VIEW) || (*p->align_flag & GP_PROJECT_DEPTH_STROKE)) { + return; + } + + /* get 3d cursor and set origin for locked axis only. Uses axis-1 because the enum for XYZ start with 1 */ + gp_get_3d_reference(p, cursor); + zero_v3(origin); + origin[p->lock_axis - 1] = cursor[p->lock_axis - 1]; + + gp_project_points_to_plane(rv3d, gps, origin, p->lock_axis - 1); +} + +/* convert screen-coordinates to buffer-coordinates */ +/* XXX this method needs a total overhaul! */ +static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3], float *depth) +{ + bGPdata *gpd = p->gpd; + + /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ + if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) { + if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) { + /* projecting onto 3D-Geometry + * - nothing more needs to be done here, since view_autodist_simple() has already done it + */ + } + else { + float mval_prj[2]; + float rvec[3], dvec[3]; + float mval_f[2] = {UNPACK2(mval)}; + float zfac; + + /* Current method just converts each point in screen-coordinates to + * 3D-coordinates using the 3D-cursor as reference. In general, this + * works OK, but it could of course be improved. + * + * TODO: + * - investigate using nearest point(s) on a previous stroke as + * reference point instead or as offset, for easier stroke matching + */ + + gp_get_3d_reference(p, rvec); + zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL); + + if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + sub_v2_v2v2(mval_f, mval_prj, mval_f); + ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac); + sub_v3_v3v3(out, rvec, dvec); + } + else { + zero_v3(out); + } + } + } + + /* 2d - on 'canvas' (assume that p->v2d is set) */ + else if ((gpd->runtime.sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) { + UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]); + mul_v3_m4v3(out, p->imat, out); + } + + /* 2d - relative to screen (viewport area) */ + else { + if (p->subrect == NULL) { /* normal 3D view */ + out[0] = (float)(mval[0]) / (float)(p->ar->winx) * 100; + out[1] = (float)(mval[1]) / (float)(p->ar->winy) * 100; + } + else { /* camera view, use subrect */ + out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100; + out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100; + } + } +} + +/* add current stroke-point to buffer (returns whether point was successfully added) */ +static short gp_stroke_addpoint( + tGPsdata *p, const int mval[2], float pressure, double curtime) +{ + bGPdata *gpd = p->gpd; + tGPspoint *pt; + ToolSettings *ts = p->scene->toolsettings; + + /* check painting mode */ + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { + /* straight lines only - i.e. only store start and end point in buffer */ + if (gpd->runtime.sbuffer_size == 0) { + /* first point in buffer (start point) */ + pt = (tGPspoint *)(gpd->runtime.sbuffer); + + /* store settings */ + copy_v2_v2_int(&pt->x, mval); + pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ + pt->strength = 1.0f; + pt->time = (float)(curtime - p->inittime); + + /* increment buffer size */ + gpd->runtime.sbuffer_size++; + } + else { + /* just reset the endpoint to the latest value + * - assume that pointers for this are always valid... + */ + pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1); + + /* store settings */ + copy_v2_v2_int(&pt->x, mval); + pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ + pt->strength = 1.0f; + pt->time = (float)(curtime - p->inittime); + + /* now the buffer has 2 points (and shouldn't be allowed to get any larger) */ + gpd->runtime.sbuffer_size = 2; + } + + /* can keep carrying on this way :) */ + return GP_STROKEADD_NORMAL; + } + else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */ + /* check if still room in buffer */ + if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_OVERFLOW; + + /* get pointer to destination point */ + pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size); + + /* store settings */ + copy_v2_v2_int(&pt->x, mval); + pt->pressure = pressure; + pt->strength = 1.0f; /* unused for annotations, but initialise for easier conversions to GP Object */ + + /* point time */ + pt->time = (float)(curtime - p->inittime); + + /* increment counters */ + gpd->runtime.sbuffer_size++; + + /* check if another operation can still occur */ + if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) + return GP_STROKEADD_FULL; + else + return GP_STROKEADD_NORMAL; + } + else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { + /* get pointer to destination point */ + pt = (tGPspoint *)(gpd->runtime.sbuffer); + + /* store settings */ + copy_v2_v2_int(&pt->x, mval); + pt->pressure = 1.0f; /* T44932 - Pressure vals are unreliable, so ignore for now */ + pt->strength = 1.0f; + pt->time = (float)(curtime - p->inittime); + + /* if there's stroke for this poly line session add (or replace last) point + * to stroke. This allows to draw lines more interactively (see new segment + * during mouse slide, e.g.) + */ + if (gp_stroke_added_check(p)) { + bGPDstroke *gps = p->gpf->strokes.last; + bGPDspoint *pts; + + /* first time point is adding to temporary buffer -- need to allocate new point in stroke */ + if (gpd->runtime.sbuffer_size == 0) { + gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1)); + gps->totpoints++; + } + + pts = &gps->points[gps->totpoints - 1]; + + /* special case for poly lines: normally, + * depth is needed only when creating new stroke from buffer, + * but poly lines are converting to stroke instantly, + * so initialize depth buffer before converting coordinates + */ + if (gpencil_project_check(p)) { + View3D *v3d = p->sa->spacedata.first; + + view3d_region_operator_needs_opengl(p->win, p->ar); + ED_view3d_autodist_init( + p->depsgraph, p->ar, v3d, (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + } + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL); + /* if axis locked, reproject to plane locked (only in 3d space) */ + if (p->lock_axis > GP_LOCKAXIS_NONE) { + gp_reproject_toplane(p, gps); + } + + /* copy pressure and time */ + pts->pressure = pt->pressure; + pts->strength = pt->strength; + pts->time = pt->time; + + /* force fill recalc */ + gps->flag |= GP_STROKE_RECALC_CACHES; + } + + /* increment counters */ + if (gpd->runtime.sbuffer_size == 0) + gpd->runtime.sbuffer_size++; + + return GP_STROKEADD_NORMAL; + } + + /* return invalid state for now... */ + return GP_STROKEADD_INVALID; +} + +/* simplify a stroke (in buffer) before storing it + * - applies a reverse Chaikin filter + * - code adapted from etch-a-ton branch + */ +static void gp_stroke_simplify(tGPsdata *p) +{ + bGPdata *gpd = p->gpd; + tGPspoint *old_points = (tGPspoint *)gpd->runtime.sbuffer; + short num_points = gpd->runtime.sbuffer_size; + short flag = gpd->runtime.sbuffer_sflag; + short i, j; + + /* only simplify if simplification is enabled, and we're not doing a straight line */ + if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)) + return; + + /* don't simplify if less than 4 points in buffer */ + if ((num_points <= 4) || (old_points == NULL)) + return; + + /* clear buffer (but don't free mem yet) so that we can write to it + * - firstly set sbuffer to NULL, so a new one is allocated + * - secondly, reset flag after, as it gets cleared auto + */ + gpd->runtime.sbuffer = NULL; + gp_session_validatebuffer(p); + gpd->runtime.sbuffer_sflag = flag; + +/* macro used in loop to get position of new point + * - used due to the mixture of datatypes in use here + */ +#define GP_SIMPLIFY_AVPOINT(offs, sfac) \ + { \ + co[0] += (float)(old_points[offs].x * sfac); \ + co[1] += (float)(old_points[offs].y * sfac); \ + pressure += old_points[offs].pressure * sfac; \ + time += old_points[offs].time * sfac; \ + } (void)0 + + /* XXX Here too, do not lose start and end points! */ + gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time); + for (i = 0, j = 0; i < num_points; i++) { + if (i - j == 3) { + float co[2], pressure, time; + int mco[2]; + + /* initialize values */ + co[0] = 0.0f; + co[1] = 0.0f; + pressure = 0.0f; + time = 0.0f; + + /* using macro, calculate new point */ + GP_SIMPLIFY_AVPOINT(j, -0.25f); + GP_SIMPLIFY_AVPOINT(j + 1, 0.75f); + GP_SIMPLIFY_AVPOINT(j + 2, 0.75f); + GP_SIMPLIFY_AVPOINT(j + 3, -0.25f); + + /* set values for adding */ + mco[0] = (int)co[0]; + mco[1] = (int)co[1]; + + /* ignore return values on this... assume to be ok for now */ + gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time); + + j += 2; + } + } + gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure, + p->inittime + (double)old_points[num_points - 1].time); + + /* free old buffer */ + MEM_freeN(old_points); +} + +/* make a new stroke from the buffer data */ +static void gp_stroke_newfrombuffer(tGPsdata *p) +{ + bGPdata *gpd = p->gpd; + bGPDlayer *gpl = p->gpl; + bGPDstroke *gps; + bGPDspoint *pt; + tGPspoint *ptc; + ToolSettings *ts = p->scene->toolsettings; + + int i, totelem; + /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */ + int depth_margin = (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 4 : 0; + + /* get total number of points to allocate space for + * - drawing straight-lines only requires the endpoints + */ + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) + totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size; + else + totelem = gpd->runtime.sbuffer_size; + + /* exit with error if no valid points from this stroke */ + if (totelem == 0) { + if (G.debug & G_DEBUG) + printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->runtime.sbuffer_size); + return; + } + + /* special case for poly line -- for already added stroke during session + * coordinates are getting added to stroke immediately to allow more + * interactive behavior + */ + if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { + if (gp_stroke_added_check(p)) { + return; + } + } + + /* allocate memory for a new stroke */ + gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + + /* copy appropriate settings for stroke */ + gps->totpoints = totelem; + gps->thickness = gpl->thickness; + gps->flag = gpd->runtime.sbuffer_sflag; + gps->inittime = p->inittime; + + /* enable recalculation flag by default (only used if hq fill) */ + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* allocate enough memory for a continuous array for storage points */ + gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->tot_triangles = 0; + + /* set pointer to first non-initialized point */ + pt = gps->points + (gps->totpoints - totelem); + + /* copy points from the buffer to the stroke */ + if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { + /* straight lines only -> only endpoints */ + { + /* first point */ + ptc = gpd->runtime.sbuffer; + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); + /* if axis locked, reproject to plane locked (only in 3d space) */ + if (p->lock_axis > GP_LOCKAXIS_NONE) { + gp_reproject_toplane(p, gps); + } + /* copy pressure and time */ + pt->pressure = ptc->pressure; + pt->strength = ptc->strength; + CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt->time = ptc->time; + + pt++; + } + + if (totelem == 2) { + /* last point if applicable */ + ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1); + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); + /* if axis locked, reproject to plane locked (only in 3d space) */ + if (p->lock_axis > GP_LOCKAXIS_NONE) { + gp_reproject_toplane(p, gps); + } + + /* copy pressure and time */ + pt->pressure = ptc->pressure; + pt->strength = ptc->strength; + CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt->time = ptc->time; + } + } + else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { + /* first point */ + ptc = gpd->runtime.sbuffer; + + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); + /* if axis locked, reproject to plane locked (only in 3d space) */ + if (p->lock_axis > GP_LOCKAXIS_NONE) { + gp_reproject_toplane(p, gps); + } + /* copy pressure and time */ + pt->pressure = ptc->pressure; + pt->strength = ptc->strength; + pt->time = ptc->time; + } + else { + float *depth_arr = NULL; + + /* get an array of depths, far depths are blended */ + if (gpencil_project_check(p)) { + int mval[2], mval_prev[2] = { 0 }; + int interp_depth = 0; + int found_depth = 0; + + depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points"); + + for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) { + copy_v2_v2_int(mval, &ptc->x); + + if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) && + (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0))) + { + interp_depth = true; + } + else { + found_depth = true; + } + + copy_v2_v2_int(mval_prev, mval); + } + + if (found_depth == false) { + /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */ + for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) + depth_arr[i] = 0.9999f; + } + else { + if (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE_ENDPOINTS) { + /* remove all info between the valid endpoints */ + int first_valid = 0; + int last_valid = 0; + + for (i = 0; i < gpd->runtime.sbuffer_size; i++) { + if (depth_arr[i] != FLT_MAX) + break; + } + first_valid = i; + + for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) { + if (depth_arr[i] != FLT_MAX) + break; + } + last_valid = i; + + /* invalidate non-endpoints, so only blend between first and last */ + for (i = first_valid + 1; i < last_valid; i++) + depth_arr[i] = FLT_MAX; + + interp_depth = true; + } + + if (interp_depth) { + interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX); + } + } + } + + + pt = gps->points; + + /* convert all points (normal behavior) */ + for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && ptc; i++, ptc++, pt++) { + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL); + + /* copy pressure and time */ + pt->pressure = ptc->pressure; + pt->strength = ptc->strength; + CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt->time = ptc->time; + } + + /* if axis locked, reproject to plane locked (only in 3d space) */ + if (p->lock_axis > GP_LOCKAXIS_NONE) { + gp_reproject_toplane(p, gps); + } + + if (depth_arr) + MEM_freeN(depth_arr); + } + + /* add stroke to frame */ + BLI_addtail(&p->gpf->strokes, gps); + gp_stroke_added_enable(p); +} + +/* --- 'Eraser' for 'Paint' Tool ------ */ + +/* helper to free a stroke + * NOTE: gps->dvert and gps->triangles should be NULL, but check anyway for good measure + */ +static void gp_free_stroke(bGPdata *UNUSED(gpd), bGPDframe *gpf, bGPDstroke *gps) +{ + if (gps->points) { + MEM_freeN(gps->points); + } + + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + + if (gps->triangles) { + MEM_freeN(gps->triangles); + } + + BLI_freelinkN(&gpf->strokes, gps); +} + + +/* which which point is infront (result should only be used for comparison) */ +static float view3d_point_depth(const RegionView3D *rv3d, const float co[3]) +{ + if (rv3d->is_persp) { + return ED_view3d_calc_zfac(rv3d, co, NULL); + } + else { + return -dot_v3v3(rv3d->viewinv[2], co); + } +} + +/* only erase stroke points that are visible (3d view) */ +static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, const int x, const int y) +{ + if ((p->sa->spacetype == SPACE_VIEW3D) && + (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) + { + RegionView3D *rv3d = p->ar->regiondata; + const int mval[2] = {x, y}; + float mval_3d[3]; + + if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) { + const float depth_mval = view3d_point_depth(rv3d, mval_3d); + const float depth_pt = view3d_point_depth(rv3d, &pt->x); + + if (depth_pt > depth_mval) { + return true; + } + } + } + return false; +} + +/* eraser tool - evaluation per stroke */ +/* TODO: this could really do with some optimization (KD-Tree/BVH?) */ +static void gp_stroke_eraser_dostroke(tGPsdata *p, + bGPDframe *gpf, bGPDstroke *gps, + const int mval[2], const int mvalo[2], + const int radius, const rcti *rect) +{ + bGPDspoint *pt1, *pt2; + int pc1[2] = {0}; + int pc2[2] = {0}; + int i; + + if (gps->totpoints == 0) { + /* just free stroke */ + gp_free_stroke(p->gpd, gpf, gps); + } + else if (gps->totpoints == 1) { + /* only process if it hasn't been masked out... */ + if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) { + gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]); + + /* do boundbox check first */ + if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { + /* only check if point is inside */ + if (len_v2v2_int(mval, pc1) <= radius) { + /* free stroke */ + gp_free_stroke(p->gpd, gpf, gps); + } + } + } + } + else { + /* Perform culling? */ + bool do_cull = false; + + /* Clear Tags + * + * Note: It's better this way, as we are sure that + * we don't miss anything, though things will be + * slightly slower as a result + */ + for (i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + pt->flag &= ~GP_SPOINT_TAG; + } + + /* First Pass: Loop over the points in the stroke + * 1) Thin out parts of the stroke under the brush + * 2) Tag "too thin" parts for removal (in second pass) + */ + for (i = 0; (i + 1) < gps->totpoints; i++) { + /* get points to work with */ + pt1 = gps->points + i; + pt2 = gps->points + i + 1; + + /* only process if it hasn't been masked out... */ + if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT)) + continue; + + gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]); + gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]); + + /* Check that point segment of the boundbox of the eraser stroke */ + if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) || + ((!ELEM(V2D_IS_CLIPPED, pc2[0], pc2[1])) && BLI_rcti_isect_pt(rect, pc2[0], pc2[1]))) + { + /* Check if point segment of stroke had anything to do with + * eraser region (either within stroke painted, or on its lines) + * - this assumes that linewidth is irrelevant + */ + if (gp_stroke_inside_circle(mval, mvalo, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { + if ((gp_stroke_eraser_is_occluded(p, pt1, pc1[0], pc1[1]) == false) || + (gp_stroke_eraser_is_occluded(p, pt2, pc2[0], pc2[1]) == false)) + { + /* Edge is affected - Check individual points now */ + if (len_v2v2_int(mval, pc1) <= radius) { + pt1->flag |= GP_SPOINT_TAG; + } + if (len_v2v2_int(mval, pc2) <= radius) { + pt2->flag |= GP_SPOINT_TAG; + } + do_cull = true; + } + } + } + } + + /* Second Pass: Remove any points that are tagged */ + if (do_cull) { + gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false); + } + } +} + +/* erase strokes which fall under the eraser strokes */ +static void gp_stroke_doeraser(tGPsdata *p) +{ + bGPDframe *gpf = p->gpf; + bGPDstroke *gps, *gpn; + rcti rect; + + /* rect is rectangle of eraser */ + rect.xmin = p->mval[0] - p->radius; + rect.ymin = p->mval[1] - p->radius; + rect.xmax = p->mval[0] + p->radius; + rect.ymax = p->mval[1] + p->radius; + + if (p->sa->spacetype == SPACE_VIEW3D) { + if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) { + View3D *v3d = p->sa->spacedata.first; + view3d_region_operator_needs_opengl(p->win, p->ar); + ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, 0); + } + } + + /* loop over strokes of active layer only (session init already took care of ensuring validity), + * checking segments for intersections to remove + */ + for (gps = gpf->strokes.first; gps; gps = gpn) { + gpn = gps->next; + /* Not all strokes in the datablock may be valid in the current editor/context + * (e.g. 2D space strokes in the 3D view, if the same datablock is shared) + */ + if (ED_gpencil_stroke_can_use_direct(p->sa, gps)) { + gp_stroke_eraser_dostroke(p, gpf, gps, p->mval, p->mvalo, p->radius, &rect); + } + } +} + +/* ******************************************* */ +/* Sketching Operator */ + +/* clear the session buffers (call this before AND after a paint operation) */ +static void gp_session_validatebuffer(tGPsdata *p) +{ + bGPdata *gpd = p->gpd; + + /* clear memory of buffer (or allocate it if starting a new session) */ + if (gpd->runtime.sbuffer) { + /* printf("\t\tGP - reset sbuffer\n"); */ + memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX); + } + else { + /* printf("\t\tGP - allocate sbuffer\n"); */ + gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); + } + + /* reset indices */ + gpd->runtime.sbuffer_size = 0; + + /* reset flags */ + gpd->runtime.sbuffer_sflag = 0; + + /* reset inittime */ + p->inittime = 0.0; +} + +/* (re)init new painting data */ +static bool gp_session_initdata(bContext *C, tGPsdata *p) +{ + Main *bmain = CTX_data_main(C); + bGPdata **gpd_ptr = NULL; + ScrArea *curarea = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + /* make sure the active view (at the starting time) is a 3d-view */ + if (curarea == NULL) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: No active view for painting\n"); + return 0; + } + + /* pass on current scene and window */ + p->bmain = CTX_data_main(C); + p->scene = CTX_data_scene(C); + p->depsgraph = CTX_data_depsgraph(C); + p->win = CTX_wm_window(C); + + unit_m4(p->imat); + unit_m4(p->mat); + + switch (curarea->spacetype) { + /* supported views first */ + case SPACE_VIEW3D: + { + /* View3D *v3d = curarea->spacedata.first; */ + /* RegionView3D *rv3d = ar->regiondata; */ + + /* set current area + * - must verify that region data is 3D-view (and not something else) + */ + /* CAUTION: If this is the "toolbar", then this will change on the first stroke */ + p->sa = curarea; + p->ar = ar; + p->align_flag = &ts->annotate_v3d_align; + + if (ar->regiondata == NULL) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n"); + return 0; + } + break; + } + case SPACE_NODE: + { + /* SpaceNode *snode = curarea->spacedata.first; */ + + /* set current area */ + p->sa = curarea; + p->ar = ar; + p->v2d = &ar->v2d; + p->align_flag = &ts->gpencil_v2d_align; + break; + } + case SPACE_SEQ: + { + SpaceSeq *sseq = curarea->spacedata.first; + + /* set current area */ + p->sa = curarea; + p->ar = ar; + p->v2d = &ar->v2d; + p->align_flag = &ts->gpencil_seq_align; + + /* check that gpencil data is allowed to be drawn */ + if (sseq->mainb == SEQ_DRAW_SEQUENCE) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n"); + return 0; + } + break; + } + case SPACE_IMAGE: + { + /* SpaceImage *sima = curarea->spacedata.first; */ + + /* set the current area */ + p->sa = curarea; + p->ar = ar; + p->v2d = &ar->v2d; + p->align_flag = &ts->gpencil_ima_align; + break; + } + case SPACE_CLIP: + { + SpaceClip *sc = curarea->spacedata.first; + MovieClip *clip = ED_space_clip_get_clip(sc); + + if (clip == NULL) { + p->status = GP_STATUS_ERROR; + return false; + } + + /* set the current area */ + p->sa = curarea; + p->ar = ar; + p->v2d = &ar->v2d; + p->align_flag = &ts->gpencil_v2d_align; + + invert_m4_m4(p->imat, sc->unistabmat); + + /* custom color for new layer */ + p->custom_color[0] = 1.0f; + p->custom_color[1] = 0.0f; + p->custom_color[2] = 0.5f; + p->custom_color[3] = 0.9f; + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + int framenr = ED_space_clip_get_clip_frame_number(sc); + MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking); + MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL; + + if (marker) { + p->imat[3][0] -= marker->pos[0]; + p->imat[3][1] -= marker->pos[1]; + } + else { + p->status = GP_STATUS_ERROR; + return false; + } + } + + invert_m4_m4(p->mat, p->imat); + copy_m4_m4(p->gsc.mat, p->mat); + break; + } + /* unsupported views */ + default: + { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: Annotations are not supported in this editor\n"); + return 0; + } + } + + /* get gp-data */ + gpd_ptr = ED_gpencil_data_get_pointers(C, &p->ownerPtr); + if ((gpd_ptr == NULL) || !ED_gpencil_data_owner_is_annotation(&p->ownerPtr)) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: Current context doesn't allow for any Annotation data\n"); + return 0; + } + else { + /* if no existing GPencil block exists, add one */ + if (*gpd_ptr == NULL) { + bGPdata *gpd = BKE_gpencil_data_addnew(bmain, "Annotations"); + *gpd_ptr = gpd; + + /* mark datablock as being used for annotations */ + gpd->flag |= GP_DATA_ANNOTATIONS; + + /* annotations always in front of all objects */ + gpd->xray_mode = GP_XRAY_FRONT; + } + p->gpd = *gpd_ptr; + } + + if (ED_gpencil_session_active() == 0) { + /* initialize undo stack, + * also, existing undo stack would make buffer drawn + */ + gpencil_undo_init(p->gpd); + } + + /* clear out buffer (stored in gp-data), in case something contaminated it */ + gp_session_validatebuffer(p); + + /* lock axis */ + p->lock_axis = ts->gp_sculpt.lock_axis; + + return 1; +} + +/* init new painting session */ +static tGPsdata *gp_session_initpaint(bContext *C) +{ + tGPsdata *p = NULL; + + /* create new context data */ + p = MEM_callocN(sizeof(tGPsdata), "Annotation Drawing Data"); + + gp_session_initdata(C, p); + + /* radius for eraser circle is defined in userprefs now */ + /* NOTE: we do this here, so that if we exit immediately, + * erase size won't get lost + */ + p->radius = U.gp_eraser; + + /* return context data for running paint operator */ + return p; +} + +/* cleanup after a painting session */ +static void gp_session_cleanup(tGPsdata *p) +{ + bGPdata *gpd = (p) ? p->gpd : NULL; + + /* error checking */ + if (gpd == NULL) + return; + + /* free stroke buffer */ + if (gpd->runtime.sbuffer) { + /* printf("\t\tGP - free sbuffer\n"); */ + MEM_freeN(gpd->runtime.sbuffer); + gpd->runtime.sbuffer = NULL; + } + + /* clear flags */ + gpd->runtime.sbuffer_size = 0; + gpd->runtime.sbuffer_sflag = 0; + p->inittime = 0.0; +} + +static void gp_session_free(tGPsdata *p) +{ + MEM_freeN(p); +} + + +/* init new stroke */ +static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Depsgraph *depsgraph) +{ + Scene *scene = p->scene; + ToolSettings *ts = scene->toolsettings; + + /* get active layer (or add a new one if non-existent) */ + p->gpl = BKE_gpencil_layer_getactive(p->gpd); + if (p->gpl == NULL) { + p->gpl = BKE_gpencil_layer_addnew(p->gpd, DATA_("Note"), true); + + if (p->custom_color[3]) + copy_v3_v3(p->gpl->color, p->custom_color); + } + if (p->gpl->flag & GP_LAYER_LOCKED) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: Cannot paint on locked layer\n"); + return; + } + + /* get active frame (add a new one if not matching frame) */ + if (paintmode == GP_PAINTMODE_ERASER) { + /* Eraser mode: + * 1) Only allow erasing on the active layer (unlike for 3d-art Grease Pencil), + * since we won't be exposing layer locking in the UI + * 2) Ensure that p->gpf refers to the frame used for the active layer + * (to avoid problems with other tools which expect it to exist) + */ + bool has_layer_to_erase = false; + + if (gpencil_layer_is_editable(p->gpl)) { + /* Ensure that there's stuff to erase here (not including selection mask below)... */ + if (p->gpl->actframe && p->gpl->actframe->strokes.first) { + has_layer_to_erase = true; + } + } + + /* Ensure active frame is set correctly... */ + p->gpf = p->gpl->actframe; + + /* Restrict eraser to only affecting selected strokes, if the "selection mask" is on + * (though this is only available in editmode) + */ + if (p->gpd->flag & GP_DATA_STROKE_EDITMODE) { + if (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_SELECT_MASK) { + p->flags |= GP_PAINTFLAG_SELECTMASK; + } + } + + if (has_layer_to_erase == false) { + p->status = GP_STATUS_ERROR; + //if (G.debug & G_DEBUG) + printf("Error: Eraser will not be affecting anything (gpencil_paint_init)\n"); + return; + } + } + else { + /* Drawing Modes - Add a new frame if needed on the active layer */ + short add_frame_mode = GP_GETFRAME_ADD_NEW; + + if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) + add_frame_mode = GP_GETFRAME_ADD_COPY; + else + add_frame_mode = GP_GETFRAME_ADD_NEW; + + p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode); + + if (p->gpf == NULL) { + p->status = GP_STATUS_ERROR; + if (G.debug & G_DEBUG) + printf("Error: No frame created (gpencil_paint_init)\n"); + return; + } + else { + p->gpf->flag |= GP_FRAME_PAINT; + } + } + + /* set 'eraser' for this stroke if using eraser */ + p->paintmode = paintmode; + if (p->paintmode == GP_PAINTMODE_ERASER) { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_ERASER; + + /* check if we should respect depth while erasing */ + if (p->sa->spacetype == SPACE_VIEW3D) { + if (p->gpl->flag & GP_LAYER_NO_XRAY) { + p->flags |= GP_PAINTFLAG_V3D_ERASER_DEPTH; + } + } + } + else { + /* disable eraser flags - so that we can switch modes during a session */ + p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_ERASER; + + if (p->sa->spacetype == SPACE_VIEW3D) { + if (p->gpl->flag & GP_LAYER_NO_XRAY) { + p->flags &= ~GP_PAINTFLAG_V3D_ERASER_DEPTH; + } + } + } + + /* set 'initial run' flag, which is only used to denote when a new stroke is starting */ + p->flags |= GP_PAINTFLAG_FIRSTRUN; + + + /* when drawing in the camera view, in 2D space, set the subrect */ + p->subrect = NULL; + if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { + if (p->sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = p->sa->spacedata.first; + RegionView3D *rv3d = p->ar->regiondata; + + /* for camera view set the subrect */ + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(p->scene, depsgraph, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */ + p->subrect = &p->subrect_data; + } + } + } + + /* init stroke point space-conversion settings... */ + p->gsc.gpd = p->gpd; + p->gsc.gpl = p->gpl; + + p->gsc.sa = p->sa; + p->gsc.ar = p->ar; + p->gsc.v2d = p->v2d; + + p->gsc.subrect_data = p->subrect_data; + p->gsc.subrect = p->subrect; + + copy_m4_m4(p->gsc.mat, p->mat); + + + /* check if points will need to be made in view-aligned space */ + if (*p->align_flag & GP_PROJECT_VIEWSPACE) { + switch (p->sa->spacetype) { + case SPACE_VIEW3D: + { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_3DSPACE; + break; + } + case SPACE_NODE: + { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE; + break; + } + case SPACE_SEQ: + { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first; + + /* only set these flags if the image editor doesn't have an image active, + * otherwise user will be confused by strokes not appearing after they're drawn + * + * Admittedly, this is a bit hacky, but it works much nicer from an ergonomic standpoint! + */ + if (ELEM(NULL, sima, sima->image)) { + /* make strokes be drawn in screen space */ + p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_2DSPACE; + *(p->align_flag) &= ~GP_PROJECT_VIEWSPACE; + } + else { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE; + } + break; + } + case SPACE_CLIP: + { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_2DSPACE; + break; + } + } + } +} + +/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */ +static void gp_paint_strokeend(tGPsdata *p) +{ + ToolSettings *ts = p->scene->toolsettings; + /* for surface sketching, need to set the right OpenGL context stuff so that + * the conversions will project the values correctly... + */ + if (gpencil_project_check(p)) { + View3D *v3d = p->sa->spacedata.first; + + /* need to restore the original projection settings before packing up */ + view3d_region_operator_needs_opengl(p->win, p->ar); + ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, (ts->annotate_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + } + + /* check if doing eraser or not */ + if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) { + /* simplify stroke before transferring? */ + gp_stroke_simplify(p); + + /* transfer stroke to frame */ + gp_stroke_newfrombuffer(p); + } + + /* clean up buffer now */ + gp_session_validatebuffer(p); +} + +/* finish off stroke painting operation */ +static void gp_paint_cleanup(tGPsdata *p) +{ + /* p->gpd==NULL happens when stroke failed to initialize, + * for example when GP is hidden in current space (sergey) + */ + if (p->gpd) { + /* finish off a stroke */ + gp_paint_strokeend(p); + } + + /* "unlock" frame */ + if (p->gpf) + p->gpf->flag &= ~GP_FRAME_PAINT; +} + +/* ------------------------------- */ + +/* Helper callback for drawing the cursor itself */ +static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) +{ + tGPsdata *p = (tGPsdata *)p_ptr; + + if (p->paintmode == GP_PAINTMODE_ERASER) { + GPUVertFormat *format = immVertexFormat(); + const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + GPU_line_smooth(true); + GPU_blend(true); + GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + + immUniformColor4ub(255, 100, 100, 20); + imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); + + immUnbindProgram(); + + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + GPU_viewport_size_get_f(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f); + immUniform1i("colors_len", 0); /* "simple" mode */ + immUniform1f("dash_width", 12.0f); + immUniform1f("dash_factor", 0.5f); + + imm_draw_circle_wire_2d(shdr_pos, x, y, p->radius, + /* XXX Dashed shader gives bad results with sets of small segments currently, + * temp hack around the issue. :( */ + max_ii(8, p->radius / 2)); /* was fixed 40 */ + + immUnbindProgram(); + + GPU_blend(false); + GPU_line_smooth(false); + } +} + +/* Turn brush cursor in 3D view on/off */ +static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short enable) +{ + if (p->erasercursor && !enable) { + /* clear cursor */ + WM_paint_cursor_end(CTX_wm_manager(C), p->erasercursor); + p->erasercursor = NULL; + } + else if (enable && !p->erasercursor) { + /* enable cursor */ + p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C), + NULL, /* XXX */ + gpencil_draw_eraser, p); + } +} + +/* Check if tablet eraser is being used (when processing events) */ +static bool gpencil_is_tablet_eraser_active(const wmEvent *event) +{ + if (event->tablet_data) { + const wmTabletData *wmtab = event->tablet_data; + return (wmtab->Active == EVT_TABLET_ERASER); + } + + return false; +} + +/* ------------------------------- */ + +static void gpencil_draw_exit(bContext *C, wmOperator *op) +{ + tGPsdata *p = op->customdata; + + /* clear undo stack */ + gpencil_undo_finish(); + + /* restore cursor to indicate end of drawing */ + WM_cursor_modal_restore(CTX_wm_window(C)); + + /* don't assume that operator data exists at all */ + if (p) { + /* check size of buffer before cleanup, to determine if anything happened here */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + /* turn off radial brush cursor */ + gpencil_draw_toggle_eraser_cursor(C, p, false); + } + + /* always store the new eraser size to be used again next time + * NOTE: Do this even when not in eraser mode, as eraser may + * have been toggled at some point. + */ + U.gp_eraser = p->radius; + + /* cleanup */ + gp_paint_cleanup(p); + gp_session_cleanup(p); + gp_session_free(p); + } + + op->customdata = NULL; +} + +static void gpencil_draw_cancel(bContext *C, wmOperator *op) +{ + /* this is just a wrapper around exit() */ + gpencil_draw_exit(C, op); +} + +/* ------------------------------- */ + + +static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) +{ + tGPsdata *p; + eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode"); + + /* check context */ + p = op->customdata = gp_session_initpaint(C); + if ((p == NULL) || (p->status == GP_STATUS_ERROR)) { + /* something wasn't set correctly in context */ + gpencil_draw_exit(C, op); + return 0; + } + + /* init painting data */ + gp_paint_initstroke(p, paintmode, CTX_data_depsgraph(C)); + if (p->status == GP_STATUS_ERROR) { + gpencil_draw_exit(C, op); + return 0; + } + + if (event != NULL) { + p->keymodifier = event->keymodifier; + } + else { + p->keymodifier = -1; + } + + /* everything is now setup ok */ + return 1; +} + + +/* ------------------------------- */ + +/* ensure that the correct cursor icon is set */ +static void gpencil_draw_cursor_set(tGPsdata *p) +{ + if (p->paintmode == GP_PAINTMODE_ERASER) + WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */ + else + WM_cursor_modal_set(p->win, BC_PAINTBRUSHCURSOR); +} + +/* update UI indicators of status, including cursor and header prints */ +static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) +{ + /* header prints */ + switch (p->status) { + case GP_STATUS_PAINTING: + switch (p->paintmode) { + case GP_PAINTMODE_DRAW_POLY: + /* Provide usage tips, since this is modal, and unintuitive without hints */ + ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | " + "ESC/Enter to end (or click outside this area)")); + break; + default: + /* Do nothing - the others are self explanatory, exit quickly once the mouse is released + * Showing any text would just be annoying as it would flicker. + */ + break; + } + break; + + case GP_STATUS_IDLING: + /* print status info */ + switch (p->paintmode) { + case GP_PAINTMODE_ERASER: + ED_workspace_status_text(C, IFACE_("Annotation Eraser: Hold and drag LMB or RMB to erase | " + "ESC/Enter to end (or click outside this area)")); + break; + case GP_PAINTMODE_DRAW_STRAIGHT: + ED_workspace_status_text(C, IFACE_("Annotation Line Draw: Hold and drag LMB to draw | " + "ESC/Enter to end (or click outside this area)")); + break; + case GP_PAINTMODE_DRAW: + ED_workspace_status_text(C, IFACE_("Annotation Freehand Draw: Hold and drag LMB to draw | " + "E/ESC/Enter to end (or click outside this area)")); + break; + case GP_PAINTMODE_DRAW_POLY: + ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | " + "ESC/Enter to end (or click outside this area)")); + break; + + default: /* unhandled future cases */ + ED_workspace_status_text(C, IFACE_("Annotation Session: ESC/Enter to end (or click outside this area)")); + break; + } + break; + + case GP_STATUS_ERROR: + case GP_STATUS_DONE: + /* clear status string */ + ED_workspace_status_text(C, NULL); + break; + } +} + +/* ------------------------------- */ + +/* create a new stroke point at the point indicated by the painting context */ +static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph) +{ + /* handle drawing/erasing -> test for erasing first */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + /* do 'live' erasing now */ + gp_stroke_doeraser(p); + + /* store used values */ + p->mvalo[0] = p->mval[0]; + p->mvalo[1] = p->mval[1]; + p->opressure = p->pressure; + } + /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ + else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { + /* try to add point */ + short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); + + /* handle errors while adding point */ + if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { + /* finish off old stroke */ + gp_paint_strokeend(p); + /* And start a new one!!! Else, projection errors! */ + gp_paint_initstroke(p, p->paintmode, depsgraph); + + /* start a new stroke, starting from previous point */ + /* XXX Must manually reset inittime... */ + /* XXX We only need to reuse previous point if overflow! */ + if (ok == GP_STROKEADD_OVERFLOW) { + p->inittime = p->ocurtime; + gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime); + } + else { + p->inittime = p->curtime; + } + gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); + } + else if (ok == GP_STROKEADD_INVALID) { + /* the painting operation cannot continue... */ + BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke"); + p->status = GP_STATUS_ERROR; + + if (G.debug & G_DEBUG) + printf("Error: Grease-Pencil Paint - Add Point Invalid\n"); + return; + } + + /* store used values */ + p->mvalo[0] = p->mval[0]; + p->mvalo[1] = p->mval[1]; + p->opressure = p->pressure; + p->ocurtime = p->curtime; + } +} + +/* handle draw event */ +static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsgraph *depsgraph) +{ + tGPsdata *p = op->customdata; + PointerRNA itemptr; + float mousef[2]; + int tablet = 0; + + /* convert from window-space to area-space mouse coordinates + * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... + */ + p->mval[0] = event->mval[0] + 1; + p->mval[1] = event->mval[1] + 1; + + /* verify key status for straight lines */ + if ((event->ctrl > 0) || (event->alt > 0)) { + if (p->straight[0] == 0) { + int dx = abs(p->mval[0] - p->mvalo[0]); + int dy = abs(p->mval[1] - p->mvalo[1]); + if ((dx > 0) || (dy > 0)) { + /* check mouse direction to replace the other coordinate with previous values */ + if (dx >= dy) { + /* horizontal */ + p->straight[0] = 1; + p->straight[1] = p->mval[1]; /* save y */ + } + else { + /* vertical */ + p->straight[0] = 2; + p->straight[1] = p->mval[0]; /* save x */ + } + } + } + } + else { + p->straight[0] = 0; + } + + p->curtime = PIL_check_seconds_timer(); + + /* handle pressure sensitivity (which is supplied by tablets) */ + if (event->tablet_data) { + const wmTabletData *wmtab = event->tablet_data; + + tablet = (wmtab->Active != EVT_TABLET_NONE); + p->pressure = wmtab->Pressure; + + /* Hack for pressure sensitive eraser on D+RMB when using a tablet: + * The pen has to float over the tablet surface, resulting in + * zero pressure (T47101). Ignore pressure values if floating + * (i.e. "effectively zero" pressure), and only when the "active" + * end is the stylus (i.e. the default when not eraser) + */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + if ((wmtab->Active != EVT_TABLET_ERASER) && (p->pressure < 0.001f)) { + p->pressure = 1.0f; + } + } + } + else { + /* No tablet data -> No pressure info is available */ + p->pressure = 1.0f; + } + + /* special exception for start of strokes (i.e. maybe for just a dot) */ + if (p->flags & GP_PAINTFLAG_FIRSTRUN) { + p->flags &= ~GP_PAINTFLAG_FIRSTRUN; + + p->mvalo[0] = p->mval[0]; + p->mvalo[1] = p->mval[1]; + p->opressure = p->pressure; + p->inittime = p->ocurtime = p->curtime; + p->straight[0] = 0; + p->straight[1] = 0; + + /* special exception here for too high pressure values on first touch in + * windows for some tablets, then we just skip first touch... + */ + if (tablet && (p->pressure >= 0.99f)) + return; + } + + /* check if alt key is pressed and limit to straight lines */ + if (p->straight[0] != 0) { + if (p->straight[0] == 1) { + /* horizontal */ + p->mval[1] = p->straight[1]; /* replace y */ + } + else { + /* vertical */ + p->mval[0] = p->straight[1]; /* replace x */ + } + } + + /* fill in stroke data (not actually used directly by gpencil_draw_apply) */ + RNA_collection_add(op->ptr, "stroke", &itemptr); + + mousef[0] = p->mval[0]; + mousef[1] = p->mval[1]; + RNA_float_set_array(&itemptr, "mouse", mousef); + RNA_float_set(&itemptr, "pressure", p->pressure); + RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0); + + RNA_float_set(&itemptr, "time", p->curtime - p->inittime); + + /* apply the current latest drawing point */ + gpencil_draw_apply(op, p, depsgraph); + + /* force refresh */ + ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ +} + +/* ------------------------------- */ + +/* operator 'redo' (i.e. after changing some properties, but also for repeat last) */ +static int gpencil_draw_exec(bContext *C, wmOperator *op) +{ + tGPsdata *p = NULL; + Depsgraph *depsgraph = CTX_data_depsgraph(C); + + /* printf("GPencil - Starting Re-Drawing\n"); */ + + /* try to initialize context data needed while drawing */ + if (!gpencil_draw_init(C, op, NULL)) { + if (op->customdata) MEM_freeN(op->customdata); + /* printf("\tGP - no valid data\n"); */ + return OPERATOR_CANCELLED; + } + else + p = op->customdata; + + /* printf("\tGP - Start redrawing stroke\n"); */ + + /* loop over the stroke RNA elements recorded (i.e. progress of mouse movement), + * setting the relevant values in context at each step, then applying + */ + RNA_BEGIN (op->ptr, itemptr, "stroke") + { + float mousef[2]; + + /* printf("\t\tGP - stroke elem\n"); */ + + /* get relevant data for this point from stroke */ + RNA_float_get_array(&itemptr, "mouse", mousef); + p->mval[0] = (int)mousef[0]; + p->mval[1] = (int)mousef[1]; + p->pressure = RNA_float_get(&itemptr, "pressure"); + p->curtime = (double)RNA_float_get(&itemptr, "time") + p->inittime; + + if (RNA_boolean_get(&itemptr, "is_start")) { + /* if first-run flag isn't set already (i.e. not true first stroke), + * then we must terminate the previous one first before continuing + */ + if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) { + /* TODO: both of these ops can set error-status, but we probably don't need to worry */ + gp_paint_strokeend(p); + gp_paint_initstroke(p, p->paintmode, depsgraph); + } + } + + /* if first run, set previous data too */ + if (p->flags & GP_PAINTFLAG_FIRSTRUN) { + p->flags &= ~GP_PAINTFLAG_FIRSTRUN; + + p->mvalo[0] = p->mval[0]; + p->mvalo[1] = p->mval[1]; + p->opressure = p->pressure; + p->ocurtime = p->curtime; + } + + /* apply this data as necessary now (as per usual) */ + gpencil_draw_apply(op, p, depsgraph); + } + RNA_END; + + /* printf("\tGP - done\n"); */ + + /* cleanup */ + gpencil_draw_exit(C, op); + + /* refreshes */ + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + + /* done */ + return OPERATOR_FINISHED; +} + +/* ------------------------------- */ + +/* start of interactive drawing part of operator */ +static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *ob = CTX_data_active_object(C); + tGPsdata *p = NULL; + + /* GPXX Need a better solution */ + if ((ob != NULL) && (ob->type == OB_GPENCIL)) { + BKE_report(op->reports, RPT_ERROR, "Cannot draw annotation with a Grease Pencil object active"); + return OPERATOR_CANCELLED; + } + + if (G.debug & G_DEBUG) + printf("GPencil - Starting Drawing\n"); + + /* try to initialize context data needed while drawing */ + if (!gpencil_draw_init(C, op, event)) { + if (op->customdata) + MEM_freeN(op->customdata); + if (G.debug & G_DEBUG) + printf("\tGP - no valid data\n"); + return OPERATOR_CANCELLED; + } + else + p = op->customdata; + + /* TODO: set any additional settings that we can take from the events? + * TODO? if tablet is erasing, force eraser to be on? */ + + /* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway... */ + + /* if eraser is on, draw radial aid */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + gpencil_draw_toggle_eraser_cursor(C, p, true); + } + /* set cursor + * NOTE: This may change later (i.e. intentionally via brush toggle, + * or unintentionally if the user scrolls outside the area)... + */ + gpencil_draw_cursor_set(p); + + /* only start drawing immediately if we're allowed to do so... */ + if (RNA_boolean_get(op->ptr, "wait_for_input") == false) { + /* hotkey invoked - start drawing */ + /* printf("\tGP - set first spot\n"); */ + p->status = GP_STATUS_PAINTING; + + /* handle the initial drawing - i.e. for just doing a simple dot */ + gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); + op->flag |= OP_IS_MODAL_CURSOR_REGION; + } + else { + /* toolbar invoked - don't start drawing yet... */ + /* printf("\tGP - hotkey invoked... waiting for click-drag\n"); */ + op->flag |= OP_IS_MODAL_CURSOR_REGION; + } + + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + /* add a modal handler for this operator, so that we can then draw continuous strokes */ + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; +} + +/* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */ +static bool gpencil_area_exists(bContext *C, ScrArea *sa_test) +{ + bScreen *sc = CTX_wm_screen(C); + return (BLI_findindex(&sc->areabase, sa_test) != -1); +} + +static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) +{ + tGPsdata *p = op->customdata; + + /* we must check that we're still within the area that we're set up to work from + * otherwise we could crash (see bug #20586) + */ + if (CTX_wm_area(C) != p->sa) { + printf("\t\t\tGP - wrong area execution abort!\n"); + p->status = GP_STATUS_ERROR; + } + + /* printf("\t\tGP - start stroke\n"); */ + + /* we may need to set up paint env again if we're resuming */ + /* XXX: watch it with the paintmode! in future, + * it'd be nice to allow changing paint-mode when in sketching-sessions */ + + if (gp_session_initdata(C, p)) + gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C)); + + if (p->status != GP_STATUS_ERROR) { + p->status = GP_STATUS_PAINTING; + op->flag &= ~OP_IS_MODAL_CURSOR_REGION; + } + + return op->customdata; +} + +static void gpencil_stroke_end(wmOperator *op) +{ + tGPsdata *p = op->customdata; + + gp_paint_cleanup(p); + + gpencil_undo_push(p->gpd); + + gp_session_cleanup(p); + + p->status = GP_STATUS_IDLING; + op->flag |= OP_IS_MODAL_CURSOR_REGION; + + p->gpd = NULL; + p->gpl = NULL; + p->gpf = NULL; +} + +/* events handling during interactive drawing part of operator */ +static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + tGPsdata *p = op->customdata; + int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */ + + /* if (event->type == NDOF_MOTION) + * return OPERATOR_PASS_THROUGH; + * ------------------------------- + * [mce] Not quite what I was looking + * for, but a good start! GP continues to + * draw on the screen while the 3D mouse + * moves the viewpoint. Problem is that + * the stroke is converted to 3D only after + * it is finished. This approach should work + * better in tools that immediately apply + * in 3D space. + */ + + if (p->status == GP_STATUS_IDLING) { + ARegion *ar = CTX_wm_region(C); + p->ar = ar; + } + + /* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */ + if (ISKEYBOARD(event->type)) { + if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY, ZKEY)) { + /* allow some keys: + * - for frame changing [#33412] + * - for undo (during sketching sessions) + */ + } + else if (ELEM(event->type, PAD0, PAD1, PAD2, PAD3, PAD4, PAD5, PAD6, PAD7, PAD8, PAD9)) { + /* allow numpad keys so that camera/view manipulations can still take place + * - PAD0 in particular is really important for Grease Pencil drawing, + * as animators may be working "to camera", so having this working + * is essential for ensuring that they can quickly return to that view + */ + } + else if ((event->type == BKEY) && (event->val == KM_RELEASE)) { + /* Add Blank Frame + * - Since this operator is non-modal, we can just call it here, and keep going... + * - This operator is especially useful when animating + */ + WM_operator_name_call(C, "GPENCIL_OT_blank_frame_add", WM_OP_EXEC_DEFAULT, NULL); + estate = OPERATOR_RUNNING_MODAL; + } + else { + estate = OPERATOR_RUNNING_MODAL; + } + } + + //printf("\tGP - handle modal event...\n"); + + /* exit painting mode (and/or end current stroke) + * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647] + */ + if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) { + /* exit() ends the current stroke before cleaning up */ + /* printf("\t\tGP - end of paint op + end of stroke\n"); */ + p->status = GP_STATUS_DONE; + estate = OPERATOR_FINISHED; + } + + /* toggle painting mode upon mouse-button movement + * - LEFTMOUSE = standard drawing (all) / straight line drawing (all) / polyline (toolbox only) + * - RIGHTMOUSE = polyline (hotkey) / eraser (all) + * (Disabling RIGHTMOUSE case here results in bugs like [#32647]) + * also making sure we have a valid event value, to not exit too early + */ + if (ELEM(event->type, LEFTMOUSE, RIGHTMOUSE) && (ELEM(event->val, KM_PRESS, KM_RELEASE))) { + /* if painting, end stroke */ + if (p->status == GP_STATUS_PAINTING) { + int sketch = 0; + + /* basically, this should be mouse-button up = end stroke + * BUT, polyline drawing is an exception -- all knots should be added during one session + */ + sketch |= (p->paintmode == GP_PAINTMODE_DRAW_POLY); + + if (sketch) { + /* end stroke only, and then wait to resume painting soon */ + /* printf("\t\tGP - end stroke only\n"); */ + gpencil_stroke_end(op); + + /* If eraser mode is on, turn it off after the stroke finishes + * NOTE: This just makes it nicer to work with drawing sessions + */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + p->paintmode = RNA_enum_get(op->ptr, "mode"); + + /* if the original mode was *still* eraser, + * we'll let it say for now, since this gives + * users an opportunity to have visual feedback + * when adjusting eraser size + */ + if (p->paintmode != GP_PAINTMODE_ERASER) { + /* turn off cursor... + * NOTE: this should be enough for now + * Just hiding this makes it seem like + * you can paint again... + */ + gpencil_draw_toggle_eraser_cursor(C, p, false); + } + } + + /* we've just entered idling state, so this event was processed (but no others yet) */ + estate = OPERATOR_RUNNING_MODAL; + + /* stroke could be smoothed, send notifier to refresh screen */ + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + } + else { + /* printf("\t\tGP - end of stroke + op\n"); */ + p->status = GP_STATUS_DONE; + estate = OPERATOR_FINISHED; + } + } + else if (event->val == KM_PRESS) { + bool in_bounds = false; + + /* Check if we're outside the bounds of the active region + * NOTE: An exception here is that if launched from the toolbar, + * whatever region we're now in should become the new region + */ + if ((p->ar) && (p->ar->regiontype == RGN_TYPE_TOOLS)) { + /* Change to whatever region is now under the mouse */ + ARegion *current_region = BKE_area_find_region_xy(p->sa, RGN_TYPE_ANY, event->x, event->y); + + if (G.debug & G_DEBUG) { + printf("found alternative region %p (old was %p) - at %d %d (sa: %d %d -> %d %d)\n", + current_region, p->ar, event->x, event->y, + p->sa->totrct.xmin, p->sa->totrct.ymin, p->sa->totrct.xmax, p->sa->totrct.ymax); + } + + if (current_region) { + /* Assume that since we found the cursor in here, it is in bounds + * and that this should be the region that we begin drawing in + */ + p->ar = current_region; + in_bounds = true; + } + else { + /* Out of bounds, or invalid in some other way */ + p->status = GP_STATUS_ERROR; + estate = OPERATOR_CANCELLED; + + if (G.debug & G_DEBUG) + printf("%s: Region under cursor is out of bounds, so cannot be drawn on\n", __func__); + } + } + else if (p->ar) { + rcti region_rect; + + /* Perform bounds check using */ + ED_region_visible_rect(p->ar, ®ion_rect); + in_bounds = BLI_rcti_isect_pt_v(®ion_rect, event->mval); + } + else { + /* No region */ + p->status = GP_STATUS_ERROR; + estate = OPERATOR_CANCELLED; + + if (G.debug & G_DEBUG) + printf("%s: No active region found in GP Paint session data\n", __func__); + } + + if (in_bounds) { + /* Switch paintmode (temporarily if need be) based on which button was used + * NOTE: This is to make it more convenient to erase strokes when using drawing sessions + */ + if ((event->type == RIGHTMOUSE) || gpencil_is_tablet_eraser_active(event)) { + /* turn on eraser */ + p->paintmode = GP_PAINTMODE_ERASER; + } + else if (event->type == LEFTMOUSE) { + /* restore drawmode to default */ + p->paintmode = RNA_enum_get(op->ptr, "mode"); + } + + gpencil_draw_toggle_eraser_cursor(C, p, p->paintmode == GP_PAINTMODE_ERASER); + + /* not painting, so start stroke (this should be mouse-button down) */ + p = gpencil_stroke_begin(C, op); + + if (p->status == GP_STATUS_ERROR) { + estate = OPERATOR_CANCELLED; + } + } + else if (p->status != GP_STATUS_ERROR) { + /* User clicked outside bounds of window while idling, so exit paintmode + * NOTE: Don't enter this case if an error occurred while finding the + * region (as above) + */ + p->status = GP_STATUS_DONE; + estate = OPERATOR_FINISHED; + } + } + else if (event->val == KM_RELEASE) { + p->status = GP_STATUS_IDLING; + op->flag |= OP_IS_MODAL_CURSOR_REGION; + } + } + + /* handle mode-specific events */ + if (p->status == GP_STATUS_PAINTING) { + /* handle painting mouse-movements? */ + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { + /* handle drawing event */ + /* printf("\t\tGP - add point\n"); */ + gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); + + /* finish painting operation if anything went wrong just now */ + if (p->status == GP_STATUS_ERROR) { + printf("\t\t\t\tGP - add error done!\n"); + estate = OPERATOR_CANCELLED; + } + else { + /* event handled, so just tag as running modal */ + /* printf("\t\t\t\tGP - add point handled!\n"); */ + estate = OPERATOR_RUNNING_MODAL; + } + } + /* eraser size */ + else if ((p->paintmode == GP_PAINTMODE_ERASER) && + ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE, PADPLUSKEY, PADMINUS)) + { + /* just resize the brush (local version) + * TODO: fix the hardcoded size jumps (set to make a visible difference) and hardcoded keys + */ + /* printf("\t\tGP - resize eraser\n"); */ + switch (event->type) { + case WHEELDOWNMOUSE: /* larger */ + case PADPLUSKEY: + p->radius += 5; + break; + + case WHEELUPMOUSE: /* smaller */ + case PADMINUS: + p->radius -= 5; + + if (p->radius <= 0) + p->radius = 1; + break; + } + + /* force refresh */ + ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ + + /* event handled, so just tag as running modal */ + estate = OPERATOR_RUNNING_MODAL; + } + /* there shouldn't be any other events, but just in case there are, let's swallow them + * (i.e. to prevent problems with undo) + */ + else { + /* swallow event to save ourselves trouble */ + estate = OPERATOR_RUNNING_MODAL; + } + } + + /* gpencil modal operator stores area, which can be removed while using it (like fullscreen) */ + if (0 == gpencil_area_exists(C, p->sa)) + estate = OPERATOR_CANCELLED; + else { + /* update status indicators - cursor, header, etc. */ + gpencil_draw_status_indicators(C, p); + gpencil_draw_cursor_set(p); /* cursor may have changed outside our control - T44084 */ + } + + /* process last operations before exiting */ + switch (estate) { + case OPERATOR_FINISHED: + /* one last flush before we're done */ + gpencil_draw_exit(C, op); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + break; + + case OPERATOR_CANCELLED: + gpencil_draw_exit(C, op); + break; + + case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: + /* event doesn't need to be handled */ +#if 0 + printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", + event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#endif + break; + } + + /* return status code */ + return estate; +} + +/* ------------------------------- */ + +static const EnumPropertyItem prop_gpencil_drawmodes[] = { + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"}, + {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"}, + {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"}, + {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Annotation strokes"}, + {0, NULL, 0, NULL, NULL} +}; + +void GPENCIL_OT_annotate(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Annotation Draw"; + ot->idname = "GPENCIL_OT_annotate"; + ot->description = "Make annotations on the active data"; + + /* api callbacks */ + ot->exec = gpencil_draw_exec; + ot->invoke = gpencil_draw_invoke; + ot->modal = gpencil_draw_modal; + ot->cancel = gpencil_draw_cancel; + ot->poll = gpencil_draw_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* settings for drawing */ + ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); + + prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + /* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */ + prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 29b24886017..5c56877cbe6 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -46,6 +46,7 @@ #include "BLF_api.h" #include "BLT_translation.h" +#include "DNA_brush_types.h" #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -55,8 +56,13 @@ #include "DNA_object_types.h" #include "BKE_context.h" +#include "BKE_brush.h" #include "BKE_global.h" +#include "BKE_paint.h" #include "BKE_gpencil.h" +#include "BKE_image.h" + +#include "DEG_depsgraph.h" #include "WM_api.h" @@ -74,6 +80,10 @@ #include "UI_interface_icons.h" #include "UI_resources.h" +#include "IMB_imbuf_types.h" + +#include "gpencil_intern.h" + /* ************************************************** */ /* GREASE PENCIL DRAWING */ @@ -88,8 +98,7 @@ typedef enum eDrawStrokeFlags { GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */ GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */ GP_DRAWDATA_VOLUMETRIC = (1 << 7), /* draw strokes as "volumetric" circular billboards */ - GP_DRAWDATA_FILL = (1 << 8), /* fill insides/bounded-regions of strokes */ - GP_DRAWDATA_HQ_FILL = (1 << 9) /* Use high quality fill */ + GP_DRAWDATA_FILL = (1 << 8) /* fill insides/bounded-regions of strokes */ } eDrawStrokeFlags; @@ -100,12 +109,12 @@ typedef enum eDrawStrokeFlags { #endif /* conversion utility (float --> normalized unsigned byte) */ -#define F2UB(x) (unsigned char)(255.0f * x) +#define F2UB(x) (uchar)(255.0f * x) /* ----- Tool Buffer Drawing ------ */ /* helper functions to set color of buffer point */ -static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], unsigned attrib_id) +static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], uint attrib_id) { float alpha = ink[3] * pt->strength; CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); @@ -119,7 +128,7 @@ static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4]) immUniformColor3fvAlpha(ink, alpha); } -static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], unsigned attrib_id) +static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], uint attrib_id) { float alpha = ink[3] * pt->strength; CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); @@ -134,7 +143,7 @@ static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, f } int tot_triangles = totpoints - 2; /* allocate memory for temporary areas */ - unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation"); + uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation"); float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points"); /* Convert points to array and triangulate @@ -146,7 +155,7 @@ static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, f points2d[i][0] = pt->x; points2d[i][1] = pt->y; } - BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)totpoints, 0, (unsigned int(*)[3])tmp_triangles); + BLI_polyfill_calc((const float(*)[2])points2d, (uint)totpoints, 0, (uint(*)[3])tmp_triangles); /* draw triangulation data */ if (tot_triangles > 0) { @@ -253,7 +262,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short if (i != 0) { gp_set_tpoint_varying_color(pt - 1, ink, color); immVertex2iv(pos, &(pt - 1)->x); - ++draw_points; + draw_points++; } oldpressure = pt->pressure; /* reset our threshold */ @@ -262,7 +271,7 @@ static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short /* now the point we want */ gp_set_tpoint_varying_color(pt, ink, color); immVertex2iv(pos, &pt->x); - ++draw_points; + draw_points++; } /* need to have 2 points to avoid immEnd assert error */ if (draw_points < 2) { @@ -402,6 +411,50 @@ static void gp_draw_stroke_volumetric_3d( /* --------------- Stroke Fills ----------------- */ +/* calc bounding box in 2d using flat projection data */ +static void gp_calc_2d_bounding_box(const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], bool expand) +{ + copy_v2_v2(minv, points2d[0]); + copy_v2_v2(maxv, points2d[0]); + + for (int i = 1; i < totpoints; i++) { + /* min */ + if (points2d[i][0] < minv[0]) { + minv[0] = points2d[i][0]; + } + if (points2d[i][1] < minv[1]) { + minv[1] = points2d[i][1]; + } + /* max */ + if (points2d[i][0] > maxv[0]) { + maxv[0] = points2d[i][0]; + } + if (points2d[i][1] > maxv[1]) { + maxv[1] = points2d[i][1]; + } + } + /* If not expanded, use a perfect square */ + if (expand == false) { + if (maxv[0] > maxv[1]) { + maxv[1] = maxv[0]; + } + else { + maxv[0] = maxv[1]; + } + } +} + +/* calc texture coordinates using flat projected points */ +static void gp_calc_stroke_text_coordinates(const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], float(*r_uv)[2]) +{ + float d[2]; + d[0] = maxv[0] - minv[0]; + d[1] = maxv[1] - minv[1]; + for (int i = 0; i < totpoints; i++) { + r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0]; + r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1]; + } +} /* Get points of stroke always flat to view not affected by camera view or view position */ static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction) @@ -447,7 +500,6 @@ static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*po *r_direction = (int)locy[2]; } - /* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */ static void gp_triangulate_stroke_fill(bGPDstroke *gps) { @@ -455,14 +507,23 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps) /* allocate memory for temporary areas */ gps->tot_triangles = gps->totpoints - 2; - unsigned int (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation"); + uint (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation"); float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points"); + float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data"); int direction = 0; /* convert to 2d and triangulate */ gp_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction); - BLI_polyfill_calc(points2d, (unsigned int)gps->totpoints, direction, tmp_triangles); + BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles); + + /* calc texture coordinates automatically */ + float minv[2]; + float maxv[2]; + /* first needs bounding box data */ + gp_calc_2d_bounding_box((const float(*)[2])points2d, gps->totpoints, minv, maxv, false); + /* calc uv data */ + gp_calc_stroke_text_coordinates((const float(*)[2])points2d, gps->totpoints, minv, maxv, uv); /* Number of triangles */ gps->tot_triangles = gps->totpoints - 2; @@ -476,7 +537,12 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps) } for (int i = 0; i < gps->tot_triangles; i++) { - memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3])); + bGPDtriangle *stroke_triangle = &gps->triangles[i]; + memcpy(stroke_triangle->verts, tmp_triangles[i], sizeof(uint[3])); + /* copy texture coordinates */ + copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]); + copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]); + copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]); } } else { @@ -493,73 +559,128 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps) } /* clear memory */ - if (tmp_triangles) MEM_freeN(tmp_triangles); - if (points2d) MEM_freeN(points2d); + MEM_SAFE_FREE(tmp_triangles); + MEM_SAFE_FREE(points2d); + MEM_SAFE_FREE(uv); } - -/* draw fills for shapes */ -static void gp_draw_stroke_fill( - bGPdata *gpd, bGPDstroke *gps, - int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4]) +/* add a new fill point and texture coordinates to vertex buffer */ +static void gp_add_filldata_tobuffer( + const bGPDspoint *pt, const float uv[2], uint pos, uint texcoord, short flag, + int offsx, int offsy, int winx, int winy, const float diff_mat[4][4]) { float fpt[3]; + float co[2]; - BLI_assert(gps->totpoints >= 3); + mul_v3_m4v3(fpt, diff_mat, &pt->x); + /* if 2d, need conversion */ + if (!flag & GP_STROKE_3DSPACE) { + gp_calc_2d_stroke_fxy(fpt, flag, offsx, offsy, winx, winy, co); + copy_v2_v2(fpt, co); + fpt[2] = 0.0f; /* 2d always is z=0.0f */ + } - bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); + immAttrib2f(texcoord, uv[0], uv[1]); /* texture coordinates */ + immVertex3fv(pos, fpt); /* position */ +} - /* Triangulation fill if high quality flag is enabled */ - if (palcolor->flag & PC_COLOR_HQ_FILL) { - /* Calculate triangles cache for filling area (must be done only after changes) */ - if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) { - gp_triangulate_stroke_fill(gps); - } - BLI_assert(gps->tot_triangles >= 1); +#if 0 /* GPXX disabled, not used in annotations */ +/* assign image texture for filling stroke */ +static int gp_set_filling_texture(Image *image, short flag) +{ + ImBuf *ibuf; + uint *bind = &image->bindcode[TEXTARGET_TEXTURE_2D]; + int error = GL_NO_ERROR; + ImageUser iuser = { NULL }; + void *lock; - uint pos; - if (gps->flag & GP_STROKE_3DSPACE) { - pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - } + iuser.ok = true; - immUniformColor4fv(color); + ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - /* Draw all triangles for filling the polygon (cache must be calculated before) */ - immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3); - /* TODO: use batch instead of immediate mode, to share vertices */ + if (ibuf == NULL || ibuf->rect == NULL) { + BKE_image_release_ibuf(image, ibuf, NULL); + return (int)GL_INVALID_OPERATION; + } - bGPDtriangle *stroke_triangle = gps->triangles; - bGPDspoint *pt; + GPU_create_gl_tex(bind, ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, GL_TEXTURE_2D, + false, false, image); - if (gps->flag & GP_STROKE_3DSPACE) { - for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { - for (int j = 0; j < 3; j++) { - pt = &gps->points[stroke_triangle->verts[j]]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); - immVertex3fv(pos, fpt); - } - } - } - else { - for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { - for (int j = 0; j < 3; j++) { - float co[2]; - pt = &gps->points[stroke_triangle->verts[j]]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); - gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co); - immVertex3fv(pos, fpt); - } - } - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (flag & GP_STYLE_COLOR_TEX_CLAMP) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + BKE_image_release_ibuf(image, ibuf, NULL); - immEnd(); - immUnbindProgram(); + return error; +} +#endif + +/* draw fills for shapes */ +static void gp_draw_stroke_fill( + bGPdata *gpd, bGPDstroke *gps, + int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4]) +{ + BLI_assert(gps->totpoints >= 3); + Material *ma = gpd->mat[gps->mat_nr]; + MaterialGPencilStyle *gp_style = ma->gp_style; + + /* Calculate triangles cache for filling area (must be done only after changes) */ + if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) { + gp_triangulate_stroke_fill(gps); + } + BLI_assert(gps->tot_triangles >= 1); + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_GPENCIL_FILL); + + immUniformColor4fv(color); + immUniform4fv("color2", gp_style->mix_rgba); + immUniform1i("fill_type", gp_style->fill_style); + immUniform1f("mix_factor", gp_style->mix_factor); + + immUniform1f("gradient_angle", gp_style->gradient_angle); + immUniform1f("gradient_radius", gp_style->gradient_radius); + immUniform1f("pattern_gridsize", gp_style->pattern_gridsize); + immUniform2fv("gradient_scale", gp_style->gradient_scale); + immUniform2fv("gradient_shift", gp_style->gradient_shift); + + immUniform1f("texture_angle", gp_style->texture_angle); + immUniform2fv("texture_scale", gp_style->texture_scale); + immUniform2fv("texture_offset", gp_style->texture_offset); + immUniform1f("texture_opacity", gp_style->texture_opacity); + immUniform1i("t_mix", gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0); + immUniform1i("t_flip", gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0); +#if 0 /* GPXX disabled, not used in annotations */ + /* image texture */ + if ((gp_style->fill_style == GP_STYLE_FILL_STYLE_TEXTURE) || (gp_style->flag & GP_STYLE_COLOR_TEX_MIX)) { + gp_set_filling_texture(gp_style->ima, gp_style->flag); } +#endif + /* Draw all triangles for filling the polygon (cache must be calculated before) */ + immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3); + /* TODO: use batch instead of immediate mode, to share vertices */ + + const bGPDtriangle *stroke_triangle = gps->triangles; + for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { + for (int j = 0; j < 3; j++) { + gp_add_filldata_tobuffer( + &gps->points[stroke_triangle->verts[j]], stroke_triangle->uv[j], + pos, texcoord, gps->flag, + offsx, offsy, winx, winy, diff_mat); + } + } + + immEnd(); + immUnbindProgram(); } /* ----- Existing Strokes Drawing (3D and Point) ------ */ @@ -601,87 +722,81 @@ static void gp_draw_stroke_point( immUnbindProgram(); } -/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */ -static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug), - short UNUSED(sflag), const float diff_mat[4][4], const float ink[4], bool cyclic) +/* draw a given stroke in 3d (i.e. in 3d-space) */ +static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4], bool cyclic) { + bGPDspoint *points = tgpw->gps->points; + int totpoints = tgpw->gps->totpoints; + + const float viewport[2] = { (float)tgpw->winx, (float)tgpw->winy }; float curpressure = points[0].pressure; float fpt[3]; - float cyclic_fpt[3]; - int draw_points = 0; - - /* if cyclic needs one vertex more */ - int cyclic_add = 0; - if (cyclic) { - ++cyclic_add; - } + /* if cyclic needs more vertex */ + int cyclic_add = (cyclic) ? 1 : 0; GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint thickattrib = GPU_vertformat_attr_add(format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); + immBindBuiltinProgram(GPU_SHADER_GPENCIL_STROKE); + immUniform2fv("Viewport", viewport); + immUniform1f("pixsize", tgpw->rv3d->pixsize); + immUniform1f("pixelsize", U.pixelsize); + float obj_scale = (tgpw->ob->size[0] + tgpw->ob->size[1] + tgpw->ob->size[2]) / 3.0f; - /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ + immUniform1f("objscale", obj_scale); + int keep_size = (int)((tgpw->gpd) && (tgpw->gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS)); + immUniform1i("keep_size", keep_size); + immUniform1i("pixfactor", tgpw->gpd->pixfactor); + immUniform1i("xraymode", tgpw->gpd->xray_mode); /* draw stroke curve */ GPU_line_width(max_ff(curpressure * thickness, 1.0f)); - immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add); + immBeginAtMost(GPU_PRIM_LINE_STRIP_ADJ, totpoints + cyclic_add + 2); const bGPDspoint *pt = points; - for (int i = 0; i < totpoints; i++, pt++) { - gp_set_point_varying_color(pt, ink, color); - /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, - * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) - * Note: we want more visible levels of pressures when thickness is bigger. - */ - if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) { - /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */ - if (draw_points < 2) { - const bGPDspoint *pt2 = pt - 1; - mul_v3_m4v3(fpt, diff_mat, &pt2->x); - immVertex3fv(pos, fpt); + for (int i = 0; i < totpoints; i++, pt++) { + /* first point for adjacency (not drawn) */ + if (i == 0) { + gp_set_point_varying_color(points, ink, color); + immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f)); + if ((cyclic) && (totpoints > 2)) { + mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 1)->x); } - immEnd(); - draw_points = 0; - - curpressure = pt->pressure; - GPU_line_width(max_ff(curpressure * thickness, 1.0f)); - immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add); - - /* need to roll-back one point to ensure that there are no gaps in the stroke */ - if (i != 0) { - const bGPDspoint *pt2 = pt - 1; - mul_v3_m4v3(fpt, diff_mat, &pt2->x); - gp_set_point_varying_color(pt2, ink, color); - immVertex3fv(pos, fpt); - ++draw_points; + else { + mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x); } + mul_v3_fl(fpt, -1.0f); + immVertex3fv(pos, fpt); } - - /* now the point we want */ - mul_v3_m4v3(fpt, diff_mat, &pt->x); + /* set point */ + gp_set_point_varying_color(pt, ink, color); + immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f)); + mul_v3_m4v3(fpt, tgpw->diff_mat, &pt->x); immVertex3fv(pos, fpt); - ++draw_points; - if (cyclic && i == 0) { - /* save first point to use in cyclic */ - copy_v3_v3(cyclic_fpt, fpt); - } + curpressure = pt->pressure; } - if (cyclic) { + if (cyclic && totpoints > 2) { /* draw line to first point to complete the cycle */ - immVertex3fv(pos, cyclic_fpt); - ++draw_points; - } + immAttrib1f(thickattrib, max_ff(points->pressure * thickness, 1.0f)); + mul_v3_m4v3(fpt, tgpw->diff_mat, &points->x); + immVertex3fv(pos, fpt); - /* if less of two points, need to repeat last point to avoid assert in immEnd() */ - if (draw_points < 2) { - const bGPDspoint *pt2 = pt - 1; - mul_v3_m4v3(fpt, diff_mat, &pt2->x); - gp_set_point_varying_color(pt2, ink, color); + /* now add adjacency point (not drawn) */ + immAttrib1f(thickattrib, max_ff((points + 1)->pressure * thickness, 1.0f)); + mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + 1)->x); + immVertex3fv(pos, fpt); + } + /* last adjacency point (not drawn) */ + else { + gp_set_point_varying_color(points + totpoints - 1, ink, color); + immAttrib1f(thickattrib, max_ff(curpressure * thickness, 1.0f)); + mul_v3_m4v3(fpt, tgpw->diff_mat, &(points + totpoints - 2)->x); + mul_v3_fl(fpt, -1.0f); immVertex3fv(pos, fpt); } @@ -692,8 +807,9 @@ static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thi /* ----- Fancy 2D-Stroke Drawing ------ */ /* draw a given stroke in 2d */ -static void gp_draw_stroke_2d(const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, - bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4]) +static void gp_draw_stroke_2d( + const bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, + bool UNUSED(debug), int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float ink[4]) { /* otherwise thickness is twice that of the 3D view */ float thickness = (float)thickness_s * 0.5f; @@ -900,10 +1016,7 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) } /* draw a set of strokes */ -static void gp_draw_strokes( - bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, - bool debug, short lthick, const float opacity, const float tintcolor[4], - const bool onion, const bool custonion, const float diff_mat[4][4]) +static void gp_draw_strokes(tGPDdraw *tgpw) { float tcolor[4]; float tfill[4]; @@ -912,31 +1025,41 @@ static void gp_draw_strokes( GPU_enable_program_point_size(); - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + for (bGPDstroke *gps = tgpw->t_gpf->strokes.first; gps; gps = gps->next) { /* check if stroke can be drawn */ - if (gp_can_draw_stroke(gps, dflag) == false) { + if (gp_can_draw_stroke(gps, tgpw->dflag) == false) { continue; } /* check if the color is visible */ - bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); - if ((palcolor == NULL) || - (palcolor->flag & PC_COLOR_HIDE) || + Material *ma = tgpw->gpd->mat[gps->mat_nr]; + MaterialGPencilStyle *gp_style = ma->gp_style; + + if ((gp_style == NULL) || + (gp_style->flag & GP_STYLE_COLOR_HIDE) || /* if onion and ghost flag do not draw*/ - (onion && (palcolor->flag & PC_COLOR_ONIONSKIN))) + (tgpw->onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) { continue; } + /* if disable fill, the colors with fill must be omitted too except fill boundary strokes */ + if ((tgpw->disable_fill == 1) && + (gp_style->fill_rgba[3] > 0.0f) && + ((gps->flag & GP_STROKE_NOFILL) == 0)) + { + continue; + } + /* calculate thickness */ - sthickness = gps->thickness + lthick; + sthickness = gps->thickness + tgpw->lthick; if (sthickness <= 0) { continue; } /* check which stroke-drawer to use */ - if (dflag & GP_DRAWDATA_ONLY3D) { - const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); + if (tgpw->dflag & GP_DRAWDATA_ONLY3D) { + const int no_xray = (tgpw->dflag & GP_DRAWDATA_NO_XRAY); int mask_orig = 0; if (no_xray) { @@ -951,57 +1074,64 @@ static void gp_draw_strokes( /* 3D Fill */ //if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { - if (gps->totpoints >= 3) { - /* set color using palette, tint color and opacity */ - interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]); - tfill[3] = palcolor->fill[3] * opacity; - if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) { + if ((gps->totpoints >= 3) && (tgpw->disable_fill != 1)) { + /* set color using material, tint color and opacity */ + interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); + tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity; + if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) { const float *color; - if (!onion) { + if (!tgpw->onion) { color = tfill; } else { - if (custonion) { - color = tintcolor; + if (tgpw->custonion) { + color = tgpw->tintcolor; } else { - ARRAY_SET_ITEMS(tfill, UNPACK3(palcolor->fill), tintcolor[3]); + ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]); color = tfill; } } - gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color); + gp_draw_stroke_fill( + tgpw->gpd, gps, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, color); } } /* 3D Stroke */ - /* set color using palette, tint color and opacity */ - if (!onion) { - interp_v3_v3v3(tcolor, palcolor->color, tintcolor, tintcolor[3]); - tcolor[3] = palcolor->color[3] * opacity; + /* set color using material tint color and opacity */ + if (!tgpw->onion) { + interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); + tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity; copy_v4_v4(ink, tcolor); } else { - if (custonion) { - copy_v4_v4(ink, tintcolor); + if (tgpw->custonion) { + copy_v4_v4(ink, tgpw->tintcolor); } else { - ARRAY_SET_ITEMS(tcolor, palcolor->color[0], palcolor->color[1], palcolor->color[2], opacity); + ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity); copy_v4_v4(ink, tcolor); } } - if (palcolor->flag & PC_COLOR_VOLUMETRIC) { + if (gp_style->mode == GP_STYLE_MODE_DOTS) { /* volumetric stroke drawing */ - gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink); + if (tgpw->disable_fill != 1) { + gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink); + } } else { /* 3D Lines - OpenGL primitives-based */ if (gps->totpoints == 1) { - gp_draw_stroke_point(gps->points, sthickness, dflag, gps->flag, offsx, offsy, winx, winy, - diff_mat, ink); + if (tgpw->disable_fill != 1) { + gp_draw_stroke_point(gps->points, sthickness, tgpw->dflag, gps->flag, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, + tgpw->diff_mat, ink); + } } else { - gp_draw_stroke_3d(gps->points, gps->totpoints, sthickness, debug, gps->flag, - diff_mat, ink, gps->flag & GP_STROKE_CYCLIC); + tgpw->gps = gps; + gp_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC); } } if (no_xray) { @@ -1014,58 +1144,63 @@ static void gp_draw_strokes( else { /* 2D - Fill */ if (gps->totpoints >= 3) { - /* set color using palette, tint color and opacity */ - interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]); - tfill[3] = palcolor->fill[3] * opacity; - if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) { + /* set color using material, tint color and opacity */ + interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); + tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity; + if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) { const float *color; - if (!onion) { + if (!tgpw->onion) { color = tfill; } else { - if (custonion) { - color = tintcolor; + if (tgpw->custonion) { + color = tgpw->tintcolor; } else { - ARRAY_SET_ITEMS(tfill, palcolor->fill[0], palcolor->fill[1], palcolor->fill[2], - tintcolor[3]); + ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]); color = tfill; } } - gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color); + gp_draw_stroke_fill( + tgpw->gpd, gps, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, color); } } /* 2D Strokes... */ - /* set color using palette, tint color and opacity */ - if (!onion) { - interp_v3_v3v3(tcolor, palcolor->color, tintcolor, tintcolor[3]); - tcolor[3] = palcolor->color[3] * opacity; + /* set color using material, tint color and opacity */ + if (!tgpw->onion) { + interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); + tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity; copy_v4_v4(ink, tcolor); } else { - if (custonion) { - copy_v4_v4(ink, tintcolor); + if (tgpw->custonion) { + copy_v4_v4(ink, tgpw->tintcolor); } else { - ARRAY_SET_ITEMS(tcolor, palcolor->color[0], palcolor->color[1], palcolor->color[2], opacity); + ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity); copy_v4_v4(ink, tcolor); } } - if (palcolor->flag & PC_COLOR_VOLUMETRIC) { + if (gp_style->mode == GP_STYLE_MODE_DOTS) { /* blob/disk-based "volumetric" drawing */ - gp_draw_stroke_volumetric_2d(gps->points, gps->totpoints, sthickness, dflag, gps->flag, - offsx, offsy, winx, winy, diff_mat, ink); + gp_draw_stroke_volumetric_2d( + gps->points, gps->totpoints, sthickness, tgpw->dflag, gps->flag, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, ink); } else { /* normal 2D strokes */ if (gps->totpoints == 1) { - gp_draw_stroke_point(gps->points, sthickness, dflag, gps->flag, offsx, offsy, winx, winy, - diff_mat, ink); + gp_draw_stroke_point( + gps->points, sthickness, tgpw->dflag, gps->flag, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, + tgpw->diff_mat, ink); } else { - gp_draw_stroke_2d(gps->points, gps->totpoints, sthickness, dflag, gps->flag, debug, - offsx, offsy, winx, winy, diff_mat, ink); + gp_draw_stroke_2d( + gps->points, gps->totpoints, sthickness, tgpw->dflag, gps->flag, false, + tgpw->offsx, tgpw->offsy, tgpw->winx, tgpw->winy, tgpw->diff_mat, ink); } } } @@ -1114,14 +1249,16 @@ static void gp_draw_strokes_edit( if ((gps->flag & GP_STROKE_SELECT) == 0) continue; - /* verify palette color lock */ + /* verify color lock */ { - bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); - if (palcolor != NULL) { - if (palcolor->flag & PC_COLOR_HIDE) { + Material *ma = gpd->mat[gps->mat_nr]; + MaterialGPencilStyle *gp_style = ma->gp_style; + + if (gp_style != NULL) { + if (gp_style->flag & GP_STYLE_COLOR_HIDE) { continue; } - if (((lflag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED)) { + if (((lflag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_STYLE_COLOR_LOCKED)) { continue; } } @@ -1143,8 +1280,9 @@ static void gp_draw_strokes_edit( } /* for now, we assume that the base color of the points is not too close to the real color */ - /* set color using palette */ - bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); + /* set color using material */ + Material *ma = gpd->mat[gps->mat_nr]; + MaterialGPencilStyle *gp_style = ma->gp_style; float selectColor[4]; UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); @@ -1153,7 +1291,7 @@ static void gp_draw_strokes_edit( GPUVertFormat *format = immVertexFormat(); uint pos; /* specified later */ uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); if (gps->flag & GP_STROKE_3DSPACE) { pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -1189,7 +1327,7 @@ static void gp_draw_strokes_edit( immAttrib1f(size, vsize); } else { - immAttrib3fv(color, palcolor->color); + immAttrib3fv(color, gp_style->stroke_rgba); immAttrib1f(size, bsize); } @@ -1229,98 +1367,75 @@ static void gp_draw_strokes_edit( /* ----- General Drawing ------ */ -/* draw onion-skinning for a layer */ -static void gp_draw_onionskins( - bGPdata *gpd, const bGPDlayer *gpl, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, - int UNUSED(cfra), int dflag, bool debug, const float diff_mat[4][4]) + +/* draw interpolate strokes (used only while operator is running) */ +void ED_gp_draw_interpolation(const bContext *C, tGPDinterpolate *tgpi, const int type) { - const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)}; - const float alpha = 1.0f; + tGPDdraw tgpw; + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + tGPDinterpolate_layer *tgpil; + Object *obact = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + float color[4]; - /* 1) Draw Previous Frames First */ - if (gpl->flag & GP_LAYER_GHOST_PREVCOL) { - copy_v3_v3(color, gpl->gcolor_prev); - } - else { - copy_v3_v3(color, default_color); + UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, color); + color[3] = 0.6f; + int dflag = 0; + /* if 3d stuff, enable flags */ + if (type == REGION_DRAW_POST_VIEW) { + dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); } - if (gpl->gstep > 0) { - /* draw previous frames first */ - for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) { - /* check if frame is drawable */ - if ((gpf->framenum - gf->framenum) <= gpl->gstep) { - /* alpha decreases with distance from curframe index */ - float fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1)); - color[3] = alpha * fac * 0.66f; - gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, - true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat); - } - else - break; - } - } - else if (gpl->gstep == 0) { - /* draw the strokes for the ghost frames (at half of the alpha set by user) */ - if (gpf->prev) { - color[3] = (alpha / 7); - gp_draw_strokes(gpd, gpf->prev, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, - true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat); - } - } - else { - /* don't draw - disabled */ - } + tgpw.rv3d = rv3d; + tgpw.depsgraph = depsgraph; + tgpw.ob = obact; + tgpw.gpd = tgpi->gpd; + tgpw.offsx = 0; + tgpw.offsy = 0; + tgpw.winx = tgpi->ar->winx; + tgpw.winy = tgpi->ar->winy; + tgpw.dflag = dflag; - /* 2) Now draw next frames */ - if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) { - copy_v3_v3(color, gpl->gcolor_next); - } - else { - copy_v3_v3(color, default_color); - } + /* turn on alpha-blending */ + glEnable(GL_BLEND); + for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) { + /* calculate parent position */ + ED_gpencil_parent_location(depsgraph, obact, tgpi->gpd, tgpil->gpl, tgpw.diff_mat); + if (tgpil->interFrame) { + tgpw.gpl = tgpil->gpl; + tgpw.gpf = tgpil->interFrame; + tgpw.t_gpf = tgpil->interFrame; - if (gpl->gstep_next > 0) { - /* now draw next frames */ - for (bGPDframe *gf = gpf->next; gf; gf = gf->next) { - /* check if frame is drawable */ - if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) { - /* alpha decreases with distance from curframe index */ - float fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1)); - color[3] = alpha * fac * 0.66f; - gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, - true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat); - } - else - break; - } - } - else if (gpl->gstep_next == 0) { - /* draw the strokes for the ghost frames (at half of the alpha set by user) */ - if (gpf->next) { - color[3] = (alpha / 4); - gp_draw_strokes(gpd, gpf->next, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, - true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat); + tgpw.lthick = tgpil->gpl->line_change; + tgpw.opacity = 1.0; + copy_v4_v4(tgpw.tintcolor, color); + tgpw.onion = true; + tgpw.custonion = true; + + gp_draw_strokes(&tgpw); } } - else { - /* don't draw - disabled */ - } + glDisable(GL_BLEND); } /* draw interpolate strokes (used only while operator is running) */ -void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type) +void ED_gp_draw_primitives(const bContext *C, tGPDprimitive *tgpi, const int type) { - tGPDinterpolate_layer *tgpil; - float diff_mat[4][4]; - float color[4]; + tGPDdraw tgpw; + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + + /* if idle, do not draw */ + if (tgpi->flag == 0) { + return; + } - int offsx = 0; - int offsy = 0; - int winx = tgpi->ar->winx; - int winy = tgpi->ar->winy; + Object *obact = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + float color[4]; UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, color); color[3] = 0.6f; int dflag = 0; @@ -1329,32 +1444,71 @@ void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type) dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); } + tgpw.rv3d = rv3d; + tgpw.depsgraph = depsgraph; + tgpw.ob = obact; + tgpw.gpd = tgpi->gpd; + tgpw.offsx = 0; + tgpw.offsy = 0; + tgpw.winx = tgpi->ar->winx; + tgpw.winy = tgpi->ar->winy; + tgpw.dflag = dflag; + /* turn on alpha-blending */ GPU_blend(true); - for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) { - /* calculate parent position */ - ED_gpencil_parent_location(tgpil->gpl, diff_mat); - if (tgpil->interFrame) { - gp_draw_strokes(tgpi->gpd, tgpil->interFrame, offsx, offsy, winx, winy, dflag, false, - tgpil->gpl->thickness, 1.0f, color, true, true, diff_mat); + /* calculate parent position */ + ED_gpencil_parent_location(depsgraph, obact, tgpi->gpd, tgpi->gpl, tgpw.diff_mat); + if (tgpi->gpf) { + tgpw.gps = tgpi->gpf->strokes.first; + if (tgpw.gps->totpoints > 0) { + tgpw.gpl = tgpi->gpl; + tgpw.gpf = tgpi->gpf; + tgpw.t_gpf = tgpi->gpf; + + tgpw.lthick = tgpi->gpl->line_change; + tgpw.opacity = 1.0; + copy_v4_v4(tgpw.tintcolor, color); + tgpw.onion = true; + tgpw.custonion = true; + + gp_draw_strokes(&tgpw); } } GPU_blend(false); } +/* wrapper to draw strokes for filling operator */ +void ED_gp_draw_fill(tGPDdraw *tgpw) +{ + gp_draw_strokes(tgpw); +} + /* loop over gpencil data layers, drawing them */ -static void gp_draw_data_layers( - const bGPDbrush *brush, float alpha, bGPdata *gpd, +static void gp_draw_data_layers(RegionView3D *rv3d, + const Brush *brush, float alpha, Object *ob, bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) { float diff_mat[4][4]; + tGPDdraw tgpw; + + tgpw.rv3d = rv3d; + tgpw.depsgraph = NULL; /* XXX: This is not used here */ + tgpw.ob = ob; + tgpw.gpd = gpd; + tgpw.gpl = NULL; + tgpw.gpf = NULL; + tgpw.t_gpf = NULL; + tgpw.offsx = offsx; + tgpw.offsy = offsy; + tgpw.winx = winx; + tgpw.winy = winy; + tgpw.dflag = dflag; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* calculate parent position */ - ED_gpencil_parent_location(gpl, diff_mat); + ED_gpencil_parent_location(tgpw.depsgraph, ob, gpd, gpl, diff_mat); - bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG); - short lthick = brush->thickness + gpl->thickness; + short lthick = brush->size + gpl->line_change; /* don't draw layer if hidden */ if (gpl->flag & GP_LAYER_HIDE) @@ -1383,30 +1537,20 @@ static void gp_draw_data_layers( /* volumetric strokes... */ GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_VOLUMETRIC), GP_DRAWDATA_VOLUMETRIC); - /* HQ fills... */ - GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_HQ_FILL), GP_DRAWDATA_HQ_FILL); - #undef GP_DRAWFLAG_APPLY - /* Draw 'onionskins' (frame left + right) - * - It is only possible to show these if the option is enabled - * - The "no onions" flag prevents ghosts from appearing during animation playback/scrubbing - * and in renders - * - The per-layer "always show" flag however overrides the playback/render restriction, - * allowing artists to selectively turn onionskins on/off during playback - */ - if ((gpl->flag & GP_LAYER_ONIONSKIN) && - ((dflag & GP_DRAWDATA_NO_ONIONS) == 0 || (gpl->flag & GP_LAYER_GHOST_ALWAYS))) - { - /* Drawing method - only immediately surrounding (gstep = 0), - * or within a frame range on either side (gstep > 0) - */ - gp_draw_onionskins(gpd, gpl, gpf, offsx, offsy, winx, winy, cfra, dflag, debug, diff_mat); - } + tgpw.gpl = gpl; + tgpw.gpf = gpf; + tgpw.t_gpf = gpf; // XXX? + tgpw.lthick = gpl->line_change; + tgpw.opacity = gpl->opacity; + copy_v4_v4(tgpw.tintcolor, gpl->tintcolor); + tgpw.onion = false; + tgpw.custonion = false; + copy_m4_m4(tgpw.diff_mat, diff_mat); /* draw the strokes already in active frame */ - gp_draw_strokes(gpd, gpf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, - gpl->opacity, gpl->tintcolor, false, false, diff_mat); + gp_draw_strokes(&tgpw); /* Draw verts of selected strokes * - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering @@ -1435,19 +1579,25 @@ static void gp_draw_data_layers( * It should also be noted that sbuffer contains temporary point types * i.e. tGPspoints NOT bGPDspoints */ - if (gpd->sflag & PC_COLOR_VOLUMETRIC) { - gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, - dflag, gpd->scolor); + if (gpd->runtime.mode == GP_STYLE_MODE_DOTS) { + gp_draw_stroke_volumetric_buffer( + gpd->runtime.sbuffer, + gpd->runtime.sbuffer_size, lthick, + dflag, gpd->runtime.scolor); } else { - gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor, gpd->sfill); + gp_draw_stroke_buffer( + gpd->runtime.sbuffer, + gpd->runtime.sbuffer_size, lthick, + dflag, gpd->runtime.sbuffer_sflag, + gpd->runtime.scolor, gpd->runtime.sfill); } } } } /* draw a short status message in the top-right corner */ -static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar) +static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar) { rcti rect; @@ -1493,8 +1643,8 @@ static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar) } /* draw grease-pencil datablock */ -static void gp_draw_data( - const bGPDbrush *brush, float alpha, bGPdata *gpd, +static void gp_draw_data(RegionView3D *rv3d, + const Brush *brush, float alpha, Object *ob, bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) { /* turn on smooth lines (i.e. anti-aliasing) */ @@ -1510,7 +1660,7 @@ static void gp_draw_data( GPU_blend(true); /* draw! */ - gp_draw_data_layers(brush, alpha, gpd, offsx, offsy, winx, winy, cfra, dflag); + gp_draw_data_layers(rv3d, brush, alpha, ob, gpd, offsx, offsy, winx, winy, cfra, dflag); /* turn off alpha blending, then smooth lines */ GPU_blend(false); // alpha blending @@ -1519,33 +1669,22 @@ static void gp_draw_data( /* if we have strokes for scenes (3d view)/clips (movie clip editor) * and objects/tracks, multiple data blocks have to be drawn */ -static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy, - int cfra, int dflag, const char spacetype) +static void gp_draw_data_all( + RegionView3D *rv3d, Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy, + int cfra, int dflag, const char UNUSED(spacetype)) { bGPdata *gpd_source = NULL; - ToolSettings *ts; - bGPDbrush *brush = NULL; + ToolSettings *ts = NULL; + Brush *brush = NULL; if (scene) { ts = scene->toolsettings; - brush = BKE_gpencil_brush_getactive(ts); - /* if no brushes, create default set */ - if (brush == NULL) { - BKE_gpencil_brush_init_presets(ts); - brush = BKE_gpencil_brush_getactive(ts); - } - - if (spacetype == SPACE_VIEW3D) { - gpd_source = (scene->gpd ? scene->gpd : NULL); - } - else if (spacetype == SPACE_CLIP && scene->clip) { - /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */ - gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL); - } + brush = BKE_brush_getactive_gpencil(ts); if (gpd_source) { if (brush != NULL) { - gp_draw_data(brush, ts->gp_sculpt.alpha, gpd_source, - offsx, offsy, winx, winy, cfra, dflag); + gp_draw_data( + rv3d, brush, 1.0f, NULL, gpd_source, + offsx, offsy, winx, winy, cfra, dflag); } } } @@ -1554,76 +1693,70 @@ static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, i * if gpd_source == gpd, we don't have any object/track data and we can skip */ if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) { if (brush != NULL) { - gp_draw_data(brush, ts->gp_sculpt.alpha, gpd, - offsx, offsy, winx, winy, cfra, dflag); + gp_draw_data( + rv3d, brush, 1.0f, NULL, gpd, + offsx, offsy, winx, winy, cfra, dflag); } } } /* ----- Grease Pencil Sketches Drawing API ------ */ -/* ............................ - * XXX - * We need to review the calls below, since they may be/are not that suitable for - * the new ways that we intend to be drawing data... - * ............................ */ -/* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ -void ED_gpencil_draw_2dimage(const bContext *C) +/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly + * Note: this gets called twice - first time with only3d=true to draw 3d-strokes, + * second time with only3d=false for screen-aligned strokes */ +void ED_gpencil_draw_view3d( + wmWindowManager *wm, + Scene *scene, + ViewLayer *view_layer, + struct Depsgraph *depsgraph, + View3D *v3d, + ARegion *ar, + bool only3d) { - wmWindowManager *wm = CTX_wm_manager(C); - ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - - int offsx, offsy, sizex, sizey; - int dflag = GP_DRAWDATA_NOSTATUS; + int dflag = 0; + RegionView3D *rv3d = ar->regiondata; + int offsx, offsy, winx, winy; - bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX + /* check that we have grease-pencil stuff to draw */ + // XXX: This is the only place that still uses this function + bGPdata *gpd = ED_gpencil_data_get_active_v3d(view_layer); if (gpd == NULL) return; - /* calculate rect */ - switch (sa->spacetype) { - case SPACE_IMAGE: /* image */ - case SPACE_CLIP: /* clip */ - { - /* just draw using standard scaling (settings here are currently ignored anyways) */ - /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ - offsx = 0; - offsy = 0; - sizex = ar->winx; - sizey = ar->winy; + /* when rendering to the offscreen buffer we don't want to + * deal with the camera border, otherwise map the coords to the camera border. */ + if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) { + rctf rectf; + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */ - wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax); + offsx = round_fl_to_int(rectf.xmin); + offsy = round_fl_to_int(rectf.ymin); + winx = round_fl_to_int(rectf.xmax - rectf.xmin); + winy = round_fl_to_int(rectf.ymax - rectf.ymin); + } + else { + offsx = 0; + offsy = 0; + winx = ar->winx; + winy = ar->winy; + } - dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK; - break; - } - case SPACE_SEQ: /* sequence */ - { - /* just draw using standard scaling (settings here are currently ignored anyways) */ - offsx = 0; - offsy = 0; - sizex = ar->winx; - sizey = ar->winy; - - /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated - * and everything moved to standard View2d - */ - dflag |= GP_DRAWDATA_ONLYV2D; - break; - } - default: /* for spacetype not yet handled */ - offsx = 0; - offsy = 0; - sizex = ar->winx; - sizey = ar->winy; - - dflag |= GP_DRAWDATA_ONLYI2D; - break; + /* set flags */ + if (only3d) { + /* 3D strokes/3D space: + * - only 3D space points + * - don't status text either (as it's the wrong space) + */ + dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); } - if (ED_screen_animation_playing(wm)) { + if (v3d->flag2 & V3D_RENDER_OVERRIDE) { + /* don't draw status text when "only render" flag is set */ + dflag |= GP_DRAWDATA_NOSTATUS; + } + + if ((wm == NULL) || ED_screen_animation_playing(wm)) { /* don't show onionskins during animation playback/scrub (i.e. it obscures the poses) * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes) */ @@ -1631,85 +1764,46 @@ void ED_gpencil_draw_2dimage(const bContext *C) } /* draw it! */ - gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype); + gp_draw_data_all(rv3d, scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype); } -/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes, - * second time with onlyv2d=false for screen-aligned strokes */ -void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d) -{ - wmWindowManager *wm = CTX_wm_manager(C); - ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - int dflag = 0; - - /* check that we have grease-pencil stuff to draw */ - if (sa == NULL) return; - bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX - if (gpd == NULL) return; - - /* special hack for Image Editor */ - /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ - if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP)) - dflag |= GP_DRAWDATA_IEDITHACK; - - /* draw it! */ - if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS); - if (ED_screen_animation_playing(wm)) dflag |= GP_DRAWDATA_NO_ONIONS; - - gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype); - - /* draw status text (if in screen/pixel-space) */ - if (!onlyv2d) { - gp_draw_status_text(gpd, ar); - } -} - -/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with only3d=true to draw 3d-strokes, - * second time with only3d=false for screen-aligned strokes */ -void ED_gpencil_draw_view3d(wmWindowManager *wm, - Scene *scene, - ViewLayer *view_layer, - struct Depsgraph *depsgraph, - View3D *v3d, - ARegion *ar, - bool only3d) +/* draw grease-pencil sketches to specified 3d-view for gp object + * assuming that matrices are already set correctly + */ +void ED_gpencil_draw_view3d_object(wmWindowManager *wm, Scene *scene, Depsgraph *depsgraph, Object *ob, View3D *v3d, ARegion *ar, bool only3d) { int dflag = 0; RegionView3D *rv3d = ar->regiondata; - int offsx, offsy, winx, winy; + int offsx, offsy, winx, winy; /* check that we have grease-pencil stuff to draw */ - bGPdata *gpd = ED_gpencil_data_get_active_v3d(scene, view_layer); + bGPdata *gpd = ob->data; if (gpd == NULL) return; /* when rendering to the offscreen buffer we don't want to - * deal with the camera border, otherwise map the coords to the camera border. */ + * deal with the camera border, otherwise map the coords to the camera border. */ if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) { rctf rectf; ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */ offsx = round_fl_to_int(rectf.xmin); offsy = round_fl_to_int(rectf.ymin); - winx = round_fl_to_int(rectf.xmax - rectf.xmin); - winy = round_fl_to_int(rectf.ymax - rectf.ymin); + winx = round_fl_to_int(rectf.xmax - rectf.xmin); + winy = round_fl_to_int(rectf.ymax - rectf.ymin); } else { offsx = 0; offsy = 0; - winx = ar->winx; - winy = ar->winy; + winx = ar->winx; + winy = ar->winy; } /* set flags */ if (only3d) { /* 3D strokes/3D space: - * - only 3D space points - * - don't status text either (as it's the wrong space) - */ + * - only 3D space points + * - don't status text either (as it's the wrong space) + */ dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS); } @@ -1720,20 +1814,23 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm, if ((wm == NULL) || ED_screen_animation_playing(wm)) { /* don't show onionskins during animation playback/scrub (i.e. it obscures the poses) - * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes) - */ + * OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes) + */ dflag |= GP_DRAWDATA_NO_ONIONS; } /* draw it! */ - gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype); + ToolSettings *ts = scene->toolsettings; + Brush *brush = BKE_brush_getactive_gpencil(ts); + if (brush != NULL) { + gp_draw_data(rv3d, brush, 1.0f, ob, gpd, + offsx, offsy, winx, winy, CFRA, dflag); + } } -void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype) +void ED_gpencil_draw_ex(RegionView3D *rv3d, Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype) { int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D; - gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype); + gp_draw_data_all(rv3d, scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype); } - -/* ************************************************** */ diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 5e62a87caf3..88f935eb8bf 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -492,6 +492,8 @@ bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode) /* make a copy of stroke, then of its points array */ gpsn = MEM_dupallocN(gps); gpsn->points = MEM_dupallocN(gps->points); + gpsn->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, gpsn); /* duplicate triangle information */ gpsn->triangles = MEM_dupallocN(gps->triangles); /* append stroke to frame */ diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c new file mode 100644 index 00000000000..8a7128adde1 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_add_monkey.c @@ -0,0 +1,1567 @@ +/* + * ***** 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) 2017 Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez, Matias Mendiola + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/gpencil_add_monkey.c + * \ingroup edgpencil + */ + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" + +/* Definition of the most important info from a color */ +typedef struct ColorTemplate { + const char *name; + float line[4]; + float fill[4]; +} ColorTemplate; + +/* Add color an ensure duplications (matched by name) */ +static int gpencil_monkey_color(Main *bmain, Object *ob, const ColorTemplate *pct) +{ + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + if (STREQ(ma->id.name, pct->name)) { + return i; + } + } + + /* create a new one */ + BKE_object_material_slot_add(bmain, ob); + ma = BKE_material_add_gpencil(bmain, pct->name); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + + copy_v4_v4(ma->gp_style->stroke_rgba, pct->line); + copy_v4_v4(ma->gp_style->fill_rgba, pct->fill); + + return BKE_object_material_slot_find_index(ob, ma) - 1; +} + +/* ***************************************************************** */ +/* Monkey Geometry */ + +static const float data0[538 * GP_PRIM_DATABUF_SIZE] = { + -0.509f, 0.0f, -0.156f, 0.267f, 0.362f, -0.522f, 0.0f, -0.159f, 0.31f, 0.407f, -0.531f, 0.0f, -0.16f, 0.347f, 0.426f, -0.543f, -0.0f, -0.162f, 0.38f, 0.439f, + -0.554f, -0.0f, -0.163f, 0.409f, 0.448f, -0.566f, -0.0f, -0.165f, 0.433f, 0.458f, -0.578f, -0.0f, -0.167f, 0.454f, 0.478f, -0.591f, -0.0f, -0.168f, 0.471f, 0.5f, + -0.604f, -0.0f, -0.169f, 0.485f, 0.51f, -0.619f, -0.0f, -0.171f, 0.496f, 0.516f, -0.634f, -0.0f, -0.171f, 0.504f, 0.519f, -0.649f, -0.0f, -0.171f, 0.511f, 0.519f, + -0.665f, -0.0f, -0.17f, 0.516f, 0.521f, -0.681f, -0.0f, -0.17f, 0.521f, 0.53f, -0.697f, -0.0f, -0.169f, 0.524f, 0.533f, -0.713f, -0.0f, -0.167f, 0.527f, 0.533f, + -0.729f, 0.0f, -0.165f, 0.53f, 0.534f, -0.745f, 0.0f, -0.161f, 0.531f, 0.534f, -0.761f, 0.0f, -0.157f, 0.533f, 0.535f, -0.777f, 0.0f, -0.153f, 0.534f, 0.535f, + -0.792f, 0.0f, -0.148f, 0.535f, 0.536f, -0.808f, 0.0f, -0.144f, 0.535f, 0.535f, -0.822f, 0.0f, -0.139f, 0.536f, 0.537f, -0.837f, 0.0f, -0.133f, 0.536f, 0.537f, + -0.852f, 0.0f, -0.128f, 0.536f, 0.537f, -0.866f, 0.0f, -0.122f, 0.536f, 0.537f, -0.88f, 0.0f, -0.115f, 0.536f, 0.537f, -0.894f, 0.0f, -0.109f, 0.536f, 0.537f, + -0.908f, 0.0f, -0.101f, 0.535f, 0.535f, -0.922f, 0.0f, -0.092f, 0.535f, 0.535f, -0.936f, 0.0f, -0.082f, 0.534f, 0.534f, -0.949f, 0.0f, -0.072f, 0.534f, 0.534f, + -0.963f, 0.0f, -0.061f, 0.534f, 0.534f, -0.976f, 0.0f, -0.05f, 0.534f, 0.534f, -0.988f, 0.0f, -0.039f, 0.534f, 0.534f, -1.0f, 0.0f, -0.028f, 0.533f, 0.534f, + -1.011f, 0.0f, -0.017f, 0.533f, 0.533f, -1.022f, 0.0f, -0.007f, 0.533f, 0.534f, -1.033f, 0.0f, 0.004f, 0.533f, 0.533f, -1.043f, 0.0f, 0.014f, 0.532f, 0.532f, + -1.053f, 0.0f, 0.025f, 0.532f, 0.532f, -1.062f, 0.0f, 0.036f, 0.531f, 0.531f, -1.071f, 0.0f, 0.046f, 0.531f, 0.531f, -1.078f, 0.0f, 0.057f, 0.531f, 0.531f, + -1.085f, 0.0f, 0.068f, 0.531f, 0.531f, -1.092f, 0.0f, 0.08f, 0.532f, 0.532f, -1.098f, 0.0f, 0.091f, 0.533f, 0.533f, -1.104f, 0.0f, 0.105f, 0.535f, 0.535f, + -1.11f, 0.0f, 0.119f, 0.539f, 0.539f, -1.115f, 0.0f, 0.133f, 0.54f, 0.54f, -1.118f, 0.0f, 0.148f, 0.541f, 0.541f, -1.121f, 0.0f, 0.162f, 0.542f, 0.542f, + -1.123f, 0.0f, 0.177f, 0.542f, 0.542f, -1.125f, 0.0f, 0.193f, 0.543f, 0.543f, -1.125f, 0.0f, 0.208f, 0.543f, 0.543f, -1.125f, 0.0f, 0.225f, 0.543f, 0.543f, + -1.124f, 0.0f, 0.241f, 0.545f, 0.545f, -1.122f, 0.0f, 0.258f, 0.546f, 0.546f, -1.119f, 0.0f, 0.274f, 0.548f, 0.548f, -1.116f, 0.0f, 0.29f, 0.549f, 0.549f, + -1.111f, 0.0f, 0.305f, 0.549f, 0.549f, -1.106f, 0.0f, 0.318f, 0.549f, 0.549f, -1.1f, 0.0f, 0.33f, 0.549f, 0.549f, -1.094f, 0.0f, 0.34f, 0.549f, 0.549f, + -1.087f, 0.0f, 0.349f, 0.55f, 0.55f, -1.08f, 0.0f, 0.357f, 0.549f, 0.549f, -1.072f, 0.0f, 0.365f, 0.55f, 0.55f, -1.063f, 0.0f, 0.372f, 0.551f, 0.551f, + -1.054f, 0.0f, 0.379f, 0.552f, 0.552f, -1.044f, 0.0f, 0.385f, 0.553f, 0.553f, -1.034f, 0.0f, 0.391f, 0.553f, 0.553f, -1.024f, 0.0f, 0.396f, 0.554f, 0.554f, + -1.013f, 0.0f, 0.401f, 0.554f, 0.554f, -1.003f, 0.0f, 0.405f, 0.554f, 0.554f, -0.991f, 0.0f, 0.409f, 0.554f, 0.554f, -0.978f, 0.0f, 0.412f, 0.555f, 0.555f, + -0.964f, -0.0f, 0.414f, 0.555f, 0.555f, -0.949f, -0.0f, 0.414f, 0.556f, 0.556f, -0.934f, -0.0f, 0.413f, 0.556f, 0.556f, -0.919f, -0.0f, 0.412f, 0.557f, 0.557f, + -0.905f, -0.0f, 0.41f, 0.557f, 0.557f, -0.892f, -0.0f, 0.406f, 0.557f, 0.557f, -0.879f, -0.0f, 0.402f, 0.557f, 0.558f, -0.867f, -0.0f, 0.398f, 0.557f, 0.557f, + -0.855f, -0.0f, 0.394f, 0.557f, 0.557f, -0.843f, -0.0f, 0.388f, 0.557f, 0.557f, -0.831f, -0.0f, 0.381f, 0.558f, 0.557f, -0.82f, -0.0f, 0.375f, 0.558f, 0.557f, + -0.81f, -0.0f, 0.368f, 0.558f, 0.558f, -0.801f, -0.0f, 0.362f, 0.558f, 0.558f, -0.793f, -0.0f, 0.357f, 0.557f, 0.559f, -0.784f, 0.0f, 0.353f, 0.557f, 0.559f, + -0.776f, 0.0f, 0.35f, 0.556f, 0.559f, -0.768f, 0.0f, 0.348f, 0.556f, 0.559f, -0.76f, 0.0f, 0.346f, 0.555f, 0.559f, -0.752f, 0.0f, 0.346f, 0.554f, 0.559f, + -0.744f, 0.0f, 0.347f, 0.553f, 0.554f, -0.737f, 0.0f, 0.348f, 0.552f, 0.548f, -0.729f, 0.0f, 0.351f, 0.551f, 0.544f, -0.723f, 0.0f, 0.355f, 0.551f, 0.546f, + -0.716f, 0.0f, 0.36f, 0.55f, 0.546f, -0.709f, 0.0f, 0.366f, 0.55f, 0.547f, -0.702f, 0.0f, 0.372f, 0.549f, 0.547f, -0.696f, 0.0f, 0.379f, 0.549f, 0.547f, + -0.689f, 0.0f, 0.386f, 0.549f, 0.548f, -0.683f, 0.0f, 0.394f, 0.549f, 0.548f, -0.676f, 0.0f, 0.403f, 0.549f, 0.549f, -0.67f, 0.0f, 0.413f, 0.549f, 0.548f, + -0.664f, 0.0f, 0.422f, 0.549f, 0.549f, -0.658f, 0.0f, 0.432f, 0.55f, 0.549f, -0.652f, 0.0f, 0.441f, 0.551f, 0.548f, -0.646f, 0.0f, 0.451f, 0.552f, 0.548f, + -0.639f, 0.0f, 0.46f, 0.554f, 0.548f, -0.632f, 0.0f, 0.469f, 0.556f, 0.549f, -0.624f, 0.0f, 0.478f, 0.559f, 0.549f, -0.616f, 0.0f, 0.487f, 0.563f, 0.549f, + -0.609f, 0.0f, 0.497f, 0.567f, 0.549f, -0.6f, 0.0f, 0.507f, 0.572f, 0.558f, -0.592f, 0.0f, 0.518f, 0.577f, 0.574f, -0.584f, 0.0f, 0.528f, 0.582f, 0.587f, + -0.575f, 0.0f, 0.538f, 0.586f, 0.592f, -0.566f, 0.0f, 0.548f, 0.591f, 0.595f, -0.556f, 0.0f, 0.557f, 0.594f, 0.597f, -0.546f, 0.0f, 0.567f, 0.597f, 0.598f, + -0.536f, 0.0f, 0.577f, 0.6f, 0.6f, -0.525f, 0.0f, 0.586f, 0.602f, 0.603f, -0.514f, 0.0f, 0.596f, 0.604f, 0.605f, -0.503f, 0.0f, 0.606f, 0.605f, 0.606f, + -0.492f, 0.0f, 0.615f, 0.606f, 0.607f, -0.482f, 0.0f, 0.624f, 0.607f, 0.607f, -0.471f, 0.0f, 0.632f, 0.608f, 0.607f, -0.462f, 0.0f, 0.64f, 0.609f, 0.607f, + -0.453f, 0.0f, 0.647f, 0.61f, 0.61f, -0.444f, 0.0f, 0.654f, 0.612f, 0.611f, -0.435f, 0.0f, 0.66f, 0.614f, 0.613f, -0.427f, 0.0f, 0.666f, 0.616f, 0.615f, + -0.418f, 0.0f, 0.672f, 0.617f, 0.618f, -0.409f, 0.0f, 0.677f, 0.619f, 0.621f, -0.399f, 0.0f, 0.683f, 0.621f, 0.622f, -0.389f, 0.0f, 0.69f, 0.623f, 0.623f, + -0.379f, 0.0f, 0.696f, 0.624f, 0.624f, -0.368f, 0.0f, 0.702f, 0.626f, 0.626f, -0.356f, 0.0f, 0.708f, 0.628f, 0.628f, -0.345f, 0.0f, 0.713f, 0.63f, 0.63f, + -0.333f, 0.0f, 0.719f, 0.633f, 0.631f, -0.32f, 0.0f, 0.724f, 0.637f, 0.632f, -0.307f, 0.0f, 0.729f, 0.641f, 0.64f, -0.294f, 0.0f, 0.732f, 0.646f, 0.644f, + -0.281f, 0.0f, 0.736f, 0.65f, 0.655f, -0.268f, 0.0f, 0.739f, 0.654f, 0.657f, -0.255f, 0.0f, 0.742f, 0.657f, 0.658f, -0.243f, 0.0f, 0.745f, 0.659f, 0.661f, + -0.23f, 0.0f, 0.747f, 0.662f, 0.663f, -0.217f, 0.0f, 0.75f, 0.664f, 0.664f, -0.203f, 0.0f, 0.753f, 0.666f, 0.666f, -0.19f, 0.0f, 0.755f, 0.667f, 0.668f, + -0.177f, 0.0f, 0.757f, 0.669f, 0.67f, -0.163f, 0.0f, 0.76f, 0.671f, 0.671f, -0.15f, 0.0f, 0.762f, 0.673f, 0.672f, -0.136f, 0.0f, 0.764f, 0.674f, 0.674f, + -0.122f, 0.0f, 0.767f, 0.676f, 0.676f, -0.108f, 0.0f, 0.769f, 0.677f, 0.678f, -0.093f, 0.0f, 0.771f, 0.678f, 0.68f, -0.079f, 0.0f, 0.773f, 0.678f, 0.68f, + -0.064f, 0.0f, 0.774f, 0.679f, 0.679f, -0.049f, 0.0f, 0.775f, 0.68f, 0.68f, -0.033f, 0.0f, 0.775f, 0.68f, 0.68f, -0.018f, 0.0f, 0.776f, 0.68f, 0.68f, + -0.002f, 0.0f, 0.776f, 0.681f, 0.68f, 0.013f, 0.0f, 0.777f, 0.681f, 0.681f, 0.029f, 0.0f, 0.777f, 0.682f, 0.681f, 0.045f, 0.0f, 0.777f, 0.682f, 0.681f, + 0.061f, 0.0f, 0.777f, 0.683f, 0.683f, 0.077f, 0.0f, 0.776f, 0.683f, 0.683f, 0.094f, 0.0f, 0.775f, 0.684f, 0.684f, 0.11f, 0.0f, 0.774f, 0.685f, 0.683f, + 0.126f, 0.0f, 0.773f, 0.685f, 0.685f, 0.142f, 0.0f, 0.771f, 0.687f, 0.685f, 0.158f, 0.0f, 0.769f, 0.688f, 0.685f, 0.174f, 0.0f, 0.767f, 0.69f, 0.686f, + 0.19f, 0.0f, 0.765f, 0.691f, 0.692f, 0.206f, 0.0f, 0.762f, 0.693f, 0.694f, 0.222f, 0.0f, 0.757f, 0.695f, 0.696f, 0.238f, 0.0f, 0.752f, 0.697f, 0.697f, + 0.254f, 0.0f, 0.747f, 0.699f, 0.698f, 0.27f, 0.0f, 0.742f, 0.7f, 0.7f, 0.286f, 0.0f, 0.736f, 0.702f, 0.702f, 0.302f, 0.0f, 0.73f, 0.704f, 0.704f, + 0.318f, 0.0f, 0.724f, 0.705f, 0.71f, 0.335f, 0.0f, 0.717f, 0.707f, 0.71f, 0.351f, 0.0f, 0.709f, 0.708f, 0.71f, 0.367f, 0.0f, 0.701f, 0.709f, 0.711f, + 0.382f, 0.0f, 0.692f, 0.71f, 0.713f, 0.397f, 0.0f, 0.683f, 0.711f, 0.713f, 0.41f, 0.0f, 0.675f, 0.712f, 0.713f, 0.422f, 0.0f, 0.666f, 0.712f, 0.714f, + 0.434f, 0.0f, 0.658f, 0.713f, 0.714f, 0.446f, 0.0f, 0.649f, 0.714f, 0.714f, 0.458f, 0.0f, 0.641f, 0.714f, 0.714f, 0.47f, 0.0f, 0.632f, 0.715f, 0.715f, + 0.483f, 0.0f, 0.622f, 0.715f, 0.716f, 0.496f, 0.0f, 0.611f, 0.715f, 0.716f, 0.51f, 0.0f, 0.6f, 0.716f, 0.717f, 0.523f, 0.0f, 0.588f, 0.716f, 0.716f, + 0.536f, 0.0f, 0.576f, 0.717f, 0.717f, 0.55f, 0.0f, 0.563f, 0.717f, 0.717f, 0.564f, 0.0f, 0.549f, 0.717f, 0.717f, 0.577f, 0.0f, 0.536f, 0.718f, 0.717f, + 0.59f, 0.0f, 0.522f, 0.718f, 0.717f, 0.603f, 0.0f, 0.508f, 0.718f, 0.718f, 0.615f, 0.0f, 0.496f, 0.718f, 0.718f, 0.625f, 0.0f, 0.484f, 0.718f, 0.718f, + 0.635f, 0.0f, 0.473f, 0.719f, 0.718f, 0.645f, 0.0f, 0.461f, 0.719f, 0.718f, 0.654f, 0.0f, 0.45f, 0.719f, 0.718f, 0.662f, 0.0f, 0.44f, 0.719f, 0.719f, + 0.67f, 0.0f, 0.431f, 0.719f, 0.719f, 0.676f, 0.0f, 0.422f, 0.719f, 0.719f, 0.682f, 0.0f, 0.414f, 0.719f, 0.719f, 0.687f, 0.0f, 0.407f, 0.719f, 0.719f, + 0.692f, 0.0f, 0.4f, 0.719f, 0.719f, 0.697f, 0.0f, 0.394f, 0.719f, 0.719f, 0.701f, 0.0f, 0.388f, 0.718f, 0.718f, 0.705f, 0.0f, 0.383f, 0.718f, 0.717f, + 0.708f, 0.0f, 0.378f, 0.718f, 0.717f, 0.711f, 0.0f, 0.374f, 0.717f, 0.717f, 0.714f, 0.0f, 0.37f, 0.717f, 0.717f, 0.717f, 0.0f, 0.366f, 0.717f, 0.717f, + 0.719f, 0.0f, 0.362f, 0.718f, 0.717f, 0.722f, 0.0f, 0.359f, 0.718f, 0.718f, 0.724f, 0.0f, 0.356f, 0.718f, 0.717f, 0.727f, 0.0f, 0.352f, 0.717f, 0.719f, + 0.73f, 0.0f, 0.349f, 0.717f, 0.719f, 0.734f, 0.0f, 0.347f, 0.715f, 0.719f, 0.737f, 0.0f, 0.344f, 0.714f, 0.714f, 0.742f, 0.0f, 0.341f, 0.713f, 0.709f, + 0.746f, 0.0f, 0.339f, 0.714f, 0.707f, 0.751f, 0.0f, 0.336f, 0.718f, 0.704f, 0.757f, 0.0f, 0.334f, 0.724f, 0.705f, 0.763f, 0.0f, 0.332f, 0.732f, 0.705f, + 0.769f, -0.0f, 0.329f, 0.742f, 0.704f, 0.775f, -0.0f, 0.328f, 0.753f, 0.713f, 0.782f, -0.0f, 0.327f, 0.764f, 0.804f, 0.789f, -0.0f, 0.327f, 0.774f, 0.813f, + 0.797f, -0.0f, 0.327f, 0.783f, 0.815f, 0.805f, -0.0f, 0.328f, 0.791f, 0.815f, 0.814f, -0.0f, 0.329f, 0.797f, 0.816f, 0.823f, -0.0f, 0.331f, 0.802f, 0.815f, + 0.832f, 0.0f, 0.335f, 0.806f, 0.816f, 0.841f, 0.0f, 0.341f, 0.809f, 0.816f, 0.851f, 0.0f, 0.346f, 0.811f, 0.816f, 0.861f, 0.0f, 0.351f, 0.812f, 0.816f, + 0.871f, 0.0f, 0.356f, 0.813f, 0.815f, 0.881f, 0.0f, 0.361f, 0.814f, 0.816f, 0.893f, 0.0f, 0.365f, 0.814f, 0.816f, 0.906f, 0.0f, 0.368f, 0.814f, 0.817f, + 0.922f, 0.0f, 0.372f, 0.813f, 0.816f, 0.939f, 0.0f, 0.375f, 0.812f, 0.817f, 0.957f, 0.0f, 0.377f, 0.811f, 0.817f, 0.977f, 0.0f, 0.379f, 0.81f, 0.815f, + 0.995f, 0.0f, 0.38f, 0.808f, 0.813f, 1.012f, 0.0f, 0.379f, 0.806f, 0.807f, 1.028f, 0.0f, 0.377f, 0.803f, 0.803f, 1.042f, 0.0f, 0.374f, 0.8f, 0.801f, + 1.054f, 0.0f, 0.371f, 0.797f, 0.8f, 1.065f, 0.0f, 0.366f, 0.794f, 0.8f, 1.076f, 0.0f, 0.361f, 0.791f, 0.792f, 1.085f, 0.0f, 0.355f, 0.788f, 0.781f, + 1.093f, 0.0f, 0.348f, 0.785f, 0.781f, 1.1f, 0.0f, 0.34f, 0.783f, 0.78f, 1.106f, 0.0f, 0.33f, 0.782f, 0.78f, 1.113f, 0.0f, 0.321f, 0.781f, 0.778f, + 1.117f, 0.0f, 0.31f, 0.78f, 0.777f, 1.122f, -0.0f, 0.299f, 0.779f, 0.777f, 1.125f, -0.0f, 0.286f, 0.778f, 0.776f, 1.129f, -0.0f, 0.274f, 0.778f, 0.777f, + 1.131f, -0.0f, 0.262f, 0.778f, 0.777f, 1.132f, -0.0f, 0.249f, 0.777f, 0.777f, 1.134f, -0.0f, 0.237f, 0.777f, 0.778f, 1.134f, -0.0f, 0.225f, 0.777f, 0.778f, + 1.135f, -0.0f, 0.213f, 0.776f, 0.777f, 1.134f, -0.0f, 0.201f, 0.776f, 0.776f, 1.134f, -0.0f, 0.189f, 0.776f, 0.775f, 1.132f, -0.0f, 0.177f, 0.775f, 0.776f, + 1.13f, -0.0f, 0.164f, 0.775f, 0.775f, 1.129f, -0.0f, 0.152f, 0.774f, 0.774f, 1.126f, -0.0f, 0.141f, 0.774f, 0.773f, 1.122f, -0.0f, 0.13f, 0.774f, 0.772f, + 1.118f, -0.0f, 0.118f, 0.773f, 0.772f, 1.113f, -0.0f, 0.108f, 0.773f, 0.773f, 1.107f, -0.0f, 0.097f, 0.773f, 0.774f, 1.102f, -0.0f, 0.087f, 0.772f, 0.773f, + 1.095f, -0.0f, 0.077f, 0.772f, 0.773f, 1.088f, -0.0f, 0.067f, 0.771f, 0.772f, 1.081f, -0.0f, 0.057f, 0.771f, 0.773f, 1.073f, -0.0f, 0.048f, 0.77f, 0.772f, + 1.066f, -0.0f, 0.038f, 0.769f, 0.767f, 1.058f, -0.0f, 0.029f, 0.768f, 0.766f, 1.05f, -0.0f, 0.019f, 0.768f, 0.765f, 1.041f, -0.0f, 0.011f, 0.767f, 0.765f, + 1.032f, -0.0f, 0.003f, 0.767f, 0.766f, 1.023f, -0.0f, -0.004f, 0.766f, 0.765f, 1.013f, -0.0f, -0.011f, 0.766f, 0.765f, 1.003f, -0.0f, -0.019f, 0.765f, 0.766f, + 0.993f, -0.0f, -0.026f, 0.765f, 0.765f, 0.983f, -0.0f, -0.034f, 0.764f, 0.765f, 0.972f, -0.0f, -0.041f, 0.762f, 0.765f, 0.962f, -0.0f, -0.048f, 0.761f, 0.765f, + 0.951f, -0.0f, -0.055f, 0.759f, 0.762f, 0.94f, -0.0f, -0.063f, 0.756f, 0.761f, 0.929f, -0.0f, -0.07f, 0.754f, 0.755f, 0.918f, -0.0f, -0.078f, 0.751f, 0.751f, + 0.907f, -0.0f, -0.085f, 0.748f, 0.747f, 0.896f, -0.0f, -0.092f, 0.745f, 0.744f, 0.884f, -0.0f, -0.099f, 0.742f, 0.742f, 0.873f, -0.0f, -0.105f, 0.739f, 0.738f, + 0.861f, -0.0f, -0.11f, 0.736f, 0.737f, 0.849f, 0.0f, -0.115f, 0.733f, 0.731f, 0.836f, 0.0f, -0.119f, 0.73f, 0.73f, 0.823f, 0.0f, -0.124f, 0.728f, 0.727f, + 0.81f, 0.0f, -0.128f, 0.725f, 0.725f, 0.796f, 0.0f, -0.132f, 0.723f, 0.723f, 0.783f, 0.0f, -0.136f, 0.72f, 0.719f, 0.77f, 0.0f, -0.141f, 0.718f, 0.717f, + 0.756f, 0.0f, -0.145f, 0.715f, 0.712f, 0.742f, 0.0f, -0.15f, 0.713f, 0.708f, 0.728f, 0.0f, -0.152f, 0.711f, 0.707f, 0.713f, 0.0f, -0.155f, 0.709f, 0.706f, + 0.699f, 0.0f, -0.156f, 0.706f, 0.706f, 0.684f, 0.0f, -0.158f, 0.704f, 0.705f, 0.67f, 0.0f, -0.159f, 0.702f, 0.705f, 0.656f, 0.0f, -0.16f, 0.7f, 0.704f, + 0.642f, 0.0f, -0.161f, 0.698f, 0.702f, 0.628f, 0.0f, -0.161f, 0.695f, 0.698f, 0.614f, 0.0f, -0.162f, 0.693f, 0.695f, 0.6f, 0.0f, -0.162f, 0.691f, 0.691f, + 0.587f, 0.0f, -0.162f, 0.688f, 0.686f, 0.574f, 0.0f, -0.162f, 0.686f, 0.685f, 0.561f, 0.0f, -0.161f, 0.683f, 0.683f, 0.548f, 0.0f, -0.161f, 0.681f, 0.683f, + 0.535f, 0.0f, -0.161f, 0.678f, 0.678f, 0.523f, 0.0f, -0.16f, 0.676f, 0.676f, 0.512f, 0.0f, -0.16f, 0.673f, 0.674f, 0.501f, 0.0f, -0.16f, 0.671f, 0.67f, + 0.49f, 0.0f, -0.16f, 0.668f, 0.668f, 0.48f, 0.0f, -0.161f, 0.666f, 0.663f, 0.469f, 0.0f, -0.162f, 0.665f, 0.66f, 0.458f, 0.0f, -0.165f, 0.663f, 0.66f, + 0.447f, 0.0f, -0.167f, 0.662f, 0.659f, 0.437f, 0.0f, -0.171f, 0.661f, 0.659f, 0.426f, 0.0f, -0.175f, 0.66f, 0.659f, 0.415f, 0.0f, -0.18f, 0.66f, 0.659f, + 0.404f, 0.0f, -0.185f, 0.659f, 0.659f, 0.393f, 0.0f, -0.191f, 0.659f, 0.657f, 0.383f, 0.0f, -0.196f, 0.659f, 0.657f, 0.373f, 0.0f, -0.202f, 0.658f, 0.659f, + 0.363f, -0.0f, -0.208f, 0.658f, 0.658f, 0.353f, -0.0f, -0.215f, 0.658f, 0.659f, 0.344f, -0.0f, -0.223f, 0.658f, 0.659f, 0.336f, -0.0f, -0.23f, 0.658f, 0.659f, + 0.327f, -0.0f, -0.238f, 0.658f, 0.658f, 0.319f, -0.0f, -0.245f, 0.657f, 0.657f, 0.312f, -0.0f, -0.253f, 0.657f, 0.656f, 0.305f, -0.0f, -0.261f, 0.656f, 0.658f, + 0.299f, -0.0f, -0.269f, 0.655f, 0.658f, 0.293f, 0.0f, -0.278f, 0.653f, 0.657f, 0.288f, 0.0f, -0.287f, 0.65f, 0.657f, 0.283f, 0.0f, -0.295f, 0.646f, 0.656f, + 0.279f, 0.0f, -0.304f, 0.642f, 0.655f, 0.275f, 0.0f, -0.313f, 0.637f, 0.642f, 0.271f, 0.0f, -0.322f, 0.633f, 0.637f, 0.268f, 0.0f, -0.331f, 0.628f, 0.609f, + 0.265f, 0.0f, -0.341f, 0.624f, 0.607f, 0.263f, 0.0f, -0.35f, 0.62f, 0.608f, 0.261f, 0.0f, -0.359f, 0.617f, 0.608f, 0.259f, 0.0f, -0.369f, 0.614f, 0.607f, + 0.258f, 0.0f, -0.379f, 0.612f, 0.606f, 0.257f, 0.0f, -0.389f, 0.61f, 0.606f, 0.258f, 0.0f, -0.399f, 0.609f, 0.605f, 0.258f, 0.0f, -0.41f, 0.608f, 0.604f, + 0.26f, 0.0f, -0.421f, 0.608f, 0.606f, 0.263f, 0.0f, -0.431f, 0.607f, 0.606f, 0.266f, 0.0f, -0.441f, 0.607f, 0.606f, 0.27f, 0.0f, -0.452f, 0.606f, 0.607f, + 0.274f, 0.0f, -0.463f, 0.606f, 0.607f, 0.279f, 0.0f, -0.475f, 0.605f, 0.607f, 0.283f, 0.0f, -0.487f, 0.604f, 0.607f, 0.288f, 0.0f, -0.498f, 0.603f, 0.607f, + 0.293f, 0.0f, -0.511f, 0.601f, 0.607f, 0.297f, 0.0f, -0.523f, 0.598f, 0.606f, 0.301f, 0.0f, -0.536f, 0.595f, 0.605f, 0.305f, 0.0f, -0.549f, 0.591f, 0.602f, + 0.309f, 0.0f, -0.562f, 0.588f, 0.597f, 0.312f, 0.0f, -0.576f, 0.583f, 0.585f, 0.315f, 0.0f, -0.59f, 0.579f, 0.577f, 0.318f, 0.0f, -0.604f, 0.574f, 0.576f, + 0.321f, 0.0f, -0.618f, 0.569f, 0.57f, 0.323f, 0.0f, -0.633f, 0.564f, 0.564f, 0.326f, 0.0f, -0.647f, 0.559f, 0.554f, 0.328f, 0.0f, -0.663f, 0.555f, 0.549f, + 0.33f, 0.0f, -0.678f, 0.551f, 0.546f, 0.332f, 0.0f, -0.693f, 0.547f, 0.543f, 0.334f, 0.0f, -0.709f, 0.544f, 0.543f, 0.336f, 0.0f, -0.726f, 0.541f, 0.541f, + 0.338f, 0.0f, -0.742f, 0.538f, 0.54f, 0.338f, 0.0f, -0.758f, 0.536f, 0.538f, 0.338f, 0.0f, -0.773f, 0.534f, 0.53f, 0.337f, 0.0f, -0.787f, 0.532f, 0.528f, + 0.337f, 0.0f, -0.801f, 0.53f, 0.528f, 0.336f, 0.0f, -0.814f, 0.529f, 0.528f, 0.334f, 0.0f, -0.827f, 0.527f, 0.528f, 0.333f, 0.0f, -0.84f, 0.525f, 0.529f, + 0.331f, 0.0f, -0.853f, 0.523f, 0.529f, 0.328f, 0.0f, -0.866f, 0.521f, 0.528f, 0.324f, 0.0f, -0.877f, 0.519f, 0.516f, 0.32f, 0.0f, -0.889f, 0.516f, 0.515f, + 0.315f, 0.0f, -0.9f, 0.513f, 0.515f, 0.31f, 0.0f, -0.91f, 0.51f, 0.514f, 0.304f, 0.0f, -0.921f, 0.507f, 0.513f, 0.297f, 0.0f, -0.931f, 0.505f, 0.507f, + 0.289f, 0.0f, -0.94f, 0.502f, 0.498f, 0.281f, 0.0f, -0.948f, 0.499f, 0.494f, 0.272f, 0.0f, -0.956f, 0.497f, 0.491f, 0.262f, 0.0f, -0.963f, 0.495f, 0.49f, + 0.253f, 0.0f, -0.969f, 0.494f, 0.491f, 0.242f, 0.0f, -0.975f, 0.493f, 0.491f, 0.231f, 0.0f, -0.98f, 0.492f, 0.49f, 0.22f, 0.0f, -0.986f, 0.491f, 0.489f, + 0.208f, 0.0f, -0.99f, 0.491f, 0.49f, 0.195f, 0.0f, -0.994f, 0.491f, 0.491f, 0.181f, 0.0f, -0.998f, 0.491f, 0.491f, 0.168f, 0.0f, -1.001f, 0.491f, 0.492f, + 0.154f, 0.0f, -1.005f, 0.491f, 0.492f, 0.141f, 0.0f, -1.008f, 0.492f, 0.492f, 0.126f, 0.0f, -1.01f, 0.492f, 0.492f, 0.112f, 0.0f, -1.011f, 0.492f, 0.492f, + 0.097f, 0.0f, -1.013f, 0.492f, 0.492f, 0.081f, 0.0f, -1.013f, 0.492f, 0.492f, 0.066f, 0.0f, -1.014f, 0.493f, 0.493f, 0.05f, 0.0f, -1.014f, 0.493f, 0.494f, + 0.035f, 0.0f, -1.014f, 0.493f, 0.494f, 0.019f, 0.0f, -1.013f, 0.493f, 0.494f, 0.004f, 0.0f, -1.012f, 0.493f, 0.494f, -0.011f, 0.0f, -1.011f, 0.493f, 0.493f, + -0.026f, 0.0f, -1.01f, 0.492f, 0.493f, -0.041f, 0.0f, -1.008f, 0.492f, 0.492f, -0.056f, 0.0f, -1.006f, 0.492f, 0.492f, -0.07f, 0.0f, -1.004f, 0.491f, 0.492f, + -0.084f, 0.0f, -1.001f, 0.491f, 0.492f, -0.098f, 0.0f, -0.999f, 0.491f, 0.491f, -0.112f, 0.0f, -0.995f, 0.491f, 0.49f, -0.125f, 0.0f, -0.992f, 0.49f, 0.49f, + -0.138f, 0.0f, -0.987f, 0.49f, 0.491f, -0.15f, 0.0f, -0.983f, 0.49f, 0.49f, -0.162f, 0.0f, -0.978f, 0.49f, 0.49f, -0.174f, 0.0f, -0.973f, 0.489f, 0.489f, + -0.185f, 0.0f, -0.967f, 0.489f, 0.488f, -0.196f, 0.0f, -0.961f, 0.489f, 0.489f, -0.207f, 0.0f, -0.955f, 0.489f, 0.489f, -0.218f, 0.0f, -0.949f, 0.489f, 0.49f, + -0.229f, 0.0f, -0.943f, 0.489f, 0.489f, -0.24f, 0.0f, -0.936f, 0.489f, 0.489f, -0.25f, 0.0f, -0.929f, 0.489f, 0.489f, -0.261f, 0.0f, -0.922f, 0.489f, 0.489f, + -0.271f, 0.0f, -0.914f, 0.489f, 0.49f, -0.28f, 0.0f, -0.907f, 0.49f, 0.49f, -0.289f, 0.0f, -0.898f, 0.49f, 0.489f, -0.298f, 0.0f, -0.89f, 0.49f, 0.489f, + -0.306f, 0.0f, -0.882f, 0.49f, 0.49f, -0.314f, 0.0f, -0.875f, 0.491f, 0.489f, -0.322f, 0.0f, -0.866f, 0.492f, 0.489f, -0.328f, 0.0f, -0.857f, 0.492f, 0.489f, + -0.333f, 0.0f, -0.847f, 0.493f, 0.49f, -0.336f, 0.0f, -0.836f, 0.494f, 0.488f, -0.338f, 0.0f, -0.824f, 0.496f, 0.49f, -0.338f, 0.0f, -0.811f, 0.497f, 0.49f, + -0.338f, 0.0f, -0.798f, 0.499f, 0.491f, -0.337f, 0.0f, -0.785f, 0.501f, 0.497f, -0.337f, 0.0f, -0.772f, 0.503f, 0.5f, -0.337f, 0.0f, -0.759f, 0.505f, 0.504f, + -0.336f, -0.0f, -0.746f, 0.507f, 0.505f, -0.336f, -0.0f, -0.733f, 0.51f, 0.51f, -0.335f, -0.0f, -0.719f, 0.512f, 0.513f, -0.334f, -0.0f, -0.706f, 0.515f, 0.515f, + -0.333f, -0.0f, -0.692f, 0.518f, 0.516f, -0.332f, -0.0f, -0.678f, 0.52f, 0.522f, -0.331f, -0.0f, -0.665f, 0.523f, 0.523f, -0.329f, -0.0f, -0.651f, 0.525f, 0.528f, + -0.327f, -0.0f, -0.637f, 0.528f, 0.53f, -0.325f, -0.0f, -0.624f, 0.53f, 0.532f, -0.322f, -0.0f, -0.61f, 0.532f, 0.534f, -0.319f, -0.0f, -0.597f, 0.535f, 0.535f, + -0.316f, -0.0f, -0.584f, 0.537f, 0.538f, -0.313f, -0.0f, -0.57f, 0.539f, 0.54f, -0.31f, -0.0f, -0.557f, 0.541f, 0.542f, -0.307f, -0.0f, -0.544f, 0.542f, 0.545f, + -0.303f, -0.0f, -0.531f, 0.544f, 0.546f, -0.3f, -0.0f, -0.519f, 0.546f, 0.549f, -0.298f, -0.0f, -0.506f, 0.547f, 0.549f, -0.295f, -0.0f, -0.494f, 0.548f, 0.549f, + -0.292f, -0.0f, -0.482f, 0.549f, 0.55f, -0.29f, -0.0f, -0.47f, 0.55f, 0.552f, -0.287f, -0.0f, -0.459f, 0.551f, 0.552f, -0.285f, -0.0f, -0.447f, 0.551f, 0.552f, + -0.284f, -0.0f, -0.436f, 0.552f, 0.552f, -0.282f, -0.0f, -0.425f, 0.552f, 0.553f, -0.281f, -0.0f, -0.413f, 0.553f, 0.553f, -0.28f, -0.0f, -0.402f, 0.553f, 0.553f, + -0.28f, -0.0f, -0.392f, 0.553f, 0.553f, -0.281f, -0.0f, -0.381f, 0.554f, 0.553f, -0.283f, -0.0f, -0.369f, 0.554f, 0.554f, -0.286f, -0.0f, -0.359f, 0.554f, 0.554f, + -0.289f, -0.0f, -0.348f, 0.555f, 0.554f, -0.294f, -0.0f, -0.337f, 0.555f, 0.555f, -0.299f, -0.0f, -0.327f, 0.555f, 0.554f, -0.305f, -0.0f, -0.317f, 0.556f, 0.555f, + -0.312f, -0.0f, -0.307f, 0.556f, 0.555f, -0.319f, -0.0f, -0.297f, 0.556f, 0.557f, -0.326f, 0.0f, -0.287f, 0.557f, 0.558f, -0.334f, 0.0f, -0.278f, 0.557f, 0.557f, + -0.341f, 0.0f, -0.268f, 0.557f, 0.558f, -0.349f, 0.0f, -0.259f, 0.558f, 0.558f, -0.359f, 0.0f, -0.251f, 0.558f, 0.558f, -0.368f, 0.0f, -0.243f, 0.558f, 0.558f, + -0.378f, 0.0f, -0.235f, 0.558f, 0.559f, -0.388f, 0.0f, -0.228f, 0.558f, 0.558f, -0.398f, 0.0f, -0.221f, 0.559f, 0.559f, -0.408f, 0.0f, -0.214f, 0.559f, 0.559f, + -0.418f, 0.0f, -0.208f, 0.559f, 0.559f, -0.427f, 0.0f, -0.202f, 0.559f, 0.558f, -0.436f, 0.0f, -0.196f, 0.559f, 0.559f, -0.445f, 0.0f, -0.191f, 0.559f, 0.559f, + -0.453f, 0.0f, -0.187f, 0.558f, 0.559f, -0.462f, 0.0f, -0.183f, 0.558f, 0.558f, -0.469f, 0.0f, -0.18f, 0.558f, 0.558f, -0.477f, 0.0f, -0.176f, 0.558f, 0.558f, + -0.484f, 0.0f, -0.174f, 0.557f, 0.558f, -0.493f, 0.0f, -0.17f, 0.555f, 0.559f, +}; + + +static const float data1[136 * GP_PRIM_DATABUF_SIZE] = { + -0.369f, 0.0f, -0.048f, 0.065f, 0.065f, -0.378f, 0.0f, -0.046f, 0.239f, 0.293f, -0.383f, 0.0f, -0.044f, 0.316f, 0.339f, -0.39f, 0.0f, -0.041f, 0.348f, 0.355f, + -0.398f, 0.0f, -0.038f, 0.364f, 0.368f, -0.405f, 0.0f, -0.035f, 0.373f, 0.374f, -0.413f, 0.0f, -0.031f, 0.381f, 0.381f, -0.421f, 0.0f, -0.026f, 0.388f, 0.391f, + -0.429f, 0.0f, -0.02f, 0.392f, 0.394f, -0.437f, 0.0f, -0.014f, 0.395f, 0.396f, -0.445f, 0.0f, -0.008f, 0.397f, 0.397f, -0.453f, 0.0f, -0.001f, 0.399f, 0.4f, + -0.461f, 0.0f, 0.007f, 0.401f, 0.401f, -0.468f, -0.0f, 0.016f, 0.404f, 0.404f, -0.474f, 0.0f, 0.023f, 0.406f, 0.407f, -0.479f, 0.0f, 0.03f, 0.409f, 0.409f, + -0.485f, 0.0f, 0.039f, 0.412f, 0.412f, -0.49f, 0.0f, 0.048f, 0.415f, 0.415f, -0.495f, 0.0f, 0.057f, 0.417f, 0.417f, -0.499f, 0.0f, 0.068f, 0.42f, 0.421f, + -0.503f, 0.0f, 0.079f, 0.421f, 0.421f, -0.507f, -0.0f, 0.091f, 0.423f, 0.423f, -0.51f, -0.0f, 0.102f, 0.424f, 0.424f, -0.513f, -0.0f, 0.112f, 0.424f, 0.425f, + -0.515f, -0.0f, 0.123f, 0.425f, 0.425f, -0.517f, -0.0f, 0.135f, 0.425f, 0.425f, -0.518f, -0.0f, 0.146f, 0.426f, 0.425f, -0.519f, -0.0f, 0.158f, 0.426f, 0.425f, + -0.52f, -0.0f, 0.169f, 0.426f, 0.426f, -0.52f, -0.0f, 0.181f, 0.427f, 0.427f, -0.519f, -0.0f, 0.192f, 0.427f, 0.427f, -0.518f, -0.0f, 0.203f, 0.427f, 0.427f, + -0.517f, -0.0f, 0.213f, 0.427f, 0.428f, -0.515f, -0.0f, 0.222f, 0.428f, 0.427f, -0.513f, -0.0f, 0.232f, 0.428f, 0.427f, -0.51f, -0.0f, 0.241f, 0.429f, 0.427f, + -0.508f, -0.0f, 0.25f, 0.43f, 0.428f, -0.505f, -0.0f, 0.259f, 0.431f, 0.431f, -0.501f, -0.0f, 0.267f, 0.431f, 0.432f, -0.497f, -0.0f, 0.276f, 0.432f, 0.433f, + -0.493f, -0.0f, 0.284f, 0.433f, 0.433f, -0.488f, -0.0f, 0.293f, 0.434f, 0.434f, -0.484f, -0.0f, 0.301f, 0.434f, 0.435f, -0.479f, -0.0f, 0.308f, 0.435f, 0.436f, + -0.474f, -0.0f, 0.316f, 0.435f, 0.435f, -0.468f, -0.0f, 0.322f, 0.436f, 0.436f, -0.463f, -0.0f, 0.329f, 0.436f, 0.436f, -0.457f, -0.0f, 0.335f, 0.436f, 0.436f, + -0.451f, -0.0f, 0.341f, 0.437f, 0.436f, -0.445f, -0.0f, 0.347f, 0.438f, 0.437f, -0.438f, -0.0f, 0.352f, 0.44f, 0.437f, -0.432f, -0.0f, 0.357f, 0.442f, 0.441f, + -0.426f, 0.0f, 0.362f, 0.444f, 0.446f, -0.419f, 0.0f, 0.366f, 0.445f, 0.447f, -0.413f, 0.0f, 0.369f, 0.446f, 0.447f, -0.407f, 0.0f, 0.373f, 0.446f, 0.447f, + -0.401f, 0.0f, 0.376f, 0.447f, 0.447f, -0.395f, 0.0f, 0.378f, 0.447f, 0.448f, -0.388f, 0.0f, 0.381f, 0.447f, 0.448f, -0.382f, 0.0f, 0.383f, 0.448f, 0.448f, + -0.375f, 0.0f, 0.384f, 0.448f, 0.448f, -0.369f, 0.0f, 0.386f, 0.448f, 0.448f, -0.362f, 0.0f, 0.387f, 0.448f, 0.448f, -0.355f, 0.0f, 0.388f, 0.448f, 0.448f, + -0.348f, 0.0f, 0.388f, 0.448f, 0.448f, -0.341f, 0.0f, 0.387f, 0.448f, 0.449f, -0.334f, 0.0f, 0.387f, 0.448f, 0.448f, -0.327f, 0.0f, 0.386f, 0.448f, 0.449f, + -0.32f, 0.0f, 0.384f, 0.449f, 0.449f, -0.313f, 0.0f, 0.382f, 0.449f, 0.449f, -0.307f, 0.0f, 0.38f, 0.449f, 0.449f, -0.3f, 0.0f, 0.377f, 0.449f, 0.45f, + -0.294f, 0.0f, 0.375f, 0.45f, 0.45f, -0.288f, -0.0f, 0.372f, 0.45f, 0.45f, -0.282f, -0.0f, 0.368f, 0.45f, 0.451f, -0.276f, -0.0f, 0.365f, 0.45f, 0.451f, + -0.27f, -0.0f, 0.361f, 0.45f, 0.451f, -0.264f, -0.0f, 0.357f, 0.45f, 0.451f, -0.258f, -0.0f, 0.352f, 0.45f, 0.45f, -0.251f, -0.0f, 0.347f, 0.45f, 0.451f, + -0.245f, -0.0f, 0.341f, 0.451f, 0.451f, -0.24f, -0.0f, 0.335f, 0.451f, 0.451f, -0.234f, -0.0f, 0.329f, 0.451f, 0.451f, -0.228f, -0.0f, 0.323f, 0.452f, 0.452f, + -0.223f, -0.0f, 0.316f, 0.452f, 0.453f, -0.218f, -0.0f, 0.309f, 0.452f, 0.453f, -0.213f, -0.0f, 0.301f, 0.453f, 0.453f, -0.208f, -0.0f, 0.294f, 0.453f, 0.453f, + -0.204f, -0.0f, 0.286f, 0.453f, 0.453f, -0.2f, -0.0f, 0.277f, 0.453f, 0.454f, -0.196f, -0.0f, 0.269f, 0.453f, 0.454f, -0.192f, -0.0f, 0.26f, 0.454f, 0.454f, + -0.189f, -0.0f, 0.25f, 0.454f, 0.454f, -0.186f, -0.0f, 0.241f, 0.454f, 0.455f, -0.183f, -0.0f, 0.231f, 0.454f, 0.455f, -0.181f, -0.0f, 0.221f, 0.454f, 0.455f, + -0.179f, -0.0f, 0.209f, 0.455f, 0.455f, -0.177f, -0.0f, 0.197f, 0.455f, 0.455f, -0.176f, -0.0f, 0.184f, 0.455f, 0.455f, -0.176f, -0.0f, 0.171f, 0.455f, 0.456f, + -0.176f, -0.0f, 0.158f, 0.455f, 0.456f, -0.177f, -0.0f, 0.145f, 0.455f, 0.456f, -0.178f, -0.0f, 0.132f, 0.455f, 0.456f, -0.18f, -0.0f, 0.12f, 0.456f, 0.456f, + -0.182f, -0.0f, 0.108f, 0.456f, 0.456f, -0.185f, -0.0f, 0.097f, 0.456f, 0.456f, -0.188f, -0.0f, 0.086f, 0.456f, 0.457f, -0.191f, -0.0f, 0.076f, 0.456f, 0.457f, + -0.194f, -0.0f, 0.067f, 0.457f, 0.457f, -0.198f, -0.0f, 0.058f, 0.457f, 0.457f, -0.202f, -0.0f, 0.05f, 0.457f, 0.457f, -0.206f, -0.0f, 0.042f, 0.457f, 0.457f, + -0.21f, -0.0f, 0.034f, 0.458f, 0.457f, -0.215f, -0.0f, 0.027f, 0.458f, 0.457f, -0.22f, -0.0f, 0.02f, 0.458f, 0.458f, -0.225f, -0.0f, 0.014f, 0.458f, 0.458f, + -0.23f, -0.0f, 0.007f, 0.458f, 0.458f, -0.235f, -0.0f, 0.002f, 0.459f, 0.458f, -0.24f, -0.0f, -0.004f, 0.459f, 0.458f, -0.246f, -0.0f, -0.009f, 0.46f, 0.459f, + -0.251f, 0.0f, -0.013f, 0.464f, 0.463f, -0.257f, 0.0f, -0.018f, 0.467f, 0.468f, -0.262f, 0.0f, -0.022f, 0.469f, 0.469f, -0.268f, 0.0f, -0.026f, 0.471f, 0.47f, + -0.274f, 0.0f, -0.029f, 0.477f, 0.478f, -0.28f, 0.0f, -0.033f, 0.478f, 0.478f, -0.286f, 0.0f, -0.036f, 0.478f, 0.478f, -0.292f, 0.0f, -0.038f, 0.479f, 0.479f, + -0.298f, 0.0f, -0.041f, 0.48f, 0.48f, -0.305f, 0.0f, -0.043f, 0.48f, 0.48f, -0.311f, 0.0f, -0.045f, 0.482f, 0.482f, -0.318f, 0.0f, -0.047f, 0.482f, 0.482f, + -0.324f, 0.0f, -0.048f, 0.482f, 0.482f, -0.331f, 0.0f, -0.049f, 0.48f, 0.482f, -0.336f, 0.0f, -0.05f, 0.457f, 0.485f, -0.344f, 0.0f, -0.05f, 0.32f, 0.32f, +}; + +static const float data2[2 * GP_PRIM_DATABUF_SIZE] = { + -0.512f, 0.0f, -0.168f, 0.545f, 0.557f, -0.521f, 0.0f, -0.167f, 0.535f, 0.558f, +}; + +static const float data3[1 * GP_PRIM_DATABUF_SIZE] = { + -1.014f, 0.0f, 0.186f, 0.0f, 0.003f, +}; + +static const float data4[1 * GP_PRIM_DATABUF_SIZE] = { + -1.014f, 0.0f, 0.186f, 0.02f, 0.02f, +}; + +static const float data5[48 * GP_PRIM_DATABUF_SIZE] = { + -1.014f, 0.0f, 0.187f, 0.066f, 0.066f, -1.013f, 0.0f, 0.2f, 0.222f, 0.356f, -1.01f, 0.0f, 0.208f, 0.295f, 0.404f, -1.006f, 0.0f, 0.218f, 0.354f, 0.431f, + -1.001f, 0.0f, 0.226f, 0.392f, 0.445f, -0.994f, 0.0f, 0.233f, 0.418f, 0.453f, -0.987f, 0.0f, 0.238f, 0.437f, 0.457f, -0.979f, 0.0f, 0.242f, 0.45f, 0.47f, + -0.97f, 0.0f, 0.245f, 0.459f, 0.473f, -0.96f, -0.0f, 0.246f, 0.465f, 0.474f, -0.951f, -0.0f, 0.245f, 0.469f, 0.475f, -0.942f, 0.0f, 0.242f, 0.471f, 0.473f, + -0.932f, 0.0f, 0.239f, 0.472f, 0.474f, -0.924f, 0.0f, 0.234f, 0.471f, 0.474f, -0.915f, 0.0f, 0.228f, 0.469f, 0.474f, -0.906f, 0.0f, 0.22f, 0.464f, 0.47f, + -0.898f, 0.0f, 0.212f, 0.458f, 0.46f, -0.89f, 0.0f, 0.203f, 0.451f, 0.453f, -0.882f, 0.0f, 0.193f, 0.443f, 0.443f, -0.875f, 0.0f, 0.182f, 0.435f, 0.437f, + -0.869f, 0.0f, 0.172f, 0.426f, 0.428f, -0.863f, 0.0f, 0.161f, 0.417f, 0.415f, -0.858f, 0.0f, 0.148f, 0.409f, 0.41f, -0.854f, 0.0f, 0.137f, 0.399f, 0.399f, + -0.85f, 0.0f, 0.126f, 0.39f, 0.392f, -0.847f, 0.0f, 0.116f, 0.379f, 0.386f, -0.846f, 0.0f, 0.109f, 0.369f, 0.371f, -0.846f, 0.0f, 0.104f, 0.361f, 0.357f, + -0.847f, 0.0f, 0.101f, 0.355f, 0.339f, -0.849f, 0.0f, 0.101f, 0.353f, 0.334f, -0.853f, 0.0f, 0.103f, 0.354f, 0.345f, -0.859f, 0.0f, 0.108f, 0.357f, 0.35f, + -0.865f, 0.0f, 0.116f, 0.363f, 0.365f, -0.873f, 0.0f, 0.126f, 0.369f, 0.375f, -0.881f, 0.0f, 0.137f, 0.375f, 0.379f, -0.89f, 0.0f, 0.149f, 0.381f, 0.38f, + -0.899f, 0.0f, 0.159f, 0.387f, 0.385f, -0.908f, 0.0f, 0.168f, 0.394f, 0.394f, -0.919f, 0.0f, 0.177f, 0.401f, 0.398f, -0.932f, 0.0f, 0.184f, 0.409f, 0.404f, + -0.945f, 0.0f, 0.191f, 0.418f, 0.415f, -0.958f, 0.0f, 0.195f, 0.427f, 0.431f, -0.969f, 0.0f, 0.197f, 0.434f, 0.443f, -0.979f, 0.0f, 0.197f, 0.436f, 0.445f, + -0.987f, 0.0f, 0.195f, 0.428f, 0.463f, -0.995f, 0.0f, 0.192f, 0.398f, 0.46f, -1.001f, 0.0f, 0.189f, 0.345f, 0.465f, -1.01f, 0.0f, 0.183f, 0.236f, 0.236f, +}; + +static const float data6[47 * GP_PRIM_DATABUF_SIZE] = { + 0.022f, 0.0f, -0.353f, 0.125f, 0.125f, 0.012f, 0.0f, -0.352f, 0.175f, 0.288f, 0.004f, 0.0f, -0.352f, 0.206f, 0.313f, -0.006f, 0.0f, -0.352f, 0.241f, 0.323f, + -0.017f, 0.0f, -0.352f, 0.27f, 0.33f, -0.029f, 0.0f, -0.351f, 0.295f, 0.334f, -0.041f, 0.0f, -0.349f, 0.314f, 0.337f, -0.052f, 0.0f, -0.344f, 0.327f, 0.341f, + -0.063f, 0.0f, -0.337f, 0.336f, 0.344f, -0.072f, 0.0f, -0.329f, 0.341f, 0.345f, -0.081f, 0.0f, -0.32f, 0.345f, 0.345f, -0.088f, 0.0f, -0.311f, 0.348f, 0.345f, + -0.093f, 0.0f, -0.303f, 0.352f, 0.347f, -0.098f, 0.0f, -0.295f, 0.356f, 0.352f, -0.101f, 0.0f, -0.287f, 0.361f, 0.357f, -0.102f, 0.0f, -0.279f, 0.367f, 0.364f, + -0.103f, 0.0f, -0.271f, 0.373f, 0.378f, -0.102f, 0.0f, -0.263f, 0.379f, 0.382f, -0.1f, 0.0f, -0.255f, 0.383f, 0.389f, -0.098f, 0.0f, -0.247f, 0.387f, 0.391f, + -0.094f, 0.0f, -0.24f, 0.389f, 0.393f, -0.09f, 0.0f, -0.233f, 0.391f, 0.393f, -0.086f, 0.0f, -0.227f, 0.392f, 0.393f, -0.082f, 0.0f, -0.222f, 0.393f, 0.393f, + -0.078f, 0.0f, -0.219f, 0.394f, 0.393f, -0.075f, 0.0f, -0.217f, 0.397f, 0.393f, -0.072f, 0.0f, -0.217f, 0.4f, 0.393f, -0.07f, 0.0f, -0.219f, 0.402f, 0.408f, + -0.069f, 0.0f, -0.222f, 0.404f, 0.408f, -0.069f, 0.0f, -0.228f, 0.406f, 0.409f, -0.069f, 0.0f, -0.234f, 0.407f, 0.409f, -0.07f, 0.0f, -0.241f, 0.408f, 0.409f, + -0.07f, 0.0f, -0.248f, 0.408f, 0.409f, -0.07f, 0.0f, -0.256f, 0.409f, 0.409f, -0.07f, 0.0f, -0.263f, 0.409f, 0.41f, -0.069f, 0.0f, -0.271f, 0.41f, 0.411f, + -0.068f, 0.0f, -0.279f, 0.41f, 0.411f, -0.065f, 0.0f, -0.287f, 0.41f, 0.411f, -0.062f, 0.0f, -0.295f, 0.409f, 0.411f, -0.057f, 0.0f, -0.303f, 0.409f, 0.409f, + -0.052f, 0.0f, -0.31f, 0.408f, 0.409f, -0.047f, 0.0f, -0.318f, 0.407f, 0.408f, -0.041f, 0.0f, -0.324f, 0.406f, 0.407f, -0.035f, 0.0f, -0.329f, 0.403f, 0.407f, + -0.027f, 0.0f, -0.333f, 0.4f, 0.408f, -0.021f, 0.0f, -0.336f, 0.398f, 0.403f, -0.012f, 0.0f, -0.339f, 0.393f, 0.393f, +}; + +static const float data7[162 * GP_PRIM_DATABUF_SIZE] = { + -0.291f, 0.0f, -0.34f, 0.093f, 0.093f, -0.289f, -0.0f, -0.35f, 0.149f, 0.176f, -0.287f, -0.0f, -0.357f, 0.182f, 0.242f, -0.284f, -0.0f, -0.365f, 0.215f, 0.257f, + -0.281f, -0.0f, -0.374f, 0.242f, 0.266f, -0.278f, -0.0f, -0.384f, 0.266f, 0.287f, -0.275f, -0.0f, -0.394f, 0.285f, 0.304f, -0.271f, 0.0f, -0.405f, 0.302f, 0.316f, + -0.267f, 0.0f, -0.417f, 0.317f, 0.326f, -0.263f, 0.0f, -0.429f, 0.33f, 0.337f, -0.259f, 0.0f, -0.442f, 0.342f, 0.346f, -0.256f, 0.0f, -0.454f, 0.354f, 0.351f, + -0.253f, 0.0f, -0.467f, 0.365f, 0.362f, -0.251f, 0.0f, -0.48f, 0.376f, 0.38f, -0.249f, -0.0f, -0.493f, 0.386f, 0.391f, -0.247f, -0.0f, -0.505f, 0.394f, 0.396f, + -0.246f, -0.0f, -0.518f, 0.401f, 0.405f, -0.245f, 0.0f, -0.53f, 0.408f, 0.409f, -0.245f, 0.0f, -0.542f, 0.415f, 0.413f, -0.245f, 0.0f, -0.554f, 0.421f, 0.42f, + -0.245f, 0.0f, -0.565f, 0.426f, 0.43f, -0.246f, 0.0f, -0.575f, 0.43f, 0.433f, -0.246f, -0.0f, -0.585f, 0.432f, 0.435f, -0.247f, -0.0f, -0.594f, 0.434f, 0.436f, + -0.247f, -0.0f, -0.603f, 0.435f, 0.436f, -0.248f, -0.0f, -0.612f, 0.436f, 0.436f, -0.25f, -0.0f, -0.621f, 0.437f, 0.438f, -0.252f, -0.0f, -0.631f, 0.437f, 0.438f, + -0.254f, -0.0f, -0.642f, 0.438f, 0.438f, -0.255f, 0.0f, -0.653f, 0.438f, 0.438f, -0.258f, 0.0f, -0.664f, 0.438f, 0.439f, -0.26f, 0.0f, -0.674f, 0.439f, 0.439f, + -0.261f, 0.0f, -0.685f, 0.439f, 0.439f, -0.262f, 0.0f, -0.696f, 0.439f, 0.439f, -0.264f, 0.0f, -0.706f, 0.439f, 0.439f, -0.265f, 0.0f, -0.717f, 0.439f, 0.439f, + -0.265f, 0.0f, -0.727f, 0.438f, 0.439f, -0.266f, 0.0f, -0.738f, 0.437f, 0.439f, -0.266f, 0.0f, -0.749f, 0.435f, 0.438f, -0.266f, 0.0f, -0.76f, 0.433f, 0.433f, + -0.265f, 0.0f, -0.771f, 0.431f, 0.428f, -0.265f, 0.0f, -0.781f, 0.43f, 0.428f, -0.263f, 0.0f, -0.792f, 0.429f, 0.428f, -0.26f, 0.0f, -0.802f, 0.428f, 0.429f, + -0.257f, 0.0f, -0.812f, 0.426f, 0.427f, -0.254f, 0.0f, -0.821f, 0.423f, 0.426f, -0.25f, 0.0f, -0.829f, 0.421f, 0.42f, -0.247f, 0.0f, -0.837f, 0.418f, 0.416f, + -0.242f, 0.0f, -0.844f, 0.417f, 0.415f, -0.238f, 0.0f, -0.85f, 0.415f, 0.413f, -0.234f, 0.0f, -0.857f, 0.415f, 0.413f, -0.229f, 0.0f, -0.864f, 0.414f, 0.413f, + -0.224f, 0.0f, -0.87f, 0.414f, 0.413f, -0.219f, 0.0f, -0.877f, 0.414f, 0.414f, -0.214f, 0.0f, -0.883f, 0.414f, 0.413f, -0.208f, 0.0f, -0.89f, 0.413f, 0.413f, + -0.203f, 0.0f, -0.897f, 0.413f, 0.413f, -0.197f, 0.0f, -0.903f, 0.413f, 0.413f, -0.191f, 0.0f, -0.909f, 0.413f, 0.413f, -0.186f, 0.0f, -0.914f, 0.413f, 0.413f, + -0.181f, 0.0f, -0.92f, 0.413f, 0.413f, -0.175f, -0.0f, -0.925f, 0.413f, 0.413f, -0.17f, -0.0f, -0.931f, 0.413f, 0.413f, -0.164f, -0.0f, -0.936f, 0.413f, 0.413f, + -0.159f, -0.0f, -0.942f, 0.413f, 0.413f, -0.152f, -0.0f, -0.948f, 0.413f, 0.413f, -0.145f, -0.0f, -0.955f, 0.413f, 0.413f, -0.137f, -0.0f, -0.961f, 0.414f, 0.413f, + -0.13f, -0.0f, -0.967f, 0.414f, 0.413f, -0.122f, -0.0f, -0.974f, 0.414f, 0.414f, -0.114f, -0.0f, -0.979f, 0.414f, 0.413f, -0.106f, -0.0f, -0.985f, 0.414f, 0.413f, + -0.098f, -0.0f, -0.989f, 0.414f, 0.414f, -0.091f, -0.0f, -0.993f, 0.414f, 0.413f, -0.083f, -0.0f, -0.997f, 0.414f, 0.414f, -0.075f, -0.0f, -0.999f, 0.414f, 0.414f, + -0.066f, -0.0f, -1.001f, 0.414f, 0.414f, -0.057f, -0.0f, -1.003f, 0.414f, 0.413f, -0.046f, -0.0f, -1.006f, 0.414f, 0.413f, -0.038f, -0.0f, -1.008f, 0.414f, 0.413f, + -0.031f, -0.0f, -1.009f, 0.421f, 0.413f, -0.036f, -0.0f, -1.008f, 0.423f, 0.424f, -0.045f, -0.0f, -1.006f, 0.425f, 0.425f, -0.054f, -0.0f, -1.005f, 0.425f, 0.425f, + -0.064f, -0.0f, -1.005f, 0.425f, 0.425f, -0.073f, -0.0f, -1.004f, 0.425f, 0.425f, -0.084f, -0.0f, -1.003f, 0.425f, 0.425f, -0.095f, -0.0f, -1.001f, 0.424f, 0.424f, + -0.105f, -0.0f, -0.997f, 0.423f, 0.424f, -0.116f, -0.0f, -0.994f, 0.422f, 0.422f, -0.127f, -0.0f, -0.991f, 0.421f, 0.419f, -0.137f, -0.0f, -0.987f, 0.42f, 0.419f, + -0.148f, -0.0f, -0.983f, 0.42f, 0.419f, -0.158f, -0.0f, -0.98f, 0.42f, 0.419f, -0.167f, -0.0f, -0.976f, 0.419f, 0.419f, -0.176f, -0.0f, -0.973f, 0.419f, 0.419f, + -0.184f, -0.0f, -0.969f, 0.419f, 0.419f, -0.192f, -0.0f, -0.966f, 0.419f, 0.418f, -0.2f, 0.0f, -0.962f, 0.419f, 0.418f, -0.207f, 0.0f, -0.957f, 0.419f, 0.419f, + -0.215f, 0.0f, -0.953f, 0.419f, 0.418f, -0.223f, 0.0f, -0.948f, 0.419f, 0.419f, -0.231f, 0.0f, -0.944f, 0.419f, 0.419f, -0.239f, 0.0f, -0.939f, 0.419f, 0.419f, + -0.247f, 0.0f, -0.934f, 0.419f, 0.419f, -0.255f, 0.0f, -0.929f, 0.419f, 0.419f, -0.262f, 0.0f, -0.924f, 0.419f, 0.419f, -0.269f, 0.0f, -0.919f, 0.419f, 0.418f, + -0.275f, 0.0f, -0.914f, 0.419f, 0.419f, -0.281f, 0.0f, -0.909f, 0.419f, 0.418f, -0.287f, 0.0f, -0.904f, 0.419f, 0.418f, -0.293f, 0.0f, -0.899f, 0.419f, 0.418f, + -0.299f, 0.0f, -0.894f, 0.42f, 0.419f, -0.304f, 0.0f, -0.888f, 0.421f, 0.42f, -0.311f, 0.0f, -0.882f, 0.423f, 0.422f, -0.317f, 0.0f, -0.876f, 0.424f, 0.424f, + -0.322f, 0.0f, -0.869f, 0.426f, 0.426f, -0.328f, 0.0f, -0.861f, 0.427f, 0.427f, -0.332f, 0.0f, -0.853f, 0.429f, 0.429f, -0.336f, 0.0f, -0.843f, 0.43f, 0.429f, + -0.339f, 0.0f, -0.834f, 0.432f, 0.431f, -0.341f, 0.0f, -0.821f, 0.435f, 0.434f, -0.342f, 0.0f, -0.809f, 0.438f, 0.439f, -0.343f, 0.0f, -0.796f, 0.44f, 0.44f, + -0.343f, 0.0f, -0.783f, 0.442f, 0.442f, -0.343f, 0.0f, -0.772f, 0.446f, 0.445f, -0.342f, 0.0f, -0.76f, 0.45f, 0.45f, -0.342f, 0.0f, -0.748f, 0.454f, 0.455f, + -0.34f, 0.0f, -0.735f, 0.457f, 0.457f, -0.339f, 0.0f, -0.723f, 0.46f, 0.46f, -0.338f, 0.0f, -0.711f, 0.463f, 0.464f, -0.336f, 0.0f, -0.7f, 0.465f, 0.465f, + -0.335f, 0.0f, -0.688f, 0.466f, 0.466f, -0.332f, 0.0f, -0.676f, 0.467f, 0.467f, -0.331f, 0.0f, -0.664f, 0.467f, 0.467f, -0.33f, 0.0f, -0.651f, 0.467f, 0.467f, + -0.328f, 0.0f, -0.638f, 0.467f, 0.467f, -0.325f, 0.0f, -0.625f, 0.467f, 0.467f, -0.323f, 0.0f, -0.614f, 0.467f, 0.467f, -0.321f, 0.0f, -0.603f, 0.467f, 0.466f, + -0.318f, 0.0f, -0.592f, 0.467f, 0.466f, -0.315f, 0.0f, -0.581f, 0.467f, 0.466f, -0.313f, 0.0f, -0.569f, 0.467f, 0.467f, -0.311f, -0.0f, -0.557f, 0.467f, 0.467f, + -0.309f, -0.0f, -0.543f, 0.467f, 0.467f, -0.306f, -0.0f, -0.531f, 0.467f, 0.467f, -0.303f, -0.0f, -0.519f, 0.467f, 0.467f, -0.301f, -0.0f, -0.507f, 0.467f, 0.468f, + -0.299f, -0.0f, -0.497f, 0.467f, 0.467f, -0.297f, -0.0f, -0.487f, 0.467f, 0.467f, -0.295f, 0.0f, -0.476f, 0.465f, 0.467f, -0.293f, 0.0f, -0.466f, 0.463f, 0.467f, + -0.292f, 0.0f, -0.456f, 0.46f, 0.466f, -0.291f, 0.0f, -0.445f, 0.455f, 0.459f, -0.29f, 0.0f, -0.435f, 0.449f, 0.457f, -0.29f, 0.0f, -0.424f, 0.44f, 0.448f, + -0.29f, 0.0f, -0.413f, 0.43f, 0.44f, -0.29f, 0.0f, -0.403f, 0.418f, 0.437f, -0.29f, -0.0f, -0.393f, 0.404f, 0.415f, -0.291f, -0.0f, -0.384f, 0.388f, 0.393f, + -0.29f, -0.0f, -0.376f, 0.374f, 0.379f, -0.29f, -0.0f, -0.365f, 0.352f, 0.352f, +}; + +static const float data8[55 * GP_PRIM_DATABUF_SIZE] = { + 0.781f, 0.0f, 0.098f, 0.109f, 0.109f, 0.784f, 0.0f, 0.105f, 0.202f, 0.338f, 0.785f, 0.0f, 0.108f, 0.254f, 0.369f, 0.787f, 0.0f, 0.113f, 0.306f, 0.382f, + 0.787f, 0.0f, 0.118f, 0.344f, 0.392f, 0.789f, 0.0f, 0.123f, 0.372f, 0.401f, 0.79f, 0.0f, 0.128f, 0.392f, 0.41f, 0.792f, 0.0f, 0.135f, 0.406f, 0.42f, + 0.794f, 0.0f, 0.142f, 0.416f, 0.424f, 0.797f, 0.0f, 0.152f, 0.424f, 0.428f, 0.801f, 0.0f, 0.161f, 0.429f, 0.431f, 0.807f, 0.0f, 0.172f, 0.432f, 0.435f, + 0.814f, 0.0f, 0.182f, 0.435f, 0.438f, 0.821f, 0.0f, 0.19f, 0.437f, 0.439f, 0.828f, 0.0f, 0.197f, 0.439f, 0.44f, 0.836f, 0.0f, 0.204f, 0.44f, 0.441f, + 0.845f, -0.0f, 0.211f, 0.44f, 0.441f, 0.853f, -0.0f, 0.215f, 0.441f, 0.441f, 0.861f, -0.0f, 0.219f, 0.441f, 0.441f, 0.87f, -0.0f, 0.222f, 0.441f, 0.442f, + 0.878f, -0.0f, 0.224f, 0.441f, 0.442f, 0.886f, -0.0f, 0.226f, 0.441f, 0.442f, 0.895f, -0.0f, 0.227f, 0.44f, 0.442f, 0.903f, 0.0f, 0.226f, 0.439f, 0.441f, + 0.911f, 0.0f, 0.225f, 0.436f, 0.441f, 0.919f, 0.0f, 0.224f, 0.432f, 0.441f, 0.927f, 0.0f, 0.221f, 0.425f, 0.436f, 0.934f, 0.0f, 0.218f, 0.415f, 0.429f, + 0.94f, 0.0f, 0.215f, 0.404f, 0.406f, 0.944f, 0.0f, 0.211f, 0.393f, 0.389f, 0.947f, 0.0f, 0.208f, 0.384f, 0.378f, 0.948f, 0.0f, 0.204f, 0.376f, 0.371f, + 0.946f, 0.0f, 0.2f, 0.369f, 0.364f, 0.943f, 0.0f, 0.196f, 0.365f, 0.358f, 0.937f, 0.0f, 0.193f, 0.364f, 0.354f, 0.931f, 0.0f, 0.189f, 0.366f, 0.359f, + 0.925f, 0.0f, 0.186f, 0.37f, 0.367f, 0.917f, 0.0f, 0.182f, 0.374f, 0.375f, 0.908f, 0.0f, 0.177f, 0.378f, 0.382f, 0.899f, 0.0f, 0.172f, 0.381f, 0.384f, + 0.889f, 0.0f, 0.167f, 0.384f, 0.385f, 0.876f, 0.0f, 0.163f, 0.387f, 0.387f, 0.864f, 0.0f, 0.156f, 0.39f, 0.388f, 0.852f, 0.0f, 0.15f, 0.393f, 0.39f, + 0.841f, 0.0f, 0.144f, 0.396f, 0.396f, 0.832f, 0.0f, 0.138f, 0.399f, 0.401f, 0.826f, 0.0f, 0.133f, 0.401f, 0.404f, 0.82f, 0.0f, 0.127f, 0.403f, 0.405f, + 0.816f, 0.0f, 0.122f, 0.403f, 0.407f, 0.812f, 0.0f, 0.119f, 0.399f, 0.406f, 0.808f, 0.0f, 0.115f, 0.39f, 0.405f, 0.805f, 0.0f, 0.113f, 0.371f, 0.407f, + 0.801f, 0.0f, 0.111f, 0.341f, 0.407f, 0.799f, 0.0f, 0.109f, 0.309f, 0.405f, 0.795f, 0.0f, 0.106f, 0.255f, 0.255f, +}; + +static const float data9[70 * GP_PRIM_DATABUF_SIZE] = { + 0.819f, -0.0f, 0.325f, 0.109f, 0.109f, 0.829f, -0.0f, 0.328f, 0.258f, 0.403f, 0.835f, -0.0f, 0.329f, 0.327f, 0.428f, 0.843f, -0.0f, 0.331f, 0.383f, 0.452f, + 0.851f, -0.0f, 0.332f, 0.419f, 0.465f, 0.861f, -0.0f, 0.334f, 0.444f, 0.473f, 0.87f, -0.0f, 0.336f, 0.461f, 0.48f, 0.881f, -0.0f, 0.337f, 0.473f, 0.486f, + 0.892f, -0.0f, 0.339f, 0.482f, 0.496f, 0.904f, -0.0f, 0.341f, 0.489f, 0.501f, 0.917f, -0.0f, 0.342f, 0.494f, 0.503f, 0.931f, -0.0f, 0.342f, 0.498f, 0.505f, + 0.945f, -0.0f, 0.342f, 0.501f, 0.505f, 0.958f, -0.0f, 0.342f, 0.503f, 0.506f, 0.971f, -0.0f, 0.341f, 0.505f, 0.506f, 0.984f, -0.0f, 0.341f, 0.506f, 0.506f, + 0.997f, -0.0f, 0.339f, 0.507f, 0.508f, 1.009f, -0.0f, 0.337f, 0.507f, 0.507f, 1.021f, -0.0f, 0.333f, 0.508f, 0.508f, 1.033f, -0.0f, 0.33f, 0.508f, 0.508f, + 1.044f, -0.0f, 0.326f, 0.508f, 0.508f, 1.056f, -0.0f, 0.322f, 0.508f, 0.508f, 1.068f, -0.0f, 0.317f, 0.508f, 0.508f, 1.078f, -0.0f, 0.311f, 0.507f, 0.508f, + 1.089f, -0.0f, 0.304f, 0.506f, 0.508f, 1.099f, 0.0f, 0.294f, 0.503f, 0.506f, 1.107f, 0.0f, 0.287f, 0.498f, 0.506f, 1.113f, 0.0f, 0.28f, 0.49f, 0.505f, + 1.117f, 0.0f, 0.276f, 0.48f, 0.501f, 1.121f, 0.0f, 0.272f, 0.468f, 0.492f, 1.124f, 0.0f, 0.27f, 0.455f, 0.467f, 1.127f, 0.0f, 0.27f, 0.443f, 0.431f, + 1.129f, 0.0f, 0.271f, 0.431f, 0.4f, 1.13f, 0.0f, 0.274f, 0.422f, 0.399f, 1.13f, 0.0f, 0.278f, 0.414f, 0.399f, 1.13f, 0.0f, 0.286f, 0.408f, 0.399f, + 1.128f, 0.0f, 0.295f, 0.404f, 0.399f, 1.124f, 0.0f, 0.305f, 0.402f, 0.399f, 1.119f, 0.0f, 0.316f, 0.403f, 0.4f, 1.113f, -0.0f, 0.327f, 0.405f, 0.401f, + 1.107f, -0.0f, 0.337f, 0.408f, 0.411f, 1.1f, -0.0f, 0.345f, 0.412f, 0.412f, 1.094f, -0.0f, 0.352f, 0.416f, 0.413f, 1.087f, -0.0f, 0.357f, 0.421f, 0.422f, + 1.08f, -0.0f, 0.363f, 0.426f, 0.428f, 1.071f, -0.0f, 0.368f, 0.429f, 0.43f, 1.062f, -0.0f, 0.373f, 0.431f, 0.431f, 1.051f, -0.0f, 0.377f, 0.433f, 0.431f, + 1.039f, -0.0f, 0.381f, 0.436f, 0.437f, 1.026f, -0.0f, 0.383f, 0.438f, 0.44f, 1.013f, -0.0f, 0.384f, 0.44f, 0.44f, 1.0f, -0.0f, 0.385f, 0.441f, 0.443f, + 0.987f, -0.0f, 0.385f, 0.442f, 0.443f, 0.975f, -0.0f, 0.384f, 0.443f, 0.443f, 0.962f, -0.0f, 0.383f, 0.443f, 0.444f, 0.949f, -0.0f, 0.381f, 0.443f, 0.443f, + 0.936f, -0.0f, 0.38f, 0.443f, 0.444f, 0.923f, -0.0f, 0.378f, 0.443f, 0.444f, 0.909f, -0.0f, 0.375f, 0.443f, 0.444f, 0.897f, -0.0f, 0.371f, 0.443f, 0.444f, + 0.886f, -0.0f, 0.367f, 0.443f, 0.443f, 0.876f, -0.0f, 0.363f, 0.443f, 0.444f, 0.868f, -0.0f, 0.359f, 0.443f, 0.442f, 0.86f, -0.0f, 0.355f, 0.442f, 0.443f, + 0.852f, -0.0f, 0.35f, 0.441f, 0.443f, 0.844f, -0.0f, 0.347f, 0.433f, 0.443f, 0.837f, -0.0f, 0.343f, 0.409f, 0.443f, 0.83f, -0.0f, 0.338f, 0.344f, 0.443f, + 0.824f, -0.0f, 0.335f, 0.239f, 0.437f, 0.815f, -0.0f, 0.326f, 0.0f, 0.003f, +}; + +static const float data10[227 * GP_PRIM_DATABUF_SIZE] = { + -0.675f, 0.0f, 0.411f, 0.099f, 0.099f, -0.669f, 0.0f, 0.418f, 0.358f, 0.358f, -0.666f, 0.0f, 0.424f, 0.381f, 0.381f, -0.662f, 0.0f, 0.431f, 0.389f, 0.389f, + -0.658f, 0.0f, 0.438f, 0.393f, 0.393f, -0.649f, 0.0f, 0.448f, 0.404f, 0.404f, -0.641f, 0.0f, 0.458f, 0.419f, 0.419f, -0.632f, 0.0f, 0.468f, 0.431f, 0.434f, + -0.626f, 0.0f, 0.476f, 0.435f, 0.436f, -0.62f, 0.0f, 0.484f, 0.437f, 0.438f, -0.615f, 0.0f, 0.492f, 0.439f, 0.439f, -0.61f, 0.0f, 0.499f, 0.439f, 0.44f, + -0.605f, 0.0f, 0.506f, 0.44f, 0.44f, -0.6f, 0.0f, 0.512f, 0.44f, 0.44f, -0.595f, 0.0f, 0.519f, 0.44f, 0.44f, -0.59f, 0.0f, 0.526f, 0.441f, 0.441f, + -0.584f, 0.0f, 0.532f, 0.441f, 0.441f, -0.579f, 0.0f, 0.539f, 0.441f, 0.441f, -0.573f, 0.0f, 0.545f, 0.442f, 0.442f, -0.566f, 0.0f, 0.551f, 0.443f, 0.443f, + -0.559f, 0.0f, 0.557f, 0.443f, 0.443f, -0.552f, 0.0f, 0.563f, 0.444f, 0.444f, -0.545f, 0.0f, 0.569f, 0.445f, 0.445f, -0.538f, 0.0f, 0.576f, 0.447f, 0.447f, + -0.532f, 0.0f, 0.582f, 0.448f, 0.448f, -0.525f, 0.0f, 0.589f, 0.45f, 0.45f, -0.519f, 0.0f, 0.595f, 0.451f, 0.452f, -0.513f, 0.0f, 0.602f, 0.452f, 0.453f, + -0.506f, 0.0f, 0.608f, 0.453f, 0.453f, -0.5f, 0.0f, 0.613f, 0.453f, 0.454f, -0.493f, 0.0f, 0.619f, 0.453f, 0.454f, -0.486f, 0.0f, 0.625f, 0.453f, 0.454f, + -0.479f, 0.0f, 0.631f, 0.453f, 0.454f, -0.472f, 0.0f, 0.637f, 0.453f, 0.454f, -0.464f, 0.0f, 0.642f, 0.453f, 0.454f, -0.457f, 0.0f, 0.649f, 0.453f, 0.454f, + -0.45f, 0.0f, 0.655f, 0.453f, 0.453f, -0.443f, 0.0f, 0.661f, 0.453f, 0.453f, -0.435f, 0.0f, 0.667f, 0.453f, 0.454f, -0.427f, 0.0f, 0.672f, 0.453f, 0.454f, + -0.419f, 0.0f, 0.677f, 0.453f, 0.454f, -0.411f, 0.0f, 0.682f, 0.453f, 0.453f, -0.403f, 0.0f, 0.688f, 0.453f, 0.453f, -0.395f, 0.0f, 0.692f, 0.453f, 0.454f, + -0.387f, 0.0f, 0.697f, 0.453f, 0.454f, -0.379f, 0.0f, 0.702f, 0.453f, 0.454f, -0.372f, 0.0f, 0.707f, 0.454f, 0.454f, -0.364f, 0.0f, 0.712f, 0.454f, 0.454f, + -0.356f, 0.0f, 0.716f, 0.454f, 0.454f, -0.349f, 0.0f, 0.721f, 0.454f, 0.454f, -0.342f, 0.0f, 0.725f, 0.454f, 0.454f, -0.334f, 0.0f, 0.73f, 0.454f, 0.454f, + -0.326f, 0.0f, 0.733f, 0.454f, 0.454f, -0.318f, 0.0f, 0.737f, 0.454f, 0.454f, -0.31f, 0.0f, 0.74f, 0.454f, 0.454f, -0.301f, 0.0f, 0.743f, 0.454f, 0.454f, + -0.293f, 0.0f, 0.746f, 0.454f, 0.455f, -0.284f, 0.0f, 0.749f, 0.454f, 0.455f, -0.274f, 0.0f, 0.752f, 0.455f, 0.455f, -0.265f, 0.0f, 0.755f, 0.455f, 0.455f, + -0.255f, 0.0f, 0.757f, 0.455f, 0.455f, -0.245f, 0.0f, 0.76f, 0.456f, 0.455f, -0.234f, 0.0f, 0.762f, 0.457f, 0.456f, -0.223f, 0.0f, 0.764f, 0.458f, 0.458f, + -0.212f, 0.0f, 0.766f, 0.459f, 0.46f, -0.201f, 0.0f, 0.769f, 0.461f, 0.46f, -0.189f, 0.0f, 0.771f, 0.462f, 0.461f, -0.177f, 0.0f, 0.773f, 0.464f, 0.463f, + -0.166f, 0.0f, 0.775f, 0.465f, 0.465f, -0.153f, 0.0f, 0.777f, 0.467f, 0.467f, -0.141f, 0.0f, 0.779f, 0.469f, 0.469f, -0.128f, 0.0f, 0.781f, 0.472f, 0.472f, + -0.116f, 0.0f, 0.782f, 0.474f, 0.473f, -0.101f, 0.0f, 0.782f, 0.477f, 0.477f, -0.087f, 0.0f, 0.783f, 0.482f, 0.477f, -0.073f, 0.0f, 0.783f, 0.489f, 0.483f, + -0.059f, 0.0f, 0.783f, 0.497f, 0.5f, -0.046f, 0.0f, 0.784f, 0.503f, 0.509f, -0.033f, 0.0f, 0.784f, 0.508f, 0.51f, -0.022f, 0.0f, 0.784f, 0.51f, 0.512f, + -0.011f, 0.0f, 0.785f, 0.512f, 0.512f, -0.0f, 0.0f, 0.786f, 0.513f, 0.512f, 0.011f, 0.0f, 0.786f, 0.515f, 0.513f, 0.022f, 0.0f, 0.786f, 0.517f, 0.517f, + 0.032f, 0.0f, 0.786f, 0.52f, 0.519f, 0.044f, 0.0f, 0.786f, 0.522f, 0.524f, 0.055f, 0.0f, 0.785f, 0.525f, 0.525f, 0.066f, 0.0f, 0.785f, 0.527f, 0.525f, + 0.076f, 0.0f, 0.784f, 0.53f, 0.53f, 0.086f, 0.0f, 0.783f, 0.532f, 0.533f, 0.097f, 0.0f, 0.782f, 0.535f, 0.534f, 0.108f, 0.0f, 0.782f, 0.538f, 0.541f, + 0.119f, 0.0f, 0.781f, 0.54f, 0.542f, 0.13f, 0.0f, 0.781f, 0.543f, 0.543f, 0.141f, 0.0f, 0.78f, 0.545f, 0.545f, 0.154f, 0.0f, 0.779f, 0.547f, 0.547f, + 0.165f, 0.0f, 0.777f, 0.549f, 0.548f, 0.177f, 0.0f, 0.775f, 0.55f, 0.552f, 0.188f, 0.0f, 0.772f, 0.552f, 0.552f, 0.199f, 0.0f, 0.77f, 0.553f, 0.553f, + 0.209f, 0.0f, 0.767f, 0.554f, 0.554f, 0.218f, 0.0f, 0.765f, 0.555f, 0.556f, 0.226f, 0.0f, 0.763f, 0.556f, 0.557f, 0.235f, 0.0f, 0.761f, 0.557f, 0.557f, + 0.244f, 0.0f, 0.758f, 0.558f, 0.558f, 0.253f, 0.0f, 0.755f, 0.559f, 0.559f, 0.263f, 0.0f, 0.752f, 0.56f, 0.559f, 0.272f, 0.0f, 0.749f, 0.561f, 0.56f, + 0.285f, 0.0f, 0.745f, 0.562f, 0.56f, 0.299f, 0.0f, 0.741f, 0.563f, 0.563f, 0.316f, 0.0f, 0.736f, 0.564f, 0.564f, 0.331f, 0.0f, 0.728f, 0.565f, 0.567f, + 0.349f, 0.0f, 0.718f, 0.565f, 0.568f, 0.365f, 0.0f, 0.708f, 0.566f, 0.568f, 0.38f, 0.0f, 0.699f, 0.566f, 0.568f, 0.39f, 0.0f, 0.693f, 0.566f, 0.568f, + 0.397f, 0.0f, 0.687f, 0.566f, 0.569f, 0.4f, 0.0f, 0.683f, 0.566f, 0.569f, 0.401f, 0.0f, 0.681f, 0.565f, 0.57f, 0.4f, 0.0f, 0.679f, 0.565f, 0.57f, + 0.397f, 0.0f, 0.678f, 0.564f, 0.57f, 0.393f, 0.0f, 0.678f, 0.564f, 0.565f, 0.387f, 0.0f, 0.678f, 0.563f, 0.559f, 0.379f, 0.0f, 0.679f, 0.562f, 0.558f, + 0.37f, 0.0f, 0.681f, 0.561f, 0.557f, 0.357f, 0.0f, 0.684f, 0.561f, 0.557f, 0.342f, 0.0f, 0.689f, 0.56f, 0.557f, 0.324f, 0.0f, 0.694f, 0.56f, 0.557f, + 0.307f, 0.0f, 0.697f, 0.559f, 0.558f, 0.291f, 0.0f, 0.699f, 0.559f, 0.558f, 0.274f, 0.0f, 0.701f, 0.559f, 0.557f, 0.26f, 0.0f, 0.703f, 0.558f, 0.558f, + 0.246f, 0.0f, 0.705f, 0.558f, 0.558f, 0.235f, 0.0f, 0.707f, 0.558f, 0.558f, 0.224f, 0.0f, 0.709f, 0.558f, 0.558f, 0.214f, 0.0f, 0.711f, 0.558f, 0.558f, + 0.203f, 0.0f, 0.713f, 0.558f, 0.559f, 0.192f, 0.0f, 0.714f, 0.558f, 0.558f, 0.181f, 0.0f, 0.714f, 0.557f, 0.557f, 0.17f, 0.0f, 0.714f, 0.557f, 0.557f, + 0.16f, 0.0f, 0.715f, 0.557f, 0.556f, 0.149f, 0.0f, 0.715f, 0.557f, 0.556f, 0.139f, 0.0f, 0.716f, 0.557f, 0.556f, 0.129f, 0.0f, 0.716f, 0.558f, 0.556f, + 0.119f, 0.0f, 0.717f, 0.558f, 0.556f, 0.109f, 0.0f, 0.717f, 0.558f, 0.557f, 0.099f, 0.0f, 0.718f, 0.558f, 0.557f, 0.089f, 0.0f, 0.718f, 0.559f, 0.557f, + 0.079f, 0.0f, 0.718f, 0.559f, 0.558f, 0.068f, 0.0f, 0.719f, 0.559f, 0.559f, 0.057f, 0.0f, 0.719f, 0.56f, 0.56f, 0.046f, 0.0f, 0.718f, 0.56f, 0.561f, + 0.035f, 0.0f, 0.718f, 0.561f, 0.561f, 0.024f, 0.0f, 0.718f, 0.561f, 0.562f, 0.013f, 0.0f, 0.717f, 0.562f, 0.562f, 0.002f, 0.0f, 0.717f, 0.562f, 0.563f, + -0.01f, 0.0f, 0.717f, 0.563f, 0.564f, -0.021f, 0.0f, 0.717f, 0.563f, 0.564f, -0.032f, 0.0f, 0.716f, 0.563f, 0.564f, -0.044f, 0.0f, 0.715f, 0.564f, 0.564f, + -0.055f, 0.0f, 0.714f, 0.564f, 0.565f, -0.066f, 0.0f, 0.713f, 0.564f, 0.565f, -0.078f, 0.0f, 0.712f, 0.564f, 0.564f, -0.089f, 0.0f, 0.711f, 0.564f, 0.564f, + -0.101f, 0.0f, 0.709f, 0.565f, 0.564f, -0.112f, 0.0f, 0.708f, 0.565f, 0.564f, -0.124f, 0.0f, 0.707f, 0.565f, 0.564f, -0.135f, 0.0f, 0.705f, 0.565f, 0.564f, + -0.146f, 0.0f, 0.704f, 0.566f, 0.564f, -0.158f, 0.0f, 0.702f, 0.566f, 0.564f, -0.169f, 0.0f, 0.7f, 0.566f, 0.566f, -0.18f, 0.0f, 0.698f, 0.567f, 0.568f, + -0.191f, 0.0f, 0.696f, 0.567f, 0.568f, -0.203f, 0.0f, 0.693f, 0.567f, 0.568f, -0.215f, 0.0f, 0.69f, 0.567f, 0.568f, -0.227f, 0.0f, 0.687f, 0.567f, 0.568f, + -0.238f, 0.0f, 0.684f, 0.567f, 0.568f, -0.25f, 0.0f, 0.681f, 0.567f, 0.569f, -0.262f, 0.0f, 0.678f, 0.567f, 0.569f, -0.273f, 0.0f, 0.675f, 0.567f, 0.567f, + -0.284f, 0.0f, 0.673f, 0.567f, 0.566f, -0.295f, 0.0f, 0.671f, 0.567f, 0.567f, -0.305f, 0.0f, 0.669f, 0.566f, 0.567f, -0.316f, 0.0f, 0.666f, 0.566f, 0.567f, + -0.326f, 0.0f, 0.663f, 0.565f, 0.566f, -0.337f, 0.0f, 0.66f, 0.565f, 0.566f, -0.348f, 0.0f, 0.655f, 0.564f, 0.564f, -0.359f, 0.0f, 0.652f, 0.563f, 0.564f, + -0.369f, 0.0f, 0.648f, 0.562f, 0.563f, -0.379f, 0.0f, 0.644f, 0.561f, 0.56f, -0.389f, 0.0f, 0.64f, 0.561f, 0.559f, -0.399f, 0.0f, 0.636f, 0.56f, 0.559f, + -0.409f, 0.0f, 0.633f, 0.559f, 0.559f, -0.419f, 0.0f, 0.629f, 0.559f, 0.559f, -0.428f, 0.0f, 0.625f, 0.559f, 0.558f, -0.438f, 0.0f, 0.62f, 0.559f, 0.559f, + -0.447f, 0.0f, 0.615f, 0.559f, 0.559f, -0.457f, 0.0f, 0.61f, 0.559f, 0.559f, -0.466f, 0.0f, 0.605f, 0.559f, 0.559f, -0.474f, 0.0f, 0.6f, 0.559f, 0.559f, + -0.483f, 0.0f, 0.595f, 0.559f, 0.559f, -0.492f, 0.0f, 0.591f, 0.559f, 0.559f, -0.5f, 0.0f, 0.586f, 0.559f, 0.559f, -0.508f, 0.0f, 0.58f, 0.559f, 0.559f, + -0.515f, 0.0f, 0.574f, 0.559f, 0.559f, -0.523f, 0.0f, 0.568f, 0.559f, 0.559f, -0.531f, 0.0f, 0.562f, 0.559f, 0.558f, -0.54f, 0.0f, 0.556f, 0.559f, 0.558f, + -0.548f, 0.0f, 0.549f, 0.559f, 0.559f, -0.556f, 0.0f, 0.543f, 0.559f, 0.559f, -0.562f, 0.0f, 0.537f, 0.559f, 0.559f, -0.568f, 0.0f, 0.531f, 0.559f, 0.559f, + -0.574f, 0.0f, 0.524f, 0.559f, 0.559f, -0.58f, 0.0f, 0.518f, 0.558f, 0.559f, -0.586f, 0.0f, 0.512f, 0.557f, 0.558f, -0.591f, 0.0f, 0.506f, 0.555f, 0.557f, + -0.597f, 0.0f, 0.5f, 0.551f, 0.556f, -0.603f, 0.0f, 0.493f, 0.546f, 0.547f, -0.609f, 0.0f, 0.487f, 0.541f, 0.538f, -0.614f, 0.0f, 0.48f, 0.536f, 0.535f, + -0.621f, 0.0f, 0.473f, 0.534f, 0.534f, -0.628f, 0.0f, 0.467f, 0.534f, 0.534f, -0.637f, 0.0f, 0.459f, 0.534f, 0.534f, -0.642f, 0.0f, 0.452f, 0.532f, 0.532f, + -0.65f, 0.0f, 0.445f, 0.528f, 0.528f, -0.654f, 0.0f, 0.438f, 0.525f, 0.525f, -0.659f, 0.0f, 0.431f, 0.522f, 0.522f, +}; + +static const float data11[1 * GP_PRIM_DATABUF_SIZE] = { + -0.525f, 0.0f, 0.174f, 0.124f, 0.124f, +}; + +static const float data12[123 * GP_PRIM_DATABUF_SIZE] = { + -0.53f, 0.0f, 0.193f, 0.147f, 0.147f, -0.532f, 0.0f, 0.186f, 0.316f, 0.316f, -0.534f, 0.0f, 0.18f, 0.353f, 0.353f, -0.535f, 0.0f, 0.173f, 0.382f, 0.382f, + -0.537f, 0.0f, 0.165f, 0.384f, 0.384f, -0.538f, 0.0f, 0.155f, 0.387f, 0.387f, -0.539f, 0.0f, 0.145f, 0.393f, 0.393f, -0.54f, -0.0f, 0.134f, 0.399f, 0.399f, + -0.541f, -0.0f, 0.123f, 0.4f, 0.4f, -0.542f, -0.0f, 0.11f, 0.401f, 0.401f, -0.542f, 0.0f, 0.094f, 0.402f, 0.402f, -0.54f, 0.0f, 0.078f, 0.403f, 0.403f, + -0.538f, 0.0f, 0.061f, 0.404f, 0.404f, -0.535f, 0.0f, 0.045f, 0.404f, 0.404f, -0.531f, 0.0f, 0.031f, 0.404f, 0.404f, -0.526f, 0.0f, 0.018f, 0.404f, 0.404f, + -0.52f, -0.0f, 0.005f, 0.405f, 0.405f, -0.513f, -0.0f, -0.01f, 0.405f, 0.405f, -0.505f, -0.0f, -0.024f, 0.405f, 0.405f, -0.495f, -0.0f, -0.037f, 0.405f, 0.405f, + -0.485f, 0.0f, -0.051f, 0.405f, 0.405f, -0.474f, 0.0f, -0.064f, 0.406f, 0.406f, -0.462f, 0.0f, -0.076f, 0.405f, 0.405f, -0.451f, 0.0f, -0.086f, 0.406f, 0.406f, + -0.442f, 0.0f, -0.094f, 0.406f, 0.406f, -0.432f, 0.0f, -0.102f, 0.406f, 0.406f, -0.422f, 0.0f, -0.108f, 0.405f, 0.405f, -0.411f, 0.0f, -0.114f, 0.406f, 0.406f, + -0.4f, 0.0f, -0.119f, 0.405f, 0.405f, -0.389f, 0.0f, -0.122f, 0.406f, 0.406f, -0.378f, 0.0f, -0.125f, 0.407f, 0.407f, -0.365f, 0.0f, -0.127f, 0.412f, 0.412f, + -0.354f, 0.0f, -0.129f, 0.418f, 0.418f, -0.342f, 0.0f, -0.131f, 0.44f, 0.44f, -0.33f, 0.0f, -0.131f, 0.448f, 0.448f, -0.317f, 0.0f, -0.131f, 0.469f, 0.469f, + -0.305f, 0.0f, -0.13f, 0.477f, 0.477f, -0.293f, 0.0f, -0.128f, 0.482f, 0.482f, -0.278f, 0.0f, -0.125f, 0.494f, 0.494f, -0.266f, 0.0f, -0.121f, 0.5f, 0.5f, + -0.253f, 0.0f, -0.116f, 0.507f, 0.507f, -0.242f, 0.0f, -0.111f, 0.509f, 0.509f, -0.231f, 0.0f, -0.105f, 0.511f, 0.511f, -0.222f, 0.0f, -0.099f, 0.511f, 0.511f, + -0.213f, 0.0f, -0.092f, 0.512f, 0.512f, -0.206f, 0.0f, -0.084f, 0.513f, 0.513f, -0.199f, 0.0f, -0.076f, 0.514f, 0.514f, -0.192f, 0.0f, -0.067f, 0.515f, 0.515f, + -0.186f, -0.0f, -0.058f, 0.516f, 0.516f, -0.18f, -0.0f, -0.049f, 0.516f, 0.516f, -0.175f, -0.0f, -0.04f, 0.515f, 0.515f, -0.17f, -0.0f, -0.03f, 0.515f, 0.515f, + -0.166f, -0.0f, -0.02f, 0.516f, 0.516f, -0.163f, -0.0f, -0.01f, 0.504f, 0.504f, -0.159f, -0.0f, 0.002f, 0.502f, 0.502f, -0.155f, -0.0f, 0.014f, 0.501f, 0.501f, + -0.152f, -0.0f, 0.027f, 0.502f, 0.502f, -0.149f, -0.0f, 0.043f, 0.5f, 0.5f, -0.148f, -0.0f, 0.058f, 0.49f, 0.49f, -0.147f, -0.0f, 0.075f, 0.47f, 0.47f, + -0.146f, -0.0f, 0.09f, 0.463f, 0.463f, -0.146f, -0.0f, 0.105f, 0.454f, 0.454f, -0.146f, -0.0f, 0.12f, 0.427f, 0.427f, -0.148f, 0.0f, 0.133f, 0.413f, 0.413f, + -0.15f, 0.0f, 0.144f, 0.4f, 0.4f, -0.153f, 0.0f, 0.152f, 0.383f, 0.383f, -0.156f, 0.0f, 0.157f, 0.369f, 0.369f, -0.158f, 0.0f, 0.16f, 0.36f, 0.36f, + -0.16f, 0.0f, 0.158f, 0.349f, 0.349f, -0.162f, 0.0f, 0.154f, 0.364f, 0.364f, -0.164f, 0.0f, 0.147f, 0.37f, 0.37f, -0.166f, 0.0f, 0.139f, 0.378f, 0.378f, + -0.168f, 0.0f, 0.13f, 0.386f, 0.386f, -0.172f, 0.0f, 0.119f, 0.394f, 0.394f, -0.176f, -0.0f, 0.108f, 0.405f, 0.405f, -0.18f, -0.0f, 0.096f, 0.412f, 0.412f, + -0.185f, -0.0f, 0.084f, 0.417f, 0.417f, -0.191f, -0.0f, 0.073f, 0.425f, 0.425f, -0.196f, -0.0f, 0.063f, 0.431f, 0.431f, -0.202f, -0.0f, 0.053f, 0.441f, 0.441f, + -0.208f, -0.0f, 0.043f, 0.444f, 0.444f, -0.214f, -0.0f, 0.034f, 0.451f, 0.451f, -0.22f, 0.0f, 0.026f, 0.46f, 0.46f, -0.226f, 0.0f, 0.018f, 0.463f, 0.463f, + -0.232f, 0.0f, 0.01f, 0.474f, 0.474f, -0.239f, 0.0f, 0.004f, 0.477f, 0.477f, -0.247f, 0.0f, -0.003f, 0.48f, 0.48f, -0.255f, 0.0f, -0.008f, 0.483f, 0.483f, + -0.264f, 0.0f, -0.013f, 0.497f, 0.497f, -0.274f, 0.0f, -0.018f, 0.501f, 0.501f, -0.285f, 0.0f, -0.022f, 0.505f, 0.505f, -0.297f, 0.0f, -0.024f, 0.509f, 0.509f, + -0.311f, 0.0f, -0.025f, 0.51f, 0.51f, -0.325f, 0.0f, -0.024f, 0.512f, 0.512f, -0.339f, 0.0f, -0.023f, 0.512f, 0.512f, -0.354f, 0.0f, -0.022f, 0.513f, 0.513f, + -0.368f, 0.0f, -0.02f, 0.513f, 0.513f, -0.382f, 0.0f, -0.017f, 0.514f, 0.514f, -0.397f, 0.0f, -0.013f, 0.514f, 0.514f, -0.41f, 0.0f, -0.007f, 0.514f, 0.514f, + -0.422f, 0.0f, 0.001f, 0.513f, 0.513f, -0.434f, 0.0f, 0.009f, 0.514f, 0.514f, -0.446f, 0.0f, 0.018f, 0.514f, 0.514f, -0.458f, 0.0f, 0.028f, 0.514f, 0.514f, + -0.47f, -0.0f, 0.039f, 0.514f, 0.514f, -0.48f, 0.0f, 0.048f, 0.514f, 0.514f, -0.487f, 0.0f, 0.057f, 0.514f, 0.514f, -0.493f, 0.0f, 0.068f, 0.514f, 0.514f, + -0.498f, 0.0f, 0.08f, 0.514f, 0.514f, -0.502f, 0.0f, 0.092f, 0.514f, 0.514f, -0.506f, 0.0f, 0.104f, 0.514f, 0.514f, -0.509f, -0.0f, 0.116f, 0.515f, 0.515f, + -0.511f, -0.0f, 0.125f, 0.515f, 0.515f, -0.513f, -0.0f, 0.133f, 0.515f, 0.515f, -0.515f, -0.0f, 0.141f, 0.515f, 0.515f, -0.517f, 0.0f, 0.148f, 0.515f, 0.515f, + -0.519f, 0.0f, 0.155f, 0.514f, 0.514f, -0.52f, 0.0f, 0.161f, 0.514f, 0.514f, -0.522f, 0.0f, 0.168f, 0.514f, 0.514f, -0.523f, 0.0f, 0.174f, 0.514f, 0.514f, + -0.525f, 0.0f, 0.18f, 0.514f, 0.514f, -0.526f, 0.0f, 0.185f, 0.514f, 0.514f, -0.527f, 0.0f, 0.191f, 0.513f, 0.513f, +}; + +static const float data13[125 * GP_PRIM_DATABUF_SIZE] = { + 0.184f, 0.0f, 0.22f, 0.026f, 0.026f, 0.182f, 0.0f, 0.21f, 0.275f, 0.275f, 0.18f, 0.0f, 0.203f, 0.301f, 0.301f, 0.178f, 0.0f, 0.195f, 0.322f, 0.322f, + 0.176f, 0.0f, 0.186f, 0.343f, 0.343f, 0.173f, 0.0f, 0.176f, 0.36f, 0.36f, 0.17f, -0.0f, 0.166f, 0.367f, 0.367f, 0.168f, -0.0f, 0.156f, 0.38f, 0.38f, + 0.165f, -0.0f, 0.145f, 0.385f, 0.385f, 0.163f, -0.0f, 0.132f, 0.391f, 0.391f, 0.161f, -0.0f, 0.119f, 0.401f, 0.401f, 0.16f, -0.0f, 0.103f, 0.405f, 0.405f, + 0.161f, -0.0f, 0.086f, 0.405f, 0.405f, 0.163f, -0.0f, 0.068f, 0.407f, 0.407f, 0.165f, 0.0f, 0.051f, 0.409f, 0.409f, 0.168f, 0.0f, 0.034f, 0.409f, 0.409f, + 0.172f, 0.0f, 0.018f, 0.409f, 0.409f, 0.177f, 0.0f, 0.004f, 0.409f, 0.409f, 0.183f, 0.0f, -0.008f, 0.411f, 0.411f, 0.19f, 0.0f, -0.022f, 0.411f, 0.411f, + 0.196f, 0.0f, -0.034f, 0.411f, 0.411f, 0.203f, 0.0f, -0.045f, 0.411f, 0.411f, 0.211f, 0.0f, -0.055f, 0.411f, 0.411f, 0.219f, 0.0f, -0.064f, 0.411f, 0.411f, + 0.227f, 0.0f, -0.072f, 0.411f, 0.411f, 0.235f, 0.0f, -0.08f, 0.412f, 0.412f, 0.244f, 0.0f, -0.087f, 0.412f, 0.412f, 0.253f, 0.0f, -0.094f, 0.413f, 0.413f, + 0.262f, 0.0f, -0.1f, 0.413f, 0.413f, 0.273f, 0.0f, -0.105f, 0.413f, 0.413f, 0.284f, 0.0f, -0.11f, 0.413f, 0.413f, 0.295f, 0.0f, -0.114f, 0.419f, 0.419f, + 0.307f, 0.0f, -0.117f, 0.425f, 0.425f, 0.321f, -0.0f, -0.118f, 0.433f, 0.433f, 0.334f, -0.0f, -0.12f, 0.446f, 0.446f, 0.347f, -0.0f, -0.12f, 0.474f, 0.474f, + 0.36f, -0.0f, -0.12f, 0.481f, 0.481f, 0.374f, -0.0f, -0.119f, 0.491f, 0.491f, 0.387f, -0.0f, -0.118f, 0.494f, 0.494f, 0.401f, 0.0f, -0.116f, 0.5f, 0.5f, + 0.414f, 0.0f, -0.112f, 0.505f, 0.505f, 0.426f, -0.0f, -0.107f, 0.51f, 0.51f, 0.438f, -0.0f, -0.101f, 0.513f, 0.513f, 0.449f, -0.0f, -0.094f, 0.515f, 0.515f, + 0.46f, -0.0f, -0.086f, 0.517f, 0.517f, 0.47f, -0.0f, -0.078f, 0.519f, 0.519f, 0.478f, -0.0f, -0.07f, 0.52f, 0.52f, 0.486f, -0.0f, -0.061f, 0.522f, 0.522f, + 0.493f, -0.0f, -0.052f, 0.523f, 0.523f, 0.499f, -0.0f, -0.044f, 0.522f, 0.522f, 0.505f, -0.0f, -0.035f, 0.522f, 0.522f, 0.51f, -0.0f, -0.027f, 0.523f, 0.523f, + 0.514f, -0.0f, -0.018f, 0.523f, 0.523f, 0.517f, -0.0f, -0.009f, 0.523f, 0.523f, 0.52f, -0.0f, -0.001f, 0.524f, 0.524f, 0.522f, -0.0f, 0.008f, 0.523f, 0.523f, + 0.525f, -0.0f, 0.018f, 0.521f, 0.522f, 0.527f, -0.0f, 0.027f, 0.515f, 0.514f, 0.529f, -0.0f, 0.036f, 0.512f, 0.512f, 0.531f, -0.0f, 0.045f, 0.509f, 0.51f, + 0.533f, -0.0f, 0.053f, 0.506f, 0.505f, 0.535f, -0.0f, 0.062f, 0.503f, 0.503f, 0.536f, -0.0f, 0.071f, 0.5f, 0.5f, 0.538f, -0.0f, 0.08f, 0.496f, 0.497f, + 0.538f, -0.0f, 0.09f, 0.491f, 0.492f, 0.539f, -0.0f, 0.1f, 0.485f, 0.486f, 0.539f, 0.0f, 0.11f, 0.475f, 0.476f, 0.539f, 0.0f, 0.12f, 0.46f, 0.459f, + 0.539f, 0.0f, 0.13f, 0.444f, 0.448f, 0.538f, 0.0f, 0.139f, 0.406f, 0.405f, 0.537f, 0.0f, 0.144f, 0.399f, 0.399f, 0.536f, 0.0f, 0.146f, 0.395f, 0.395f, + 0.535f, 0.0f, 0.144f, 0.412f, 0.412f, 0.533f, 0.0f, 0.139f, 0.413f, 0.413f, 0.53f, 0.0f, 0.131f, 0.414f, 0.413f, 0.528f, 0.0f, 0.122f, 0.419f, 0.418f, + 0.525f, 0.0f, 0.112f, 0.425f, 0.424f, 0.521f, 0.0f, 0.102f, 0.444f, 0.444f, 0.518f, 0.0f, 0.094f, 0.451f, 0.452f, 0.514f, 0.0f, 0.085f, 0.457f, 0.457f, + 0.509f, 0.0f, 0.078f, 0.461f, 0.46f, 0.504f, 0.0f, 0.069f, 0.469f, 0.468f, 0.499f, 0.0f, 0.06f, 0.481f, 0.481f, 0.493f, 0.0f, 0.052f, 0.489f, 0.489f, + 0.487f, 0.0f, 0.044f, 0.492f, 0.492f, 0.481f, 0.0f, 0.037f, 0.501f, 0.5f, 0.474f, 0.0f, 0.029f, 0.513f, 0.513f, 0.467f, 0.0f, 0.022f, 0.521f, 0.521f, + 0.458f, 0.0f, 0.015f, 0.524f, 0.524f, 0.449f, 0.0f, 0.008f, 0.525f, 0.525f, 0.439f, 0.0f, 0.001f, 0.528f, 0.528f, 0.427f, 0.0f, -0.005f, 0.532f, 0.532f, + 0.416f, 0.0f, -0.011f, 0.533f, 0.533f, 0.401f, 0.0f, -0.015f, 0.537f, 0.537f, 0.386f, 0.0f, -0.018f, 0.539f, 0.539f, 0.371f, 0.0f, -0.02f, 0.538f, 0.538f, + 0.356f, 0.0f, -0.021f, 0.543f, 0.543f, 0.341f, 0.0f, -0.023f, 0.543f, 0.543f, 0.326f, 0.0f, -0.023f, 0.543f, 0.543f, 0.312f, 0.0f, -0.022f, 0.543f, 0.543f, + 0.298f, 0.0f, -0.018f, 0.543f, 0.543f, 0.286f, 0.0f, -0.014f, 0.543f, 0.543f, 0.273f, 0.0f, -0.006f, 0.543f, 0.543f, 0.26f, 0.0f, 0.004f, 0.543f, 0.543f, + 0.247f, 0.0f, 0.013f, 0.543f, 0.543f, 0.235f, 0.0f, 0.022f, 0.543f, 0.543f, 0.225f, 0.0f, 0.033f, 0.543f, 0.543f, 0.215f, 0.0f, 0.045f, 0.542f, 0.542f, + 0.206f, 0.0f, 0.061f, 0.54f, 0.54f, 0.199f, 0.0f, 0.078f, 0.542f, 0.542f, 0.193f, 0.0f, 0.094f, 0.542f, 0.542f, 0.189f, -0.0f, 0.109f, 0.541f, 0.541f, + 0.186f, -0.0f, 0.119f, 0.542f, 0.542f, 0.185f, -0.0f, 0.127f, 0.542f, 0.542f, 0.184f, -0.0f, 0.135f, 0.542f, 0.542f, 0.184f, -0.0f, 0.142f, 0.542f, 0.542f, + 0.183f, -0.0f, 0.149f, 0.541f, 0.541f, 0.183f, -0.0f, 0.156f, 0.538f, 0.538f, 0.183f, -0.0f, 0.163f, 0.539f, 0.539f, 0.183f, -0.0f, 0.17f, 0.54f, 0.54f, + 0.183f, 0.0f, 0.177f, 0.54f, 0.54f, 0.183f, 0.0f, 0.184f, 0.54f, 0.54f, 0.183f, 0.0f, 0.191f, 0.54f, 0.54f, 0.184f, 0.0f, 0.196f, 0.539f, 0.539f, + 0.184f, 0.0f, 0.204f, 0.518f, 0.518f, +}; + +static const float data14[45 * GP_PRIM_DATABUF_SIZE] = { + -0.096f, -0.0f, -0.305f, 0.01f, 0.01f, -0.09f, -0.0f, -0.313f, 0.121f, 0.362f, -0.086f, -0.0f, -0.318f, 0.179f, 0.368f, -0.081f, -0.0f, -0.325f, 0.234f, 0.37f, + -0.075f, -0.0f, -0.331f, 0.272f, 0.37f, -0.068f, -0.0f, -0.338f, 0.302f, 0.371f, -0.061f, -0.0f, -0.345f, 0.324f, 0.374f, -0.053f, -0.0f, -0.352f, 0.34f, 0.377f, + -0.044f, -0.0f, -0.358f, 0.352f, 0.378f, -0.035f, -0.0f, -0.362f, 0.362f, 0.377f, -0.026f, -0.0f, -0.366f, 0.37f, 0.378f, -0.018f, -0.0f, -0.368f, 0.377f, 0.378f, + -0.009f, -0.0f, -0.369f, 0.383f, 0.376f, -0.001f, -0.0f, -0.369f, 0.389f, 0.369f, 0.007f, -0.0f, -0.368f, 0.395f, 0.364f, 0.015f, -0.0f, -0.367f, 0.4f, 0.388f, + 0.023f, -0.0f, -0.365f, 0.405f, 0.41f, 0.03f, -0.0f, -0.363f, 0.41f, 0.429f, 0.038f, -0.0f, -0.36f, 0.414f, 0.438f, 0.044f, -0.0f, -0.357f, 0.417f, 0.441f, + 0.05f, -0.0f, -0.355f, 0.419f, 0.444f, 0.055f, -0.0f, -0.352f, 0.42f, 0.441f, 0.06f, -0.0f, -0.349f, 0.421f, 0.445f, 0.063f, -0.0f, -0.347f, 0.421f, 0.446f, + 0.065f, -0.0f, -0.344f, 0.42f, 0.443f, 0.065f, -0.0f, -0.342f, 0.42f, 0.437f, 0.065f, -0.0f, -0.341f, 0.419f, 0.413f, 0.063f, -0.0f, -0.339f, 0.418f, 0.404f, + 0.061f, -0.0f, -0.338f, 0.418f, 0.403f, 0.057f, -0.0f, -0.337f, 0.418f, 0.402f, 0.052f, -0.0f, -0.337f, 0.418f, 0.407f, 0.046f, -0.0f, -0.337f, 0.419f, 0.411f, + 0.04f, 0.0f, -0.336f, 0.42f, 0.416f, 0.032f, 0.0f, -0.337f, 0.422f, 0.421f, 0.023f, 0.0f, -0.339f, 0.424f, 0.425f, 0.014f, 0.0f, -0.34f, 0.426f, 0.427f, + 0.003f, 0.0f, -0.341f, 0.428f, 0.427f, -0.007f, 0.0f, -0.341f, 0.43f, 0.433f, -0.018f, 0.0f, -0.339f, 0.432f, 0.437f, -0.027f, 0.0f, -0.335f, 0.434f, 0.438f, + -0.037f, 0.0f, -0.33f, 0.435f, 0.437f, -0.046f, -0.0f, -0.326f, 0.436f, 0.438f, -0.055f, -0.0f, -0.321f, 0.436f, 0.44f, -0.062f, -0.0f, -0.316f, 0.437f, 0.439f, + -0.073f, -0.0f, -0.31f, 0.437f, 0.437f, +}; + +static const float data16[84 * GP_PRIM_DATABUF_SIZE] = { + 0.737f, 0.0f, 0.177f, 0.148f, 0.148f, 0.735f, 0.0f, 0.164f, 0.214f, 0.39f, 0.734f, 0.0f, 0.155f, 0.254f, 0.402f, 0.732f, 0.0f, 0.143f, 0.295f, 0.413f, + 0.73f, 0.0f, 0.132f, 0.328f, 0.415f, 0.728f, 0.0f, 0.121f, 0.355f, 0.415f, 0.726f, 0.0f, 0.109f, 0.375f, 0.416f, 0.724f, 0.0f, 0.097f, 0.39f, 0.417f, + 0.721f, 0.0f, 0.086f, 0.401f, 0.418f, 0.719f, 0.0f, 0.074f, 0.408f, 0.419f, 0.716f, 0.0f, 0.062f, 0.413f, 0.42f, 0.713f, 0.0f, 0.05f, 0.416f, 0.42f, + 0.71f, 0.0f, 0.039f, 0.418f, 0.421f, 0.707f, 0.0f, 0.028f, 0.42f, 0.421f, 0.703f, 0.0f, 0.017f, 0.421f, 0.422f, 0.7f, 0.0f, 0.006f, 0.421f, 0.422f, + 0.696f, 0.0f, -0.005f, 0.422f, 0.422f, 0.693f, 0.0f, -0.015f, 0.422f, 0.422f, 0.689f, 0.0f, -0.025f, 0.423f, 0.423f, 0.685f, 0.0f, -0.034f, 0.423f, 0.423f, + 0.681f, 0.0f, -0.044f, 0.423f, 0.423f, 0.677f, 0.0f, -0.053f, 0.423f, 0.423f, 0.672f, 0.0f, -0.062f, 0.423f, 0.423f, 0.668f, 0.0f, -0.071f, 0.422f, 0.424f, + 0.662f, 0.0f, -0.08f, 0.422f, 0.424f, 0.657f, 0.0f, -0.088f, 0.422f, 0.422f, 0.651f, 0.0f, -0.095f, 0.421f, 0.419f, 0.645f, 0.0f, -0.103f, 0.42f, 0.419f, + 0.638f, 0.0f, -0.109f, 0.42f, 0.419f, 0.631f, 0.0f, -0.115f, 0.419f, 0.419f, 0.624f, 0.0f, -0.12f, 0.419f, 0.419f, 0.617f, 0.0f, -0.125f, 0.419f, 0.419f, + 0.61f, 0.0f, -0.129f, 0.418f, 0.418f, 0.602f, 0.0f, -0.133f, 0.418f, 0.416f, 0.594f, 0.0f, -0.137f, 0.417f, 0.416f, 0.587f, 0.0f, -0.14f, 0.417f, 0.415f, + 0.579f, 0.0f, -0.142f, 0.417f, 0.416f, 0.571f, 0.0f, -0.144f, 0.417f, 0.415f, 0.564f, 0.0f, -0.145f, 0.417f, 0.416f, 0.556f, 0.0f, -0.146f, 0.417f, 0.415f, + 0.549f, 0.0f, -0.146f, 0.417f, 0.415f, 0.541f, 0.0f, -0.146f, 0.417f, 0.415f, 0.535f, 0.0f, -0.145f, 0.417f, 0.416f, 0.53f, 0.0f, -0.143f, 0.418f, 0.418f, + 0.526f, 0.0f, -0.14f, 0.418f, 0.418f, 0.524f, 0.0f, -0.136f, 0.42f, 0.418f, 0.524f, 0.0f, -0.132f, 0.422f, 0.416f, 0.527f, 0.0f, -0.126f, 0.424f, 0.424f, + 0.531f, 0.0f, -0.121f, 0.427f, 0.428f, 0.536f, 0.0f, -0.115f, 0.43f, 0.433f, 0.542f, 0.0f, -0.109f, 0.433f, 0.436f, 0.548f, 0.0f, -0.102f, 0.435f, 0.436f, + 0.555f, 0.0f, -0.095f, 0.436f, 0.437f, 0.562f, 0.0f, -0.088f, 0.437f, 0.438f, 0.568f, 0.0f, -0.081f, 0.437f, 0.438f, 0.575f, 0.0f, -0.073f, 0.438f, 0.438f, + 0.581f, 0.0f, -0.065f, 0.438f, 0.438f, 0.587f, 0.0f, -0.058f, 0.438f, 0.438f, 0.593f, 0.0f, -0.05f, 0.438f, 0.438f, 0.599f, 0.0f, -0.041f, 0.438f, 0.438f, + 0.605f, 0.0f, -0.033f, 0.438f, 0.438f, 0.61f, 0.0f, -0.024f, 0.438f, 0.438f, 0.615f, 0.0f, -0.015f, 0.438f, 0.438f, 0.621f, 0.0f, -0.006f, 0.438f, 0.438f, + 0.626f, 0.0f, 0.004f, 0.438f, 0.438f, 0.631f, 0.0f, 0.013f, 0.437f, 0.438f, 0.636f, 0.0f, 0.023f, 0.436f, 0.438f, 0.641f, 0.0f, 0.032f, 0.434f, 0.438f, + 0.647f, 0.0f, 0.042f, 0.432f, 0.437f, 0.652f, 0.0f, 0.051f, 0.431f, 0.429f, 0.657f, 0.0f, 0.06f, 0.429f, 0.426f, 0.662f, 0.0f, 0.069f, 0.427f, 0.425f, + 0.668f, 0.0f, 0.078f, 0.425f, 0.425f, 0.673f, 0.0f, 0.087f, 0.423f, 0.424f, 0.678f, 0.0f, 0.095f, 0.42f, 0.422f, 0.683f, 0.0f, 0.104f, 0.416f, 0.42f, + 0.688f, 0.0f, 0.112f, 0.411f, 0.421f, 0.693f, 0.0f, 0.12f, 0.403f, 0.417f, 0.698f, 0.0f, 0.128f, 0.394f, 0.411f, 0.702f, 0.0f, 0.135f, 0.382f, 0.404f, + 0.707f, 0.0f, 0.143f, 0.369f, 0.388f, 0.711f, 0.0f, 0.15f, 0.352f, 0.371f, 0.714f, 0.0f, 0.155f, 0.338f, 0.352f, 0.719f, 0.0f, 0.164f, 0.315f, 0.315f, +}; + +static const float data15[44 * GP_PRIM_DATABUF_SIZE] = { + -0.085f, 0.0f, -0.816f, 0.138f, 0.138f, -0.079f, 0.0f, -0.825f, 0.246f, 0.309f, -0.074f, 0.0f, -0.832f, 0.302f, 0.34f, -0.067f, 0.0f, -0.84f, 0.335f, 0.352f, + -0.059f, 0.0f, -0.848f, 0.357f, 0.374f, -0.05f, 0.0f, -0.855f, 0.371f, 0.378f, -0.041f, 0.0f, -0.861f, 0.382f, 0.383f, -0.031f, 0.0f, -0.866f, 0.391f, 0.396f, + -0.021f, 0.0f, -0.871f, 0.398f, 0.401f, -0.011f, 0.0f, -0.874f, 0.404f, 0.407f, -0.001f, 0.0f, -0.877f, 0.409f, 0.411f, 0.01f, 0.0f, -0.878f, 0.415f, 0.412f, + 0.02f, 0.0f, -0.878f, 0.422f, 0.417f, 0.031f, 0.0f, -0.878f, 0.43f, 0.421f, 0.042f, 0.0f, -0.876f, 0.438f, 0.437f, 0.052f, 0.0f, -0.873f, 0.445f, 0.451f, + 0.062f, 0.0f, -0.868f, 0.451f, 0.459f, 0.071f, 0.0f, -0.863f, 0.456f, 0.463f, 0.08f, 0.0f, -0.857f, 0.46f, 0.465f, 0.087f, 0.0f, -0.85f, 0.462f, 0.465f, + 0.094f, 0.0f, -0.842f, 0.461f, 0.465f, 0.098f, 0.0f, -0.835f, 0.458f, 0.467f, 0.101f, 0.0f, -0.827f, 0.451f, 0.457f, 0.103f, 0.0f, -0.82f, 0.436f, 0.451f, + 0.102f, 0.0f, -0.815f, 0.422f, 0.418f, 0.1f, 0.0f, -0.811f, 0.419f, 0.378f, 0.096f, 0.0f, -0.814f, 0.436f, 0.447f, 0.089f, 0.0f, -0.817f, 0.454f, 0.465f, + 0.082f, 0.0f, -0.821f, 0.465f, 0.47f, 0.072f, 0.0f, -0.825f, 0.473f, 0.477f, 0.061f, 0.0f, -0.828f, 0.477f, 0.479f, 0.049f, 0.0f, -0.832f, 0.48f, 0.485f, + 0.036f, 0.0f, -0.834f, 0.483f, 0.48f, 0.023f, 0.0f, -0.836f, 0.484f, 0.485f, 0.01f, 0.0f, -0.838f, 0.486f, 0.487f, -0.003f, 0.0f, -0.84f, 0.486f, 0.488f, + -0.016f, 0.0f, -0.84f, 0.486f, 0.489f, -0.027f, 0.0f, -0.84f, 0.485f, 0.485f, -0.039f, 0.0f, -0.839f, 0.484f, 0.484f, -0.049f, 0.0f, -0.837f, 0.483f, 0.485f, + -0.058f, 0.0f, -0.834f, 0.48f, 0.481f, -0.066f, 0.0f, -0.83f, 0.473f, 0.479f, -0.072f, 0.0f, -0.827f, 0.462f, 0.472f, -0.081f, 0.0f, -0.823f, 0.442f, 0.442f, +}; + +static const float data17[56 * GP_PRIM_DATABUF_SIZE] = { + -1.007f, -0.0f, 0.183f, 0.022f, 0.022f, -1.003f, -0.0f, 0.181f, 0.192f, 0.436f, -0.998f, -0.0f, 0.18f, 0.28f, 0.451f, -0.99f, -0.0f, 0.178f, 0.355f, 0.459f, + -0.98f, -0.0f, 0.175f, 0.402f, 0.464f, -0.967f, -0.0f, 0.169f, 0.432f, 0.467f, -0.952f, -0.0f, 0.152f, 0.449f, 0.468f, -0.943f, 0.0f, 0.138f, 0.459f, 0.469f, + -0.939f, 0.0f, 0.128f, 0.464f, 0.469f, -0.934f, 0.0f, 0.119f, 0.467f, 0.47f, -0.929f, 0.0f, 0.11f, 0.469f, 0.47f, -0.924f, 0.0f, 0.101f, 0.47f, 0.47f, + -0.919f, 0.0f, 0.092f, 0.47f, 0.471f, -0.913f, 0.0f, 0.082f, 0.471f, 0.471f, -0.908f, 0.0f, 0.072f, 0.471f, 0.471f, -0.903f, 0.0f, 0.063f, 0.472f, 0.472f, + -0.897f, 0.0f, 0.053f, 0.472f, 0.472f, -0.892f, 0.0f, 0.044f, 0.473f, 0.473f, -0.886f, 0.0f, 0.035f, 0.473f, 0.473f, -0.881f, 0.0f, 0.026f, 0.473f, 0.473f, + -0.876f, 0.0f, 0.018f, 0.473f, 0.473f, -0.87f, 0.0f, 0.012f, 0.472f, 0.473f, -0.865f, 0.0f, 0.006f, 0.47f, 0.473f, -0.86f, 0.0f, 0.003f, 0.468f, 0.473f, + -0.855f, 0.0f, 0.001f, 0.466f, 0.469f, -0.85f, 0.0f, 0.001f, 0.463f, 0.469f, -0.846f, 0.0f, 0.003f, 0.46f, 0.45f, -0.843f, 0.0f, 0.008f, 0.458f, 0.454f, + -0.84f, 0.0f, 0.014f, 0.456f, 0.454f, -0.838f, 0.0f, 0.021f, 0.455f, 0.454f, -0.836f, 0.0f, 0.03f, 0.453f, 0.455f, -0.835f, 0.0f, 0.039f, 0.451f, 0.455f, + -0.835f, 0.0f, 0.049f, 0.449f, 0.453f, -0.836f, 0.0f, 0.059f, 0.447f, 0.445f, -0.837f, 0.0f, 0.068f, 0.445f, 0.441f, -0.84f, 0.0f, 0.078f, 0.443f, 0.44f, + -0.843f, 0.0f, 0.087f, 0.442f, 0.44f, -0.846f, 0.0f, 0.095f, 0.442f, 0.44f, -0.851f, -0.0f, 0.103f, 0.441f, 0.441f, -0.855f, -0.0f, 0.111f, 0.441f, 0.44f, + -0.86f, -0.0f, 0.119f, 0.441f, 0.441f, -0.865f, -0.0f, 0.127f, 0.441f, 0.441f, -0.871f, -0.0f, 0.134f, 0.441f, 0.441f, -0.877f, -0.0f, 0.141f, 0.441f, 0.441f, + -0.883f, -0.0f, 0.149f, 0.441f, 0.442f, -0.889f, -0.0f, 0.156f, 0.441f, 0.441f, -0.896f, -0.0f, 0.163f, 0.441f, 0.442f, -0.904f, -0.0f, 0.169f, 0.442f, 0.441f, + -0.913f, -0.0f, 0.176f, 0.442f, 0.441f, -0.925f, -0.0f, 0.183f, 0.443f, 0.441f, -0.941f, -0.0f, 0.19f, 0.444f, 0.442f, -0.956f, -0.0f, 0.195f, 0.446f, 0.443f, + -0.971f, -0.0f, 0.198f, 0.448f, 0.443f, -0.983f, -0.0f, 0.198f, 0.451f, 0.452f, -0.992f, -0.0f, 0.198f, 0.454f, 0.456f, -1.001f, 0.0f, 0.196f, 0.457f, 0.457f, +}; + +static const float data18[59 * GP_PRIM_DATABUF_SIZE] = { + 0.782f, 0.0f, 0.099f, 0.04f, 0.04f, 0.779f, 0.0f, 0.088f, 0.108f, 0.34f, 0.777f, 0.0f, 0.08f, 0.149f, 0.35f, 0.774f, 0.0f, 0.071f, 0.194f, 0.352f, + 0.772f, 0.0f, 0.062f, 0.231f, 0.352f, 0.771f, 0.0f, 0.053f, 0.263f, 0.353f, 0.769f, 0.0f, 0.044f, 0.289f, 0.353f, 0.768f, 0.0f, 0.036f, 0.31f, 0.353f, + 0.767f, 0.0f, 0.029f, 0.327f, 0.353f, 0.767f, 0.0f, 0.023f, 0.341f, 0.353f, 0.767f, 0.0f, 0.017f, 0.353f, 0.353f, 0.768f, 0.0f, 0.013f, 0.363f, 0.353f, + 0.769f, 0.0f, 0.01f, 0.373f, 0.353f, 0.771f, 0.0f, 0.009f, 0.382f, 0.351f, 0.773f, 0.0f, 0.008f, 0.39f, 0.393f, 0.776f, 0.0f, 0.009f, 0.399f, 0.41f, + 0.779f, 0.0f, 0.011f, 0.407f, 0.425f, 0.783f, 0.0f, 0.015f, 0.415f, 0.434f, 0.787f, 0.0f, 0.019f, 0.423f, 0.44f, 0.792f, 0.0f, 0.024f, 0.429f, 0.441f, + 0.797f, 0.0f, 0.03f, 0.435f, 0.444f, 0.802f, 0.0f, 0.037f, 0.441f, 0.447f, 0.807f, 0.0f, 0.044f, 0.445f, 0.453f, 0.813f, 0.0f, 0.051f, 0.449f, 0.457f, + 0.819f, 0.0f, 0.058f, 0.452f, 0.458f, 0.825f, 0.0f, 0.066f, 0.455f, 0.46f, 0.831f, 0.0f, 0.074f, 0.457f, 0.462f, 0.838f, 0.0f, 0.082f, 0.459f, 0.462f, + 0.845f, 0.0f, 0.09f, 0.461f, 0.462f, 0.852f, 0.0f, 0.098f, 0.462f, 0.463f, 0.859f, 0.0f, 0.106f, 0.463f, 0.464f, 0.867f, 0.0f, 0.113f, 0.464f, 0.464f, + 0.874f, 0.0f, 0.121f, 0.465f, 0.465f, 0.882f, 0.0f, 0.129f, 0.465f, 0.465f, 0.889f, 0.0f, 0.136f, 0.466f, 0.466f, 0.897f, 0.0f, 0.143f, 0.466f, 0.467f, + 0.904f, 0.0f, 0.15f, 0.467f, 0.466f, 0.911f, 0.0f, 0.157f, 0.467f, 0.467f, 0.916f, 0.0f, 0.163f, 0.468f, 0.468f, 0.921f, 0.0f, 0.169f, 0.468f, 0.469f, + 0.924f, 0.0f, 0.173f, 0.468f, 0.469f, 0.926f, 0.0f, 0.177f, 0.469f, 0.468f, 0.925f, 0.0f, 0.18f, 0.469f, 0.468f, 0.922f, 0.0f, 0.181f, 0.469f, 0.469f, + 0.918f, 0.0f, 0.181f, 0.469f, 0.469f, 0.912f, 0.0f, 0.18f, 0.469f, 0.469f, 0.905f, 0.0f, 0.178f, 0.468f, 0.47f, 0.898f, 0.0f, 0.175f, 0.466f, 0.471f, + 0.89f, 0.0f, 0.172f, 0.462f, 0.469f, 0.882f, 0.0f, 0.168f, 0.454f, 0.468f, 0.874f, 0.0f, 0.164f, 0.442f, 0.467f, 0.866f, 0.0f, 0.159f, 0.423f, 0.467f, + 0.858f, 0.0f, 0.154f, 0.398f, 0.468f, 0.851f, 0.0f, 0.149f, 0.366f, 0.468f, 0.844f, 0.0f, 0.144f, 0.326f, 0.469f, 0.837f, 0.0f, 0.139f, 0.282f, 0.469f, + 0.83f, 0.0f, 0.134f, 0.231f, 0.467f, 0.824f, 0.0f, 0.13f, 0.184f, 0.415f, 0.816f, 0.0f, 0.124f, 0.111f, 0.111f, +}; + +static const float data19[100 * GP_PRIM_DATABUF_SIZE] = { + -0.279f, 0.0f, 0.568f, 0.154f, 0.154f, -0.266f, 0.0f, 0.569f, 0.249f, 0.318f, -0.258f, 0.0f, 0.57f, 0.296f, 0.357f, -0.248f, 0.0f, 0.571f, 0.337f, 0.383f, + -0.238f, 0.0f, 0.571f, 0.363f, 0.396f, -0.229f, 0.0f, 0.571f, 0.381f, 0.403f, -0.219f, 0.0f, 0.57f, 0.392f, 0.407f, -0.209f, 0.0f, 0.568f, 0.399f, 0.407f, + -0.2f, 0.0f, 0.566f, 0.403f, 0.408f, -0.19f, 0.0f, 0.563f, 0.406f, 0.41f, -0.181f, 0.0f, 0.559f, 0.407f, 0.41f, -0.171f, 0.0f, 0.555f, 0.409f, 0.41f, + -0.161f, 0.0f, 0.551f, 0.409f, 0.411f, -0.152f, 0.0f, 0.546f, 0.41f, 0.411f, -0.142f, 0.0f, 0.542f, 0.41f, 0.412f, -0.132f, 0.0f, 0.537f, 0.411f, 0.411f, + -0.122f, 0.0f, 0.533f, 0.411f, 0.411f, -0.112f, 0.0f, 0.528f, 0.411f, 0.412f, -0.102f, 0.0f, 0.524f, 0.411f, 0.412f, -0.092f, 0.0f, 0.519f, 0.41f, 0.412f, + -0.081f, 0.0f, 0.515f, 0.407f, 0.411f, -0.071f, 0.0f, 0.511f, 0.403f, 0.408f, -0.061f, 0.0f, 0.507f, 0.399f, 0.401f, -0.051f, 0.0f, 0.503f, 0.394f, 0.395f, + -0.041f, 0.0f, 0.499f, 0.39f, 0.388f, -0.031f, 0.0f, 0.495f, 0.386f, 0.383f, -0.021f, 0.0f, 0.491f, 0.383f, 0.38f, -0.011f, 0.0f, 0.488f, 0.381f, 0.378f, + -0.001f, 0.0f, 0.486f, 0.379f, 0.377f, 0.009f, 0.0f, 0.484f, 0.378f, 0.377f, 0.019f, 0.0f, 0.483f, 0.377f, 0.375f, 0.03f, 0.0f, 0.482f, 0.377f, 0.375f, + 0.041f, 0.0f, 0.482f, 0.378f, 0.376f, 0.051f, 0.0f, 0.483f, 0.379f, 0.376f, 0.062f, 0.0f, 0.484f, 0.381f, 0.376f, 0.073f, 0.0f, 0.486f, 0.385f, 0.379f, + 0.085f, 0.0f, 0.488f, 0.389f, 0.382f, 0.096f, 0.0f, 0.491f, 0.395f, 0.392f, 0.108f, 0.0f, 0.494f, 0.402f, 0.4f, 0.12f, 0.0f, 0.497f, 0.409f, 0.409f, + 0.132f, 0.0f, 0.501f, 0.415f, 0.416f, 0.144f, 0.0f, 0.505f, 0.421f, 0.427f, 0.157f, 0.0f, 0.509f, 0.425f, 0.43f, 0.17f, 0.0f, 0.513f, 0.429f, 0.433f, + 0.181f, 0.0f, 0.517f, 0.431f, 0.433f, 0.192f, 0.0f, 0.52f, 0.433f, 0.434f, 0.201f, 0.0f, 0.522f, 0.433f, 0.435f, 0.208f, 0.0f, 0.524f, 0.433f, 0.435f, + 0.213f, 0.0f, 0.524f, 0.432f, 0.436f, 0.216f, 0.0f, 0.523f, 0.431f, 0.435f, 0.217f, 0.0f, 0.521f, 0.43f, 0.426f, 0.215f, 0.0f, 0.518f, 0.429f, 0.427f, + 0.213f, 0.0f, 0.515f, 0.428f, 0.427f, 0.208f, 0.0f, 0.511f, 0.428f, 0.427f, 0.203f, 0.0f, 0.506f, 0.428f, 0.427f, 0.196f, 0.0f, 0.502f, 0.428f, 0.427f, + 0.189f, 0.0f, 0.497f, 0.428f, 0.427f, 0.181f, 0.0f, 0.492f, 0.428f, 0.427f, 0.173f, 0.0f, 0.487f, 0.428f, 0.428f, 0.163f, 0.0f, 0.482f, 0.429f, 0.428f, + 0.154f, 0.0f, 0.477f, 0.429f, 0.429f, 0.145f, 0.0f, 0.472f, 0.43f, 0.43f, 0.135f, 0.0f, 0.467f, 0.431f, 0.431f, 0.125f, 0.0f, 0.462f, 0.432f, 0.43f, + 0.116f, 0.0f, 0.457f, 0.433f, 0.431f, 0.106f, 0.0f, 0.453f, 0.435f, 0.434f, 0.096f, 0.0f, 0.448f, 0.436f, 0.436f, 0.086f, 0.0f, 0.444f, 0.437f, 0.438f, + 0.076f, 0.0f, 0.44f, 0.438f, 0.44f, 0.065f, 0.0f, 0.436f, 0.439f, 0.441f, 0.055f, 0.0f, 0.433f, 0.44f, 0.441f, 0.044f, 0.0f, 0.431f, 0.441f, 0.442f, + 0.033f, 0.0f, 0.429f, 0.441f, 0.442f, 0.022f, 0.0f, 0.427f, 0.441f, 0.442f, 0.011f, 0.0f, 0.426f, 0.442f, 0.443f, -0.0f, 0.0f, 0.426f, 0.442f, 0.442f, + -0.011f, 0.0f, 0.426f, 0.442f, 0.442f, -0.022f, 0.0f, 0.427f, 0.442f, 0.442f, -0.033f, 0.0f, 0.429f, 0.442f, 0.442f, -0.042f, 0.0f, 0.432f, 0.441f, 0.442f, + -0.052f, 0.0f, 0.435f, 0.441f, 0.441f, -0.061f, 0.0f, 0.439f, 0.441f, 0.441f, -0.07f, 0.0f, 0.443f, 0.441f, 0.441f, -0.078f, 0.0f, 0.448f, 0.441f, 0.441f, + -0.087f, 0.0f, 0.453f, 0.441f, 0.442f, -0.095f, 0.0f, 0.458f, 0.441f, 0.441f, -0.104f, 0.0f, 0.463f, 0.44f, 0.44f, -0.113f, 0.0f, 0.468f, 0.44f, 0.44f, + -0.122f, 0.0f, 0.473f, 0.44f, 0.44f, -0.132f, 0.0f, 0.479f, 0.44f, 0.44f, -0.143f, 0.0f, 0.485f, 0.44f, 0.44f, -0.154f, 0.0f, 0.491f, 0.44f, 0.44f, + -0.165f, 0.0f, 0.498f, 0.44f, 0.44f, -0.176f, 0.0f, 0.504f, 0.439f, 0.439f, -0.187f, 0.0f, 0.51f, 0.435f, 0.44f, -0.198f, 0.0f, 0.516f, 0.424f, 0.44f, + -0.209f, 0.0f, 0.522f, 0.393f, 0.44f, -0.219f, 0.0f, 0.527f, 0.324f, 0.44f, -0.228f, 0.0f, 0.532f, 0.222f, 0.404f, -0.241f, 0.0f, 0.538f, 0.037f, 0.037f, +}; + +static const float data20[136 * GP_PRIM_DATABUF_SIZE] = { + 0.331f, 0.0f, -0.036f, 0.065f, 0.065f, 0.322f, 0.0f, -0.034f, 0.239f, 0.293f, 0.317f, 0.0f, -0.032f, 0.316f, 0.339f, 0.31f, 0.0f, -0.029f, 0.348f, 0.355f, + 0.302f, 0.0f, -0.027f, 0.364f, 0.368f, 0.295f, 0.0f, -0.023f, 0.373f, 0.374f, 0.287f, 0.0f, -0.02f, 0.381f, 0.381f, 0.279f, 0.0f, -0.015f, 0.388f, 0.391f, + 0.271f, 0.0f, -0.01f, 0.392f, 0.394f, 0.263f, 0.0f, -0.004f, 0.395f, 0.396f, 0.255f, 0.0f, 0.002f, 0.397f, 0.397f, 0.247f, 0.0f, 0.008f, 0.399f, 0.4f, + 0.239f, 0.0f, 0.016f, 0.401f, 0.401f, 0.232f, -0.0f, 0.024f, 0.404f, 0.404f, 0.226f, 0.0f, 0.031f, 0.406f, 0.407f, 0.221f, 0.0f, 0.038f, 0.409f, 0.409f, + 0.215f, 0.0f, 0.045f, 0.412f, 0.412f, 0.21f, 0.0f, 0.054f, 0.415f, 0.415f, 0.205f, 0.0f, 0.063f, 0.417f, 0.417f, 0.201f, 0.0f, 0.073f, 0.42f, 0.421f, + 0.197f, 0.0f, 0.083f, 0.421f, 0.421f, 0.193f, -0.0f, 0.094f, 0.423f, 0.423f, 0.19f, -0.0f, 0.104f, 0.424f, 0.424f, 0.187f, -0.0f, 0.114f, 0.424f, 0.425f, + 0.185f, -0.0f, 0.125f, 0.425f, 0.425f, 0.183f, -0.0f, 0.135f, 0.425f, 0.425f, 0.182f, -0.0f, 0.146f, 0.426f, 0.425f, 0.181f, -0.0f, 0.157f, 0.426f, 0.425f, + 0.18f, -0.0f, 0.168f, 0.426f, 0.426f, 0.18f, -0.0f, 0.179f, 0.427f, 0.427f, 0.181f, -0.0f, 0.189f, 0.427f, 0.427f, 0.182f, -0.0f, 0.199f, 0.427f, 0.427f, + 0.183f, -0.0f, 0.208f, 0.427f, 0.428f, 0.185f, -0.0f, 0.218f, 0.428f, 0.427f, 0.187f, -0.0f, 0.226f, 0.428f, 0.427f, 0.19f, -0.0f, 0.235f, 0.429f, 0.427f, + 0.192f, -0.0f, 0.243f, 0.43f, 0.428f, 0.196f, -0.0f, 0.252f, 0.431f, 0.431f, 0.199f, -0.0f, 0.26f, 0.431f, 0.432f, 0.203f, -0.0f, 0.268f, 0.432f, 0.433f, + 0.207f, -0.0f, 0.276f, 0.433f, 0.433f, 0.212f, -0.0f, 0.283f, 0.434f, 0.434f, 0.216f, -0.0f, 0.291f, 0.434f, 0.435f, 0.221f, -0.0f, 0.298f, 0.435f, 0.436f, + 0.227f, -0.0f, 0.305f, 0.435f, 0.435f, 0.232f, -0.0f, 0.311f, 0.436f, 0.436f, 0.238f, -0.0f, 0.317f, 0.436f, 0.436f, 0.243f, -0.0f, 0.323f, 0.436f, 0.436f, + 0.249f, -0.0f, 0.329f, 0.437f, 0.436f, 0.255f, -0.0f, 0.334f, 0.438f, 0.437f, 0.262f, -0.0f, 0.339f, 0.44f, 0.437f, 0.268f, -0.0f, 0.344f, 0.442f, 0.441f, + 0.274f, 0.0f, 0.348f, 0.444f, 0.446f, 0.281f, 0.0f, 0.352f, 0.445f, 0.447f, 0.287f, 0.0f, 0.355f, 0.446f, 0.447f, 0.293f, 0.0f, 0.358f, 0.446f, 0.447f, + 0.299f, 0.0f, 0.361f, 0.447f, 0.447f, 0.306f, 0.0f, 0.363f, 0.447f, 0.448f, 0.312f, 0.0f, 0.366f, 0.447f, 0.448f, 0.318f, 0.0f, 0.368f, 0.448f, 0.448f, + 0.325f, 0.0f, 0.369f, 0.448f, 0.448f, 0.331f, 0.0f, 0.371f, 0.448f, 0.448f, 0.338f, 0.0f, 0.372f, 0.448f, 0.448f, 0.345f, 0.0f, 0.372f, 0.448f, 0.448f, + 0.352f, 0.0f, 0.372f, 0.448f, 0.448f, 0.359f, 0.0f, 0.372f, 0.448f, 0.449f, 0.366f, 0.0f, 0.371f, 0.448f, 0.448f, 0.373f, 0.0f, 0.37f, 0.448f, 0.449f, + 0.38f, 0.0f, 0.369f, 0.449f, 0.449f, 0.387f, 0.0f, 0.367f, 0.449f, 0.449f, 0.393f, 0.0f, 0.365f, 0.449f, 0.449f, 0.4f, 0.0f, 0.363f, 0.449f, 0.45f, + 0.406f, 0.0f, 0.36f, 0.45f, 0.45f, 0.412f, -0.0f, 0.357f, 0.45f, 0.45f, 0.418f, -0.0f, 0.354f, 0.45f, 0.451f, 0.424f, -0.0f, 0.351f, 0.45f, 0.451f, + 0.43f, -0.0f, 0.347f, 0.45f, 0.451f, 0.436f, -0.0f, 0.343f, 0.45f, 0.451f, 0.443f, -0.0f, 0.339f, 0.45f, 0.45f, 0.449f, -0.0f, 0.334f, 0.45f, 0.451f, + 0.455f, -0.0f, 0.329f, 0.451f, 0.451f, 0.46f, -0.0f, 0.323f, 0.451f, 0.451f, 0.466f, -0.0f, 0.318f, 0.451f, 0.451f, 0.472f, -0.0f, 0.311f, 0.452f, 0.452f, + 0.477f, -0.0f, 0.305f, 0.452f, 0.453f, 0.482f, -0.0f, 0.298f, 0.452f, 0.453f, 0.487f, -0.0f, 0.291f, 0.453f, 0.453f, 0.492f, -0.0f, 0.284f, 0.453f, 0.453f, + 0.496f, -0.0f, 0.277f, 0.453f, 0.453f, 0.5f, -0.0f, 0.269f, 0.453f, 0.454f, 0.504f, -0.0f, 0.261f, 0.453f, 0.454f, 0.508f, -0.0f, 0.252f, 0.454f, 0.454f, + 0.511f, -0.0f, 0.244f, 0.454f, 0.454f, 0.514f, -0.0f, 0.235f, 0.454f, 0.455f, 0.517f, -0.0f, 0.225f, 0.454f, 0.455f, 0.519f, -0.0f, 0.216f, 0.454f, 0.455f, + 0.521f, -0.0f, 0.205f, 0.455f, 0.455f, 0.523f, -0.0f, 0.194f, 0.455f, 0.455f, 0.524f, -0.0f, 0.182f, 0.455f, 0.455f, 0.524f, -0.0f, 0.169f, 0.455f, 0.456f, + 0.524f, -0.0f, 0.157f, 0.455f, 0.456f, 0.523f, -0.0f, 0.145f, 0.455f, 0.456f, 0.522f, -0.0f, 0.133f, 0.455f, 0.456f, 0.52f, -0.0f, 0.122f, 0.456f, 0.456f, + 0.518f, -0.0f, 0.11f, 0.456f, 0.456f, 0.515f, -0.0f, 0.1f, 0.456f, 0.456f, 0.513f, -0.0f, 0.09f, 0.456f, 0.457f, 0.509f, -0.0f, 0.081f, 0.456f, 0.457f, + 0.506f, -0.0f, 0.072f, 0.457f, 0.457f, 0.502f, -0.0f, 0.064f, 0.457f, 0.457f, 0.498f, -0.0f, 0.056f, 0.457f, 0.457f, 0.494f, -0.0f, 0.049f, 0.457f, 0.457f, + 0.49f, -0.0f, 0.041f, 0.458f, 0.457f, 0.485f, -0.0f, 0.034f, 0.458f, 0.457f, 0.48f, -0.0f, 0.028f, 0.458f, 0.458f, 0.475f, -0.0f, 0.022f, 0.458f, 0.458f, + 0.47f, -0.0f, 0.016f, 0.458f, 0.458f, 0.465f, -0.0f, 0.011f, 0.459f, 0.458f, 0.46f, -0.0f, 0.006f, 0.459f, 0.458f, 0.454f, -0.0f, 0.001f, 0.46f, 0.459f, + 0.449f, 0.0f, -0.003f, 0.464f, 0.463f, 0.443f, 0.0f, -0.007f, 0.467f, 0.468f, 0.438f, 0.0f, -0.011f, 0.469f, 0.469f, 0.432f, 0.0f, -0.015f, 0.471f, 0.47f, + 0.426f, 0.0f, -0.018f, 0.477f, 0.478f, 0.42f, 0.0f, -0.021f, 0.478f, 0.478f, 0.414f, 0.0f, -0.024f, 0.478f, 0.478f, 0.408f, 0.0f, -0.027f, 0.479f, 0.479f, + 0.402f, 0.0f, -0.029f, 0.48f, 0.48f, 0.395f, 0.0f, -0.031f, 0.48f, 0.48f, 0.389f, 0.0f, -0.033f, 0.482f, 0.482f, 0.382f, 0.0f, -0.035f, 0.482f, 0.482f, + 0.376f, 0.0f, -0.036f, 0.482f, 0.482f, 0.369f, 0.0f, -0.037f, 0.48f, 0.482f, 0.364f, 0.0f, -0.037f, 0.457f, 0.485f, 0.356f, 0.0f, -0.038f, 0.32f, 0.32f, +}; + +static const float data21[353 * GP_PRIM_DATABUF_SIZE] = { + -0.382f, 0.0f, 0.397f, 0.0f, 1.0f, -0.386f, 0.0f, 0.394f, 0.0f, 1.0f, -0.389f, 0.0f, 0.392f, 0.0f, 1.0f, -0.392f, 0.0f, 0.39f, 0.0f, 1.0f, + -0.395f, 0.0f, 0.388f, 0.0f, 1.0f, -0.399f, 0.0f, 0.385f, 0.0f, 1.0f, -0.402f, 0.0f, 0.383f, 0.0f, 1.0f, -0.405f, 0.0f, 0.381f, 0.0f, 1.0f, + -0.408f, 0.0f, 0.379f, 0.0f, 1.0f, -0.411f, 0.0f, 0.377f, 0.0f, 1.0f, -0.414f, 0.0f, 0.375f, 0.0f, 1.0f, -0.417f, 0.0f, 0.372f, 0.0f, 1.0f, + -0.42f, 0.0f, 0.37f, 0.0f, 1.0f, -0.423f, 0.0f, 0.368f, 0.0f, 1.0f, -0.425f, 0.0f, 0.366f, 0.0f, 1.0f, -0.428f, 0.0f, 0.364f, 0.0f, 1.0f, + -0.431f, 0.0f, 0.362f, 0.0f, 1.0f, -0.433f, 0.0f, 0.359f, 0.0f, 1.0f, -0.436f, 0.0f, 0.357f, 0.0f, 1.0f, -0.438f, 0.0f, 0.355f, 0.0f, 1.0f, + -0.441f, 0.0f, 0.353f, 0.0f, 1.0f, -0.443f, 0.0f, 0.351f, 0.0f, 1.0f, -0.445f, 0.0f, 0.349f, 0.0f, 1.0f, -0.447f, 0.0f, 0.346f, 0.0f, 1.0f, + -0.45f, 0.0f, 0.344f, 0.0f, 1.0f, -0.452f, 0.0f, 0.342f, 0.0f, 1.0f, -0.454f, 0.0f, 0.34f, 0.0f, 1.0f, -0.456f, 0.0f, 0.337f, 0.0f, 1.0f, + -0.458f, 0.0f, 0.335f, 0.0f, 1.0f, -0.46f, 0.0f, 0.333f, 0.0f, 1.0f, -0.462f, 0.0f, 0.33f, 0.0f, 1.0f, -0.464f, 0.0f, 0.328f, 0.0f, 1.0f, + -0.466f, 0.0f, 0.326f, 0.0f, 1.0f, -0.468f, 0.0f, 0.323f, 0.0f, 1.0f, -0.47f, 0.0f, 0.321f, 0.0f, 1.0f, -0.472f, 0.0f, 0.319f, 0.0f, 1.0f, + -0.474f, 0.0f, 0.316f, 0.0f, 1.0f, -0.475f, 0.0f, 0.314f, 0.0f, 1.0f, -0.477f, 0.0f, 0.311f, 0.0f, 1.0f, -0.479f, 0.0f, 0.309f, 0.0f, 1.0f, + -0.481f, 0.0f, 0.307f, 0.0f, 1.0f, -0.482f, 0.0f, 0.304f, 0.0f, 1.0f, -0.484f, 0.0f, 0.302f, 0.0f, 1.0f, -0.486f, 0.0f, 0.299f, 0.0f, 1.0f, + -0.487f, 0.0f, 0.297f, 0.0f, 1.0f, -0.489f, 0.0f, 0.294f, 0.0f, 1.0f, -0.49f, 0.0f, 0.292f, 0.0f, 1.0f, -0.492f, 0.0f, 0.289f, 0.0f, 1.0f, + -0.494f, 0.0f, 0.286f, 0.0f, 1.0f, -0.495f, 0.0f, 0.284f, 0.0f, 1.0f, -0.497f, 0.0f, 0.281f, 0.0f, 1.0f, -0.498f, 0.0f, 0.279f, 0.001f, 1.0f, + -0.499f, 0.0f, 0.276f, 0.001f, 1.0f, -0.501f, 0.0f, 0.273f, 0.002f, 1.0f, -0.502f, 0.0f, 0.271f, 0.003f, 1.0f, -0.504f, 0.0f, 0.268f, 0.005f, 1.0f, + -0.505f, 0.0f, 0.265f, 0.008f, 1.0f, -0.506f, 0.0f, 0.262f, 0.011f, 1.0f, -0.508f, 0.0f, 0.259f, 0.016f, 1.0f, -0.509f, 0.0f, 0.256f, 0.021f, 1.0f, + -0.51f, 0.0f, 0.254f, 0.027f, 1.0f, -0.512f, 0.0f, 0.251f, 0.035f, 1.0f, -0.513f, 0.0f, 0.248f, 0.043f, 1.0f, -0.514f, 0.0f, 0.245f, 0.053f, 1.0f, + -0.515f, 0.0f, 0.242f, 0.064f, 1.0f, -0.516f, 0.0f, 0.239f, 0.076f, 1.0f, -0.517f, 0.0f, 0.235f, 0.09f, 1.0f, -0.519f, 0.0f, 0.232f, 0.105f, 1.0f, + -0.52f, 0.0f, 0.229f, 0.122f, 1.0f, -0.521f, 0.0f, 0.226f, 0.14f, 1.0f, -0.521f, 0.0f, 0.222f, 0.159f, 1.0f, -0.522f, 0.0f, 0.219f, 0.179f, 1.0f, + -0.523f, 0.0f, 0.216f, 0.2f, 1.0f, -0.524f, 0.0f, 0.212f, 0.221f, 1.0f, -0.525f, 0.0f, 0.209f, 0.243f, 1.0f, -0.526f, 0.0f, 0.205f, 0.265f, 1.0f, + -0.526f, 0.0f, 0.202f, 0.286f, 1.0f, -0.527f, 0.0f, 0.198f, 0.306f, 1.0f, -0.527f, 0.0f, 0.195f, 0.326f, 1.0f, -0.528f, 0.0f, 0.191f, 0.345f, 1.0f, + -0.528f, 0.0f, 0.187f, 0.363f, 1.0f, -0.529f, 0.0f, 0.184f, 0.38f, 1.0f, -0.529f, 0.0f, 0.18f, 0.395f, 1.0f, -0.529f, 0.0f, 0.176f, 0.41f, 1.0f, + -0.53f, 0.0f, 0.173f, 0.424f, 1.0f, -0.53f, 0.0f, 0.169f, 0.438f, 1.0f, -0.53f, 0.0f, 0.165f, 0.452f, 1.0f, -0.53f, 0.0f, 0.161f, 0.465f, 1.0f, + -0.53f, 0.0f, 0.157f, 0.478f, 1.0f, -0.53f, 0.0f, 0.154f, 0.492f, 1.0f, -0.53f, 0.0f, 0.15f, 0.505f, 1.0f, -0.53f, 0.0f, 0.146f, 0.517f, 1.0f, + -0.53f, 0.0f, 0.142f, 0.53f, 1.0f, -0.529f, 0.0f, 0.138f, 0.542f, 1.0f, -0.529f, 0.0f, 0.134f, 0.553f, 1.0f, -0.528f, 0.0f, 0.13f, 0.564f, 1.0f, + -0.528f, 0.0f, 0.127f, 0.574f, 1.0f, -0.527f, 0.0f, 0.123f, 0.583f, 1.0f, -0.527f, 0.0f, 0.119f, 0.592f, 1.0f, -0.526f, 0.0f, 0.115f, 0.6f, 1.0f, + -0.526f, 0.0f, 0.111f, 0.608f, 1.0f, -0.525f, 0.0f, 0.108f, 0.615f, 1.0f, -0.524f, 0.0f, 0.104f, 0.622f, 1.0f, -0.523f, 0.0f, 0.1f, 0.628f, 1.0f, + -0.522f, 0.0f, 0.097f, 0.635f, 1.0f, -0.521f, 0.0f, 0.093f, 0.641f, 1.0f, -0.52f, 0.0f, 0.089f, 0.647f, 1.0f, -0.519f, 0.0f, 0.086f, 0.653f, 1.0f, + -0.518f, 0.0f, 0.082f, 0.659f, 1.0f, -0.517f, 0.0f, 0.079f, 0.664f, 1.0f, -0.515f, 0.0f, 0.075f, 0.67f, 1.0f, -0.514f, 0.0f, 0.072f, 0.675f, 1.0f, + -0.513f, 0.0f, 0.069f, 0.68f, 1.0f, -0.511f, 0.0f, 0.065f, 0.685f, 1.0f, -0.51f, 0.0f, 0.062f, 0.69f, 1.0f, -0.509f, 0.0f, 0.059f, 0.695f, 1.0f, + -0.507f, 0.0f, 0.056f, 0.7f, 1.0f, -0.505f, 0.0f, 0.053f, 0.704f, 1.0f, -0.504f, 0.0f, 0.049f, 0.709f, 1.0f, -0.502f, 0.0f, 0.046f, 0.714f, 1.0f, + -0.5f, 0.0f, 0.043f, 0.719f, 1.0f, -0.499f, 0.0f, 0.04f, 0.724f, 1.0f, -0.497f, 0.0f, 0.038f, 0.73f, 1.0f, -0.495f, 0.0f, 0.035f, 0.735f, 1.0f, + -0.493f, 0.0f, 0.032f, 0.741f, 1.0f, -0.491f, 0.0f, 0.029f, 0.748f, 1.0f, -0.489f, 0.0f, 0.026f, 0.754f, 1.0f, -0.488f, -0.0f, 0.024f, 0.76f, 1.0f, + -0.486f, -0.0f, 0.022f, 0.767f, 1.0f, -0.485f, -0.0f, 0.019f, 0.773f, 1.0f, -0.483f, -0.0f, 0.017f, 0.779f, 1.0f, -0.482f, -0.0f, 0.015f, 0.785f, 1.0f, + -0.48f, -0.0f, 0.013f, 0.79f, 1.0f, -0.478f, -0.0f, 0.01f, 0.795f, 1.0f, -0.476f, -0.0f, 0.008f, 0.8f, 1.0f, -0.474f, -0.0f, 0.006f, 0.804f, 1.0f, + -0.472f, -0.0f, 0.004f, 0.808f, 1.0f, -0.47f, -0.0f, 0.002f, 0.811f, 1.0f, -0.468f, -0.0f, -0.0f, 0.814f, 1.0f, -0.466f, -0.0f, -0.002f, 0.816f, 1.0f, + -0.464f, -0.0f, -0.004f, 0.818f, 1.0f, -0.461f, -0.0f, -0.006f, 0.82f, 1.0f, -0.459f, -0.0f, -0.008f, 0.822f, 1.0f, -0.456f, -0.0f, -0.01f, 0.823f, 1.0f, + -0.454f, -0.0f, -0.012f, 0.825f, 1.0f, -0.451f, -0.0f, -0.014f, 0.826f, 1.0f, -0.448f, -0.0f, -0.016f, 0.827f, 1.0f, -0.445f, -0.0f, -0.018f, 0.828f, 1.0f, + -0.442f, -0.0f, -0.02f, 0.829f, 1.0f, -0.439f, -0.0f, -0.022f, 0.829f, 1.0f, -0.436f, -0.0f, -0.024f, 0.83f, 1.0f, -0.433f, -0.0f, -0.026f, 0.83f, 1.0f, + -0.43f, -0.0f, -0.027f, 0.83f, 1.0f, -0.426f, -0.0f, -0.029f, 0.83f, 1.0f, -0.423f, 0.0f, -0.031f, 0.83f, 1.0f, -0.42f, 0.0f, -0.032f, 0.83f, 1.0f, + -0.417f, 0.0f, -0.033f, 0.831f, 1.0f, -0.414f, 0.0f, -0.034f, 0.831f, 1.0f, -0.411f, 0.0f, -0.035f, 0.831f, 1.0f, -0.408f, 0.0f, -0.037f, 0.831f, 1.0f, + -0.405f, 0.0f, -0.038f, 0.831f, 1.0f, -0.402f, 0.0f, -0.039f, 0.831f, 1.0f, -0.399f, 0.0f, -0.039f, 0.831f, 1.0f, -0.396f, 0.0f, -0.04f, 0.832f, 1.0f, + -0.393f, 0.0f, -0.041f, 0.832f, 1.0f, -0.389f, 0.0f, -0.042f, 0.832f, 1.0f, -0.386f, 0.0f, -0.043f, 0.832f, 1.0f, -0.383f, 0.0f, -0.044f, 0.832f, 1.0f, + -0.379f, 0.0f, -0.044f, 0.832f, 1.0f, -0.376f, 0.0f, -0.045f, 0.832f, 1.0f, -0.372f, 0.0f, -0.045f, 0.832f, 1.0f, -0.369f, 0.0f, -0.046f, 0.832f, 1.0f, + -0.366f, 0.0f, -0.047f, 0.832f, 1.0f, -0.362f, 0.0f, -0.047f, 0.832f, 1.0f, -0.359f, 0.0f, -0.047f, 0.831f, 1.0f, -0.355f, 0.0f, -0.048f, 0.831f, 1.0f, + -0.352f, 0.0f, -0.048f, 0.83f, 1.0f, -0.348f, 0.0f, -0.048f, 0.83f, 1.0f, -0.345f, 0.0f, -0.049f, 0.829f, 1.0f, -0.341f, 0.0f, -0.049f, 0.828f, 1.0f, + -0.338f, 0.0f, -0.049f, 0.827f, 1.0f, -0.334f, 0.0f, -0.049f, 0.826f, 1.0f, -0.331f, 0.0f, -0.049f, 0.823f, 1.0f, -0.327f, 0.0f, -0.049f, 0.82f, 1.0f, + -0.323f, 0.0f, -0.048f, 0.816f, 1.0f, -0.32f, 0.0f, -0.048f, 0.811f, 1.0f, -0.316f, 0.0f, -0.048f, 0.804f, 1.0f, -0.313f, 0.0f, -0.048f, 0.797f, 1.0f, + -0.309f, 0.0f, -0.047f, 0.79f, 1.0f, -0.306f, 0.0f, -0.047f, 0.782f, 1.0f, -0.302f, 0.0f, -0.046f, 0.774f, 1.0f, -0.299f, 0.0f, -0.045f, 0.767f, 1.0f, + -0.295f, 0.0f, -0.044f, 0.76f, 1.0f, -0.292f, 0.0f, -0.044f, 0.753f, 1.0f, -0.288f, 0.0f, -0.043f, 0.748f, 1.0f, -0.285f, 0.0f, -0.042f, 0.742f, 1.0f, + -0.282f, 0.0f, -0.041f, 0.738f, 1.0f, -0.278f, 0.0f, -0.04f, 0.734f, 1.0f, -0.275f, 0.0f, -0.039f, 0.73f, 1.0f, -0.272f, 0.0f, -0.037f, 0.726f, 1.0f, + -0.269f, 0.0f, -0.036f, 0.723f, 1.0f, -0.266f, 0.0f, -0.035f, 0.72f, 1.0f, -0.263f, 0.0f, -0.034f, 0.717f, 1.0f, -0.26f, 0.0f, -0.032f, 0.713f, 1.0f, + -0.257f, 0.0f, -0.031f, 0.71f, 1.0f, -0.255f, 0.0f, -0.029f, 0.706f, 1.0f, -0.252f, 0.0f, -0.028f, 0.702f, 1.0f, -0.249f, 0.0f, -0.026f, 0.698f, 1.0f, + -0.247f, 0.0f, -0.025f, 0.693f, 1.0f, -0.244f, 0.0f, -0.023f, 0.688f, 1.0f, -0.242f, 0.0f, -0.021f, 0.684f, 1.0f, -0.239f, 0.0f, -0.02f, 0.679f, 1.0f, + -0.237f, 0.0f, -0.018f, 0.675f, 1.0f, -0.234f, 0.0f, -0.016f, 0.671f, 1.0f, -0.232f, 0.0f, -0.014f, 0.667f, 1.0f, -0.23f, 0.0f, -0.013f, 0.663f, 1.0f, + -0.228f, 0.0f, -0.011f, 0.66f, 1.0f, -0.225f, 0.0f, -0.009f, 0.657f, 1.0f, -0.223f, 0.0f, -0.007f, 0.654f, 1.0f, -0.221f, 0.0f, -0.005f, 0.651f, 1.0f, + -0.219f, 0.0f, -0.003f, 0.649f, 1.0f, -0.217f, 0.0f, -0.001f, 0.645f, 1.0f, -0.215f, 0.0f, 0.002f, 0.642f, 1.0f, -0.213f, 0.0f, 0.004f, 0.639f, 1.0f, + -0.211f, 0.0f, 0.006f, 0.635f, 1.0f, -0.209f, 0.0f, 0.008f, 0.631f, 1.0f, -0.207f, 0.0f, 0.011f, 0.627f, 1.0f, -0.206f, 0.0f, 0.013f, 0.623f, 1.0f, + -0.204f, 0.0f, 0.016f, 0.619f, 1.0f, -0.202f, 0.0f, 0.018f, 0.615f, 1.0f, -0.2f, 0.0f, 0.021f, 0.61f, 1.0f, -0.199f, 0.0f, 0.023f, 0.606f, 1.0f, + -0.197f, 0.0f, 0.026f, 0.602f, 1.0f, -0.195f, 0.0f, 0.029f, 0.598f, 1.0f, -0.194f, 0.0f, 0.032f, 0.595f, 1.0f, -0.192f, 0.0f, 0.034f, 0.592f, 1.0f, + -0.191f, 0.0f, 0.037f, 0.589f, 1.0f, -0.19f, 0.0f, 0.04f, 0.587f, 1.0f, -0.188f, 0.0f, 0.043f, 0.585f, 1.0f, -0.187f, 0.0f, 0.046f, 0.584f, 1.0f, + -0.186f, 0.0f, 0.05f, 0.583f, 1.0f, -0.185f, 0.0f, 0.053f, 0.582f, 1.0f, -0.183f, 0.0f, 0.056f, 0.581f, 1.0f, -0.182f, 0.0f, 0.059f, 0.581f, 1.0f, + -0.181f, 0.0f, 0.062f, 0.581f, 1.0f, -0.18f, 0.0f, 0.066f, 0.581f, 1.0f, -0.179f, 0.0f, 0.069f, 0.58f, 1.0f, -0.178f, 0.0f, 0.072f, 0.58f, 1.0f, + -0.177f, 0.0f, 0.076f, 0.58f, 1.0f, -0.177f, 0.0f, 0.079f, 0.58f, 1.0f, -0.176f, 0.0f, 0.083f, 0.58f, 1.0f, -0.175f, 0.0f, 0.086f, 0.58f, 1.0f, + -0.174f, 0.0f, 0.09f, 0.58f, 1.0f, -0.174f, 0.0f, 0.093f, 0.58f, 1.0f, -0.173f, 0.0f, 0.097f, 0.58f, 1.0f, -0.172f, 0.0f, 0.1f, 0.58f, 1.0f, + -0.172f, 0.0f, 0.104f, 0.58f, 1.0f, -0.171f, 0.0f, 0.108f, 0.579f, 1.0f, -0.171f, 0.0f, 0.111f, 0.579f, 1.0f, -0.17f, 0.0f, 0.115f, 0.578f, 1.0f, + -0.17f, 0.0f, 0.119f, 0.578f, 1.0f, -0.17f, 0.0f, 0.122f, 0.577f, 1.0f, -0.169f, 0.0f, 0.126f, 0.577f, 1.0f, -0.169f, 0.0f, 0.13f, 0.576f, 1.0f, + -0.169f, 0.0f, 0.134f, 0.576f, 1.0f, -0.169f, 0.0f, 0.137f, 0.575f, 1.0f, -0.169f, 0.0f, 0.141f, 0.575f, 1.0f, -0.169f, 0.0f, 0.145f, 0.574f, 1.0f, + -0.169f, 0.0f, 0.149f, 0.572f, 1.0f, -0.169f, 0.0f, 0.153f, 0.571f, 1.0f, -0.169f, 0.0f, 0.157f, 0.569f, 1.0f, -0.169f, 0.0f, 0.16f, 0.566f, 1.0f, + -0.169f, 0.0f, 0.164f, 0.562f, 1.0f, -0.17f, 0.0f, 0.168f, 0.558f, 1.0f, -0.17f, 0.0f, 0.172f, 0.553f, 1.0f, -0.17f, 0.0f, 0.176f, 0.547f, 1.0f, + -0.171f, 0.0f, 0.18f, 0.539f, 1.0f, -0.171f, 0.0f, 0.183f, 0.531f, 1.0f, -0.172f, 0.0f, 0.187f, 0.522f, 1.0f, -0.172f, 0.0f, 0.191f, 0.513f, 1.0f, + -0.173f, 0.0f, 0.194f, 0.503f, 1.0f, -0.173f, 0.0f, 0.198f, 0.493f, 1.0f, -0.174f, 0.0f, 0.202f, 0.483f, 1.0f, -0.175f, 0.0f, 0.205f, 0.473f, 1.0f, + -0.176f, 0.0f, 0.209f, 0.464f, 1.0f, -0.177f, 0.0f, 0.212f, 0.455f, 1.0f, -0.178f, 0.0f, 0.215f, 0.446f, 1.0f, -0.178f, 0.0f, 0.219f, 0.438f, 1.0f, + -0.179f, 0.0f, 0.222f, 0.428f, 1.0f, -0.18f, 0.0f, 0.226f, 0.418f, 1.0f, -0.182f, 0.0f, 0.229f, 0.407f, 1.0f, -0.183f, 0.0f, 0.232f, 0.394f, 1.0f, + -0.184f, 0.0f, 0.236f, 0.38f, 1.0f, -0.185f, 0.0f, 0.239f, 0.364f, 1.0f, -0.186f, 0.0f, 0.242f, 0.348f, 1.0f, -0.187f, 0.0f, 0.245f, 0.33f, 1.0f, + -0.188f, 0.0f, 0.249f, 0.311f, 1.0f, -0.19f, 0.0f, 0.252f, 0.293f, 1.0f, -0.191f, 0.0f, 0.255f, 0.275f, 1.0f, -0.192f, 0.0f, 0.258f, 0.258f, 1.0f, + -0.194f, 0.0f, 0.261f, 0.242f, 1.0f, -0.195f, 0.0f, 0.264f, 0.228f, 1.0f, -0.196f, 0.0f, 0.267f, 0.214f, 1.0f, -0.198f, 0.0f, 0.27f, 0.202f, 1.0f, + -0.199f, 0.0f, 0.273f, 0.191f, 1.0f, -0.201f, 0.0f, 0.276f, 0.181f, 1.0f, -0.202f, 0.0f, 0.279f, 0.171f, 1.0f, -0.204f, 0.0f, 0.282f, 0.162f, 1.0f, + -0.205f, 0.0f, 0.285f, 0.152f, 1.0f, -0.206f, 0.0f, 0.287f, 0.143f, 1.0f, -0.208f, 0.0f, 0.29f, 0.134f, 1.0f, -0.21f, 0.0f, 0.293f, 0.126f, 1.0f, + -0.211f, 0.0f, 0.295f, 0.117f, 1.0f, -0.213f, 0.0f, 0.298f, 0.109f, 1.0f, -0.214f, 0.0f, 0.301f, 0.101f, 1.0f, -0.216f, 0.0f, 0.303f, 0.094f, 1.0f, + -0.217f, 0.0f, 0.306f, 0.087f, 1.0f, -0.219f, 0.0f, 0.308f, 0.081f, 1.0f, -0.221f, 0.0f, 0.311f, 0.076f, 1.0f, -0.223f, 0.0f, 0.313f, 0.071f, 1.0f, + -0.224f, 0.0f, 0.316f, 0.067f, 1.0f, -0.226f, 0.0f, 0.318f, 0.065f, 1.0f, -0.228f, 0.0f, 0.321f, 0.062f, 1.0f, -0.23f, 0.0f, 0.323f, 0.061f, 1.0f, + -0.232f, 0.0f, 0.326f, 0.06f, 1.0f, -0.233f, 0.0f, 0.328f, 0.06f, 1.0f, -0.235f, 0.0f, 0.331f, 0.061f, 1.0f, -0.237f, 0.0f, 0.334f, 0.061f, 1.0f, + -0.239f, 0.0f, 0.336f, 0.062f, 1.0f, -0.241f, 0.0f, 0.339f, 0.063f, 1.0f, -0.243f, 0.0f, 0.341f, 0.064f, 1.0f, -0.245f, 0.0f, 0.344f, 0.065f, 1.0f, + -0.248f, 0.0f, 0.346f, 0.065f, 1.0f, -0.25f, 0.0f, 0.349f, 0.065f, 1.0f, -0.252f, 0.0f, 0.351f, 0.064f, 1.0f, -0.254f, 0.0f, 0.354f, 0.062f, 1.0f, + -0.256f, 0.0f, 0.356f, 0.06f, 1.0f, -0.258f, 0.0f, 0.359f, 0.058f, 1.0f, -0.261f, 0.0f, 0.361f, 0.055f, 1.0f, -0.263f, 0.0f, 0.364f, 0.051f, 1.0f, + -0.265f, 0.0f, 0.366f, 0.046f, 1.0f, -0.267f, 0.0f, 0.368f, 0.04f, 1.0f, -0.269f, 0.0f, 0.37f, 0.034f, 1.0f, -0.272f, 0.0f, 0.373f, 0.027f, 1.0f, + -0.274f, 0.0f, 0.375f, 0.019f, 1.0f, -0.276f, 0.0f, 0.377f, 0.012f, 1.0f, -0.278f, 0.0f, 0.379f, 0.007f, 1.0f, -0.28f, 0.0f, 0.381f, 0.003f, 1.0f, + -0.282f, 0.0f, 0.383f, 0.001f, 1.0f, -0.284f, 0.0f, 0.385f, 0.0f, 1.0f, -0.286f, 0.0f, 0.387f, 0.0f, 1.0f, -0.287f, 0.0f, 0.388f, 0.0f, 1.0f, + -0.289f, 0.0f, 0.39f, 0.0f, 1.0f, +}; + +static const float data22[309 * GP_PRIM_DATABUF_SIZE] = { + 0.294f, 0.0f, 0.372f, 0.0f, 1.0f, 0.291f, 0.0f, 0.37f, 0.001f, 1.0f, 0.289f, 0.0f, 0.368f, 0.002f, 1.0f, 0.286f, 0.0f, 0.366f, 0.003f, 1.0f, + 0.284f, 0.0f, 0.364f, 0.006f, 1.0f, 0.282f, 0.0f, 0.362f, 0.01f, 1.0f, 0.279f, 0.0f, 0.36f, 0.015f, 1.0f, 0.277f, 0.0f, 0.358f, 0.022f, 1.0f, + 0.274f, 0.0f, 0.356f, 0.03f, 1.0f, 0.272f, 0.0f, 0.353f, 0.04f, 1.0f, 0.269f, 0.0f, 0.351f, 0.051f, 1.0f, 0.267f, 0.0f, 0.349f, 0.062f, 1.0f, + 0.265f, 0.0f, 0.347f, 0.074f, 1.0f, 0.262f, 0.0f, 0.344f, 0.086f, 1.0f, 0.26f, 0.0f, 0.342f, 0.097f, 1.0f, 0.258f, 0.0f, 0.34f, 0.108f, 1.0f, + 0.256f, 0.0f, 0.337f, 0.119f, 1.0f, 0.253f, 0.0f, 0.335f, 0.128f, 1.0f, 0.251f, 0.0f, 0.333f, 0.137f, 1.0f, 0.249f, 0.0f, 0.33f, 0.145f, 1.0f, + 0.247f, 0.0f, 0.328f, 0.153f, 1.0f, 0.246f, 0.0f, 0.325f, 0.161f, 1.0f, 0.244f, 0.0f, 0.323f, 0.168f, 1.0f, 0.242f, 0.0f, 0.321f, 0.176f, 1.0f, + 0.24f, 0.0f, 0.318f, 0.183f, 1.0f, 0.239f, 0.0f, 0.316f, 0.191f, 1.0f, 0.237f, 0.0f, 0.314f, 0.198f, 1.0f, 0.235f, 0.0f, 0.311f, 0.206f, 1.0f, + 0.233f, 0.0f, 0.309f, 0.214f, 1.0f, 0.231f, 0.0f, 0.306f, 0.223f, 1.0f, 0.23f, 0.0f, 0.304f, 0.231f, 1.0f, 0.228f, 0.0f, 0.301f, 0.24f, 1.0f, + 0.226f, 0.0f, 0.299f, 0.248f, 1.0f, 0.224f, 0.0f, 0.296f, 0.256f, 1.0f, 0.223f, 0.0f, 0.294f, 0.264f, 1.0f, 0.221f, 0.0f, 0.291f, 0.272f, 1.0f, + 0.219f, 0.0f, 0.288f, 0.28f, 1.0f, 0.218f, 0.0f, 0.286f, 0.287f, 1.0f, 0.216f, 0.0f, 0.283f, 0.294f, 1.0f, 0.214f, 0.0f, 0.281f, 0.301f, 1.0f, + 0.213f, 0.0f, 0.278f, 0.307f, 1.0f, 0.211f, 0.0f, 0.275f, 0.314f, 1.0f, 0.21f, 0.0f, 0.273f, 0.32f, 1.0f, 0.208f, 0.0f, 0.27f, 0.327f, 1.0f, + 0.206f, 0.0f, 0.267f, 0.333f, 1.0f, 0.205f, 0.0f, 0.265f, 0.339f, 1.0f, 0.204f, 0.0f, 0.262f, 0.345f, 1.0f, 0.202f, 0.0f, 0.259f, 0.351f, 1.0f, + 0.201f, 0.0f, 0.256f, 0.357f, 1.0f, 0.199f, 0.0f, 0.253f, 0.362f, 1.0f, 0.198f, 0.0f, 0.25f, 0.368f, 1.0f, 0.197f, 0.0f, 0.247f, 0.373f, 1.0f, + 0.195f, 0.0f, 0.244f, 0.379f, 1.0f, 0.194f, 0.0f, 0.241f, 0.383f, 1.0f, 0.193f, 0.0f, 0.238f, 0.388f, 1.0f, 0.192f, 0.0f, 0.235f, 0.392f, 1.0f, + 0.191f, 0.0f, 0.232f, 0.396f, 1.0f, 0.19f, 0.0f, 0.229f, 0.399f, 1.0f, 0.189f, 0.0f, 0.226f, 0.402f, 1.0f, 0.188f, 0.0f, 0.222f, 0.405f, 1.0f, + 0.187f, 0.0f, 0.219f, 0.407f, 1.0f, 0.186f, 0.0f, 0.216f, 0.409f, 1.0f, 0.185f, 0.0f, 0.213f, 0.411f, 1.0f, 0.184f, 0.0f, 0.209f, 0.412f, 1.0f, + 0.183f, 0.0f, 0.206f, 0.413f, 1.0f, 0.183f, 0.0f, 0.203f, 0.414f, 1.0f, 0.182f, 0.0f, 0.199f, 0.415f, 1.0f, 0.181f, 0.0f, 0.196f, 0.416f, 1.0f, + 0.181f, 0.0f, 0.193f, 0.417f, 1.0f, 0.18f, 0.0f, 0.189f, 0.417f, 1.0f, 0.18f, 0.0f, 0.186f, 0.418f, 1.0f, 0.179f, 0.0f, 0.182f, 0.419f, 1.0f, + 0.179f, 0.0f, 0.179f, 0.421f, 1.0f, 0.179f, 0.0f, 0.176f, 0.422f, 1.0f, 0.178f, 0.0f, 0.172f, 0.423f, 1.0f, 0.178f, 0.0f, 0.169f, 0.425f, 1.0f, + 0.178f, 0.0f, 0.165f, 0.427f, 1.0f, 0.178f, 0.0f, 0.162f, 0.429f, 1.0f, 0.178f, 0.0f, 0.158f, 0.431f, 1.0f, 0.178f, 0.0f, 0.155f, 0.434f, 1.0f, + 0.178f, 0.0f, 0.152f, 0.436f, 1.0f, 0.178f, 0.0f, 0.148f, 0.439f, 1.0f, 0.178f, 0.0f, 0.145f, 0.442f, 1.0f, 0.178f, 0.0f, 0.141f, 0.446f, 1.0f, + 0.178f, 0.0f, 0.138f, 0.449f, 1.0f, 0.178f, 0.0f, 0.134f, 0.453f, 1.0f, 0.178f, 0.0f, 0.131f, 0.458f, 1.0f, 0.179f, 0.0f, 0.127f, 0.462f, 1.0f, + 0.179f, 0.0f, 0.124f, 0.467f, 1.0f, 0.179f, 0.0f, 0.12f, 0.472f, 1.0f, 0.18f, 0.0f, 0.117f, 0.478f, 1.0f, 0.18f, 0.0f, 0.113f, 0.483f, 1.0f, + 0.181f, 0.0f, 0.11f, 0.489f, 1.0f, 0.182f, 0.0f, 0.106f, 0.494f, 1.0f, 0.182f, 0.0f, 0.103f, 0.5f, 1.0f, 0.183f, 0.0f, 0.099f, 0.505f, 1.0f, + 0.184f, 0.0f, 0.096f, 0.511f, 1.0f, 0.185f, 0.0f, 0.092f, 0.516f, 1.0f, 0.185f, 0.0f, 0.089f, 0.521f, 1.0f, 0.186f, 0.0f, 0.086f, 0.525f, 1.0f, + 0.187f, 0.0f, 0.082f, 0.53f, 1.0f, 0.188f, 0.0f, 0.079f, 0.534f, 1.0f, 0.189f, 0.0f, 0.076f, 0.537f, 1.0f, 0.191f, 0.0f, 0.073f, 0.541f, 1.0f, + 0.192f, 0.0f, 0.069f, 0.544f, 1.0f, 0.193f, 0.0f, 0.066f, 0.547f, 1.0f, 0.194f, 0.0f, 0.063f, 0.55f, 1.0f, 0.196f, 0.0f, 0.061f, 0.553f, 1.0f, + 0.197f, 0.0f, 0.058f, 0.556f, 1.0f, 0.198f, 0.0f, 0.055f, 0.559f, 1.0f, 0.2f, 0.0f, 0.052f, 0.562f, 1.0f, 0.201f, 0.0f, 0.049f, 0.564f, 1.0f, + 0.203f, 0.0f, 0.047f, 0.566f, 1.0f, 0.205f, 0.0f, 0.044f, 0.569f, 1.0f, 0.206f, 0.0f, 0.042f, 0.571f, 1.0f, 0.208f, 0.0f, 0.039f, 0.573f, 1.0f, + 0.21f, 0.0f, 0.037f, 0.575f, 1.0f, 0.212f, 0.0f, 0.035f, 0.576f, 1.0f, 0.214f, 0.0f, 0.032f, 0.578f, 1.0f, 0.215f, 0.0f, 0.03f, 0.579f, 1.0f, + 0.217f, 0.0f, 0.028f, 0.581f, 1.0f, 0.22f, 0.0f, 0.025f, 0.582f, 1.0f, 0.222f, 0.0f, 0.023f, 0.583f, 1.0f, 0.224f, 0.0f, 0.021f, 0.585f, 1.0f, + 0.226f, 0.0f, 0.019f, 0.587f, 1.0f, 0.228f, 0.0f, 0.016f, 0.589f, 1.0f, 0.231f, 0.0f, 0.014f, 0.592f, 1.0f, 0.233f, 0.0f, 0.012f, 0.596f, 1.0f, + 0.236f, 0.0f, 0.01f, 0.599f, 1.0f, 0.238f, 0.0f, 0.008f, 0.604f, 1.0f, 0.241f, 0.0f, 0.006f, 0.608f, 1.0f, 0.243f, 0.0f, 0.004f, 0.612f, 1.0f, + 0.246f, 0.0f, 0.002f, 0.615f, 1.0f, 0.249f, 0.0f, 0.0f, 0.619f, 1.0f, 0.251f, 0.0f, -0.002f, 0.622f, 1.0f, 0.254f, 0.0f, -0.003f, 0.624f, 1.0f, + 0.257f, 0.0f, -0.005f, 0.626f, 1.0f, 0.26f, 0.0f, -0.007f, 0.628f, 1.0f, 0.263f, 0.0f, -0.008f, 0.63f, 1.0f, 0.266f, 0.0f, -0.01f, 0.632f, 1.0f, + 0.269f, 0.0f, -0.011f, 0.634f, 1.0f, 0.272f, 0.0f, -0.013f, 0.636f, 1.0f, 0.275f, 0.0f, -0.014f, 0.638f, 1.0f, 0.278f, 0.0f, -0.015f, 0.64f, 1.0f, + 0.281f, 0.0f, -0.017f, 0.642f, 1.0f, 0.284f, 0.0f, -0.018f, 0.644f, 1.0f, 0.288f, 0.0f, -0.019f, 0.647f, 1.0f, 0.291f, 0.0f, -0.02f, 0.649f, 1.0f, + 0.294f, 0.0f, -0.021f, 0.651f, 1.0f, 0.297f, 0.0f, -0.022f, 0.653f, 1.0f, 0.301f, 0.0f, -0.023f, 0.656f, 1.0f, 0.304f, 0.0f, -0.024f, 0.658f, 1.0f, + 0.307f, 0.0f, -0.025f, 0.659f, 1.0f, 0.31f, 0.0f, -0.026f, 0.661f, 1.0f, 0.314f, 0.0f, -0.027f, 0.662f, 1.0f, 0.317f, 0.0f, -0.027f, 0.664f, 1.0f, + 0.32f, 0.0f, -0.028f, 0.665f, 1.0f, 0.324f, 0.0f, -0.028f, 0.665f, 1.0f, 0.327f, 0.0f, -0.029f, 0.666f, 1.0f, 0.33f, 0.0f, -0.029f, 0.666f, 1.0f, + 0.334f, 0.0f, -0.029f, 0.667f, 1.0f, 0.337f, 0.0f, -0.03f, 0.667f, 1.0f, 0.341f, 0.0f, -0.03f, 0.668f, 1.0f, 0.344f, 0.0f, -0.03f, 0.668f, 1.0f, + 0.348f, 0.0f, -0.03f, 0.668f, 1.0f, 0.351f, 0.0f, -0.03f, 0.668f, 1.0f, 0.354f, 0.0f, -0.03f, 0.668f, 1.0f, 0.358f, 0.0f, -0.029f, 0.668f, 1.0f, + 0.361f, 0.0f, -0.029f, 0.668f, 1.0f, 0.365f, 0.0f, -0.029f, 0.668f, 1.0f, 0.368f, 0.0f, -0.028f, 0.668f, 1.0f, 0.372f, 0.0f, -0.028f, 0.668f, 1.0f, + 0.375f, 0.0f, -0.027f, 0.668f, 1.0f, 0.378f, 0.0f, -0.027f, 0.668f, 1.0f, 0.382f, 0.0f, -0.026f, 0.667f, 1.0f, 0.385f, 0.0f, -0.025f, 0.667f, 1.0f, + 0.388f, 0.0f, -0.025f, 0.666f, 1.0f, 0.392f, 0.0f, -0.024f, 0.666f, 1.0f, 0.395f, 0.0f, -0.023f, 0.665f, 1.0f, 0.398f, 0.0f, -0.022f, 0.664f, 1.0f, + 0.401f, 0.0f, -0.021f, 0.664f, 1.0f, 0.405f, 0.0f, -0.02f, 0.663f, 1.0f, 0.408f, 0.0f, -0.019f, 0.663f, 1.0f, 0.411f, 0.0f, -0.018f, 0.662f, 1.0f, + 0.414f, 0.0f, -0.017f, 0.662f, 1.0f, 0.417f, 0.0f, -0.016f, 0.662f, 1.0f, 0.42f, 0.0f, -0.015f, 0.662f, 1.0f, 0.423f, 0.0f, -0.014f, 0.661f, 1.0f, + 0.426f, 0.0f, -0.012f, 0.661f, 1.0f, 0.429f, 0.0f, -0.011f, 0.661f, 1.0f, 0.432f, 0.0f, -0.01f, 0.661f, 1.0f, 0.434f, 0.0f, -0.009f, 0.66f, 1.0f, + 0.437f, 0.0f, -0.007f, 0.66f, 1.0f, 0.44f, 0.0f, -0.006f, 0.659f, 1.0f, 0.442f, 0.0f, -0.005f, 0.659f, 1.0f, 0.445f, 0.0f, -0.003f, 0.658f, 1.0f, + 0.448f, 0.0f, -0.002f, 0.658f, 1.0f, 0.45f, 0.0f, -0.001f, 0.657f, 1.0f, 0.452f, 0.0f, 0.001f, 0.656f, 1.0f, 0.455f, 0.0f, 0.002f, 0.655f, 1.0f, + 0.457f, 0.0f, 0.004f, 0.654f, 1.0f, 0.459f, 0.0f, 0.005f, 0.653f, 1.0f, 0.462f, 0.0f, 0.007f, 0.652f, 1.0f, 0.464f, 0.0f, 0.009f, 0.651f, 1.0f, + 0.466f, 0.0f, 0.01f, 0.65f, 1.0f, 0.468f, 0.0f, 0.012f, 0.65f, 1.0f, 0.47f, 0.0f, 0.014f, 0.649f, 1.0f, 0.472f, 0.0f, 0.016f, 0.648f, 1.0f, + 0.474f, 0.0f, 0.018f, 0.647f, 1.0f, 0.476f, 0.0f, 0.019f, 0.646f, 1.0f, 0.478f, 0.0f, 0.021f, 0.645f, 1.0f, 0.479f, 0.0f, 0.023f, 0.644f, 1.0f, + 0.481f, 0.0f, 0.025f, 0.643f, 1.0f, 0.483f, 0.0f, 0.027f, 0.642f, 1.0f, 0.485f, 0.0f, 0.03f, 0.642f, 1.0f, 0.486f, 0.0f, 0.032f, 0.641f, 1.0f, + 0.488f, 0.0f, 0.034f, 0.64f, 1.0f, 0.49f, 0.0f, 0.036f, 0.639f, 1.0f, 0.491f, 0.0f, 0.038f, 0.638f, 1.0f, 0.493f, 0.0f, 0.041f, 0.637f, 1.0f, + 0.494f, 0.0f, 0.043f, 0.636f, 1.0f, 0.496f, 0.0f, 0.045f, 0.635f, 1.0f, 0.497f, 0.0f, 0.048f, 0.635f, 1.0f, 0.499f, 0.0f, 0.05f, 0.634f, 1.0f, + 0.5f, 0.0f, 0.053f, 0.633f, 1.0f, 0.502f, 0.0f, 0.055f, 0.632f, 1.0f, 0.503f, 0.0f, 0.058f, 0.631f, 1.0f, 0.505f, 0.0f, 0.06f, 0.63f, 1.0f, + 0.506f, 0.0f, 0.063f, 0.63f, 1.0f, 0.507f, 0.0f, 0.066f, 0.629f, 1.0f, 0.509f, 0.0f, 0.068f, 0.628f, 1.0f, 0.51f, 0.0f, 0.071f, 0.628f, 1.0f, + 0.511f, 0.0f, 0.074f, 0.627f, 1.0f, 0.513f, 0.0f, 0.077f, 0.626f, 1.0f, 0.514f, 0.0f, 0.079f, 0.625f, 1.0f, 0.515f, 0.0f, 0.082f, 0.625f, 1.0f, + 0.516f, 0.0f, 0.085f, 0.624f, 1.0f, 0.518f, 0.0f, 0.088f, 0.623f, 1.0f, 0.519f, 0.0f, 0.091f, 0.622f, 1.0f, 0.52f, 0.0f, 0.094f, 0.62f, 1.0f, + 0.521f, 0.0f, 0.098f, 0.619f, 1.0f, 0.522f, 0.0f, 0.101f, 0.617f, 1.0f, 0.523f, 0.0f, 0.104f, 0.615f, 1.0f, 0.524f, 0.0f, 0.107f, 0.613f, 1.0f, + 0.525f, 0.0f, 0.111f, 0.611f, 1.0f, 0.526f, 0.0f, 0.114f, 0.609f, 1.0f, 0.527f, 0.0f, 0.118f, 0.607f, 1.0f, 0.527f, 0.0f, 0.121f, 0.605f, 1.0f, + 0.528f, 0.0f, 0.124f, 0.603f, 1.0f, 0.529f, 0.0f, 0.128f, 0.602f, 1.0f, 0.529f, 0.0f, 0.132f, 0.6f, 1.0f, 0.53f, 0.0f, 0.135f, 0.599f, 1.0f, + 0.531f, 0.0f, 0.139f, 0.598f, 1.0f, 0.531f, 0.0f, 0.142f, 0.598f, 1.0f, 0.531f, 0.0f, 0.146f, 0.597f, 1.0f, 0.532f, 0.0f, 0.15f, 0.596f, 1.0f, + 0.532f, 0.0f, 0.154f, 0.596f, 1.0f, 0.532f, 0.0f, 0.157f, 0.595f, 1.0f, 0.532f, 0.0f, 0.161f, 0.595f, 1.0f, 0.532f, 0.0f, 0.165f, 0.594f, 1.0f, + 0.532f, 0.0f, 0.169f, 0.593f, 1.0f, 0.532f, 0.0f, 0.173f, 0.592f, 1.0f, 0.532f, 0.0f, 0.177f, 0.591f, 1.0f, 0.532f, 0.0f, 0.181f, 0.59f, 1.0f, + 0.531f, 0.0f, 0.185f, 0.589f, 1.0f, 0.531f, 0.0f, 0.189f, 0.588f, 1.0f, 0.53f, 0.0f, 0.194f, 0.587f, 1.0f, 0.529f, 0.0f, 0.198f, 0.586f, 1.0f, + 0.528f, 0.0f, 0.202f, 0.585f, 1.0f, 0.527f, 0.0f, 0.207f, 0.584f, 1.0f, 0.526f, 0.0f, 0.211f, 0.584f, 1.0f, 0.525f, 0.0f, 0.215f, 0.583f, 1.0f, + 0.523f, 0.0f, 0.22f, 0.583f, 1.0f, 0.522f, 0.0f, 0.224f, 0.583f, 1.0f, 0.52f, 0.0f, 0.229f, 0.582f, 1.0f, 0.518f, 0.0f, 0.234f, 0.582f, 1.0f, + 0.515f, 0.0f, 0.238f, 0.582f, 1.0f, 0.513f, 0.0f, 0.243f, 0.581f, 1.0f, 0.51f, 0.0f, 0.247f, 0.58f, 1.0f, 0.508f, 0.0f, 0.252f, 0.579f, 1.0f, + 0.505f, 0.0f, 0.257f, 0.578f, 1.0f, 0.502f, 0.0f, 0.261f, 0.576f, 1.0f, 0.499f, 0.0f, 0.266f, 0.573f, 1.0f, 0.496f, 0.0f, 0.27f, 0.57f, 1.0f, + 0.492f, 0.0f, 0.275f, 0.566f, 1.0f, 0.489f, 0.0f, 0.279f, 0.561f, 1.0f, 0.485f, 0.0f, 0.284f, 0.555f, 1.0f, 0.481f, 0.0f, 0.288f, 0.548f, 1.0f, + 0.478f, 0.0f, 0.293f, 0.54f, 1.0f, 0.473f, 0.0f, 0.297f, 0.531f, 1.0f, 0.469f, 0.0f, 0.301f, 0.521f, 1.0f, 0.465f, 0.0f, 0.305f, 0.509f, 1.0f, + 0.461f, 0.0f, 0.309f, 0.496f, 1.0f, 0.456f, 0.0f, 0.313f, 0.481f, 1.0f, 0.452f, 0.0f, 0.317f, 0.464f, 1.0f, 0.448f, 0.0f, 0.321f, 0.445f, 1.0f, + 0.443f, 0.0f, 0.324f, 0.424f, 1.0f, 0.438f, 0.0f, 0.328f, 0.401f, 1.0f, 0.434f, 0.0f, 0.331f, 0.374f, 1.0f, 0.429f, 0.0f, 0.334f, 0.346f, 1.0f, + 0.425f, 0.0f, 0.337f, 0.314f, 1.0f, 0.421f, 0.0f, 0.34f, 0.281f, 1.0f, 0.416f, 0.0f, 0.343f, 0.245f, 1.0f, 0.412f, 0.0f, 0.346f, 0.208f, 1.0f, + 0.408f, 0.0f, 0.349f, 0.169f, 1.0f, 0.404f, 0.0f, 0.351f, 0.13f, 1.0f, 0.401f, 0.0f, 0.354f, 0.089f, 1.0f, 0.398f, 0.0f, 0.356f, 0.054f, 1.0f, + 0.394f, 0.0f, 0.359f, 0.0f, 1.0f, +}; + +static const float data23[209 * GP_PRIM_DATABUF_SIZE] = { + -0.751f, 0.0f, 0.173f, 0.0f, 1.0f, -0.751f, 0.0f, 0.168f, 0.0f, 1.0f, -0.75f, 0.0f, 0.164f, 0.0f, 1.0f, -0.75f, 0.0f, 0.16f, 0.0f, 1.0f, + -0.75f, 0.0f, 0.156f, 0.0f, 1.0f, -0.749f, 0.0f, 0.152f, 0.0f, 1.0f, -0.749f, 0.0f, 0.148f, 0.0f, 1.0f, -0.748f, 0.0f, 0.144f, 0.0f, 1.0f, + -0.747f, 0.0f, 0.14f, 0.001f, 1.0f, -0.747f, 0.0f, 0.137f, 0.002f, 1.0f, -0.746f, 0.0f, 0.133f, 0.005f, 1.0f, -0.745f, 0.0f, 0.129f, 0.008f, 1.0f, + -0.745f, 0.0f, 0.125f, 0.013f, 1.0f, -0.744f, 0.0f, 0.122f, 0.02f, 1.0f, -0.743f, 0.0f, 0.118f, 0.028f, 1.0f, -0.742f, 0.0f, 0.115f, 0.038f, 1.0f, + -0.741f, 0.0f, 0.111f, 0.049f, 1.0f, -0.74f, 0.0f, 0.108f, 0.061f, 1.0f, -0.739f, 0.0f, 0.105f, 0.073f, 1.0f, -0.738f, 0.0f, 0.101f, 0.085f, 1.0f, + -0.736f, 0.0f, 0.098f, 0.097f, 1.0f, -0.735f, 0.0f, 0.095f, 0.109f, 1.0f, -0.734f, 0.0f, 0.091f, 0.119f, 1.0f, -0.732f, 0.0f, 0.088f, 0.129f, 1.0f, + -0.731f, 0.0f, 0.085f, 0.138f, 1.0f, -0.729f, 0.0f, 0.082f, 0.146f, 1.0f, -0.728f, 0.0f, 0.079f, 0.153f, 1.0f, -0.726f, 0.0f, 0.076f, 0.158f, 1.0f, + -0.725f, 0.0f, 0.073f, 0.163f, 1.0f, -0.723f, 0.0f, 0.07f, 0.167f, 1.0f, -0.722f, 0.0f, 0.067f, 0.17f, 1.0f, -0.72f, 0.0f, 0.065f, 0.173f, 1.0f, + -0.718f, 0.0f, 0.062f, 0.174f, 1.0f, -0.717f, 0.0f, 0.059f, 0.175f, 1.0f, -0.715f, 0.0f, 0.057f, 0.176f, 1.0f, -0.714f, 0.0f, 0.054f, 0.176f, 1.0f, + -0.712f, 0.0f, 0.051f, 0.176f, 1.0f, -0.71f, 0.0f, 0.049f, 0.176f, 1.0f, -0.709f, 0.0f, 0.046f, 0.176f, 1.0f, -0.707f, 0.0f, 0.043f, 0.176f, 1.0f, + -0.705f, 0.0f, 0.041f, 0.176f, 1.0f, -0.703f, 0.0f, 0.038f, 0.176f, 1.0f, -0.701f, 0.0f, 0.035f, 0.176f, 1.0f, -0.7f, 0.0f, 0.033f, 0.177f, 1.0f, + -0.698f, 0.0f, 0.03f, 0.177f, 1.0f, -0.696f, 0.0f, 0.027f, 0.178f, 1.0f, -0.694f, 0.0f, 0.024f, 0.179f, 1.0f, -0.692f, 0.0f, 0.022f, 0.18f, 1.0f, + -0.69f, 0.0f, 0.019f, 0.181f, 1.0f, -0.688f, 0.0f, 0.016f, 0.182f, 1.0f, -0.685f, 0.0f, 0.013f, 0.184f, 1.0f, -0.683f, 0.0f, 0.01f, 0.187f, 1.0f, + -0.681f, 0.0f, 0.007f, 0.19f, 1.0f, -0.679f, 0.0f, 0.004f, 0.194f, 1.0f, -0.677f, 0.0f, 0.001f, 0.198f, 1.0f, -0.675f, 0.0f, -0.002f, 0.203f, 1.0f, + -0.673f, 0.0f, -0.005f, 0.209f, 1.0f, -0.67f, 0.0f, -0.008f, 0.215f, 1.0f, -0.668f, 0.0f, -0.011f, 0.222f, 1.0f, -0.666f, 0.0f, -0.014f, 0.229f, 1.0f, + -0.664f, 0.0f, -0.017f, 0.237f, 1.0f, -0.661f, 0.0f, -0.02f, 0.246f, 1.0f, -0.659f, 0.0f, -0.023f, 0.255f, 1.0f, -0.657f, 0.0f, -0.025f, 0.264f, 1.0f, + -0.654f, 0.0f, -0.028f, 0.275f, 1.0f, -0.652f, 0.0f, -0.031f, 0.285f, 1.0f, -0.65f, 0.0f, -0.034f, 0.297f, 1.0f, -0.647f, 0.0f, -0.037f, 0.309f, 1.0f, + -0.644f, 0.0f, -0.04f, 0.322f, 1.0f, -0.642f, 0.0f, -0.043f, 0.335f, 1.0f, -0.639f, 0.0f, -0.046f, 0.348f, 1.0f, -0.636f, 0.0f, -0.049f, 0.361f, 1.0f, + -0.633f, 0.0f, -0.052f, 0.374f, 1.0f, -0.63f, 0.0f, -0.055f, 0.386f, 1.0f, -0.627f, 0.0f, -0.058f, 0.397f, 1.0f, -0.624f, 0.0f, -0.061f, 0.408f, 1.0f, + -0.62f, 0.0f, -0.064f, 0.418f, 1.0f, -0.617f, 0.0f, -0.067f, 0.427f, 1.0f, -0.614f, 0.0f, -0.07f, 0.435f, 1.0f, -0.611f, 0.0f, -0.073f, 0.443f, 1.0f, + -0.607f, 0.0f, -0.075f, 0.451f, 1.0f, -0.604f, 0.0f, -0.078f, 0.458f, 1.0f, -0.6f, 0.0f, -0.081f, 0.465f, 1.0f, -0.597f, 0.0f, -0.084f, 0.472f, 1.0f, + -0.593f, 0.0f, -0.086f, 0.479f, 1.0f, -0.59f, 0.0f, -0.089f, 0.486f, 1.0f, -0.586f, 0.0f, -0.092f, 0.492f, 1.0f, -0.583f, 0.0f, -0.094f, 0.499f, 1.0f, + -0.579f, 0.0f, -0.097f, 0.505f, 1.0f, -0.575f, 0.0f, -0.099f, 0.512f, 1.0f, -0.571f, 0.0f, -0.102f, 0.518f, 1.0f, -0.567f, 0.0f, -0.105f, 0.524f, 1.0f, + -0.563f, 0.0f, -0.107f, 0.53f, 1.0f, -0.559f, 0.0f, -0.11f, 0.536f, 1.0f, -0.555f, 0.0f, -0.112f, 0.541f, 1.0f, -0.551f, 0.0f, -0.115f, 0.546f, 1.0f, + -0.546f, 0.0f, -0.117f, 0.551f, 1.0f, -0.542f, 0.0f, -0.12f, 0.555f, 1.0f, -0.538f, 0.0f, -0.122f, 0.559f, 1.0f, -0.533f, 0.0f, -0.125f, 0.562f, 1.0f, + -0.529f, 0.0f, -0.127f, 0.565f, 1.0f, -0.525f, 0.0f, -0.129f, 0.568f, 1.0f, -0.52f, 0.0f, -0.132f, 0.57f, 1.0f, -0.516f, 0.0f, -0.134f, 0.572f, 1.0f, + -0.512f, 0.0f, -0.137f, 0.574f, 1.0f, -0.508f, 0.0f, -0.139f, 0.576f, 1.0f, -0.503f, 0.0f, -0.141f, 0.577f, 1.0f, -0.499f, 0.0f, -0.144f, 0.578f, 1.0f, + -0.495f, 0.0f, -0.146f, 0.579f, 1.0f, -0.491f, 0.0f, -0.148f, 0.579f, 1.0f, -0.487f, 0.0f, -0.151f, 0.578f, 1.0f, -0.483f, 0.0f, -0.153f, 0.577f, 1.0f, + -0.479f, 0.0f, -0.155f, 0.574f, 1.0f, -0.475f, 0.0f, -0.158f, 0.571f, 1.0f, -0.471f, 0.0f, -0.16f, 0.567f, 1.0f, -0.467f, 0.0f, -0.162f, 0.561f, 1.0f, + -0.463f, 0.0f, -0.165f, 0.555f, 1.0f, -0.459f, 0.0f, -0.167f, 0.548f, 1.0f, -0.456f, 0.0f, -0.169f, 0.54f, 1.0f, -0.452f, 0.0f, -0.172f, 0.532f, 1.0f, + -0.448f, 0.0f, -0.174f, 0.523f, 1.0f, -0.445f, 0.0f, -0.176f, 0.514f, 1.0f, -0.441f, 0.0f, -0.179f, 0.505f, 1.0f, -0.438f, 0.0f, -0.181f, 0.497f, 1.0f, + -0.435f, 0.0f, -0.183f, 0.488f, 1.0f, -0.431f, 0.0f, -0.185f, 0.48f, 1.0f, -0.428f, 0.0f, -0.188f, 0.472f, 1.0f, -0.425f, 0.0f, -0.19f, 0.464f, 1.0f, + -0.422f, 0.0f, -0.192f, 0.457f, 1.0f, -0.419f, 0.0f, -0.194f, 0.451f, 1.0f, -0.416f, 0.0f, -0.196f, 0.444f, 1.0f, -0.413f, 0.0f, -0.198f, 0.439f, 1.0f, + -0.41f, 0.0f, -0.2f, 0.434f, 1.0f, -0.407f, 0.0f, -0.202f, 0.429f, 1.0f, -0.404f, 0.0f, -0.204f, 0.426f, 1.0f, -0.401f, 0.0f, -0.206f, 0.422f, 1.0f, + -0.398f, 0.0f, -0.208f, 0.419f, 1.0f, -0.396f, 0.0f, -0.21f, 0.417f, 1.0f, -0.393f, 0.0f, -0.212f, 0.415f, 1.0f, -0.39f, 0.0f, -0.213f, 0.413f, 1.0f, + -0.388f, 0.0f, -0.215f, 0.412f, 1.0f, -0.385f, 0.0f, -0.217f, 0.411f, 1.0f, -0.382f, 0.0f, -0.219f, 0.41f, 1.0f, -0.38f, 0.0f, -0.221f, 0.41f, 1.0f, + -0.377f, 0.0f, -0.222f, 0.409f, 1.0f, -0.375f, 0.0f, -0.224f, 0.409f, 1.0f, -0.372f, 0.0f, -0.226f, 0.409f, 1.0f, -0.37f, 0.0f, -0.228f, 0.409f, 1.0f, + -0.367f, 0.0f, -0.229f, 0.409f, 1.0f, -0.365f, 0.0f, -0.231f, 0.409f, 1.0f, -0.362f, 0.0f, -0.233f, 0.409f, 1.0f, -0.36f, 0.0f, -0.235f, 0.409f, 1.0f, + -0.357f, 0.0f, -0.236f, 0.409f, 1.0f, -0.355f, 0.0f, -0.238f, 0.409f, 1.0f, -0.352f, 0.0f, -0.24f, 0.408f, 1.0f, -0.35f, 0.0f, -0.242f, 0.408f, 1.0f, + -0.348f, 0.0f, -0.243f, 0.407f, 1.0f, -0.345f, 0.0f, -0.245f, 0.406f, 1.0f, -0.343f, 0.0f, -0.247f, 0.405f, 1.0f, -0.34f, 0.0f, -0.249f, 0.404f, 1.0f, + -0.338f, 0.0f, -0.251f, 0.403f, 1.0f, -0.336f, 0.0f, -0.253f, 0.401f, 1.0f, -0.333f, 0.0f, -0.255f, 0.399f, 1.0f, -0.331f, 0.0f, -0.256f, 0.397f, 1.0f, + -0.329f, 0.0f, -0.258f, 0.394f, 1.0f, -0.327f, 0.0f, -0.26f, 0.391f, 1.0f, -0.324f, 0.0f, -0.262f, 0.387f, 1.0f, -0.322f, 0.0f, -0.264f, 0.383f, 1.0f, + -0.32f, 0.0f, -0.266f, 0.379f, 1.0f, -0.318f, 0.0f, -0.268f, 0.374f, 1.0f, -0.316f, 0.0f, -0.27f, 0.368f, 1.0f, -0.314f, 0.0f, -0.272f, 0.362f, 1.0f, + -0.312f, 0.0f, -0.275f, 0.356f, 1.0f, -0.309f, 0.0f, -0.277f, 0.349f, 1.0f, -0.307f, 0.0f, -0.279f, 0.341f, 1.0f, -0.305f, 0.0f, -0.281f, 0.333f, 1.0f, + -0.303f, 0.0f, -0.283f, 0.325f, 1.0f, -0.301f, 0.0f, -0.286f, 0.316f, 1.0f, -0.299f, 0.0f, -0.288f, 0.307f, 1.0f, -0.297f, 0.0f, -0.29f, 0.298f, 1.0f, + -0.295f, 0.0f, -0.293f, 0.289f, 1.0f, -0.293f, 0.0f, -0.295f, 0.279f, 1.0f, -0.291f, 0.0f, -0.298f, 0.269f, 1.0f, -0.29f, 0.0f, -0.3f, 0.259f, 1.0f, + -0.288f, 0.0f, -0.303f, 0.249f, 1.0f, -0.286f, 0.0f, -0.306f, 0.238f, 1.0f, -0.284f, 0.0f, -0.308f, 0.227f, 1.0f, -0.282f, 0.0f, -0.311f, 0.215f, 1.0f, + -0.28f, 0.0f, -0.314f, 0.203f, 1.0f, -0.278f, 0.0f, -0.317f, 0.191f, 1.0f, -0.277f, 0.0f, -0.32f, 0.178f, 1.0f, -0.275f, 0.0f, -0.323f, 0.165f, 1.0f, + -0.273f, 0.0f, -0.326f, 0.151f, 1.0f, -0.271f, 0.0f, -0.33f, 0.138f, 1.0f, -0.27f, 0.0f, -0.333f, 0.124f, 1.0f, -0.268f, 0.0f, -0.336f, 0.11f, 1.0f, + -0.267f, 0.0f, -0.34f, 0.097f, 1.0f, -0.265f, 0.0f, -0.343f, 0.085f, 1.0f, -0.264f, 0.0f, -0.346f, 0.073f, 1.0f, -0.262f, 0.0f, -0.35f, 0.062f, 1.0f, + -0.261f, 0.0f, -0.353f, 0.052f, 1.0f, -0.259f, 0.0f, -0.357f, 0.043f, 1.0f, -0.258f, 0.0f, -0.36f, 0.035f, 1.0f, -0.257f, 0.0f, -0.363f, 0.028f, 1.0f, + -0.255f, 0.0f, -0.366f, 0.021f, 1.0f, -0.254f, 0.0f, -0.369f, 0.016f, 1.0f, -0.253f, 0.0f, -0.372f, 0.01f, 1.0f, -0.252f, 0.0f, -0.375f, 0.006f, 1.0f, + -0.251f, 0.0f, -0.379f, 0.0f, 1.0f, +}; + +static const float data24[133 * GP_PRIM_DATABUF_SIZE] = { + 0.233f, 0.0f, -0.376f, 0.021f, 1.0f, 0.234f, 0.0f, -0.372f, 0.08f, 1.0f, 0.234f, 0.0f, -0.369f, 0.116f, 1.0f, 0.234f, 0.0f, -0.366f, 0.156f, 1.0f, + 0.235f, 0.0f, -0.362f, 0.191f, 1.0f, 0.236f, 0.0f, -0.359f, 0.222f, 1.0f, 0.236f, 0.0f, -0.356f, 0.248f, 1.0f, 0.237f, 0.0f, -0.353f, 0.27f, 1.0f, + 0.238f, 0.0f, -0.35f, 0.289f, 1.0f, 0.239f, 0.0f, -0.346f, 0.304f, 1.0f, 0.24f, 0.0f, -0.343f, 0.319f, 1.0f, 0.241f, 0.0f, -0.34f, 0.334f, 1.0f, + 0.242f, 0.0f, -0.337f, 0.35f, 1.0f, 0.243f, 0.0f, -0.335f, 0.367f, 1.0f, 0.244f, 0.0f, -0.332f, 0.385f, 1.0f, 0.245f, 0.0f, -0.329f, 0.401f, 1.0f, + 0.247f, 0.0f, -0.327f, 0.415f, 1.0f, 0.248f, 0.0f, -0.324f, 0.426f, 1.0f, 0.249f, 0.0f, -0.322f, 0.435f, 1.0f, 0.251f, 0.0f, -0.32f, 0.443f, 1.0f, + 0.252f, 0.0f, -0.318f, 0.449f, 1.0f, 0.254f, 0.0f, -0.316f, 0.455f, 1.0f, 0.255f, 0.0f, -0.314f, 0.461f, 1.0f, 0.257f, 0.0f, -0.312f, 0.467f, 1.0f, + 0.258f, 0.0f, -0.311f, 0.474f, 1.0f, 0.26f, 0.0f, -0.309f, 0.48f, 1.0f, 0.262f, 0.0f, -0.307f, 0.487f, 1.0f, 0.263f, 0.0f, -0.305f, 0.493f, 1.0f, + 0.265f, 0.0f, -0.303f, 0.499f, 1.0f, 0.267f, 0.0f, -0.3f, 0.505f, 1.0f, 0.269f, 0.0f, -0.298f, 0.511f, 1.0f, 0.271f, 0.0f, -0.296f, 0.518f, 1.0f, + 0.273f, 0.0f, -0.294f, 0.524f, 1.0f, 0.276f, 0.0f, -0.291f, 0.531f, 1.0f, 0.278f, 0.0f, -0.289f, 0.539f, 1.0f, 0.281f, 0.0f, -0.287f, 0.546f, 1.0f, + 0.283f, 0.0f, -0.284f, 0.552f, 1.0f, 0.286f, 0.0f, -0.281f, 0.557f, 1.0f, 0.289f, 0.0f, -0.279f, 0.561f, 1.0f, 0.292f, 0.0f, -0.276f, 0.565f, 1.0f, + 0.294f, 0.0f, -0.274f, 0.568f, 1.0f, 0.297f, 0.0f, -0.271f, 0.57f, 1.0f, 0.3f, 0.0f, -0.269f, 0.572f, 1.0f, 0.303f, 0.0f, -0.267f, 0.574f, 1.0f, + 0.306f, 0.0f, -0.264f, 0.575f, 1.0f, 0.308f, 0.0f, -0.262f, 0.576f, 1.0f, 0.311f, 0.0f, -0.26f, 0.577f, 1.0f, 0.314f, 0.0f, -0.257f, 0.578f, 1.0f, + 0.316f, 0.0f, -0.255f, 0.578f, 1.0f, 0.319f, 0.0f, -0.253f, 0.579f, 1.0f, 0.322f, 0.0f, -0.25f, 0.579f, 1.0f, 0.325f, 0.0f, -0.248f, 0.58f, 1.0f, + 0.328f, 0.0f, -0.246f, 0.58f, 1.0f, 0.331f, 0.0f, -0.243f, 0.58f, 1.0f, 0.334f, 0.0f, -0.241f, 0.58f, 1.0f, 0.337f, 0.0f, -0.239f, 0.58f, 1.0f, + 0.341f, 0.0f, -0.236f, 0.58f, 1.0f, 0.344f, 0.0f, -0.233f, 0.581f, 1.0f, 0.348f, 0.0f, -0.231f, 0.581f, 1.0f, 0.352f, 0.0f, -0.228f, 0.581f, 1.0f, + 0.356f, 0.0f, -0.225f, 0.582f, 1.0f, 0.36f, 0.0f, -0.222f, 0.582f, 1.0f, 0.365f, 0.0f, -0.219f, 0.582f, 1.0f, 0.369f, 0.0f, -0.216f, 0.582f, 1.0f, + 0.374f, 0.0f, -0.214f, 0.582f, 1.0f, 0.378f, 0.0f, -0.211f, 0.582f, 1.0f, 0.383f, 0.0f, -0.208f, 0.583f, 1.0f, 0.387f, 0.0f, -0.205f, 0.583f, 1.0f, + 0.392f, 0.0f, -0.202f, 0.583f, 1.0f, 0.397f, 0.0f, -0.199f, 0.583f, 1.0f, 0.401f, 0.0f, -0.197f, 0.583f, 1.0f, 0.406f, 0.0f, -0.194f, 0.583f, 1.0f, + 0.411f, 0.0f, -0.191f, 0.583f, 1.0f, 0.416f, 0.0f, -0.188f, 0.583f, 1.0f, 0.42f, 0.0f, -0.186f, 0.583f, 1.0f, 0.425f, 0.0f, -0.183f, 0.583f, 1.0f, + 0.43f, 0.0f, -0.18f, 0.583f, 1.0f, 0.434f, 0.0f, -0.178f, 0.583f, 1.0f, 0.439f, 0.0f, -0.175f, 0.583f, 1.0f, 0.444f, 0.0f, -0.172f, 0.583f, 1.0f, + 0.449f, 0.0f, -0.17f, 0.584f, 1.0f, 0.453f, 0.0f, -0.167f, 0.584f, 1.0f, 0.458f, 0.0f, -0.164f, 0.584f, 1.0f, 0.463f, 0.0f, -0.161f, 0.585f, 1.0f, + 0.468f, 0.0f, -0.158f, 0.585f, 1.0f, 0.473f, 0.0f, -0.155f, 0.585f, 1.0f, 0.478f, 0.0f, -0.152f, 0.585f, 1.0f, 0.483f, 0.0f, -0.149f, 0.585f, 1.0f, + 0.488f, 0.0f, -0.146f, 0.585f, 1.0f, 0.492f, 0.0f, -0.143f, 0.585f, 1.0f, 0.497f, 0.0f, -0.14f, 0.586f, 1.0f, 0.501f, 0.0f, -0.137f, 0.586f, 1.0f, + 0.506f, 0.0f, -0.134f, 0.586f, 1.0f, 0.51f, 0.0f, -0.13f, 0.586f, 1.0f, 0.515f, 0.0f, -0.127f, 0.586f, 1.0f, 0.52f, 0.0f, -0.124f, 0.586f, 1.0f, + 0.524f, 0.0f, -0.12f, 0.586f, 1.0f, 0.529f, 0.0f, -0.117f, 0.586f, 1.0f, 0.534f, 0.0f, -0.113f, 0.586f, 1.0f, 0.539f, 0.0f, -0.109f, 0.586f, 1.0f, + 0.544f, 0.0f, -0.105f, 0.586f, 1.0f, 0.55f, 0.0f, -0.1f, 0.586f, 1.0f, 0.555f, 0.0f, -0.095f, 0.586f, 1.0f, 0.561f, 0.0f, -0.09f, 0.586f, 1.0f, + 0.567f, 0.0f, -0.084f, 0.587f, 1.0f, 0.573f, 0.0f, -0.078f, 0.587f, 1.0f, 0.579f, 0.0f, -0.071f, 0.587f, 1.0f, 0.586f, 0.0f, -0.063f, 0.588f, 1.0f, + 0.593f, 0.0f, -0.055f, 0.588f, 1.0f, 0.6f, 0.0f, -0.047f, 0.588f, 1.0f, 0.607f, 0.0f, -0.038f, 0.589f, 1.0f, 0.614f, 0.0f, -0.028f, 0.589f, 1.0f, + 0.621f, 0.0f, -0.018f, 0.589f, 1.0f, 0.629f, 0.0f, -0.007f, 0.589f, 1.0f, 0.636f, 0.0f, 0.004f, 0.589f, 1.0f, 0.643f, 0.0f, 0.015f, 0.59f, 1.0f, + 0.65f, 0.0f, 0.026f, 0.589f, 1.0f, 0.656f, 0.0f, 0.038f, 0.589f, 1.0f, 0.663f, 0.0f, 0.049f, 0.588f, 1.0f, 0.669f, 0.0f, 0.06f, 0.587f, 1.0f, + 0.676f, 0.0f, 0.072f, 0.584f, 1.0f, 0.682f, 0.0f, 0.084f, 0.579f, 1.0f, 0.688f, 0.0f, 0.096f, 0.571f, 1.0f, 0.694f, 0.0f, 0.108f, 0.558f, 1.0f, + 0.7f, 0.0f, 0.12f, 0.54f, 1.0f, 0.706f, 0.0f, 0.133f, 0.514f, 1.0f, 0.712f, 0.0f, 0.145f, 0.478f, 1.0f, 0.718f, 0.0f, 0.158f, 0.431f, 1.0f, + 0.723f, 0.0f, 0.17f, 0.369f, 1.0f, 0.728f, 0.0f, 0.182f, 0.294f, 1.0f, 0.733f, 0.0f, 0.194f, 0.205f, 1.0f, 0.737f, 0.0f, 0.204f, 0.125f, 1.0f, + 0.743f, 0.0f, 0.218f, 0.0f, 1.0f, +}; + +static const float data25[389 * GP_PRIM_DATABUF_SIZE] = { + -0.284f, 0.0f, -0.444f, 0.0f, 1.0f, -0.285f, 0.0f, -0.448f, 0.0f, 1.0f, -0.285f, 0.0f, -0.45f, 0.0f, 1.0f, -0.286f, 0.0f, -0.454f, 0.0f, 1.0f, + -0.286f, 0.0f, -0.457f, 0.0f, 1.0f, -0.287f, 0.0f, -0.46f, 0.0f, 1.0f, -0.288f, 0.0f, -0.463f, 0.0f, 1.0f, -0.289f, 0.0f, -0.466f, 0.0f, 1.0f, + -0.289f, 0.0f, -0.47f, 0.0f, 1.0f, -0.29f, 0.0f, -0.473f, 0.0f, 1.0f, -0.291f, 0.0f, -0.476f, 0.0f, 1.0f, -0.292f, 0.0f, -0.48f, 0.0f, 1.0f, + -0.293f, 0.0f, -0.484f, 0.0f, 1.0f, -0.294f, 0.0f, -0.487f, 0.0f, 1.0f, -0.295f, 0.0f, -0.491f, 0.0f, 1.0f, -0.296f, 0.0f, -0.494f, 0.0f, 1.0f, + -0.297f, 0.0f, -0.498f, 0.0f, 1.0f, -0.298f, 0.0f, -0.502f, 0.0f, 1.0f, -0.299f, 0.0f, -0.505f, 0.0f, 1.0f, -0.3f, 0.0f, -0.509f, 0.0f, 1.0f, + -0.301f, 0.0f, -0.513f, 0.0f, 1.0f, -0.302f, 0.0f, -0.517f, 0.0f, 1.0f, -0.303f, 0.0f, -0.52f, 0.0f, 1.0f, -0.304f, 0.0f, -0.524f, 0.0f, 1.0f, + -0.305f, 0.0f, -0.528f, 0.0f, 1.0f, -0.306f, 0.0f, -0.532f, 0.0f, 1.0f, -0.307f, 0.0f, -0.535f, 0.0f, 1.0f, -0.308f, 0.0f, -0.539f, 0.0f, 1.0f, + -0.309f, 0.0f, -0.543f, 0.0f, 1.0f, -0.31f, 0.0f, -0.547f, 0.0f, 1.0f, -0.311f, 0.0f, -0.55f, 0.0f, 1.0f, -0.312f, 0.0f, -0.554f, 0.0f, 1.0f, + -0.313f, 0.0f, -0.558f, 0.0f, 1.0f, -0.314f, 0.0f, -0.562f, 0.0f, 1.0f, -0.315f, 0.0f, -0.565f, 0.0f, 1.0f, -0.316f, 0.0f, -0.569f, 0.0f, 1.0f, + -0.317f, 0.0f, -0.573f, 0.0f, 1.0f, -0.318f, 0.0f, -0.576f, 0.0f, 1.0f, -0.319f, 0.0f, -0.58f, 0.0f, 1.0f, -0.32f, 0.0f, -0.583f, 0.0f, 1.0f, + -0.321f, 0.0f, -0.587f, 0.0f, 1.0f, -0.322f, 0.0f, -0.591f, 0.0f, 1.0f, -0.323f, 0.0f, -0.594f, 0.0f, 1.0f, -0.323f, 0.0f, -0.598f, 0.0f, 1.0f, + -0.324f, 0.0f, -0.601f, 0.0f, 1.0f, -0.325f, 0.0f, -0.605f, 0.0f, 1.0f, -0.326f, 0.0f, -0.608f, 0.0f, 1.0f, -0.326f, 0.0f, -0.612f, 0.0f, 1.0f, + -0.327f, 0.0f, -0.615f, 0.0f, 1.0f, -0.328f, 0.0f, -0.619f, 0.0f, 1.0f, -0.328f, 0.0f, -0.622f, 0.0f, 1.0f, -0.329f, 0.0f, -0.625f, 0.0f, 1.0f, + -0.33f, 0.0f, -0.629f, 0.0f, 1.0f, -0.33f, 0.0f, -0.632f, 0.0f, 1.0f, -0.331f, 0.0f, -0.635f, 0.001f, 1.0f, -0.331f, 0.0f, -0.639f, 0.001f, 1.0f, + -0.332f, 0.0f, -0.642f, 0.002f, 1.0f, -0.332f, 0.0f, -0.645f, 0.002f, 1.0f, -0.333f, 0.0f, -0.649f, 0.003f, 1.0f, -0.333f, 0.0f, -0.652f, 0.005f, 1.0f, + -0.334f, 0.0f, -0.655f, 0.006f, 1.0f, -0.334f, 0.0f, -0.658f, 0.009f, 1.0f, -0.335f, 0.0f, -0.662f, 0.011f, 1.0f, -0.335f, 0.0f, -0.665f, 0.015f, 1.0f, + -0.335f, 0.0f, -0.668f, 0.019f, 1.0f, -0.336f, 0.0f, -0.672f, 0.024f, 1.0f, -0.336f, 0.0f, -0.675f, 0.031f, 1.0f, -0.337f, 0.0f, -0.678f, 0.038f, 1.0f, + -0.337f, 0.0f, -0.682f, 0.046f, 1.0f, -0.337f, 0.0f, -0.685f, 0.056f, 1.0f, -0.338f, 0.0f, -0.689f, 0.067f, 1.0f, -0.338f, 0.0f, -0.692f, 0.079f, 1.0f, + -0.338f, 0.0f, -0.696f, 0.093f, 1.0f, -0.339f, 0.0f, -0.699f, 0.107f, 1.0f, -0.339f, 0.0f, -0.703f, 0.123f, 1.0f, -0.34f, 0.0f, -0.706f, 0.139f, 1.0f, + -0.34f, 0.0f, -0.71f, 0.157f, 1.0f, -0.34f, 0.0f, -0.714f, 0.174f, 1.0f, -0.34f, 0.0f, -0.717f, 0.193f, 1.0f, -0.341f, 0.0f, -0.721f, 0.211f, 1.0f, + -0.341f, 0.0f, -0.725f, 0.23f, 1.0f, -0.341f, 0.0f, -0.729f, 0.248f, 1.0f, -0.342f, 0.0f, -0.732f, 0.266f, 1.0f, -0.342f, 0.0f, -0.736f, 0.284f, 1.0f, + -0.342f, 0.0f, -0.74f, 0.302f, 1.0f, -0.342f, 0.0f, -0.744f, 0.318f, 1.0f, -0.342f, 0.0f, -0.748f, 0.334f, 1.0f, -0.342f, 0.0f, -0.752f, 0.349f, 1.0f, + -0.343f, 0.0f, -0.756f, 0.364f, 1.0f, -0.343f, 0.0f, -0.76f, 0.377f, 1.0f, -0.343f, 0.0f, -0.763f, 0.389f, 1.0f, -0.343f, 0.0f, -0.767f, 0.401f, 1.0f, + -0.343f, 0.0f, -0.771f, 0.411f, 1.0f, -0.343f, 0.0f, -0.775f, 0.421f, 1.0f, -0.342f, 0.0f, -0.779f, 0.429f, 1.0f, -0.342f, 0.0f, -0.783f, 0.437f, 1.0f, + -0.342f, 0.0f, -0.786f, 0.444f, 1.0f, -0.342f, 0.0f, -0.79f, 0.451f, 1.0f, -0.342f, 0.0f, -0.794f, 0.456f, 1.0f, -0.341f, 0.0f, -0.797f, 0.461f, 1.0f, + -0.341f, 0.0f, -0.801f, 0.466f, 1.0f, -0.34f, 0.0f, -0.805f, 0.469f, 1.0f, -0.34f, 0.0f, -0.808f, 0.473f, 1.0f, -0.339f, 0.0f, -0.812f, 0.476f, 1.0f, + -0.339f, 0.0f, -0.815f, 0.478f, 1.0f, -0.338f, 0.0f, -0.818f, 0.48f, 1.0f, -0.338f, 0.0f, -0.822f, 0.482f, 1.0f, -0.337f, 0.0f, -0.825f, 0.483f, 1.0f, + -0.336f, 0.0f, -0.828f, 0.484f, 1.0f, -0.335f, 0.0f, -0.831f, 0.485f, 1.0f, -0.334f, 0.0f, -0.834f, 0.486f, 1.0f, -0.333f, 0.0f, -0.837f, 0.487f, 1.0f, + -0.332f, 0.0f, -0.84f, 0.487f, 1.0f, -0.331f, 0.0f, -0.843f, 0.487f, 1.0f, -0.33f, 0.0f, -0.846f, 0.488f, 1.0f, -0.329f, 0.0f, -0.849f, 0.488f, 1.0f, + -0.328f, 0.0f, -0.852f, 0.488f, 1.0f, -0.326f, 0.0f, -0.855f, 0.488f, 1.0f, -0.325f, 0.0f, -0.857f, 0.488f, 1.0f, -0.324f, 0.0f, -0.86f, 0.488f, 1.0f, + -0.322f, 0.0f, -0.863f, 0.488f, 1.0f, -0.321f, 0.0f, -0.865f, 0.488f, 1.0f, -0.319f, 0.0f, -0.868f, 0.488f, 1.0f, -0.318f, 0.0f, -0.871f, 0.488f, 1.0f, + -0.316f, 0.0f, -0.873f, 0.489f, 1.0f, -0.314f, 0.0f, -0.876f, 0.489f, 1.0f, -0.312f, 0.0f, -0.878f, 0.489f, 1.0f, -0.311f, 0.0f, -0.881f, 0.489f, 1.0f, + -0.309f, 0.0f, -0.883f, 0.489f, 1.0f, -0.307f, 0.0f, -0.885f, 0.489f, 1.0f, -0.305f, 0.0f, -0.888f, 0.49f, 1.0f, -0.303f, 0.0f, -0.89f, 0.491f, 1.0f, + -0.301f, 0.0f, -0.892f, 0.491f, 1.0f, -0.298f, 0.0f, -0.894f, 0.492f, 1.0f, -0.296f, 0.0f, -0.897f, 0.494f, 1.0f, -0.294f, 0.0f, -0.899f, 0.495f, 1.0f, + -0.292f, 0.0f, -0.901f, 0.497f, 1.0f, -0.289f, 0.0f, -0.903f, 0.5f, 1.0f, -0.287f, 0.0f, -0.905f, 0.502f, 1.0f, -0.284f, 0.0f, -0.907f, 0.505f, 1.0f, + -0.282f, 0.0f, -0.909f, 0.509f, 1.0f, -0.279f, 0.0f, -0.912f, 0.512f, 1.0f, -0.277f, 0.0f, -0.914f, 0.517f, 1.0f, -0.274f, 0.0f, -0.916f, 0.521f, 1.0f, + -0.271f, 0.0f, -0.918f, 0.526f, 1.0f, -0.269f, 0.0f, -0.919f, 0.531f, 1.0f, -0.266f, 0.0f, -0.921f, 0.537f, 1.0f, -0.263f, 0.0f, -0.923f, 0.543f, 1.0f, + -0.26f, 0.0f, -0.925f, 0.548f, 1.0f, -0.257f, 0.0f, -0.927f, 0.554f, 1.0f, -0.255f, 0.0f, -0.929f, 0.56f, 1.0f, -0.252f, 0.0f, -0.931f, 0.566f, 1.0f, + -0.249f, 0.0f, -0.932f, 0.571f, 1.0f, -0.246f, 0.0f, -0.934f, 0.577f, 1.0f, -0.243f, 0.0f, -0.936f, 0.582f, 1.0f, -0.24f, 0.0f, -0.938f, 0.587f, 1.0f, + -0.237f, 0.0f, -0.939f, 0.592f, 1.0f, -0.234f, 0.0f, -0.941f, 0.597f, 1.0f, -0.231f, 0.0f, -0.943f, 0.601f, 1.0f, -0.228f, 0.0f, -0.944f, 0.605f, 1.0f, + -0.225f, 0.0f, -0.946f, 0.609f, 1.0f, -0.222f, 0.0f, -0.948f, 0.613f, 1.0f, -0.219f, 0.0f, -0.949f, 0.617f, 1.0f, -0.216f, 0.0f, -0.951f, 0.62f, 1.0f, + -0.213f, 0.0f, -0.953f, 0.624f, 1.0f, -0.21f, 0.0f, -0.954f, 0.627f, 1.0f, -0.207f, 0.0f, -0.956f, 0.63f, 1.0f, -0.204f, 0.0f, -0.958f, 0.633f, 1.0f, + -0.201f, 0.0f, -0.959f, 0.636f, 1.0f, -0.198f, 0.0f, -0.961f, 0.639f, 1.0f, -0.195f, 0.0f, -0.962f, 0.641f, 1.0f, -0.191f, 0.0f, -0.964f, 0.643f, 1.0f, + -0.188f, 0.0f, -0.965f, 0.646f, 1.0f, -0.185f, 0.0f, -0.967f, 0.648f, 1.0f, -0.181f, 0.0f, -0.968f, 0.649f, 1.0f, -0.178f, 0.0f, -0.969f, 0.651f, 1.0f, + -0.175f, 0.0f, -0.971f, 0.653f, 1.0f, -0.171f, 0.0f, -0.972f, 0.654f, 1.0f, -0.168f, 0.0f, -0.973f, 0.655f, 1.0f, -0.165f, 0.0f, -0.974f, 0.657f, 1.0f, + -0.161f, 0.0f, -0.976f, 0.658f, 1.0f, -0.158f, 0.0f, -0.977f, 0.659f, 1.0f, -0.154f, 0.0f, -0.978f, 0.66f, 1.0f, -0.151f, 0.0f, -0.979f, 0.661f, 1.0f, + -0.148f, 0.0f, -0.98f, 0.662f, 1.0f, -0.144f, 0.0f, -0.981f, 0.664f, 1.0f, -0.141f, 0.0f, -0.982f, 0.665f, 1.0f, -0.137f, 0.0f, -0.983f, 0.667f, 1.0f, + -0.134f, 0.0f, -0.984f, 0.669f, 1.0f, -0.13f, 0.0f, -0.985f, 0.671f, 1.0f, -0.127f, 0.0f, -0.986f, 0.673f, 1.0f, -0.124f, 0.0f, -0.987f, 0.675f, 1.0f, + -0.12f, 0.0f, -0.988f, 0.678f, 1.0f, -0.117f, 0.0f, -0.989f, 0.68f, 1.0f, -0.113f, 0.0f, -0.99f, 0.683f, 1.0f, -0.11f, 0.0f, -0.991f, 0.685f, 1.0f, + -0.107f, 0.0f, -0.992f, 0.688f, 1.0f, -0.103f, 0.0f, -0.992f, 0.691f, 1.0f, -0.1f, 0.0f, -0.993f, 0.693f, 1.0f, -0.097f, 0.0f, -0.994f, 0.696f, 1.0f, + -0.093f, 0.0f, -0.995f, 0.698f, 1.0f, -0.09f, 0.0f, -0.996f, 0.701f, 1.0f, -0.087f, 0.0f, -0.997f, 0.703f, 1.0f, -0.084f, 0.0f, -0.997f, 0.705f, 1.0f, + -0.08f, 0.0f, -0.998f, 0.707f, 1.0f, -0.077f, 0.0f, -0.999f, 0.708f, 1.0f, -0.074f, 0.0f, -1.0f, 0.71f, 1.0f, -0.07f, 0.0f, -1.0f, 0.712f, 1.0f, + -0.067f, 0.0f, -1.001f, 0.713f, 1.0f, -0.063f, 0.0f, -1.002f, 0.715f, 1.0f, -0.06f, 0.0f, -1.002f, 0.717f, 1.0f, -0.056f, 0.0f, -1.003f, 0.718f, 1.0f, + -0.053f, 0.0f, -1.003f, 0.72f, 1.0f, -0.049f, 0.0f, -1.004f, 0.723f, 1.0f, -0.045f, 0.0f, -1.004f, 0.725f, 1.0f, -0.041f, 0.0f, -1.005f, 0.728f, 1.0f, + -0.038f, 0.0f, -1.005f, 0.73f, 1.0f, -0.034f, 0.0f, -1.006f, 0.733f, 1.0f, -0.03f, 0.0f, -1.006f, 0.736f, 1.0f, -0.026f, 0.0f, -1.007f, 0.738f, 1.0f, + -0.022f, 0.0f, -1.007f, 0.741f, 1.0f, -0.018f, 0.0f, -1.007f, 0.743f, 1.0f, -0.014f, 0.0f, -1.008f, 0.746f, 1.0f, -0.01f, 0.0f, -1.008f, 0.748f, 1.0f, + -0.006f, 0.0f, -1.009f, 0.75f, 1.0f, -0.001f, 0.0f, -1.009f, 0.752f, 1.0f, 0.003f, 0.0f, -1.009f, 0.754f, 1.0f, 0.007f, 0.0f, -1.01f, 0.755f, 1.0f, + 0.011f, 0.0f, -1.01f, 0.757f, 1.0f, 0.015f, 0.0f, -1.01f, 0.758f, 1.0f, 0.02f, 0.0f, -1.011f, 0.759f, 1.0f, 0.024f, 0.0f, -1.011f, 0.76f, 1.0f, + 0.028f, 0.0f, -1.011f, 0.761f, 1.0f, 0.033f, 0.0f, -1.011f, 0.761f, 1.0f, 0.037f, 0.0f, -1.012f, 0.762f, 1.0f, 0.041f, 0.0f, -1.012f, 0.762f, 1.0f, + 0.045f, 0.0f, -1.012f, 0.763f, 1.0f, 0.05f, 0.0f, -1.012f, 0.763f, 1.0f, 0.054f, 0.0f, -1.012f, 0.764f, 1.0f, 0.058f, 0.0f, -1.013f, 0.764f, 1.0f, + 0.062f, 0.0f, -1.013f, 0.764f, 1.0f, 0.066f, 0.0f, -1.013f, 0.764f, 1.0f, 0.071f, 0.0f, -1.013f, 0.764f, 1.0f, 0.075f, 0.0f, -1.013f, 0.765f, 1.0f, + 0.079f, 0.0f, -1.013f, 0.765f, 1.0f, 0.083f, 0.0f, -1.013f, 0.765f, 1.0f, 0.087f, 0.0f, -1.013f, 0.765f, 1.0f, 0.091f, 0.0f, -1.013f, 0.765f, 1.0f, + 0.095f, 0.0f, -1.013f, 0.765f, 1.0f, 0.099f, 0.0f, -1.013f, 0.766f, 1.0f, 0.103f, 0.0f, -1.013f, 0.766f, 1.0f, 0.108f, 0.0f, -1.012f, 0.766f, 1.0f, + 0.112f, 0.0f, -1.012f, 0.766f, 1.0f, 0.116f, 0.0f, -1.012f, 0.766f, 1.0f, 0.119f, 0.0f, -1.012f, 0.767f, 1.0f, 0.123f, 0.0f, -1.011f, 0.767f, 1.0f, + 0.127f, 0.0f, -1.011f, 0.767f, 1.0f, 0.131f, 0.0f, -1.01f, 0.767f, 1.0f, 0.135f, 0.0f, -1.01f, 0.767f, 1.0f, 0.139f, 0.0f, -1.009f, 0.768f, 1.0f, + 0.143f, 0.0f, -1.009f, 0.768f, 1.0f, 0.147f, 0.0f, -1.008f, 0.768f, 1.0f, 0.151f, 0.0f, -1.007f, 0.769f, 1.0f, 0.154f, 0.0f, -1.007f, 0.769f, 1.0f, + 0.158f, 0.0f, -1.006f, 0.769f, 1.0f, 0.162f, 0.0f, -1.005f, 0.769f, 1.0f, 0.166f, 0.0f, -1.004f, 0.77f, 1.0f, 0.17f, 0.0f, -1.003f, 0.77f, 1.0f, + 0.173f, 0.0f, -1.003f, 0.77f, 1.0f, 0.177f, 0.0f, -1.002f, 0.771f, 1.0f, 0.181f, 0.0f, -1.001f, 0.771f, 1.0f, 0.184f, 0.0f, -1.0f, 0.772f, 1.0f, + 0.188f, 0.0f, -0.999f, 0.772f, 1.0f, 0.192f, 0.0f, -0.998f, 0.773f, 1.0f, 0.195f, 0.0f, -0.997f, 0.773f, 1.0f, 0.199f, 0.0f, -0.996f, 0.774f, 1.0f, + 0.202f, 0.0f, -0.995f, 0.774f, 1.0f, 0.206f, 0.0f, -0.994f, 0.775f, 1.0f, 0.209f, 0.0f, -0.993f, 0.776f, 1.0f, 0.213f, 0.0f, -0.992f, 0.776f, 1.0f, + 0.216f, 0.0f, -0.991f, 0.777f, 1.0f, 0.22f, 0.0f, -0.99f, 0.777f, 1.0f, 0.223f, 0.0f, -0.988f, 0.778f, 1.0f, 0.227f, 0.0f, -0.987f, 0.778f, 1.0f, + 0.23f, 0.0f, -0.986f, 0.778f, 1.0f, 0.233f, 0.0f, -0.985f, 0.779f, 1.0f, 0.237f, 0.0f, -0.983f, 0.779f, 1.0f, 0.24f, 0.0f, -0.982f, 0.779f, 1.0f, + 0.243f, 0.0f, -0.981f, 0.779f, 1.0f, 0.246f, 0.0f, -0.979f, 0.778f, 1.0f, 0.249f, 0.0f, -0.978f, 0.778f, 1.0f, 0.252f, 0.0f, -0.976f, 0.777f, 1.0f, + 0.255f, 0.0f, -0.975f, 0.777f, 1.0f, 0.258f, 0.0f, -0.973f, 0.776f, 1.0f, 0.261f, 0.0f, -0.972f, 0.775f, 1.0f, 0.264f, 0.0f, -0.97f, 0.773f, 1.0f, + 0.267f, 0.0f, -0.968f, 0.772f, 1.0f, 0.269f, 0.0f, -0.967f, 0.77f, 1.0f, 0.272f, 0.0f, -0.965f, 0.769f, 1.0f, 0.275f, 0.0f, -0.963f, 0.767f, 1.0f, + 0.277f, 0.0f, -0.961f, 0.765f, 1.0f, 0.279f, 0.0f, -0.959f, 0.763f, 1.0f, 0.282f, 0.0f, -0.957f, 0.761f, 1.0f, 0.284f, 0.0f, -0.955f, 0.759f, 1.0f, + 0.286f, 0.0f, -0.953f, 0.756f, 1.0f, 0.288f, 0.0f, -0.951f, 0.754f, 1.0f, 0.29f, 0.0f, -0.948f, 0.752f, 1.0f, 0.292f, 0.0f, -0.946f, 0.749f, 1.0f, + 0.294f, 0.0f, -0.944f, 0.746f, 1.0f, 0.296f, 0.0f, -0.941f, 0.744f, 1.0f, 0.298f, 0.0f, -0.939f, 0.741f, 1.0f, 0.3f, 0.0f, -0.937f, 0.738f, 1.0f, + 0.302f, 0.0f, -0.934f, 0.736f, 1.0f, 0.303f, 0.0f, -0.932f, 0.733f, 1.0f, 0.305f, 0.0f, -0.929f, 0.73f, 1.0f, 0.306f, 0.0f, -0.926f, 0.727f, 1.0f, + 0.308f, 0.0f, -0.924f, 0.724f, 1.0f, 0.309f, 0.0f, -0.921f, 0.721f, 1.0f, 0.311f, 0.0f, -0.918f, 0.719f, 1.0f, 0.312f, 0.0f, -0.916f, 0.716f, 1.0f, + 0.313f, 0.0f, -0.913f, 0.713f, 1.0f, 0.315f, 0.0f, -0.91f, 0.71f, 1.0f, 0.316f, 0.0f, -0.907f, 0.707f, 1.0f, 0.317f, 0.0f, -0.904f, 0.704f, 1.0f, + 0.318f, 0.0f, -0.901f, 0.7f, 1.0f, 0.319f, 0.0f, -0.898f, 0.697f, 1.0f, 0.32f, 0.0f, -0.895f, 0.693f, 1.0f, 0.321f, 0.0f, -0.892f, 0.69f, 1.0f, + 0.322f, 0.0f, -0.889f, 0.686f, 1.0f, 0.323f, 0.0f, -0.886f, 0.681f, 1.0f, 0.324f, 0.0f, -0.883f, 0.677f, 1.0f, 0.325f, 0.0f, -0.88f, 0.672f, 1.0f, + 0.326f, 0.0f, -0.876f, 0.667f, 1.0f, 0.326f, 0.0f, -0.873f, 0.661f, 1.0f, 0.327f, 0.0f, -0.87f, 0.655f, 1.0f, 0.328f, 0.0f, -0.867f, 0.649f, 1.0f, + 0.329f, 0.0f, -0.864f, 0.643f, 1.0f, 0.329f, 0.0f, -0.861f, 0.637f, 1.0f, 0.33f, 0.0f, -0.857f, 0.63f, 1.0f, 0.331f, 0.0f, -0.854f, 0.624f, 1.0f, + 0.331f, 0.0f, -0.851f, 0.618f, 1.0f, 0.332f, 0.0f, -0.848f, 0.613f, 1.0f, 0.333f, 0.0f, -0.845f, 0.607f, 1.0f, 0.333f, 0.0f, -0.841f, 0.603f, 1.0f, + 0.334f, 0.0f, -0.838f, 0.598f, 1.0f, 0.334f, 0.0f, -0.835f, 0.594f, 1.0f, 0.335f, 0.0f, -0.832f, 0.591f, 1.0f, 0.335f, 0.0f, -0.828f, 0.588f, 1.0f, + 0.335f, 0.0f, -0.825f, 0.586f, 1.0f, 0.336f, 0.0f, -0.821f, 0.584f, 1.0f, 0.336f, 0.0f, -0.818f, 0.582f, 1.0f, 0.336f, 0.0f, -0.814f, 0.581f, 1.0f, + 0.337f, 0.0f, -0.811f, 0.58f, 1.0f, 0.337f, 0.0f, -0.807f, 0.58f, 1.0f, 0.337f, 0.0f, -0.803f, 0.579f, 1.0f, 0.337f, 0.0f, -0.799f, 0.579f, 1.0f, + 0.337f, 0.0f, -0.795f, 0.578f, 1.0f, 0.337f, 0.0f, -0.79f, 0.578f, 1.0f, 0.337f, 0.0f, -0.786f, 0.578f, 1.0f, 0.338f, 0.0f, -0.782f, 0.577f, 1.0f, + 0.338f, 0.0f, -0.777f, 0.576f, 1.0f, 0.337f, 0.0f, -0.772f, 0.574f, 1.0f, 0.337f, 0.0f, -0.767f, 0.572f, 1.0f, 0.337f, 0.0f, -0.762f, 0.569f, 1.0f, + 0.337f, 0.0f, -0.756f, 0.565f, 1.0f, 0.337f, 0.0f, -0.751f, 0.559f, 1.0f, 0.337f, 0.0f, -0.745f, 0.553f, 1.0f, 0.336f, 0.0f, -0.739f, 0.544f, 1.0f, + 0.336f, 0.0f, -0.732f, 0.534f, 1.0f, 0.335f, 0.0f, -0.725f, 0.521f, 1.0f, 0.334f, 0.0f, -0.718f, 0.505f, 1.0f, 0.333f, 0.0f, -0.711f, 0.487f, 1.0f, + 0.332f, 0.0f, -0.703f, 0.466f, 1.0f, 0.331f, 0.0f, -0.694f, 0.441f, 1.0f, 0.33f, 0.0f, -0.686f, 0.413f, 1.0f, 0.328f, 0.0f, -0.677f, 0.383f, 1.0f, + 0.326f, 0.0f, -0.667f, 0.35f, 1.0f, 0.325f, 0.0f, -0.657f, 0.316f, 1.0f, 0.323f, 0.0f, -0.647f, 0.281f, 1.0f, 0.32f, 0.0f, -0.636f, 0.246f, 1.0f, + 0.318f, 0.0f, -0.625f, 0.212f, 1.0f, 0.316f, 0.0f, -0.614f, 0.18f, 1.0f, 0.313f, 0.0f, -0.603f, 0.149f, 1.0f, 0.311f, 0.0f, -0.592f, 0.12f, 1.0f, + 0.308f, 0.0f, -0.581f, 0.093f, 1.0f, 0.306f, 0.0f, -0.57f, 0.069f, 1.0f, 0.303f, 0.0f, -0.559f, 0.046f, 1.0f, 0.301f, 0.0f, -0.55f, 0.027f, 1.0f, + 0.298f, 0.0f, -0.537f, 0.0f, 1.0f, +}; + +static const float data26[41 * GP_PRIM_DATABUF_SIZE] = { + -0.104f, 0.0f, -0.795f, 0.258f, 1.0f, -0.1f, 0.0f, -0.799f, 0.28f, 1.0f, -0.097f, 0.0f, -0.801f, 0.294f, 1.0f, -0.094f, 0.0f, -0.805f, 0.312f, 1.0f, + -0.09f, 0.0f, -0.808f, 0.328f, 1.0f, -0.086f, 0.0f, -0.811f, 0.345f, 1.0f, -0.082f, 0.0f, -0.815f, 0.361f, 1.0f, -0.078f, 0.0f, -0.818f, 0.377f, 1.0f, + -0.073f, 0.0f, -0.821f, 0.392f, 1.0f, -0.068f, 0.0f, -0.824f, 0.407f, 1.0f, -0.063f, 0.0f, -0.827f, 0.421f, 1.0f, -0.057f, 0.0f, -0.83f, 0.435f, 1.0f, + -0.051f, 0.0f, -0.833f, 0.448f, 1.0f, -0.045f, 0.0f, -0.835f, 0.46f, 1.0f, -0.039f, 0.0f, -0.837f, 0.471f, 1.0f, -0.033f, 0.0f, -0.839f, 0.481f, 1.0f, + -0.026f, 0.0f, -0.841f, 0.491f, 1.0f, -0.019f, 0.0f, -0.842f, 0.5f, 1.0f, -0.012f, 0.0f, -0.843f, 0.508f, 1.0f, -0.005f, 0.0f, -0.843f, 0.515f, 1.0f, + 0.002f, 0.0f, -0.843f, 0.522f, 1.0f, 0.009f, 0.0f, -0.843f, 0.527f, 1.0f, 0.016f, 0.0f, -0.842f, 0.532f, 1.0f, 0.023f, 0.0f, -0.841f, 0.535f, 1.0f, + 0.03f, 0.0f, -0.839f, 0.538f, 1.0f, 0.037f, 0.0f, -0.837f, 0.538f, 1.0f, 0.044f, 0.0f, -0.835f, 0.537f, 1.0f, 0.05f, 0.0f, -0.833f, 0.532f, 1.0f, + 0.056f, 0.0f, -0.83f, 0.524f, 1.0f, 0.062f, 0.0f, -0.827f, 0.513f, 1.0f, 0.068f, 0.0f, -0.823f, 0.496f, 1.0f, 0.074f, 0.0f, -0.82f, 0.474f, 1.0f, + 0.079f, 0.0f, -0.817f, 0.446f, 1.0f, 0.084f, 0.0f, -0.813f, 0.411f, 1.0f, 0.089f, 0.0f, -0.809f, 0.37f, 1.0f, 0.093f, 0.0f, -0.806f, 0.323f, 1.0f, + 0.098f, 0.0f, -0.802f, 0.269f, 1.0f, 0.102f, 0.0f, -0.798f, 0.211f, 1.0f, 0.106f, 0.0f, -0.795f, 0.146f, 1.0f, 0.109f, 0.0f, -0.792f, 0.089f, 1.0f, + 0.114f, 0.0f, -0.787f, 0.0f, 1.0f, +}; + +static const float data27[77 * GP_PRIM_DATABUF_SIZE] = { + -0.105f, 0.0f, -0.259f, 0.214f, 1.0f, -0.103f, 0.0f, -0.253f, 0.263f, 1.0f, -0.101f, 0.0f, -0.249f, 0.291f, 1.0f, -0.099f, 0.0f, -0.244f, 0.324f, 1.0f, + -0.098f, 0.0f, -0.24f, 0.351f, 1.0f, -0.096f, 0.0f, -0.235f, 0.376f, 1.0f, -0.094f, 0.0f, -0.231f, 0.397f, 1.0f, -0.092f, 0.0f, -0.227f, 0.416f, 1.0f, + -0.09f, 0.0f, -0.222f, 0.432f, 1.0f, -0.088f, 0.0f, -0.218f, 0.446f, 1.0f, -0.086f, 0.0f, -0.215f, 0.458f, 1.0f, -0.084f, 0.0f, -0.211f, 0.469f, 1.0f, + -0.082f, 0.0f, -0.208f, 0.478f, 1.0f, -0.079f, 0.0f, -0.205f, 0.486f, 1.0f, -0.077f, 0.0f, -0.203f, 0.494f, 1.0f, -0.075f, 0.0f, -0.2f, 0.501f, 1.0f, + -0.073f, 0.0f, -0.198f, 0.508f, 1.0f, -0.071f, 0.0f, -0.197f, 0.515f, 1.0f, -0.068f, 0.0f, -0.195f, 0.521f, 1.0f, -0.066f, 0.0f, -0.194f, 0.528f, 1.0f, + -0.064f, 0.0f, -0.194f, 0.534f, 1.0f, -0.061f, 0.0f, -0.194f, 0.54f, 1.0f, -0.059f, 0.0f, -0.194f, 0.546f, 1.0f, -0.056f, 0.0f, -0.194f, 0.551f, 1.0f, + -0.054f, 0.0f, -0.195f, 0.555f, 1.0f, -0.051f, 0.0f, -0.196f, 0.559f, 1.0f, -0.049f, 0.0f, -0.198f, 0.562f, 1.0f, -0.046f, 0.0f, -0.2f, 0.565f, 1.0f, + -0.044f, 0.0f, -0.201f, 0.567f, 1.0f, -0.041f, 0.0f, -0.204f, 0.568f, 1.0f, -0.039f, 0.0f, -0.206f, 0.569f, 1.0f, -0.036f, 0.0f, -0.208f, 0.57f, 1.0f, + -0.034f, 0.0f, -0.21f, 0.571f, 1.0f, -0.032f, 0.0f, -0.213f, 0.571f, 1.0f, -0.029f, 0.0f, -0.215f, 0.571f, 1.0f, -0.027f, 0.0f, -0.217f, 0.572f, 1.0f, + -0.024f, 0.0f, -0.219f, 0.572f, 1.0f, -0.022f, 0.0f, -0.221f, 0.572f, 1.0f, -0.019f, 0.0f, -0.222f, 0.572f, 1.0f, -0.016f, 0.0f, -0.224f, 0.572f, 1.0f, + -0.013f, 0.0f, -0.225f, 0.572f, 1.0f, -0.01f, 0.0f, -0.226f, 0.573f, 1.0f, -0.007f, 0.0f, -0.227f, 0.573f, 1.0f, -0.004f, 0.0f, -0.227f, 0.573f, 1.0f, + -0.001f, 0.0f, -0.227f, 0.574f, 1.0f, 0.002f, 0.0f, -0.227f, 0.575f, 1.0f, 0.005f, 0.0f, -0.227f, 0.576f, 1.0f, 0.008f, 0.0f, -0.226f, 0.577f, 1.0f, + 0.011f, 0.0f, -0.225f, 0.578f, 1.0f, 0.015f, 0.0f, -0.224f, 0.579f, 1.0f, 0.018f, 0.0f, -0.222f, 0.58f, 1.0f, 0.021f, 0.0f, -0.221f, 0.581f, 1.0f, + 0.024f, 0.0f, -0.219f, 0.582f, 1.0f, 0.027f, 0.0f, -0.217f, 0.582f, 1.0f, 0.03f, 0.0f, -0.215f, 0.583f, 1.0f, 0.033f, 0.0f, -0.213f, 0.583f, 1.0f, + 0.036f, 0.0f, -0.212f, 0.583f, 1.0f, 0.039f, 0.0f, -0.21f, 0.583f, 1.0f, 0.042f, 0.0f, -0.208f, 0.583f, 1.0f, 0.045f, 0.0f, -0.207f, 0.583f, 1.0f, + 0.048f, 0.0f, -0.205f, 0.583f, 1.0f, 0.051f, 0.0f, -0.204f, 0.583f, 1.0f, 0.054f, 0.0f, -0.203f, 0.583f, 1.0f, 0.058f, 0.0f, -0.203f, 0.583f, 1.0f, + 0.061f, 0.0f, -0.202f, 0.583f, 1.0f, 0.064f, 0.0f, -0.202f, 0.574f, 1.0f, 0.067f, 0.0f, -0.202f, 0.565f, 1.0f, 0.07f, 0.0f, -0.203f, 0.556f, 1.0f, + 0.073f, 0.0f, -0.203f, 0.547f, 1.0f, 0.075f, 0.0f, -0.204f, 0.515f, 1.0f, 0.078f, 0.0f, -0.204f, 0.483f, 1.0f, 0.08f, 0.0f, -0.205f, 0.451f, 1.0f, + 0.083f, 0.0f, -0.206f, 0.419f, 1.0f, 0.085f, 0.0f, -0.207f, 0.314f, 1.0f, 0.087f, 0.0f, -0.208f, 0.21f, 1.0f, 0.089f, 0.0f, -0.209f, 0.105f, 1.0f, + 0.091f, 0.0f, -0.21f, 0.0f, 1.0f, +}; + +static const float data28[257 * GP_PRIM_DATABUF_SIZE] = { + -0.637f, 0.0f, -0.172f, 0.0f, 1.0f, -0.641f, 0.0f, -0.172f, 0.0f, 1.0f, -0.643f, 0.0f, -0.172f, 0.0f, 1.0f, -0.646f, 0.0f, -0.172f, 0.0f, 1.0f, + -0.65f, 0.0f, -0.172f, 0.0f, 1.0f, -0.653f, 0.0f, -0.172f, 0.0f, 1.0f, -0.657f, 0.0f, -0.172f, 0.0f, 1.0f, -0.66f, 0.0f, -0.172f, 0.0f, 1.0f, + -0.664f, 0.0f, -0.171f, 0.0f, 1.0f, -0.668f, 0.0f, -0.171f, 0.0f, 1.0f, -0.672f, 0.0f, -0.171f, 0.0f, 1.0f, -0.677f, 0.0f, -0.171f, 0.0f, 1.0f, + -0.681f, 0.0f, -0.171f, 0.0f, 1.0f, -0.685f, 0.0f, -0.171f, 0.0f, 1.0f, -0.69f, 0.0f, -0.17f, 0.0f, 1.0f, -0.694f, 0.0f, -0.17f, 0.0f, 1.0f, + -0.699f, 0.0f, -0.17f, 0.0f, 1.0f, -0.704f, 0.0f, -0.169f, 0.0f, 1.0f, -0.708f, 0.0f, -0.169f, 0.0f, 1.0f, -0.713f, 0.0f, -0.168f, 0.0f, 1.0f, + -0.717f, 0.0f, -0.168f, 0.0f, 1.0f, -0.722f, 0.0f, -0.167f, 0.0f, 1.0f, -0.727f, 0.0f, -0.167f, 0.0f, 1.0f, -0.731f, 0.0f, -0.166f, 0.0f, 1.0f, + -0.735f, 0.0f, -0.166f, 0.0f, 1.0f, -0.74f, 0.0f, -0.165f, 0.0f, 1.0f, -0.744f, 0.0f, -0.164f, 0.0f, 1.0f, -0.749f, 0.0f, -0.163f, 0.0f, 1.0f, + -0.753f, 0.0f, -0.163f, 0.0f, 1.0f, -0.757f, 0.0f, -0.162f, 0.0f, 1.0f, -0.761f, 0.0f, -0.161f, 0.0f, 1.0f, -0.765f, 0.0f, -0.16f, 0.0f, 1.0f, + -0.769f, 0.0f, -0.159f, 0.0f, 1.0f, -0.773f, 0.0f, -0.158f, 0.0f, 1.0f, -0.777f, 0.0f, -0.157f, 0.0f, 1.0f, -0.781f, 0.0f, -0.156f, 0.001f, 1.0f, + -0.785f, 0.0f, -0.155f, 0.001f, 1.0f, -0.789f, 0.0f, -0.154f, 0.002f, 1.0f, -0.793f, 0.0f, -0.153f, 0.003f, 1.0f, -0.797f, 0.0f, -0.152f, 0.004f, 1.0f, + -0.801f, 0.0f, -0.15f, 0.005f, 1.0f, -0.805f, 0.0f, -0.149f, 0.006f, 1.0f, -0.81f, 0.0f, -0.147f, 0.008f, 1.0f, -0.814f, 0.0f, -0.146f, 0.009f, 1.0f, + -0.818f, 0.0f, -0.144f, 0.011f, 1.0f, -0.823f, 0.0f, -0.143f, 0.014f, 1.0f, -0.827f, 0.0f, -0.141f, 0.016f, 1.0f, -0.831f, 0.0f, -0.139f, 0.019f, 1.0f, + -0.836f, 0.0f, -0.138f, 0.022f, 1.0f, -0.84f, 0.0f, -0.136f, 0.024f, 1.0f, -0.844f, 0.0f, -0.135f, 0.026f, 1.0f, -0.849f, 0.0f, -0.133f, 0.027f, 1.0f, + -0.853f, 0.0f, -0.131f, 0.027f, 1.0f, -0.857f, 0.0f, -0.13f, 0.027f, 1.0f, -0.861f, 0.0f, -0.128f, 0.027f, 1.0f, -0.865f, 0.0f, -0.126f, 0.027f, 1.0f, + -0.868f, 0.0f, -0.125f, 0.026f, 1.0f, -0.872f, 0.0f, -0.123f, 0.025f, 1.0f, -0.876f, 0.0f, -0.121f, 0.025f, 1.0f, -0.879f, 0.0f, -0.119f, 0.024f, 1.0f, + -0.883f, 0.0f, -0.118f, 0.023f, 1.0f, -0.886f, 0.0f, -0.116f, 0.022f, 1.0f, -0.89f, 0.0f, -0.114f, 0.022f, 1.0f, -0.894f, 0.0f, -0.112f, 0.021f, 1.0f, + -0.898f, 0.0f, -0.11f, 0.022f, 1.0f, -0.901f, 0.0f, -0.107f, 0.022f, 1.0f, -0.905f, 0.0f, -0.105f, 0.024f, 1.0f, -0.909f, 0.0f, -0.103f, 0.026f, 1.0f, + -0.913f, 0.0f, -0.1f, 0.029f, 1.0f, -0.917f, 0.0f, -0.098f, 0.032f, 1.0f, -0.921f, 0.0f, -0.095f, 0.035f, 1.0f, -0.926f, 0.0f, -0.092f, 0.039f, 1.0f, + -0.93f, 0.0f, -0.09f, 0.043f, 1.0f, -0.934f, 0.0f, -0.087f, 0.047f, 1.0f, -0.938f, 0.0f, -0.084f, 0.051f, 1.0f, -0.942f, 0.0f, -0.081f, 0.055f, 1.0f, + -0.946f, 0.0f, -0.078f, 0.06f, 1.0f, -0.95f, 0.0f, -0.075f, 0.065f, 1.0f, -0.954f, 0.0f, -0.073f, 0.07f, 1.0f, -0.958f, 0.0f, -0.07f, 0.075f, 1.0f, + -0.961f, 0.0f, -0.067f, 0.081f, 1.0f, -0.965f, 0.0f, -0.064f, 0.087f, 1.0f, -0.968f, 0.0f, -0.061f, 0.092f, 1.0f, -0.972f, 0.0f, -0.058f, 0.098f, 1.0f, + -0.975f, 0.0f, -0.055f, 0.103f, 1.0f, -0.979f, 0.0f, -0.053f, 0.108f, 1.0f, -0.982f, 0.0f, -0.05f, 0.112f, 1.0f, -0.985f, 0.0f, -0.047f, 0.116f, 1.0f, + -0.988f, 0.0f, -0.045f, 0.12f, 1.0f, -0.991f, 0.0f, -0.042f, 0.123f, 1.0f, -0.994f, 0.0f, -0.039f, 0.126f, 1.0f, -0.997f, 0.0f, -0.037f, 0.129f, 1.0f, + -1.0f, 0.0f, -0.034f, 0.131f, 1.0f, -1.003f, 0.0f, -0.031f, 0.133f, 1.0f, -1.005f, 0.0f, -0.029f, 0.135f, 1.0f, -1.008f, 0.0f, -0.026f, 0.137f, 1.0f, + -1.01f, 0.0f, -0.024f, 0.139f, 1.0f, -1.013f, 0.0f, -0.021f, 0.141f, 1.0f, -1.016f, 0.0f, -0.018f, 0.143f, 1.0f, -1.018f, 0.0f, -0.016f, 0.144f, 1.0f, + -1.02f, 0.0f, -0.013f, 0.146f, 1.0f, -1.023f, 0.0f, -0.011f, 0.148f, 1.0f, -1.025f, 0.0f, -0.008f, 0.149f, 1.0f, -1.027f, 0.0f, -0.006f, 0.151f, 1.0f, + -1.029f, 0.0f, -0.003f, 0.152f, 1.0f, -1.032f, 0.0f, -0.001f, 0.154f, 1.0f, -1.034f, 0.0f, 0.001f, 0.154f, 1.0f, -1.036f, 0.0f, 0.004f, 0.155f, 1.0f, + -1.038f, 0.0f, 0.006f, 0.156f, 1.0f, -1.041f, 0.0f, 0.008f, 0.156f, 1.0f, -1.043f, 0.0f, 0.01f, 0.157f, 1.0f, -1.045f, 0.0f, 0.013f, 0.157f, 1.0f, + -1.047f, 0.0f, 0.015f, 0.157f, 1.0f, -1.049f, 0.0f, 0.018f, 0.158f, 1.0f, -1.051f, 0.0f, 0.02f, 0.158f, 1.0f, -1.053f, 0.0f, 0.023f, 0.158f, 1.0f, + -1.055f, 0.0f, 0.025f, 0.158f, 1.0f, -1.057f, 0.0f, 0.028f, 0.158f, 1.0f, -1.059f, 0.0f, 0.03f, 0.158f, 1.0f, -1.061f, 0.0f, 0.033f, 0.158f, 1.0f, + -1.063f, 0.0f, 0.036f, 0.158f, 1.0f, -1.065f, 0.0f, 0.038f, 0.158f, 1.0f, -1.067f, 0.0f, 0.041f, 0.158f, 1.0f, -1.069f, 0.0f, 0.044f, 0.157f, 1.0f, + -1.071f, 0.0f, 0.047f, 0.157f, 1.0f, -1.073f, 0.0f, 0.049f, 0.156f, 1.0f, -1.074f, 0.0f, 0.052f, 0.155f, 1.0f, -1.076f, 0.0f, 0.055f, 0.154f, 1.0f, + -1.078f, 0.0f, 0.058f, 0.153f, 1.0f, -1.08f, 0.0f, 0.061f, 0.152f, 1.0f, -1.082f, 0.0f, 0.064f, 0.15f, 1.0f, -1.083f, 0.0f, 0.067f, 0.148f, 1.0f, + -1.085f, 0.0f, 0.07f, 0.146f, 1.0f, -1.087f, 0.0f, 0.073f, 0.144f, 1.0f, -1.089f, 0.0f, 0.076f, 0.142f, 1.0f, -1.091f, 0.0f, 0.08f, 0.14f, 1.0f, + -1.092f, 0.0f, 0.083f, 0.138f, 1.0f, -1.094f, 0.0f, 0.086f, 0.136f, 1.0f, -1.096f, 0.0f, 0.09f, 0.135f, 1.0f, -1.097f, 0.0f, 0.093f, 0.134f, 1.0f, + -1.099f, 0.0f, 0.096f, 0.134f, 1.0f, -1.101f, 0.0f, 0.1f, 0.134f, 1.0f, -1.103f, 0.0f, 0.103f, 0.136f, 1.0f, -1.104f, 0.0f, 0.107f, 0.139f, 1.0f, + -1.106f, 0.0f, 0.111f, 0.144f, 1.0f, -1.107f, 0.0f, 0.114f, 0.15f, 1.0f, -1.109f, 0.0f, 0.118f, 0.158f, 1.0f, -1.11f, 0.0f, 0.122f, 0.167f, 1.0f, + -1.111f, 0.0f, 0.126f, 0.178f, 1.0f, -1.113f, 0.0f, 0.13f, 0.191f, 1.0f, -1.114f, 0.0f, 0.134f, 0.205f, 1.0f, -1.115f, 0.0f, 0.138f, 0.22f, 1.0f, + -1.116f, 0.0f, 0.142f, 0.237f, 1.0f, -1.117f, 0.0f, 0.146f, 0.254f, 1.0f, -1.118f, 0.0f, 0.15f, 0.272f, 1.0f, -1.119f, 0.0f, 0.155f, 0.291f, 1.0f, + -1.119f, 0.0f, 0.159f, 0.31f, 1.0f, -1.12f, 0.0f, 0.163f, 0.329f, 1.0f, -1.121f, 0.0f, 0.167f, 0.348f, 1.0f, -1.121f, 0.0f, 0.172f, 0.367f, 1.0f, + -1.122f, 0.0f, 0.176f, 0.386f, 1.0f, -1.122f, 0.0f, 0.18f, 0.405f, 1.0f, -1.123f, 0.0f, 0.184f, 0.423f, 1.0f, -1.123f, 0.0f, 0.189f, 0.441f, 1.0f, + -1.124f, 0.0f, 0.193f, 0.458f, 1.0f, -1.124f, 0.0f, 0.197f, 0.475f, 1.0f, -1.124f, 0.0f, 0.202f, 0.492f, 1.0f, -1.124f, 0.0f, 0.206f, 0.508f, 1.0f, + -1.125f, 0.0f, 0.21f, 0.524f, 1.0f, -1.125f, 0.0f, 0.214f, 0.539f, 1.0f, -1.125f, 0.0f, 0.218f, 0.554f, 1.0f, -1.124f, 0.0f, 0.223f, 0.568f, 1.0f, + -1.124f, 0.0f, 0.227f, 0.581f, 1.0f, -1.124f, 0.0f, 0.231f, 0.593f, 1.0f, -1.124f, 0.0f, 0.235f, 0.604f, 1.0f, -1.123f, 0.0f, 0.239f, 0.614f, 1.0f, + -1.123f, 0.0f, 0.243f, 0.624f, 1.0f, -1.122f, 0.0f, 0.247f, 0.632f, 1.0f, -1.122f, 0.0f, 0.251f, 0.64f, 1.0f, -1.121f, 0.0f, 0.255f, 0.646f, 1.0f, + -1.121f, 0.0f, 0.258f, 0.653f, 1.0f, -1.12f, 0.0f, 0.262f, 0.658f, 1.0f, -1.119f, 0.0f, 0.266f, 0.663f, 1.0f, -1.118f, 0.0f, 0.269f, 0.668f, 1.0f, + -1.117f, 0.0f, 0.272f, 0.673f, 1.0f, -1.117f, 0.0f, 0.276f, 0.678f, 1.0f, -1.116f, 0.0f, 0.279f, 0.682f, 1.0f, -1.115f, 0.0f, 0.282f, 0.687f, 1.0f, + -1.113f, 0.0f, 0.285f, 0.692f, 1.0f, -1.112f, 0.0f, 0.289f, 0.697f, 1.0f, -1.111f, 0.0f, 0.292f, 0.702f, 1.0f, -1.11f, 0.0f, 0.294f, 0.708f, 1.0f, + -1.109f, 0.0f, 0.297f, 0.713f, 1.0f, -1.108f, 0.0f, 0.3f, 0.718f, 1.0f, -1.106f, 0.0f, 0.303f, 0.724f, 1.0f, -1.105f, 0.0f, 0.306f, 0.73f, 1.0f, + -1.104f, 0.0f, 0.309f, 0.735f, 1.0f, -1.102f, 0.0f, 0.312f, 0.741f, 1.0f, -1.101f, 0.0f, 0.315f, 0.746f, 1.0f, -1.099f, 0.0f, 0.318f, 0.751f, 1.0f, + -1.098f, 0.0f, 0.321f, 0.756f, 1.0f, -1.096f, 0.0f, 0.323f, 0.761f, 1.0f, -1.094f, 0.0f, 0.326f, 0.766f, 1.0f, -1.093f, 0.0f, 0.329f, 0.771f, 1.0f, + -1.091f, 0.0f, 0.332f, 0.776f, 1.0f, -1.089f, 0.0f, 0.335f, 0.781f, 1.0f, -1.087f, 0.0f, 0.338f, 0.786f, 1.0f, -1.085f, 0.0f, 0.341f, 0.791f, 1.0f, + -1.082f, 0.0f, 0.344f, 0.797f, 1.0f, -1.08f, 0.0f, 0.347f, 0.802f, 1.0f, -1.078f, 0.0f, 0.349f, 0.808f, 1.0f, -1.075f, 0.0f, 0.352f, 0.814f, 1.0f, + -1.072f, 0.0f, 0.355f, 0.82f, 1.0f, -1.069f, 0.0f, 0.358f, 0.826f, 1.0f, -1.066f, 0.0f, 0.36f, 0.831f, 1.0f, -1.063f, 0.0f, 0.363f, 0.837f, 1.0f, + -1.059f, 0.0f, 0.366f, 0.842f, 1.0f, -1.055f, 0.0f, 0.368f, 0.847f, 1.0f, -1.051f, 0.0f, 0.371f, 0.851f, 1.0f, -1.047f, 0.0f, 0.373f, 0.856f, 1.0f, + -1.042f, 0.0f, 0.375f, 0.86f, 1.0f, -1.037f, 0.0f, 0.378f, 0.863f, 1.0f, -1.031f, 0.0f, 0.38f, 0.866f, 1.0f, -1.026f, 0.0f, 0.382f, 0.869f, 1.0f, + -1.02f, 0.0f, 0.384f, 0.871f, 1.0f, -1.014f, 0.0f, 0.386f, 0.873f, 1.0f, -1.007f, 0.0f, 0.387f, 0.875f, 1.0f, -1.0f, 0.0f, 0.389f, 0.876f, 1.0f, + -0.994f, 0.0f, 0.39f, 0.877f, 1.0f, -0.987f, 0.0f, 0.392f, 0.878f, 1.0f, -0.979f, 0.0f, 0.393f, 0.879f, 1.0f, -0.972f, 0.0f, 0.394f, 0.88f, 1.0f, + -0.964f, 0.0f, 0.395f, 0.881f, 1.0f, -0.956f, 0.0f, 0.395f, 0.881f, 1.0f, -0.948f, 0.0f, 0.395f, 0.882f, 1.0f, -0.94f, 0.0f, 0.395f, 0.882f, 1.0f, + -0.932f, 0.0f, 0.395f, 0.883f, 1.0f, -0.923f, 0.0f, 0.394f, 0.883f, 1.0f, -0.915f, 0.0f, 0.393f, 0.883f, 1.0f, -0.906f, 0.0f, 0.391f, 0.883f, 1.0f, + -0.896f, 0.0f, 0.389f, 0.881f, 1.0f, -0.887f, 0.0f, 0.386f, 0.876f, 1.0f, -0.877f, 0.0f, 0.382f, 0.866f, 1.0f, -0.867f, 0.0f, 0.378f, 0.85f, 1.0f, + -0.857f, 0.0f, 0.373f, 0.828f, 1.0f, -0.848f, 0.0f, 0.368f, 0.799f, 1.0f, -0.838f, 0.0f, 0.363f, 0.764f, 1.0f, -0.829f, 0.0f, 0.357f, 0.723f, 1.0f, + -0.819f, 0.0f, 0.352f, 0.679f, 1.0f, -0.811f, 0.0f, 0.347f, 0.631f, 1.0f, -0.802f, 0.0f, 0.342f, 0.579f, 1.0f, -0.794f, 0.0f, 0.338f, 0.525f, 1.0f, + -0.786f, 0.0f, 0.333f, 0.469f, 1.0f, -0.779f, 0.0f, 0.329f, 0.412f, 1.0f, -0.772f, 0.0f, 0.325f, 0.351f, 1.0f, -0.766f, 0.0f, 0.321f, 0.3f, 1.0f, + -0.757f, 0.0f, 0.317f, 0.219f, 1.0f, +}; + +static const float data29[205 * GP_PRIM_DATABUF_SIZE] = { + 0.816f, 0.0f, 0.326f, 0.285f, 1.0f, 0.819f, 0.0f, 0.328f, 0.287f, 1.0f, 0.821f, 0.0f, 0.33f, 0.29f, 1.0f, 0.823f, 0.0f, 0.331f, 0.295f, 1.0f, + 0.825f, 0.0f, 0.333f, 0.304f, 1.0f, 0.828f, 0.0f, 0.335f, 0.315f, 1.0f, 0.83f, 0.0f, 0.337f, 0.328f, 1.0f, 0.833f, 0.0f, 0.339f, 0.341f, 1.0f, + 0.836f, 0.0f, 0.341f, 0.355f, 1.0f, 0.839f, 0.0f, 0.343f, 0.368f, 1.0f, 0.842f, 0.0f, 0.345f, 0.38f, 1.0f, 0.845f, 0.0f, 0.347f, 0.392f, 1.0f, + 0.848f, 0.0f, 0.349f, 0.402f, 1.0f, 0.851f, 0.0f, 0.351f, 0.412f, 1.0f, 0.854f, 0.0f, 0.352f, 0.421f, 1.0f, 0.857f, 0.0f, 0.354f, 0.429f, 1.0f, + 0.861f, 0.0f, 0.356f, 0.437f, 1.0f, 0.865f, 0.0f, 0.357f, 0.444f, 1.0f, 0.869f, 0.0f, 0.359f, 0.452f, 1.0f, 0.872f, 0.0f, 0.36f, 0.46f, 1.0f, + 0.876f, 0.0f, 0.361f, 0.47f, 1.0f, 0.881f, 0.0f, 0.363f, 0.481f, 1.0f, 0.885f, 0.0f, 0.364f, 0.491f, 1.0f, 0.889f, 0.0f, 0.365f, 0.501f, 1.0f, + 0.893f, 0.0f, 0.366f, 0.511f, 1.0f, 0.898f, 0.0f, 0.367f, 0.52f, 1.0f, 0.902f, 0.0f, 0.368f, 0.528f, 1.0f, 0.906f, 0.0f, 0.37f, 0.535f, 1.0f, + 0.911f, 0.0f, 0.371f, 0.542f, 1.0f, 0.915f, 0.0f, 0.372f, 0.548f, 1.0f, 0.92f, 0.0f, 0.373f, 0.554f, 1.0f, 0.924f, 0.0f, 0.374f, 0.559f, 1.0f, + 0.929f, 0.0f, 0.375f, 0.564f, 1.0f, 0.933f, 0.0f, 0.376f, 0.567f, 1.0f, 0.938f, 0.0f, 0.377f, 0.57f, 1.0f, 0.943f, 0.0f, 0.378f, 0.572f, 1.0f, + 0.947f, 0.0f, 0.378f, 0.574f, 1.0f, 0.952f, 0.0f, 0.379f, 0.576f, 1.0f, 0.956f, 0.0f, 0.38f, 0.577f, 1.0f, 0.961f, 0.0f, 0.38f, 0.579f, 1.0f, + 0.966f, 0.0f, 0.381f, 0.581f, 1.0f, 0.971f, 0.0f, 0.381f, 0.585f, 1.0f, 0.975f, 0.0f, 0.382f, 0.588f, 1.0f, 0.98f, 0.0f, 0.382f, 0.591f, 1.0f, + 0.985f, 0.0f, 0.382f, 0.595f, 1.0f, 0.989f, 0.0f, 0.382f, 0.597f, 1.0f, 0.994f, 0.0f, 0.382f, 0.6f, 1.0f, 0.999f, 0.0f, 0.382f, 0.603f, 1.0f, + 1.003f, 0.0f, 0.382f, 0.605f, 1.0f, 1.008f, 0.0f, 0.381f, 0.607f, 1.0f, 1.013f, 0.0f, 0.381f, 0.61f, 1.0f, 1.017f, 0.0f, 0.381f, 0.611f, 1.0f, + 1.021f, 0.0f, 0.381f, 0.613f, 1.0f, 1.025f, 0.0f, 0.38f, 0.613f, 1.0f, 1.029f, 0.0f, 0.38f, 0.614f, 1.0f, 1.033f, 0.0f, 0.379f, 0.614f, 1.0f, + 1.037f, 0.0f, 0.379f, 0.614f, 1.0f, 1.041f, 0.0f, 0.378f, 0.614f, 1.0f, 1.044f, 0.0f, 0.378f, 0.614f, 1.0f, 1.048f, 0.0f, 0.377f, 0.614f, 1.0f, + 1.051f, 0.0f, 0.376f, 0.613f, 1.0f, 1.054f, 0.0f, 0.375f, 0.612f, 1.0f, 1.057f, 0.0f, 0.374f, 0.611f, 1.0f, 1.06f, 0.0f, 0.373f, 0.61f, 1.0f, + 1.063f, 0.0f, 0.372f, 0.609f, 1.0f, 1.066f, 0.0f, 0.371f, 0.609f, 1.0f, 1.068f, 0.0f, 0.37f, 0.608f, 1.0f, 1.071f, 0.0f, 0.368f, 0.608f, 1.0f, + 1.073f, 0.0f, 0.367f, 0.608f, 1.0f, 1.076f, 0.0f, 0.365f, 0.608f, 1.0f, 1.078f, 0.0f, 0.364f, 0.607f, 1.0f, 1.081f, 0.0f, 0.362f, 0.607f, 1.0f, + 1.083f, 0.0f, 0.36f, 0.607f, 1.0f, 1.085f, 0.0f, 0.358f, 0.606f, 1.0f, 1.087f, 0.0f, 0.356f, 0.606f, 1.0f, 1.09f, 0.0f, 0.354f, 0.606f, 1.0f, + 1.092f, 0.0f, 0.352f, 0.606f, 1.0f, 1.094f, 0.0f, 0.35f, 0.606f, 1.0f, 1.096f, 0.0f, 0.348f, 0.606f, 1.0f, 1.097f, 0.0f, 0.346f, 0.606f, 1.0f, + 1.099f, 0.0f, 0.344f, 0.606f, 1.0f, 1.101f, 0.0f, 0.341f, 0.606f, 1.0f, 1.103f, 0.0f, 0.339f, 0.606f, 1.0f, 1.104f, 0.0f, 0.337f, 0.607f, 1.0f, + 1.106f, 0.0f, 0.335f, 0.607f, 1.0f, 1.108f, 0.0f, 0.332f, 0.607f, 1.0f, 1.109f, 0.0f, 0.33f, 0.608f, 1.0f, 1.111f, 0.0f, 0.327f, 0.608f, 1.0f, + 1.113f, 0.0f, 0.324f, 0.608f, 1.0f, 1.114f, 0.0f, 0.322f, 0.609f, 1.0f, 1.116f, 0.0f, 0.319f, 0.609f, 1.0f, 1.117f, 0.0f, 0.316f, 0.609f, 1.0f, + 1.118f, 0.0f, 0.313f, 0.609f, 1.0f, 1.12f, 0.0f, 0.31f, 0.609f, 1.0f, 1.121f, 0.0f, 0.307f, 0.609f, 1.0f, 1.123f, 0.0f, 0.304f, 0.608f, 1.0f, + 1.124f, 0.0f, 0.301f, 0.608f, 1.0f, 1.125f, 0.0f, 0.297f, 0.607f, 1.0f, 1.126f, 0.0f, 0.294f, 0.606f, 1.0f, 1.127f, 0.0f, 0.29f, 0.605f, 1.0f, + 1.129f, 0.0f, 0.287f, 0.603f, 1.0f, 1.13f, 0.0f, 0.283f, 0.601f, 1.0f, 1.131f, 0.0f, 0.279f, 0.599f, 1.0f, 1.132f, 0.0f, 0.276f, 0.597f, 1.0f, + 1.132f, 0.0f, 0.272f, 0.595f, 1.0f, 1.133f, 0.0f, 0.268f, 0.593f, 1.0f, 1.134f, 0.0f, 0.264f, 0.592f, 1.0f, 1.135f, 0.0f, 0.26f, 0.591f, 1.0f, + 1.135f, 0.0f, 0.256f, 0.59f, 1.0f, 1.136f, 0.0f, 0.252f, 0.589f, 1.0f, 1.136f, 0.0f, 0.248f, 0.588f, 1.0f, 1.137f, 0.0f, 0.244f, 0.587f, 1.0f, + 1.137f, 0.0f, 0.24f, 0.586f, 1.0f, 1.138f, 0.0f, 0.236f, 0.585f, 1.0f, 1.138f, 0.0f, 0.232f, 0.584f, 1.0f, 1.138f, 0.0f, 0.228f, 0.582f, 1.0f, + 1.138f, 0.0f, 0.224f, 0.581f, 1.0f, 1.138f, 0.0f, 0.22f, 0.579f, 1.0f, 1.138f, 0.0f, 0.216f, 0.578f, 1.0f, 1.138f, 0.0f, 0.212f, 0.576f, 1.0f, + 1.138f, 0.0f, 0.208f, 0.575f, 1.0f, 1.138f, 0.0f, 0.204f, 0.573f, 1.0f, 1.137f, 0.0f, 0.2f, 0.572f, 1.0f, 1.137f, 0.0f, 0.196f, 0.571f, 1.0f, + 1.137f, 0.0f, 0.192f, 0.569f, 1.0f, 1.136f, 0.0f, 0.188f, 0.568f, 1.0f, 1.136f, 0.0f, 0.184f, 0.567f, 1.0f, 1.135f, 0.0f, 0.18f, 0.566f, 1.0f, + 1.134f, 0.0f, 0.176f, 0.565f, 1.0f, 1.133f, 0.0f, 0.172f, 0.563f, 1.0f, 1.132f, 0.0f, 0.168f, 0.561f, 1.0f, 1.131f, 0.0f, 0.164f, 0.559f, 1.0f, + 1.13f, 0.0f, 0.16f, 0.556f, 1.0f, 1.129f, 0.0f, 0.156f, 0.552f, 1.0f, 1.128f, 0.0f, 0.152f, 0.548f, 1.0f, 1.127f, 0.0f, 0.148f, 0.543f, 1.0f, + 1.126f, 0.0f, 0.144f, 0.537f, 1.0f, 1.124f, 0.0f, 0.14f, 0.53f, 1.0f, 1.123f, 0.0f, 0.136f, 0.522f, 1.0f, 1.122f, 0.0f, 0.132f, 0.514f, 1.0f, + 1.12f, 0.0f, 0.128f, 0.505f, 1.0f, 1.118f, 0.0f, 0.123f, 0.495f, 1.0f, 1.117f, 0.0f, 0.119f, 0.486f, 1.0f, 1.115f, 0.0f, 0.115f, 0.476f, 1.0f, + 1.113f, 0.0f, 0.111f, 0.466f, 1.0f, 1.111f, 0.0f, 0.107f, 0.456f, 1.0f, 1.11f, 0.0f, 0.102f, 0.446f, 1.0f, 1.108f, 0.0f, 0.098f, 0.436f, 1.0f, + 1.105f, 0.0f, 0.094f, 0.425f, 1.0f, 1.103f, 0.0f, 0.09f, 0.414f, 1.0f, 1.101f, 0.0f, 0.085f, 0.402f, 1.0f, 1.099f, 0.0f, 0.081f, 0.389f, 1.0f, + 1.096f, 0.0f, 0.077f, 0.377f, 1.0f, 1.094f, 0.0f, 0.072f, 0.364f, 1.0f, 1.091f, 0.0f, 0.068f, 0.351f, 1.0f, 1.088f, 0.0f, 0.063f, 0.338f, 1.0f, + 1.085f, 0.0f, 0.059f, 0.325f, 1.0f, 1.082f, 0.0f, 0.054f, 0.313f, 1.0f, 1.079f, 0.0f, 0.05f, 0.301f, 1.0f, 1.075f, 0.0f, 0.045f, 0.29f, 1.0f, + 1.071f, 0.0f, 0.04f, 0.281f, 1.0f, 1.067f, 0.0f, 0.035f, 0.272f, 1.0f, 1.063f, 0.0f, 0.031f, 0.266f, 1.0f, 1.059f, 0.0f, 0.026f, 0.261f, 1.0f, + 1.054f, 0.0f, 0.021f, 0.258f, 1.0f, 1.049f, 0.0f, 0.016f, 0.257f, 1.0f, 1.043f, 0.0f, 0.011f, 0.259f, 1.0f, 1.037f, 0.0f, 0.006f, 0.264f, 1.0f, + 1.031f, 0.0f, 0.0f, 0.272f, 1.0f, 1.025f, 0.0f, -0.005f, 0.283f, 1.0f, 1.018f, 0.0f, -0.01f, 0.296f, 1.0f, 1.011f, 0.0f, -0.015f, 0.313f, 1.0f, + 1.003f, 0.0f, -0.021f, 0.33f, 1.0f, 0.996f, 0.0f, -0.026f, 0.348f, 1.0f, 0.988f, 0.0f, -0.032f, 0.365f, 1.0f, 0.979f, 0.0f, -0.038f, 0.379f, 1.0f, + 0.971f, 0.0f, -0.044f, 0.389f, 1.0f, 0.962f, 0.0f, -0.05f, 0.394f, 1.0f, 0.953f, 0.0f, -0.057f, 0.392f, 1.0f, 0.944f, 0.0f, -0.063f, 0.384f, 1.0f, + 0.934f, 0.0f, -0.069f, 0.368f, 1.0f, 0.924f, 0.0f, -0.075f, 0.347f, 1.0f, 0.914f, 0.0f, -0.081f, 0.32f, 1.0f, 0.903f, 0.0f, -0.087f, 0.289f, 1.0f, + 0.893f, 0.0f, -0.092f, 0.256f, 1.0f, 0.882f, 0.0f, -0.098f, 0.223f, 1.0f, 0.871f, 0.0f, -0.103f, 0.191f, 1.0f, 0.86f, 0.0f, -0.108f, 0.162f, 1.0f, + 0.849f, 0.0f, -0.112f, 0.136f, 1.0f, 0.838f, 0.0f, -0.117f, 0.112f, 1.0f, 0.827f, 0.0f, -0.121f, 0.091f, 1.0f, 0.815f, 0.0f, -0.125f, 0.074f, 1.0f, + 0.804f, 0.0f, -0.128f, 0.059f, 1.0f, 0.793f, 0.0f, -0.132f, 0.046f, 1.0f, 0.782f, 0.0f, -0.135f, 0.036f, 1.0f, 0.771f, 0.0f, -0.138f, 0.028f, 1.0f, + 0.76f, 0.0f, -0.141f, 0.021f, 1.0f, 0.749f, 0.0f, -0.144f, 0.016f, 1.0f, 0.738f, 0.0f, -0.147f, 0.012f, 1.0f, 0.728f, 0.0f, -0.149f, 0.009f, 1.0f, + 0.718f, 0.0f, -0.152f, 0.006f, 1.0f, 0.708f, 0.0f, -0.154f, 0.004f, 1.0f, 0.699f, 0.0f, -0.157f, 0.003f, 1.0f, 0.691f, 0.0f, -0.159f, 0.002f, 1.0f, + 0.68f, 0.0f, -0.162f, 0.0f, 1.0f, +}; + +static const float data30[33 * GP_PRIM_DATABUF_SIZE] = { + -1.02f, 0.0f, 0.179f, 0.21f, 1.0f, -1.014f, 0.0f, 0.182f, 0.301f, 1.0f, -1.01f, 0.0f, 0.184f, 0.36f, 1.0f, -1.004f, 0.0f, 0.186f, 0.426f, 1.0f, + -0.999f, 0.0f, 0.188f, 0.479f, 1.0f, -0.993f, 0.0f, 0.19f, 0.519f, 1.0f, -0.987f, 0.0f, 0.191f, 0.545f, 1.0f, -0.981f, 0.0f, 0.192f, 0.562f, 1.0f, + -0.975f, 0.0f, 0.193f, 0.575f, 1.0f, -0.968f, 0.0f, 0.193f, 0.582f, 1.0f, -0.961f, 0.0f, 0.193f, 0.587f, 1.0f, -0.954f, 0.0f, 0.191f, 0.592f, 1.0f, + -0.946f, 0.0f, 0.19f, 0.597f, 1.0f, -0.938f, 0.0f, 0.187f, 0.6f, 1.0f, -0.93f, 0.0f, 0.183f, 0.603f, 1.0f, -0.922f, 0.0f, 0.178f, 0.606f, 1.0f, + -0.913f, 0.0f, 0.173f, 0.608f, 1.0f, -0.905f, 0.0f, 0.168f, 0.61f, 1.0f, -0.898f, 0.0f, 0.162f, 0.612f, 1.0f, -0.89f, 0.0f, 0.156f, 0.613f, 1.0f, + -0.883f, 0.0f, 0.15f, 0.612f, 1.0f, -0.877f, 0.0f, 0.143f, 0.608f, 1.0f, -0.871f, 0.0f, 0.137f, 0.602f, 1.0f, -0.865f, 0.0f, 0.131f, 0.593f, 1.0f, + -0.86f, 0.0f, 0.125f, 0.577f, 1.0f, -0.855f, 0.0f, 0.12f, 0.554f, 1.0f, -0.85f, 0.0f, 0.114f, 0.524f, 1.0f, -0.846f, 0.0f, 0.109f, 0.487f, 1.0f, + -0.842f, 0.0f, 0.104f, 0.443f, 1.0f, -0.838f, 0.0f, 0.1f, 0.394f, 1.0f, -0.835f, 0.0f, 0.095f, 0.339f, 1.0f, -0.832f, 0.0f, 0.091f, 0.295f, 1.0f, + -0.828f, 0.0f, 0.086f, 0.227f, 1.0f, +}; + +static const float data31[37 * GP_PRIM_DATABUF_SIZE] = { + 0.777f, 0.0f, 0.096f, 0.278f, 1.0f, 0.779f, 0.0f, 0.1f, 0.307f, 1.0f, 0.781f, 0.0f, 0.103f, 0.326f, 1.0f, 0.782f, 0.0f, 0.106f, 0.349f, 1.0f, + 0.784f, 0.0f, 0.109f, 0.372f, 1.0f, 0.786f, 0.0f, 0.112f, 0.395f, 1.0f, 0.789f, 0.0f, 0.116f, 0.418f, 1.0f, 0.791f, 0.0f, 0.119f, 0.44f, 1.0f, + 0.794f, 0.0f, 0.123f, 0.462f, 1.0f, 0.798f, 0.0f, 0.127f, 0.484f, 1.0f, 0.801f, 0.0f, 0.13f, 0.504f, 1.0f, 0.806f, 0.0f, 0.134f, 0.522f, 1.0f, + 0.81f, 0.0f, 0.138f, 0.54f, 1.0f, 0.815f, 0.0f, 0.142f, 0.556f, 1.0f, 0.82f, 0.0f, 0.146f, 0.571f, 1.0f, 0.826f, 0.0f, 0.15f, 0.584f, 1.0f, + 0.832f, 0.0f, 0.154f, 0.596f, 1.0f, 0.839f, 0.0f, 0.159f, 0.607f, 1.0f, 0.846f, 0.0f, 0.163f, 0.616f, 1.0f, 0.854f, 0.0f, 0.166f, 0.623f, 1.0f, + 0.862f, 0.0f, 0.17f, 0.628f, 1.0f, 0.87f, 0.0f, 0.174f, 0.632f, 1.0f, 0.878f, 0.0f, 0.177f, 0.632f, 1.0f, 0.887f, 0.0f, 0.18f, 0.63f, 1.0f, + 0.895f, 0.0f, 0.183f, 0.623f, 1.0f, 0.903f, 0.0f, 0.186f, 0.611f, 1.0f, 0.912f, 0.0f, 0.188f, 0.592f, 1.0f, 0.92f, 0.0f, 0.19f, 0.567f, 1.0f, + 0.928f, 0.0f, 0.192f, 0.533f, 1.0f, 0.935f, 0.0f, 0.193f, 0.492f, 1.0f, 0.943f, 0.0f, 0.194f, 0.442f, 1.0f, 0.95f, 0.0f, 0.196f, 0.385f, 1.0f, + 0.957f, 0.0f, 0.197f, 0.321f, 1.0f, 0.963f, 0.0f, 0.197f, 0.253f, 1.0f, 0.97f, 0.0f, 0.198f, 0.175f, 1.0f, 0.975f, 0.0f, 0.199f, 0.107f, 1.0f, + 0.983f, 0.0f, 0.199f, 0.0f, 1.0f, +}; + +static const float data32[201 * GP_PRIM_DATABUF_SIZE] = { + -0.437f, 0.0f, 0.508f, 0.0f, 1.0f, -0.435f, 0.0f, 0.51f, 0.0f, 1.0f, -0.434f, 0.0f, 0.511f, 0.0f, 1.0f, -0.432f, 0.0f, 0.512f, 0.0f, 1.0f, + -0.43f, 0.0f, 0.513f, 0.0f, 1.0f, -0.428f, 0.0f, 0.514f, 0.001f, 1.0f, -0.426f, 0.0f, 0.515f, 0.002f, 1.0f, -0.424f, 0.0f, 0.517f, 0.004f, 1.0f, + -0.422f, 0.0f, 0.518f, 0.007f, 1.0f, -0.42f, 0.0f, 0.519f, 0.012f, 1.0f, -0.418f, 0.0f, 0.521f, 0.018f, 1.0f, -0.416f, 0.0f, 0.522f, 0.025f, 1.0f, + -0.414f, 0.0f, 0.523f, 0.034f, 1.0f, -0.411f, 0.0f, 0.525f, 0.043f, 1.0f, -0.409f, 0.0f, 0.526f, 0.053f, 1.0f, -0.407f, 0.0f, 0.528f, 0.063f, 1.0f, + -0.404f, 0.0f, 0.529f, 0.073f, 1.0f, -0.402f, 0.0f, 0.531f, 0.083f, 1.0f, -0.399f, 0.0f, 0.532f, 0.092f, 1.0f, -0.396f, 0.0f, 0.534f, 0.101f, 1.0f, + -0.394f, 0.0f, 0.535f, 0.11f, 1.0f, -0.391f, 0.0f, 0.536f, 0.118f, 1.0f, -0.388f, 0.0f, 0.538f, 0.126f, 1.0f, -0.386f, 0.0f, 0.539f, 0.133f, 1.0f, + -0.383f, 0.0f, 0.54f, 0.14f, 1.0f, -0.38f, 0.0f, 0.542f, 0.147f, 1.0f, -0.377f, 0.0f, 0.543f, 0.153f, 1.0f, -0.374f, 0.0f, 0.544f, 0.159f, 1.0f, + -0.37f, 0.0f, 0.545f, 0.166f, 1.0f, -0.367f, 0.0f, 0.546f, 0.172f, 1.0f, -0.364f, 0.0f, 0.547f, 0.179f, 1.0f, -0.361f, 0.0f, 0.548f, 0.186f, 1.0f, + -0.357f, 0.0f, 0.549f, 0.193f, 1.0f, -0.354f, 0.0f, 0.55f, 0.202f, 1.0f, -0.35f, 0.0f, 0.551f, 0.211f, 1.0f, -0.347f, 0.0f, 0.552f, 0.221f, 1.0f, + -0.343f, 0.0f, 0.552f, 0.233f, 1.0f, -0.339f, 0.0f, 0.553f, 0.245f, 1.0f, -0.336f, 0.0f, 0.553f, 0.258f, 1.0f, -0.332f, 0.0f, 0.554f, 0.272f, 1.0f, + -0.328f, 0.0f, 0.554f, 0.286f, 1.0f, -0.324f, 0.0f, 0.554f, 0.301f, 1.0f, -0.321f, 0.0f, 0.555f, 0.317f, 1.0f, -0.317f, 0.0f, 0.555f, 0.332f, 1.0f, + -0.313f, 0.0f, 0.555f, 0.348f, 1.0f, -0.309f, 0.0f, 0.555f, 0.364f, 1.0f, -0.305f, 0.0f, 0.555f, 0.38f, 1.0f, -0.302f, 0.0f, 0.555f, 0.396f, 1.0f, + -0.298f, 0.0f, 0.555f, 0.411f, 1.0f, -0.294f, 0.0f, 0.555f, 0.426f, 1.0f, -0.29f, 0.0f, 0.554f, 0.44f, 1.0f, -0.287f, 0.0f, 0.554f, 0.454f, 1.0f, + -0.283f, 0.0f, 0.554f, 0.467f, 1.0f, -0.28f, 0.0f, 0.553f, 0.479f, 1.0f, -0.276f, 0.0f, 0.553f, 0.49f, 1.0f, -0.273f, 0.0f, 0.552f, 0.5f, 1.0f, + -0.269f, 0.0f, 0.552f, 0.51f, 1.0f, -0.266f, 0.0f, 0.551f, 0.519f, 1.0f, -0.263f, 0.0f, 0.55f, 0.527f, 1.0f, -0.26f, 0.0f, 0.549f, 0.534f, 1.0f, + -0.256f, 0.0f, 0.549f, 0.541f, 1.0f, -0.253f, 0.0f, 0.548f, 0.547f, 1.0f, -0.25f, 0.0f, 0.547f, 0.552f, 1.0f, -0.247f, 0.0f, 0.546f, 0.557f, 1.0f, + -0.244f, 0.0f, 0.545f, 0.561f, 1.0f, -0.241f, 0.0f, 0.544f, 0.564f, 1.0f, -0.238f, 0.0f, 0.543f, 0.567f, 1.0f, -0.235f, 0.0f, 0.542f, 0.57f, 1.0f, + -0.233f, 0.0f, 0.541f, 0.572f, 1.0f, -0.23f, 0.0f, 0.54f, 0.574f, 1.0f, -0.227f, 0.0f, 0.539f, 0.575f, 1.0f, -0.224f, 0.0f, 0.538f, 0.576f, 1.0f, + -0.221f, 0.0f, 0.537f, 0.577f, 1.0f, -0.219f, 0.0f, 0.535f, 0.578f, 1.0f, -0.216f, 0.0f, 0.534f, 0.578f, 1.0f, -0.213f, 0.0f, 0.533f, 0.579f, 1.0f, + -0.211f, 0.0f, 0.532f, 0.579f, 1.0f, -0.208f, 0.0f, 0.53f, 0.579f, 1.0f, -0.206f, 0.0f, 0.529f, 0.578f, 1.0f, -0.203f, 0.0f, 0.528f, 0.578f, 1.0f, + -0.2f, 0.0f, 0.526f, 0.577f, 1.0f, -0.198f, 0.0f, 0.525f, 0.576f, 1.0f, -0.195f, 0.0f, 0.523f, 0.575f, 1.0f, -0.193f, 0.0f, 0.522f, 0.574f, 1.0f, + -0.19f, 0.0f, 0.52f, 0.572f, 1.0f, -0.188f, 0.0f, 0.518f, 0.571f, 1.0f, -0.185f, 0.0f, 0.517f, 0.569f, 1.0f, -0.182f, 0.0f, 0.515f, 0.568f, 1.0f, + -0.18f, 0.0f, 0.513f, 0.567f, 1.0f, -0.177f, 0.0f, 0.512f, 0.565f, 1.0f, -0.174f, 0.0f, 0.51f, 0.564f, 1.0f, -0.172f, 0.0f, 0.508f, 0.562f, 1.0f, + -0.169f, 0.0f, 0.506f, 0.56f, 1.0f, -0.166f, 0.0f, 0.504f, 0.559f, 1.0f, -0.164f, 0.0f, 0.502f, 0.556f, 1.0f, -0.161f, 0.0f, 0.501f, 0.554f, 1.0f, + -0.158f, 0.0f, 0.499f, 0.552f, 1.0f, -0.155f, 0.0f, 0.497f, 0.55f, 1.0f, -0.153f, 0.0f, 0.495f, 0.547f, 1.0f, -0.15f, 0.0f, 0.493f, 0.545f, 1.0f, + -0.147f, 0.0f, 0.491f, 0.543f, 1.0f, -0.144f, 0.0f, 0.489f, 0.54f, 1.0f, -0.142f, 0.0f, 0.487f, 0.538f, 1.0f, -0.139f, 0.0f, 0.485f, 0.536f, 1.0f, + -0.136f, 0.0f, 0.483f, 0.533f, 1.0f, -0.133f, 0.0f, 0.481f, 0.53f, 1.0f, -0.13f, 0.0f, 0.479f, 0.527f, 1.0f, -0.127f, 0.0f, 0.477f, 0.524f, 1.0f, + -0.124f, 0.0f, 0.475f, 0.521f, 1.0f, -0.121f, 0.0f, 0.473f, 0.519f, 1.0f, -0.118f, 0.0f, 0.471f, 0.516f, 1.0f, -0.115f, 0.0f, 0.469f, 0.514f, 1.0f, + -0.112f, 0.0f, 0.467f, 0.511f, 1.0f, -0.109f, 0.0f, 0.465f, 0.509f, 1.0f, -0.106f, 0.0f, 0.463f, 0.506f, 1.0f, -0.103f, 0.0f, 0.461f, 0.503f, 1.0f, + -0.099f, 0.0f, 0.458f, 0.501f, 1.0f, -0.096f, 0.0f, 0.456f, 0.5f, 1.0f, -0.093f, 0.0f, 0.454f, 0.498f, 1.0f, -0.09f, 0.0f, 0.452f, 0.497f, 1.0f, + -0.086f, 0.0f, 0.45f, 0.496f, 1.0f, -0.083f, 0.0f, 0.448f, 0.496f, 1.0f, -0.079f, 0.0f, 0.446f, 0.495f, 1.0f, -0.076f, 0.0f, 0.444f, 0.495f, 1.0f, + -0.072f, 0.0f, 0.442f, 0.494f, 1.0f, -0.069f, 0.0f, 0.44f, 0.494f, 1.0f, -0.065f, 0.0f, 0.438f, 0.494f, 1.0f, -0.062f, 0.0f, 0.436f, 0.494f, 1.0f, + -0.058f, 0.0f, 0.435f, 0.494f, 1.0f, -0.054f, 0.0f, 0.433f, 0.494f, 1.0f, -0.05f, 0.0f, 0.431f, 0.494f, 1.0f, -0.046f, 0.0f, 0.43f, 0.494f, 1.0f, + -0.042f, 0.0f, 0.428f, 0.494f, 1.0f, -0.038f, 0.0f, 0.427f, 0.494f, 1.0f, -0.033f, 0.0f, 0.426f, 0.494f, 1.0f, -0.029f, 0.0f, 0.425f, 0.494f, 1.0f, + -0.025f, 0.0f, 0.424f, 0.494f, 1.0f, -0.02f, 0.0f, 0.423f, 0.494f, 1.0f, -0.015f, 0.0f, 0.422f, 0.494f, 1.0f, -0.011f, 0.0f, 0.422f, 0.494f, 1.0f, + -0.006f, 0.0f, 0.421f, 0.494f, 1.0f, -0.001f, 0.0f, 0.421f, 0.495f, 1.0f, 0.004f, 0.0f, 0.421f, 0.495f, 1.0f, 0.009f, 0.0f, 0.421f, 0.495f, 1.0f, + 0.014f, 0.0f, 0.422f, 0.495f, 1.0f, 0.019f, 0.0f, 0.422f, 0.495f, 1.0f, 0.024f, 0.0f, 0.423f, 0.495f, 1.0f, 0.029f, 0.0f, 0.424f, 0.495f, 1.0f, + 0.034f, 0.0f, 0.426f, 0.495f, 1.0f, 0.039f, 0.0f, 0.427f, 0.495f, 1.0f, 0.044f, 0.0f, 0.429f, 0.496f, 1.0f, 0.049f, 0.0f, 0.43f, 0.497f, 1.0f, + 0.054f, 0.0f, 0.432f, 0.498f, 1.0f, 0.059f, 0.0f, 0.435f, 0.5f, 1.0f, 0.064f, 0.0f, 0.438f, 0.502f, 1.0f, 0.069f, 0.0f, 0.44f, 0.506f, 1.0f, + 0.074f, 0.0f, 0.443f, 0.51f, 1.0f, 0.08f, 0.0f, 0.446f, 0.516f, 1.0f, 0.085f, 0.0f, 0.45f, 0.522f, 1.0f, 0.09f, 0.0f, 0.453f, 0.528f, 1.0f, + 0.095f, 0.0f, 0.456f, 0.533f, 1.0f, 0.101f, 0.0f, 0.46f, 0.537f, 1.0f, 0.107f, 0.0f, 0.463f, 0.539f, 1.0f, 0.112f, 0.0f, 0.467f, 0.542f, 1.0f, + 0.118f, 0.0f, 0.471f, 0.543f, 1.0f, 0.124f, 0.0f, 0.475f, 0.545f, 1.0f, 0.13f, 0.0f, 0.478f, 0.546f, 1.0f, 0.137f, 0.0f, 0.482f, 0.546f, 1.0f, + 0.143f, 0.0f, 0.486f, 0.547f, 1.0f, 0.149f, 0.0f, 0.49f, 0.546f, 1.0f, 0.156f, 0.0f, 0.493f, 0.544f, 1.0f, 0.163f, 0.0f, 0.497f, 0.54f, 1.0f, + 0.17f, 0.0f, 0.5f, 0.533f, 1.0f, 0.176f, 0.0f, 0.503f, 0.525f, 1.0f, 0.183f, 0.0f, 0.507f, 0.515f, 1.0f, 0.191f, 0.0f, 0.509f, 0.503f, 1.0f, + 0.198f, 0.0f, 0.512f, 0.491f, 1.0f, 0.205f, 0.0f, 0.515f, 0.477f, 1.0f, 0.214f, 0.0f, 0.518f, 0.462f, 1.0f, 0.222f, 0.0f, 0.521f, 0.445f, 1.0f, + 0.23f, 0.0f, 0.524f, 0.427f, 1.0f, 0.238f, 0.0f, 0.527f, 0.409f, 1.0f, 0.245f, 0.0f, 0.529f, 0.388f, 1.0f, 0.254f, 0.0f, 0.531f, 0.366f, 1.0f, + 0.262f, 0.0f, 0.532f, 0.343f, 1.0f, 0.272f, 0.0f, 0.533f, 0.317f, 1.0f, 0.282f, 0.0f, 0.534f, 0.289f, 1.0f, 0.292f, 0.0f, 0.535f, 0.258f, 1.0f, + 0.301f, 0.0f, 0.535f, 0.224f, 1.0f, 0.311f, 0.0f, 0.536f, 0.189f, 1.0f, 0.32f, 0.0f, 0.536f, 0.153f, 1.0f, 0.328f, 0.0f, 0.536f, 0.117f, 1.0f, + 0.338f, 0.0f, 0.537f, 0.084f, 1.0f, 0.346f, 0.0f, 0.537f, 0.057f, 1.0f, 0.353f, 0.0f, 0.536f, 0.037f, 1.0f, 0.361f, 0.0f, 0.536f, 0.022f, 1.0f, + 0.37f, 0.0f, 0.537f, 0.013f, 1.0f, 0.376f, 0.0f, 0.536f, 0.007f, 1.0f, 0.384f, 0.0f, 0.536f, 0.004f, 1.0f, 0.39f, 0.0f, 0.536f, 0.002f, 1.0f, + 0.399f, 0.0f, 0.535f, 0.0f, 1.0f, +}; + +static const float data33[69 * GP_PRIM_DATABUF_SIZE] = { + -0.308f, 0.0f, 0.151f, 0.363f, 1.0f, -0.31f, 0.0f, 0.15f, 0.377f, 1.0f, -0.311f, 0.0f, 0.149f, 0.386f, 1.0f, -0.313f, 0.0f, 0.149f, 0.397f, 1.0f, + -0.314f, 0.0f, 0.149f, 0.408f, 1.0f, -0.316f, 0.0f, 0.148f, 0.42f, 1.0f, -0.318f, 0.0f, 0.148f, 0.431f, 1.0f, -0.32f, 0.0f, 0.148f, 0.443f, 1.0f, + -0.322f, 0.0f, 0.148f, 0.455f, 1.0f, -0.325f, 0.0f, 0.149f, 0.467f, 1.0f, -0.327f, 0.0f, 0.149f, 0.478f, 1.0f, -0.33f, 0.0f, 0.151f, 0.49f, 1.0f, + -0.333f, 0.0f, 0.152f, 0.501f, 1.0f, -0.336f, 0.0f, 0.154f, 0.512f, 1.0f, -0.34f, 0.0f, 0.157f, 0.522f, 1.0f, -0.343f, 0.0f, 0.161f, 0.533f, 1.0f, + -0.346f, 0.0f, 0.166f, 0.543f, 1.0f, -0.349f, 0.0f, 0.171f, 0.553f, 1.0f, -0.351f, 0.0f, 0.178f, 0.563f, 1.0f, -0.352f, 0.0f, 0.186f, 0.572f, 1.0f, + -0.353f, 0.0f, 0.193f, 0.582f, 1.0f, -0.352f, 0.0f, 0.2f, 0.591f, 1.0f, -0.351f, 0.0f, 0.206f, 0.6f, 1.0f, -0.349f, 0.0f, 0.211f, 0.608f, 1.0f, + -0.347f, 0.0f, 0.215f, 0.616f, 1.0f, -0.345f, 0.0f, 0.219f, 0.623f, 1.0f, -0.343f, 0.0f, 0.222f, 0.63f, 1.0f, -0.341f, 0.0f, 0.224f, 0.637f, 1.0f, + -0.339f, 0.0f, 0.226f, 0.642f, 1.0f, -0.337f, 0.0f, 0.228f, 0.647f, 1.0f, -0.335f, 0.0f, 0.229f, 0.652f, 1.0f, -0.333f, 0.0f, 0.23f, 0.656f, 1.0f, + -0.332f, 0.0f, 0.231f, 0.66f, 1.0f, -0.33f, 0.0f, 0.232f, 0.663f, 1.0f, -0.328f, 0.0f, 0.232f, 0.666f, 1.0f, -0.327f, 0.0f, 0.233f, 0.669f, 1.0f, + -0.325f, 0.0f, 0.233f, 0.672f, 1.0f, -0.324f, 0.0f, 0.234f, 0.676f, 1.0f, -0.322f, 0.0f, 0.234f, 0.679f, 1.0f, -0.321f, 0.0f, 0.234f, 0.682f, 1.0f, + -0.319f, 0.0f, 0.234f, 0.686f, 1.0f, -0.317f, 0.0f, 0.234f, 0.689f, 1.0f, -0.316f, 0.0f, 0.234f, 0.693f, 1.0f, -0.314f, 0.0f, 0.234f, 0.697f, 1.0f, + -0.312f, 0.0f, 0.233f, 0.701f, 1.0f, -0.31f, 0.0f, 0.232f, 0.705f, 1.0f, -0.307f, 0.0f, 0.231f, 0.709f, 1.0f, -0.305f, 0.0f, 0.23f, 0.713f, 1.0f, + -0.302f, 0.0f, 0.228f, 0.716f, 1.0f, -0.299f, 0.0f, 0.225f, 0.719f, 1.0f, -0.295f, 0.0f, 0.222f, 0.722f, 1.0f, -0.292f, 0.0f, 0.217f, 0.725f, 1.0f, + -0.289f, 0.0f, 0.21f, 0.727f, 1.0f, -0.287f, 0.0f, 0.202f, 0.728f, 1.0f, -0.285f, 0.0f, 0.194f, 0.729f, 1.0f, -0.286f, 0.0f, 0.185f, 0.729f, 1.0f, + -0.287f, 0.0f, 0.178f, 0.728f, 1.0f, -0.289f, 0.0f, 0.171f, 0.726f, 1.0f, -0.292f, 0.0f, 0.166f, 0.723f, 1.0f, -0.294f, 0.0f, 0.162f, 0.717f, 1.0f, + -0.297f, 0.0f, 0.159f, 0.71f, 1.0f, -0.299f, 0.0f, 0.157f, 0.701f, 1.0f, -0.301f, 0.0f, 0.155f, 0.689f, 1.0f, -0.303f, 0.0f, 0.154f, 0.675f, 1.0f, + -0.305f, 0.0f, 0.152f, 0.659f, 1.0f, -0.306f, 0.0f, 0.151f, 0.641f, 1.0f, -0.308f, 0.0f, 0.151f, 0.62f, 1.0f, -0.309f, 0.0f, 0.15f, 0.602f, 1.0f, + -0.31f, 0.0f, 0.15f, 0.572f, 1.0f, +}; + +static const float data34[57 * GP_PRIM_DATABUF_SIZE] = { + 0.302f, 0.0f, 0.166f, 0.25f, 1.0f, 0.301f, 0.0f, 0.167f, 0.319f, 1.0f, 0.3f, 0.0f, 0.167f, 0.363f, 1.0f, 0.299f, 0.0f, 0.167f, 0.414f, 1.0f, + 0.298f, 0.0f, 0.167f, 0.459f, 1.0f, 0.296f, 0.0f, 0.168f, 0.501f, 1.0f, 0.295f, 0.0f, 0.168f, 0.539f, 1.0f, 0.293f, 0.0f, 0.169f, 0.573f, 1.0f, + 0.291f, 0.0f, 0.17f, 0.603f, 1.0f, 0.289f, 0.0f, 0.171f, 0.629f, 1.0f, 0.286f, 0.0f, 0.173f, 0.652f, 1.0f, 0.283f, 0.0f, 0.176f, 0.672f, 1.0f, + 0.279f, 0.0f, 0.18f, 0.69f, 1.0f, 0.276f, 0.0f, 0.186f, 0.705f, 1.0f, 0.272f, 0.0f, 0.195f, 0.719f, 1.0f, 0.271f, 0.0f, 0.205f, 0.73f, 1.0f, + 0.272f, 0.0f, 0.217f, 0.741f, 1.0f, 0.275f, 0.0f, 0.227f, 0.75f, 1.0f, 0.279f, 0.0f, 0.234f, 0.758f, 1.0f, 0.283f, 0.0f, 0.24f, 0.765f, 1.0f, + 0.287f, 0.0f, 0.243f, 0.771f, 1.0f, 0.291f, 0.0f, 0.245f, 0.776f, 1.0f, 0.294f, 0.0f, 0.247f, 0.781f, 1.0f, 0.296f, 0.0f, 0.248f, 0.785f, 1.0f, + 0.299f, 0.0f, 0.249f, 0.789f, 1.0f, 0.301f, 0.0f, 0.249f, 0.793f, 1.0f, 0.303f, 0.0f, 0.249f, 0.796f, 1.0f, 0.305f, 0.0f, 0.25f, 0.799f, 1.0f, + 0.306f, 0.0f, 0.25f, 0.802f, 1.0f, 0.308f, 0.0f, 0.249f, 0.805f, 1.0f, 0.31f, 0.0f, 0.249f, 0.808f, 1.0f, 0.311f, 0.0f, 0.249f, 0.81f, 1.0f, + 0.313f, 0.0f, 0.249f, 0.813f, 1.0f, 0.314f, 0.0f, 0.248f, 0.816f, 1.0f, 0.316f, 0.0f, 0.248f, 0.819f, 1.0f, 0.317f, 0.0f, 0.247f, 0.822f, 1.0f, + 0.319f, 0.0f, 0.246f, 0.825f, 1.0f, 0.321f, 0.0f, 0.245f, 0.828f, 1.0f, 0.323f, 0.0f, 0.244f, 0.832f, 1.0f, 0.325f, 0.0f, 0.243f, 0.835f, 1.0f, + 0.328f, 0.0f, 0.24f, 0.838f, 1.0f, 0.33f, 0.0f, 0.237f, 0.841f, 1.0f, 0.333f, 0.0f, 0.233f, 0.844f, 1.0f, 0.337f, 0.0f, 0.228f, 0.847f, 1.0f, + 0.339f, 0.0f, 0.219f, 0.849f, 1.0f, 0.341f, 0.0f, 0.209f, 0.852f, 1.0f, 0.34f, 0.0f, 0.197f, 0.854f, 1.0f, 0.336f, 0.0f, 0.186f, 0.856f, 1.0f, + 0.331f, 0.0f, 0.178f, 0.858f, 1.0f, 0.325f, 0.0f, 0.173f, 0.86f, 1.0f, 0.321f, 0.0f, 0.17f, 0.861f, 1.0f, 0.318f, 0.0f, 0.169f, 0.862f, 1.0f, + 0.315f, 0.0f, 0.168f, 0.864f, 1.0f, 0.312f, 0.0f, 0.167f, 0.865f, 1.0f, 0.311f, 0.0f, 0.167f, 0.866f, 1.0f, 0.309f, 0.0f, 0.166f, 0.867f, 1.0f, + 0.308f, 0.0f, 0.166f, 0.868f, 1.0f, +}; + +static const float data35[261 * GP_PRIM_DATABUF_SIZE] = { + -0.685f, 0.0f, 0.408f, 0.0f, 1.0f, -0.683f, 0.0f, 0.41f, 0.023f, 1.0f, -0.681f, 0.0f, 0.412f, 0.051f, 1.0f, -0.679f, 0.0f, 0.414f, 0.092f, 1.0f, + -0.678f, 0.0f, 0.415f, 0.125f, 1.0f, -0.676f, 0.0f, 0.417f, 0.149f, 1.0f, -0.674f, 0.0f, 0.419f, 0.167f, 1.0f, -0.672f, 0.0f, 0.42f, 0.183f, 1.0f, + -0.67f, 0.0f, 0.422f, 0.199f, 1.0f, -0.668f, 0.0f, 0.424f, 0.218f, 1.0f, -0.666f, 0.0f, 0.426f, 0.237f, 1.0f, -0.664f, 0.0f, 0.429f, 0.257f, 1.0f, + -0.661f, 0.0f, 0.431f, 0.275f, 1.0f, -0.659f, 0.0f, 0.434f, 0.291f, 1.0f, -0.657f, 0.0f, 0.436f, 0.305f, 1.0f, -0.655f, 0.0f, 0.439f, 0.315f, 1.0f, + -0.653f, 0.0f, 0.442f, 0.322f, 1.0f, -0.65f, 0.0f, 0.444f, 0.327f, 1.0f, -0.648f, 0.0f, 0.447f, 0.331f, 1.0f, -0.646f, 0.0f, 0.45f, 0.334f, 1.0f, + -0.643f, 0.0f, 0.453f, 0.334f, 1.0f, -0.641f, 0.0f, 0.456f, 0.334f, 1.0f, -0.639f, 0.0f, 0.459f, 0.334f, 1.0f, -0.636f, 0.0f, 0.462f, 0.333f, 1.0f, + -0.634f, 0.0f, 0.466f, 0.332f, 1.0f, -0.631f, 0.0f, 0.469f, 0.332f, 1.0f, -0.628f, 0.0f, 0.473f, 0.332f, 1.0f, -0.625f, 0.0f, 0.476f, 0.333f, 1.0f, + -0.622f, 0.0f, 0.48f, 0.335f, 1.0f, -0.618f, 0.0f, 0.483f, 0.338f, 1.0f, -0.615f, 0.0f, 0.488f, 0.342f, 1.0f, -0.611f, 0.0f, 0.492f, 0.347f, 1.0f, + -0.608f, 0.0f, 0.495f, 0.352f, 1.0f, -0.605f, 0.0f, 0.5f, 0.358f, 1.0f, -0.601f, 0.0f, 0.505f, 0.363f, 1.0f, -0.597f, 0.0f, 0.509f, 0.366f, 1.0f, + -0.593f, 0.0f, 0.514f, 0.367f, 1.0f, -0.589f, 0.0f, 0.518f, 0.367f, 1.0f, -0.585f, 0.0f, 0.522f, 0.369f, 1.0f, -0.582f, 0.0f, 0.526f, 0.372f, 1.0f, + -0.578f, 0.0f, 0.531f, 0.376f, 1.0f, -0.575f, 0.0f, 0.535f, 0.382f, 1.0f, -0.571f, 0.0f, 0.539f, 0.388f, 1.0f, -0.567f, 0.0f, 0.543f, 0.394f, 1.0f, + -0.563f, 0.0f, 0.547f, 0.4f, 1.0f, -0.56f, 0.0f, 0.551f, 0.406f, 1.0f, -0.556f, 0.0f, 0.555f, 0.411f, 1.0f, -0.552f, 0.0f, 0.559f, 0.415f, 1.0f, + -0.548f, 0.0f, 0.563f, 0.418f, 1.0f, -0.544f, 0.0f, 0.566f, 0.419f, 1.0f, -0.54f, 0.0f, 0.569f, 0.42f, 1.0f, -0.537f, 0.0f, 0.572f, 0.421f, 1.0f, + -0.533f, 0.0f, 0.576f, 0.421f, 1.0f, -0.529f, 0.0f, 0.579f, 0.421f, 1.0f, -0.526f, 0.0f, 0.582f, 0.422f, 1.0f, -0.523f, 0.0f, 0.585f, 0.422f, 1.0f, + -0.52f, 0.0f, 0.588f, 0.423f, 1.0f, -0.516f, 0.0f, 0.591f, 0.426f, 1.0f, -0.513f, 0.0f, 0.594f, 0.43f, 1.0f, -0.51f, 0.0f, 0.597f, 0.435f, 1.0f, + -0.507f, 0.0f, 0.6f, 0.441f, 1.0f, -0.504f, 0.0f, 0.603f, 0.447f, 1.0f, -0.501f, 0.0f, 0.606f, 0.453f, 1.0f, -0.498f, 0.0f, 0.609f, 0.458f, 1.0f, + -0.496f, 0.0f, 0.611f, 0.461f, 1.0f, -0.493f, 0.0f, 0.614f, 0.465f, 1.0f, -0.49f, 0.0f, 0.616f, 0.468f, 1.0f, -0.487f, 0.0f, 0.619f, 0.472f, 1.0f, + -0.484f, 0.0f, 0.621f, 0.476f, 1.0f, -0.482f, 0.0f, 0.624f, 0.48f, 1.0f, -0.479f, 0.0f, 0.627f, 0.484f, 1.0f, -0.476f, 0.0f, 0.629f, 0.487f, 1.0f, + -0.473f, 0.0f, 0.632f, 0.491f, 1.0f, -0.471f, 0.0f, 0.634f, 0.495f, 1.0f, -0.468f, 0.0f, 0.637f, 0.499f, 1.0f, -0.465f, 0.0f, 0.639f, 0.504f, 1.0f, + -0.462f, 0.0f, 0.641f, 0.508f, 1.0f, -0.459f, 0.0f, 0.643f, 0.513f, 1.0f, -0.456f, 0.0f, 0.646f, 0.519f, 1.0f, -0.453f, 0.0f, 0.648f, 0.525f, 1.0f, + -0.45f, 0.0f, 0.65f, 0.533f, 1.0f, -0.447f, 0.0f, 0.652f, 0.54f, 1.0f, -0.444f, 0.0f, 0.655f, 0.546f, 1.0f, -0.441f, 0.0f, 0.657f, 0.553f, 1.0f, + -0.438f, 0.0f, 0.659f, 0.56f, 1.0f, -0.435f, 0.0f, 0.662f, 0.567f, 1.0f, -0.432f, 0.0f, 0.664f, 0.574f, 1.0f, -0.429f, 0.0f, 0.666f, 0.58f, 1.0f, + -0.426f, 0.0f, 0.669f, 0.585f, 1.0f, -0.423f, 0.0f, 0.671f, 0.591f, 1.0f, -0.419f, 0.0f, 0.673f, 0.595f, 1.0f, -0.416f, 0.0f, 0.675f, 0.6f, 1.0f, + -0.412f, 0.0f, 0.678f, 0.604f, 1.0f, -0.409f, 0.0f, 0.68f, 0.609f, 1.0f, -0.405f, 0.0f, 0.682f, 0.613f, 1.0f, -0.401f, 0.0f, 0.684f, 0.618f, 1.0f, + -0.398f, 0.0f, 0.687f, 0.622f, 1.0f, -0.394f, 0.0f, 0.689f, 0.627f, 1.0f, -0.39f, 0.0f, 0.692f, 0.632f, 1.0f, -0.386f, 0.0f, 0.694f, 0.638f, 1.0f, + -0.381f, 0.0f, 0.697f, 0.643f, 1.0f, -0.377f, 0.0f, 0.7f, 0.649f, 1.0f, -0.373f, 0.0f, 0.702f, 0.654f, 1.0f, -0.368f, 0.0f, 0.705f, 0.659f, 1.0f, + -0.363f, 0.0f, 0.707f, 0.663f, 1.0f, -0.359f, 0.0f, 0.71f, 0.667f, 1.0f, -0.354f, 0.0f, 0.712f, 0.671f, 1.0f, -0.349f, 0.0f, 0.715f, 0.674f, 1.0f, + -0.345f, 0.0f, 0.717f, 0.677f, 1.0f, -0.34f, 0.0f, 0.72f, 0.68f, 1.0f, -0.335f, 0.0f, 0.722f, 0.683f, 1.0f, -0.33f, 0.0f, 0.725f, 0.685f, 1.0f, + -0.326f, 0.0f, 0.727f, 0.687f, 1.0f, -0.321f, 0.0f, 0.73f, 0.689f, 1.0f, -0.316f, 0.0f, 0.732f, 0.691f, 1.0f, -0.312f, 0.0f, 0.734f, 0.693f, 1.0f, + -0.307f, 0.0f, 0.736f, 0.694f, 1.0f, -0.302f, 0.0f, 0.738f, 0.696f, 1.0f, -0.298f, 0.0f, 0.74f, 0.697f, 1.0f, -0.293f, 0.0f, 0.741f, 0.698f, 1.0f, + -0.288f, 0.0f, 0.743f, 0.699f, 1.0f, -0.284f, 0.0f, 0.745f, 0.699f, 1.0f, -0.279f, 0.0f, 0.746f, 0.7f, 1.0f, -0.275f, 0.0f, 0.748f, 0.701f, 1.0f, + -0.27f, 0.0f, 0.749f, 0.702f, 1.0f, -0.265f, 0.0f, 0.751f, 0.702f, 1.0f, -0.261f, 0.0f, 0.752f, 0.704f, 1.0f, -0.256f, 0.0f, 0.753f, 0.705f, 1.0f, + -0.252f, 0.0f, 0.755f, 0.706f, 1.0f, -0.247f, 0.0f, 0.756f, 0.707f, 1.0f, -0.242f, 0.0f, 0.757f, 0.709f, 1.0f, -0.237f, 0.0f, 0.758f, 0.711f, 1.0f, + -0.233f, 0.0f, 0.759f, 0.713f, 1.0f, -0.228f, 0.0f, 0.761f, 0.715f, 1.0f, -0.223f, 0.0f, 0.762f, 0.717f, 1.0f, -0.218f, 0.0f, 0.763f, 0.719f, 1.0f, + -0.213f, 0.0f, 0.764f, 0.721f, 1.0f, -0.209f, 0.0f, 0.765f, 0.723f, 1.0f, -0.204f, 0.0f, 0.765f, 0.726f, 1.0f, -0.199f, 0.0f, 0.766f, 0.728f, 1.0f, + -0.194f, 0.0f, 0.767f, 0.73f, 1.0f, -0.189f, 0.0f, 0.768f, 0.731f, 1.0f, -0.183f, 0.0f, 0.769f, 0.733f, 1.0f, -0.178f, 0.0f, 0.77f, 0.735f, 1.0f, + -0.173f, 0.0f, 0.77f, 0.736f, 1.0f, -0.168f, 0.0f, 0.771f, 0.738f, 1.0f, -0.163f, 0.0f, 0.772f, 0.739f, 1.0f, -0.158f, 0.0f, 0.772f, 0.741f, 1.0f, + -0.152f, 0.0f, 0.773f, 0.742f, 1.0f, -0.147f, 0.0f, 0.774f, 0.744f, 1.0f, -0.142f, 0.0f, 0.774f, 0.746f, 1.0f, -0.137f, 0.0f, 0.775f, 0.748f, 1.0f, + -0.132f, 0.0f, 0.775f, 0.749f, 1.0f, -0.127f, 0.0f, 0.776f, 0.751f, 1.0f, -0.122f, 0.0f, 0.776f, 0.752f, 1.0f, -0.117f, 0.0f, 0.776f, 0.753f, 1.0f, + -0.112f, 0.0f, 0.777f, 0.754f, 1.0f, -0.108f, 0.0f, 0.777f, 0.755f, 1.0f, -0.103f, 0.0f, 0.777f, 0.755f, 1.0f, -0.099f, 0.0f, 0.777f, 0.756f, 1.0f, + -0.095f, 0.0f, 0.778f, 0.757f, 1.0f, -0.09f, 0.0f, 0.778f, 0.758f, 1.0f, -0.086f, 0.0f, 0.778f, 0.759f, 1.0f, -0.082f, 0.0f, 0.778f, 0.759f, 1.0f, + -0.077f, 0.0f, 0.778f, 0.76f, 1.0f, -0.073f, 0.0f, 0.779f, 0.76f, 1.0f, -0.069f, 0.0f, 0.779f, 0.761f, 1.0f, -0.064f, 0.0f, 0.779f, 0.761f, 1.0f, + -0.06f, 0.0f, 0.779f, 0.761f, 1.0f, -0.055f, 0.0f, 0.78f, 0.762f, 1.0f, -0.051f, 0.0f, 0.78f, 0.762f, 1.0f, -0.046f, 0.0f, 0.78f, 0.762f, 1.0f, + -0.041f, 0.0f, 0.78f, 0.762f, 1.0f, -0.037f, 0.0f, 0.781f, 0.762f, 1.0f, -0.032f, 0.0f, 0.781f, 0.763f, 1.0f, -0.027f, 0.0f, 0.781f, 0.763f, 1.0f, + -0.022f, 0.0f, 0.781f, 0.763f, 1.0f, -0.017f, 0.0f, 0.781f, 0.764f, 1.0f, -0.012f, 0.0f, 0.782f, 0.764f, 1.0f, -0.006f, 0.0f, 0.782f, 0.764f, 1.0f, + -0.001f, 0.0f, 0.782f, 0.765f, 1.0f, 0.004f, 0.0f, 0.782f, 0.766f, 1.0f, 0.009f, 0.0f, 0.782f, 0.766f, 1.0f, 0.015f, 0.0f, 0.782f, 0.767f, 1.0f, + 0.02f, 0.0f, 0.782f, 0.768f, 1.0f, 0.025f, 0.0f, 0.782f, 0.769f, 1.0f, 0.031f, 0.0f, 0.782f, 0.77f, 1.0f, 0.036f, 0.0f, 0.782f, 0.771f, 1.0f, + 0.042f, 0.0f, 0.782f, 0.772f, 1.0f, 0.048f, 0.0f, 0.782f, 0.773f, 1.0f, 0.053f, 0.0f, 0.782f, 0.774f, 1.0f, 0.059f, 0.0f, 0.782f, 0.775f, 1.0f, + 0.065f, 0.0f, 0.782f, 0.775f, 1.0f, 0.07f, 0.0f, 0.782f, 0.776f, 1.0f, 0.076f, 0.0f, 0.782f, 0.776f, 1.0f, 0.082f, 0.0f, 0.782f, 0.776f, 1.0f, + 0.088f, 0.0f, 0.782f, 0.776f, 1.0f, 0.094f, 0.0f, 0.782f, 0.777f, 1.0f, 0.1f, 0.0f, 0.781f, 0.777f, 1.0f, 0.106f, 0.0f, 0.781f, 0.778f, 1.0f, + 0.111f, 0.0f, 0.781f, 0.779f, 1.0f, 0.117f, 0.0f, 0.781f, 0.779f, 1.0f, 0.123f, 0.0f, 0.781f, 0.78f, 1.0f, 0.129f, 0.0f, 0.78f, 0.78f, 1.0f, + 0.135f, 0.0f, 0.78f, 0.781f, 1.0f, 0.141f, 0.0f, 0.779f, 0.781f, 1.0f, 0.147f, 0.0f, 0.779f, 0.782f, 1.0f, 0.153f, 0.0f, 0.778f, 0.783f, 1.0f, + 0.159f, 0.0f, 0.777f, 0.784f, 1.0f, 0.165f, 0.0f, 0.776f, 0.785f, 1.0f, 0.171f, 0.0f, 0.775f, 0.786f, 1.0f, 0.178f, 0.0f, 0.774f, 0.787f, 1.0f, + 0.185f, 0.0f, 0.773f, 0.788f, 1.0f, 0.192f, 0.0f, 0.772f, 0.789f, 1.0f, 0.2f, 0.0f, 0.771f, 0.79f, 1.0f, 0.208f, 0.0f, 0.77f, 0.791f, 1.0f, + 0.218f, 0.0f, 0.768f, 0.793f, 1.0f, 0.228f, 0.0f, 0.766f, 0.796f, 1.0f, 0.239f, 0.0f, 0.764f, 0.799f, 1.0f, 0.25f, 0.0f, 0.762f, 0.802f, 1.0f, + 0.261f, 0.0f, 0.759f, 0.806f, 1.0f, 0.271f, 0.0f, 0.755f, 0.81f, 1.0f, 0.282f, 0.0f, 0.752f, 0.815f, 1.0f, 0.293f, 0.0f, 0.748f, 0.819f, 1.0f, + 0.304f, 0.0f, 0.744f, 0.825f, 1.0f, 0.315f, 0.0f, 0.74f, 0.83f, 1.0f, 0.326f, 0.0f, 0.736f, 0.836f, 1.0f, 0.337f, 0.0f, 0.731f, 0.843f, 1.0f, + 0.349f, 0.0f, 0.727f, 0.85f, 1.0f, 0.361f, 0.0f, 0.722f, 0.858f, 1.0f, 0.372f, 0.0f, 0.718f, 0.866f, 1.0f, 0.384f, 0.0f, 0.712f, 0.874f, 1.0f, + 0.395f, 0.0f, 0.706f, 0.882f, 1.0f, 0.407f, 0.0f, 0.7f, 0.89f, 1.0f, 0.418f, 0.0f, 0.693f, 0.898f, 1.0f, 0.43f, 0.0f, 0.685f, 0.905f, 1.0f, + 0.442f, 0.0f, 0.677f, 0.912f, 1.0f, 0.458f, 0.0f, 0.666f, 0.918f, 1.0f, 0.473f, 0.0f, 0.654f, 0.924f, 1.0f, 0.49f, 0.0f, 0.64f, 0.93f, 1.0f, + 0.506f, 0.0f, 0.625f, 0.935f, 1.0f, 0.522f, 0.0f, 0.611f, 0.939f, 1.0f, 0.538f, 0.0f, 0.596f, 0.941f, 1.0f, 0.554f, 0.0f, 0.58f, 0.942f, 1.0f, + 0.569f, 0.0f, 0.564f, 0.941f, 1.0f, 0.584f, 0.0f, 0.548f, 0.935f, 1.0f, 0.598f, 0.0f, 0.533f, 0.925f, 1.0f, 0.612f, 0.0f, 0.517f, 0.91f, 1.0f, + 0.625f, 0.0f, 0.501f, 0.891f, 1.0f, 0.638f, 0.0f, 0.484f, 0.868f, 1.0f, 0.65f, 0.0f, 0.468f, 0.839f, 1.0f, 0.662f, 0.0f, 0.452f, 0.806f, 1.0f, + 0.671f, 0.0f, 0.437f, 0.766f, 1.0f, 0.679f, 0.0f, 0.423f, 0.718f, 1.0f, 0.685f, 0.0f, 0.412f, 0.661f, 1.0f, 0.691f, 0.0f, 0.403f, 0.595f, 1.0f, + 0.697f, 0.0f, 0.396f, 0.519f, 1.0f, 0.701f, 0.0f, 0.391f, 0.44f, 1.0f, 0.704f, 0.0f, 0.387f, 0.344f, 1.0f, 0.707f, 0.0f, 0.384f, 0.264f, 1.0f, + 0.711f, 0.0f, 0.38f, 0.133f, 1.0f, +}; + +/* ***************************************************************** */ +/* Monkey Color Data */ + +static const ColorTemplate gp_monkey_pct_black = { + "Black", + {0.0f, 0.0f, 0.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_monkey_pct_skin = { + "Skin", + {0.553f, 0.39f, 0.266f, 0.0f}, + {0.733f, 0.567f, 0.359f, 1.0f}, +}; + +static const ColorTemplate gp_monkey_pct_skin_light = { + "Skin_Light", + {0.553f, 0.39f, 0.266f, 0.0f}, + {0.913f, 0.828f, 0.637f, 1.0f}, +}; + +static const ColorTemplate gp_monkey_pct_skin_shadow = { + "Skin_Shadow", + {0.553f, 0.39f, 0.266f, 0.0f}, + {0.32f, 0.29f, 0.223f, 1.0f}, +}; + +static const ColorTemplate gp_monkey_pct_eyes = { + "Eyes", + {0.553f, 0.39f, 0.266f, 0.0f}, + {0.773f, 0.762f, 0.73f, 1.0f}, +}; + +static const ColorTemplate gp_monkey_pct_pupils = { + "Pupils", + {0.107f, 0.075f, 0.051f, 0.0f}, + {0.153f, 0.057f, 0.063f, 1.0f}, +}; + +/* ***************************************************************** */ +/* Monkey API */ + +/* add a 2D Suzanne (original model created by Matias Mendiola) */ +void ED_gpencil_create_monkey(bContext *C, float mat[4][4]) +{ + Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bGPdata *gpd = (bGPdata *)ob->data; + bGPDstroke *gps; + + /* create colors */ + int color_Black = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_black); + int color_Skin = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin); + int color_Skin_Light = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin_light); + int color_Skin_Shadow = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_skin_shadow); + int color_Eyes = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_eyes); + int color_Pupils = gpencil_monkey_color(bmain, ob, &gp_monkey_pct_pupils); + + /* layers */ + /* NOTE: For now, we just add new layers, to make it easier to separate out old/new instances */ + bGPDlayer *Colors = BKE_gpencil_layer_addnew(gpd, "Colors", false); + bGPDlayer *Lines = BKE_gpencil_layer_addnew(gpd, "Lines", true); + + /* frames */ + /* NOTE: No need to check for existing, as this will tkae care of it for us */ + bGPDframe *frameColor = BKE_gpencil_frame_addnew(Colors, cfra_eval); + bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, cfra_eval); + + /* generate strokes */ + gps = BKE_gpencil_add_stroke(frameColor, color_Skin, 538, 3); + BKE_gpencil_stroke_add_points(gps, data0, 538, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Eyes, 136, 3); + BKE_gpencil_stroke_add_points(gps, data1, 136, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin, 2, 3); + BKE_gpencil_stroke_add_points(gps, data2, 2, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 1, 3); + BKE_gpencil_stroke_add_points(gps, data3, 1, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 1, 3); + BKE_gpencil_stroke_add_points(gps, data4, 1, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 48, 3); + BKE_gpencil_stroke_add_points(gps, data5, 48, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 47, 3); + BKE_gpencil_stroke_add_points(gps, data6, 47, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 162, 3); + BKE_gpencil_stroke_add_points(gps, data7, 162, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 55, 3); + BKE_gpencil_stroke_add_points(gps, data8, 55, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 70, 3); + BKE_gpencil_stroke_add_points(gps, data9, 70, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Light, 227, 3); + BKE_gpencil_stroke_add_points(gps, data10, 227, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 1, 3); + BKE_gpencil_stroke_add_points(gps, data11, 1, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 123, 3); + BKE_gpencil_stroke_add_points(gps, data12, 123, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 125, 3); + BKE_gpencil_stroke_add_points(gps, data13, 125, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 45, 3); + BKE_gpencil_stroke_add_points(gps, data14, 45, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 44, 3); + BKE_gpencil_stroke_add_points(gps, data15, 44, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 84, 3); + BKE_gpencil_stroke_add_points(gps, data16, 84, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 56, 3); + BKE_gpencil_stroke_add_points(gps, data17, 56, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 59, 3); + BKE_gpencil_stroke_add_points(gps, data18, 59, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Skin_Shadow, 100, 3); + BKE_gpencil_stroke_add_points(gps, data19, 100, mat); + + gps = BKE_gpencil_add_stroke(frameColor, color_Eyes, 136, 3); + BKE_gpencil_stroke_add_points(gps, data20, 136, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 353, 3); + BKE_gpencil_stroke_add_points(gps, data21, 353, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 309, 3); + BKE_gpencil_stroke_add_points(gps, data22, 309, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 209, 3); + BKE_gpencil_stroke_add_points(gps, data23, 209, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 133, 3); + BKE_gpencil_stroke_add_points(gps, data24, 133, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 389, 3); + BKE_gpencil_stroke_add_points(gps, data25, 389, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 41, 3); + BKE_gpencil_stroke_add_points(gps, data26, 41, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 77, 3); + BKE_gpencil_stroke_add_points(gps, data27, 77, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 257, 3); + BKE_gpencil_stroke_add_points(gps, data28, 257, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 205, 3); + BKE_gpencil_stroke_add_points(gps, data29, 205, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 33, 3); + BKE_gpencil_stroke_add_points(gps, data30, 33, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 37, 3); + BKE_gpencil_stroke_add_points(gps, data31, 37, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 201, 3); + BKE_gpencil_stroke_add_points(gps, data32, 201, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Pupils, 69, 3); + BKE_gpencil_stroke_add_points(gps, data33, 69, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Pupils, 57, 3); + BKE_gpencil_stroke_add_points(gps, data34, 57, mat); + + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 261, 3); + BKE_gpencil_stroke_add_points(gps, data35, 261, mat); + + /* update depsgraph */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; +} + + +/* ***************************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index bd9bfcf7025..52642fb2570 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -48,6 +48,7 @@ #include "BLT_translation.h" +#include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -60,6 +61,9 @@ #include "BKE_library.h" #include "BKE_report.h" #include "BKE_screen.h" +#include "BKE_object_deform.h" +#include "BKE_colortools.h" +#include "BKE_material.h" #include "UI_interface.h" @@ -80,6 +84,9 @@ #include "GPU_immediate_util.h" #include "GPU_state.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "gpencil_intern.h" /* ************************************************ */ @@ -89,7 +96,9 @@ typedef struct tGP_BrushEditData { /* Current editor/region/etc. */ /* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */ + Depsgraph *depsgraph; Scene *scene; + Object *object; ScrArea *sa; ARegion *ar; @@ -114,6 +123,10 @@ typedef struct tGP_BrushEditData { /* Start of new sculpt stroke */ bool first; + /* Is multiframe editing enabled, and are we using falloff for that? */ + bool is_multiframe; + bool use_multiframe_falloff; + /* Current frame */ int cfra; @@ -128,6 +141,13 @@ typedef struct tGP_BrushEditData { /* - effect vector (e.g. 2D/3D translation for grab brush) */ float dvec[3]; + /* - multiframe falloff factor */ + float mf_falloff; + + /* active vertex group */ + int vrgroup; + + /* brush geometry (bounding box) */ rcti brush_rect; @@ -147,12 +167,34 @@ typedef struct tGP_BrushEditData { /* Callback for performing some brush operation on a single point */ -typedef bool (*GP_BrushApplyCb)(tGP_BrushEditData *gso, bGPDstroke *gps, int i, +typedef bool (*GP_BrushApplyCb)(tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, const int radius, const int co[2]); /* ************************************************ */ /* Utility Functions */ +/* apply lock axis reset */ +static void gpsculpt_compute_lock_axis(tGP_BrushEditData *gso, bGPDspoint *pt, const float save_pt[3]) +{ + if (gso->sa->spacetype != SPACE_VIEW3D) { + return; + } + + ToolSettings *ts = gso->scene->toolsettings; + int axis = ts->gp_sculpt.lock_axis; + + /* lock axis control */ + if (axis == 1) { + pt->x = save_pt[0]; + } + if (axis == 2) { + pt->y = save_pt[1]; + } + if (axis == 3) { + pt->z = save_pt[2]; + } +} + /* Context ---------------------------------------- */ /* Get the sculpting settings */ @@ -162,10 +204,18 @@ static GP_BrushEdit_Settings *gpsculpt_get_settings(Scene *scene) } /* Get the active brush */ -static GP_EditBrush_Data *gpsculpt_get_brush(Scene *scene) +static GP_EditBrush_Data *gpsculpt_get_brush(Scene *scene, bool is_weight_mode) { GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; - return &gset->brush[gset->brushtype]; + GP_EditBrush_Data *brush = NULL; + if (is_weight_mode) { + brush = &gset->brush[gset->weighttype]; + } + else { + brush = &gset->brush[gset->brushtype]; + } + + return brush; } /* Brush Operations ------------------------------- */ @@ -181,6 +231,14 @@ static bool gp_brush_invert_check(tGP_BrushEditData *gso) invert ^= true; } + /* set temporary status */ + if (invert) { + gso->brush->flag |= GP_EDITBRUSH_FLAG_TMP_INVERT; + } + else { + gso->brush->flag &= ~GP_EDITBRUSH_FLAG_TMP_INVERT; + } + return invert; } @@ -208,6 +266,9 @@ static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, c influence *= fac; } + /* apply multiframe falloff */ + influence *= gso->mf_falloff; + /* return influence */ return influence; } @@ -222,29 +283,34 @@ static float gp_brush_influence_calc(tGP_BrushEditData *gso, const int radius, c /* Smooth Brush */ /* A simple (but slower + inaccurate) smooth-brush implementation to test the algorithm for stroke smoothing */ -static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_smooth_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - GP_EditBrush_Data *brush = gso->brush; + // GP_EditBrush_Data *brush = gso->brush; float inf = gp_brush_influence_calc(gso, radius, co); - bool affect_pressure = (brush->flag & GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE) != 0; /* need one flag enabled by default */ - if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION | - GP_BRUSHEDIT_FLAG_APPLY_STRENGTH | - GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0) + if ((gso->settings->flag & + (GP_BRUSHEDIT_FLAG_APPLY_POSITION | + GP_BRUSHEDIT_FLAG_APPLY_STRENGTH | + GP_BRUSHEDIT_FLAG_APPLY_THICKNESS | + GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0) { gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION; } /* perform smoothing */ if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_POSITION) { - gp_smooth_stroke(gps, i, inf, affect_pressure); + BKE_gpencil_smooth_stroke(gps, pt_index, inf); } if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_STRENGTH) { - gp_smooth_stroke_strength(gps, i, inf); + BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf); } if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_THICKNESS) { - gp_smooth_stroke_thickness(gps, i, inf); + BKE_gpencil_smooth_stroke_thickness(gps, pt_index, inf); + } + if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_UV) { + BKE_gpencil_smooth_stroke_uv(gps, pt_index, inf); } return true; @@ -254,10 +320,11 @@ static bool gp_brush_smooth_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i /* Line Thickness Brush */ /* Make lines thicker or thinner by the specified amounts */ -static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_thickness_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; float inf; /* Compute strength of effect @@ -294,28 +361,29 @@ static bool gp_brush_thickness_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in /* Make color more or less transparent by the specified amounts */ static bool gp_brush_strength_apply( - tGP_BrushEditData *gso, bGPDstroke *gps, int i, + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; float inf; /* Compute strength of effect - * - We divide the strength by 10, so that users can set "sane" values. + * - We divide the strength, so that users can set "sane" values. * Otherwise, good default values are in the range of 0.093 */ - inf = gp_brush_influence_calc(gso, radius, co) / 10.0f; + inf = gp_brush_influence_calc(gso, radius, co) / 20.0f; /* apply */ - // XXX: this is much too strong, and it should probably do some smoothing with the surrounding stuff if (gp_brush_invert_check(gso)) { - /* make line thinner - reduce stroke pressure */ + /* make line more transparent - reduce alpha factor */ pt->strength -= inf; } else { - /* make line thicker - increase stroke pressure */ + /* make line more opaque - increase stroke strength */ pt->strength += inf; } + /* smooth the strength */ + BKE_gpencil_smooth_stroke_strength(gps, pt_index, inf); /* Strength should stay within [0.0, 1.0] */ CLAMP(pt->strength, 0.0f, 1.0f); @@ -382,8 +450,9 @@ static void gp_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps) } /* store references to stroke points in the initial stage */ -static bool gp_brush_grab_store_points(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_grab_store_points( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps); float inf = gp_brush_influence_calc(gso, radius, co); @@ -392,7 +461,7 @@ static bool gp_brush_grab_store_points(tGP_BrushEditData *gso, bGPDstroke *gps, BLI_assert(data->size < data->capacity); /* insert this point into the set of affected points */ - data->points[data->size] = i; + data->points[data->size] = pt_index; data->weights[data->size] = inf; data->size++; @@ -431,7 +500,7 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso) /* Apply grab transform to all relevant points of the affected strokes */ static void gp_brush_grab_apply_cached( - tGP_BrushEditData *gso, bGPDstroke *gps, bool parented, float diff_mat[4][4]) + tGP_BrushEditData *gso, bGPDstroke *gps, float diff_mat[4][4]) { tGPSB_Grab_StrokeData *data = BLI_ghash_lookup(gso->stroke_customdata, gps); int i; @@ -443,23 +512,21 @@ static void gp_brush_grab_apply_cached( /* adjust the amount of displacement to apply */ mul_v3_v3fl(delta, gso->dvec, data->weights[i]); - if (!parented) { - /* apply */ - add_v3_v3(&pt->x, delta); - } - else { - float fpt[3]; - /* apply transformation */ - mul_v3_m4v3(fpt, diff_mat, &pt->x); - /* apply */ - add_v3_v3(fpt, delta); - copy_v3_v3(&pt->x, fpt); - /* undo transformation to the init parent position */ - float inverse_diff_mat[4][4]; - invert_m4_m4(inverse_diff_mat, diff_mat); - mul_m4_v3(inverse_diff_mat, &pt->x); - } + float fpt[3]; + float save_pt[3]; + copy_v3_v3(save_pt, &pt->x); + /* apply transformation */ + mul_v3_m4v3(fpt, diff_mat, &pt->x); + /* apply */ + add_v3_v3v3(&pt->x, fpt, delta); + /* undo transformation to the init parent position */ + float inverse_diff_mat[4][4]; + invert_m4_m4(inverse_diff_mat, diff_mat); + mul_m4_v3(inverse_diff_mat, &pt->x); + + /* compute lock axis */ + gpsculpt_compute_lock_axis(gso, pt, save_pt); } } @@ -480,10 +547,14 @@ static void gp_brush_grab_stroke_free(void *ptr) /* Push Brush */ /* NOTE: Depends on gp_brush_grab_calc_dvec() */ -static bool gp_brush_push_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_push_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; + float save_pt[3]; + copy_v3_v3(save_pt, &pt->x); + float inf = gp_brush_influence_calc(gso, radius, co); float delta[3] = {0.0f}; @@ -493,6 +564,9 @@ static bool gp_brush_push_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, /* apply */ add_v3_v3(&pt->x, delta); + /* compute lock axis */ + gpsculpt_compute_lock_axis(gso, pt, save_pt); + /* done */ return true; } @@ -512,7 +586,8 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso) float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); - float mval_f[2] = {UNPACK2(gso->mval)}; + float mval_f[2]; + copy_v2fl_v2i(mval_f, gso->mval); float mval_prj[2]; float dvec[3]; @@ -536,12 +611,15 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso) } /* Shrink distance between midpoint and this point... */ -static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_pinch_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; float fac, inf; float vec[3]; + float save_pt[3]; + copy_v3_v3(save_pt, &pt->x); /* Scale down standard influence value to get it more manageable... * - No damping = Unmanageable at > 0.5 strength @@ -571,6 +649,9 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, /* 3) Translate back to original space, with the shrinkage applied */ add_v3_v3v3(&pt->x, gso->dvec, vec); + /* compute lock axis */ + gpsculpt_compute_lock_axis(gso, pt, save_pt); + /* done */ return true; } @@ -582,11 +663,14 @@ static bool gp_brush_pinch_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, * convert the rotated point and convert it into "data" space */ -static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_twist_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; float angle, inf; + float save_pt[3]; + copy_v3_v3(save_pt, &pt->x); /* Angle to rotate by */ inf = gp_brush_influence_calc(gso, radius, co); @@ -615,6 +699,9 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, sub_v3_v3v3(vec, &pt->x, gso->dvec); /* make relative to center (center is stored in dvec) */ mul_m3_v3(rmat, vec); add_v3_v3v3(&pt->x, vec, gso->dvec); /* restore */ + + /* compute lock axis */ + gpsculpt_compute_lock_axis(gso, pt, save_pt); } else { const float axis[3] = {0.0f, 0.0f, 1.0f}; @@ -654,10 +741,13 @@ static bool gp_brush_twist_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, /* Randomize Brush */ /* Apply some random jitter to the point */ -static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, int i, - const int radius, const int co[2]) +static bool gp_brush_randomize_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) { - bGPDspoint *pt = gps->points + i; + bGPDspoint *pt = gps->points + pt_index; + float save_pt[3]; + copy_v3_v3(save_pt, &pt->x); /* Amount of jitter to apply depends on the distance of the point to the cursor, * as well as the strength of the brush @@ -667,7 +757,8 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in /* need one flag enabled by default */ if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION | GP_BRUSHEDIT_FLAG_APPLY_STRENGTH | - GP_BRUSHEDIT_FLAG_APPLY_THICKNESS)) == 0) + GP_BRUSHEDIT_FLAG_APPLY_THICKNESS | + GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0) { gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION; } @@ -710,6 +801,8 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in float dvec[3]; ED_view3d_win_to_delta(gso->gsc.ar, svec, dvec, zfac); add_v3_v3(&pt->x, dvec); + /* compute lock axis */ + gpsculpt_compute_lock_axis(gso, pt, save_pt); } } else { @@ -749,11 +842,76 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in /* only limit lower value */ CLAMP_MIN(pt->pressure, 0.0f); } + /* apply random to UV (use pressure) */ + if (gso->settings->flag & GP_BRUSHEDIT_FLAG_APPLY_UV) { + if (BLI_rng_get_float(gso->rng) > 0.5f) { + pt->uv_rot += fac; + } + else { + pt->uv_rot -= fac; + } + CLAMP(pt->uv_rot, -M_PI_2, M_PI_2); + } /* done */ return true; } +/* Weight Paint Brush */ + +/* Change weight paint for vertex groups */ +static bool gp_brush_weight_apply( + tGP_BrushEditData *gso, bGPDstroke *gps, int pt_index, + const int radius, const int co[2]) +{ + bGPDspoint *pt = gps->points + pt_index; + MDeformVert *dvert = gps->dvert + pt_index; + float inf; + + /* Compute strength of effect + * - We divide the strength by 10, so that users can set "sane" values. + * Otherwise, good default values are in the range of 0.093 + */ + inf = gp_brush_influence_calc(gso, radius, co) / 10.0f; + + /* need a vertex group */ + if (gso->vrgroup == -1) { + if (gso->object) { + BKE_object_defgroup_add(gso->object); + gso->vrgroup = 0; + } + } + /* get current weight */ + float curweight = 0.0f; + for (int i = 0; i < dvert->totweight; i++) { + MDeformWeight *gpw = &dvert->dw[i]; + if (gpw->def_nr == gso->vrgroup) { + curweight = gpw->weight; + break; + } + } + + if (gp_brush_invert_check(gso)) { + /* reduce weight */ + curweight -= inf; + } + else { + /* increase weight */ + curweight += inf; + } + + CLAMP(curweight, 0.0f, 1.0f); + BKE_gpencil_vgroup_add_point_weight(dvert, gso->vrgroup, curweight); + + /* weight should stay within [0.0, 1.0] */ + if (pt->pressure < 0.0f) + pt->pressure = 0.0f; + + return true; +} + + + /* ************************************************ */ /* Non Callback-Based Brushes */ @@ -827,7 +985,7 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso) /* Init colormap for mapping between the pasted stroke's source colour(names) * and the final colours that will be used here instead... */ - data->new_colors = gp_copybuf_validate_colormap(gso->gpd); + data->new_colors = gp_copybuf_validate_colormap(C); } /* Free custom data used for "clone" brush */ @@ -857,9 +1015,12 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso) { tGPSB_CloneBrushData *data = gso->customdata; - Scene *scene = gso->scene; + Object *ob = CTX_data_active_object(C); bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, true); bGPDstroke *gps; float delta[3]; @@ -882,17 +1043,22 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso) new_stroke = MEM_dupallocN(gps); new_stroke->points = MEM_dupallocN(gps->points); + new_stroke->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, new_stroke); new_stroke->triangles = MEM_dupallocN(gps->triangles); new_stroke->next = new_stroke->prev = NULL; BLI_addtail(&gpf->strokes, new_stroke); /* Fix color references */ - BLI_assert(new_stroke->colorname[0] != '\0'); - new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname); - - BLI_assert(new_stroke->palcolor != NULL); - BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname)); + Material *ma = BLI_ghash_lookup(data->new_colors, &new_stroke->mat_nr); + if ((ma) && (BKE_object_material_slot_find_index(ob, ma) > 0)) { + gps->mat_nr = BKE_object_material_slot_find_index(ob, ma) - 1; + CLAMP_MIN(gps->mat_nr, 0); + } + else { + gps->mat_nr = 0; /* only if the color is not found */ + } /* Adjust all the stroke's points, so that the strokes * get pasted relative to where the cursor is now @@ -976,57 +1142,6 @@ static bool gpsculpt_brush_apply_clone(bContext *C, tGP_BrushEditData *gso) return true; } -/* ************************************************ */ -/* Cursor drawing */ - -/* Helper callback for drawing the cursor itself */ -static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)) -{ - GP_EditBrush_Data *brush = gpsculpt_get_brush(CTX_data_scene(C)); - - if (brush) { - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - GPU_line_smooth(true); - GPU_blend(true); - - /* Inner Ring: Light color for action of the brush */ - /* TODO: toggle between add and remove? */ - immUniformColor4ub(255, 255, 255, 200); - imm_draw_circle_wire_2d(pos, x, y, brush->size, 40); - - /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */ - immUniformColor3ub(30, 30, 30); - imm_draw_circle_wire_2d(pos, x, y, brush->size + 1, 40); - - immUnbindProgram(); - - GPU_blend(false); - GPU_line_smooth(false); - } -} - -/* Turn brush cursor in on/off */ -static void gpencil_toggle_brush_cursor(bContext *C, bool enable) -{ - GP_BrushEdit_Settings *gset = gpsculpt_get_settings(CTX_data_scene(C)); - - if (gset->paintcursor && !enable) { - /* clear cursor */ - WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor); - gset->paintcursor = NULL; - } - else if (enable) { - /* enable cursor */ - gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), - NULL, - gp_brush_drawcursor, NULL); - } -} - - /* ************************************************ */ /* Header Info for GPencil Sculpt */ @@ -1054,17 +1169,40 @@ static void gpsculpt_brush_header_set(bContext *C, tGP_BrushEditData *gso) static bool gpsculpt_brush_init(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); + Object *ob = CTX_data_active_object(C); + + const bool is_weight_mode = ob->mode == OB_MODE_GPENCIL_WEIGHT; + /* set the brush using the tool */ + GP_BrushEdit_Settings *gset = &ts->gp_sculpt; + eGP_EditBrush_Types mode = RNA_enum_get(op->ptr, "mode"); + const bool keep_brush = RNA_boolean_get(op->ptr, "keep_brush"); + + if (!keep_brush) { + if (is_weight_mode) { + gset->weighttype = mode; + } + else { + gset->brushtype = mode; + } + } tGP_BrushEditData *gso; /* setup operator data */ gso = MEM_callocN(sizeof(tGP_BrushEditData), "tGP_BrushEditData"); op->customdata = gso; + gso->depsgraph = CTX_data_depsgraph(C); /* store state */ gso->settings = gpsculpt_get_settings(scene); - gso->brush = gpsculpt_get_brush(scene); + gso->brush = gpsculpt_get_brush(scene, is_weight_mode); - gso->brush_type = gso->settings->brushtype; + if (is_weight_mode) { + gso->brush_type = gso->settings->weighttype; + } + else { + gso->brush_type = gso->settings->brushtype; + } /* Random generator, only init once. */ uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); @@ -1078,10 +1216,31 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op) gso->cfra = INT_MAX; /* NOTE: So that first stroke will get handled in init_stroke() */ gso->scene = scene; + gso->object = ob; + if (ob) { + gso->vrgroup = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, gso->vrgroup)) { + gso->vrgroup = -1; + } + } + else { + gso->vrgroup = - 1; + } gso->sa = CTX_wm_area(C); gso->ar = CTX_wm_region(C); + /* multiframe settings */ + gso->is_multiframe = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd); + gso->use_multiframe_falloff = (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_FRAME_FALLOFF) != 0; + + /* init multiedit falloff curve data before doing anything, + * so we won't have to do it again later + */ + if (gso->is_multiframe) { + curvemapping_initialize(ts->gp_sculpt.cur_falloff); + } + /* initialise custom data for brushes */ switch (gso->brush_type) { case GP_EDITBRUSH_TYPE_CLONE: @@ -1133,9 +1292,10 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op) gpsculpt_brush_header_set(C, gso); /* setup cursor drawing */ - WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR); - gpencil_toggle_brush_cursor(C, true); - + //WM_cursor_modal_set(CTX_wm_window(C), BC_CROSSCURSOR); + if (gso->sa->spacetype != SPACE_VIEW3D) { + ED_gpencil_toggle_brush_cursor(C, true, NULL); + } return true; } @@ -1179,7 +1339,12 @@ static void gpsculpt_brush_exit(bContext *C, wmOperator *op) /* disable cursor and headerprints */ ED_workspace_status_text(C, NULL); WM_cursor_modal_restore(win); - gpencil_toggle_brush_cursor(C, false); + if (gso->sa->spacetype != SPACE_VIEW3D) { + ED_gpencil_toggle_brush_cursor(C, false, NULL); + } + + /* disable temp invert flag */ + gso->brush->flag &= ~GP_EDITBRUSH_FLAG_TMP_INVERT; /* free operator data */ MEM_freeN(gso); @@ -1197,13 +1362,13 @@ static bool gpsculpt_brush_poll(bContext *C) static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso) { - Scene *scene = gso->scene; bGPdata *gpd = gso->gpd; + bGPDlayer *gpl; - int cfra = CFRA; + int cfra_eval = (int)DEG_get_ctime(gso->depsgraph); /* only try to add a new frame if this is the first stroke, or the frame has changed */ - if ((gpd == NULL) || (cfra == gso->cfra)) + if ((gpd == NULL) || (cfra_eval == gso->cfra)) return; /* go through each layer, and ensure that we've got a valid frame to use */ @@ -1217,21 +1382,21 @@ static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso) * spent too much time editing the wrong frame... */ // XXX: should this be allowed when framelock is enabled? - if (gpf->framenum != cfra) { - BKE_gpencil_frame_addcopy(gpl, cfra); + if (gpf->framenum != cfra_eval) { + BKE_gpencil_frame_addcopy(gpl, cfra_eval); } } } /* save off new current frame, so that next update works fine */ - gso->cfra = cfra; + gso->cfra = cfra_eval; } /* Apply ----------------------------------------------- */ /* Apply brush operation to points in this stroke */ static bool gpsculpt_brush_do_stroke( - tGP_BrushEditData *gso, bGPDstroke *gps, bool parented, + tGP_BrushEditData *gso, bGPDstroke *gps, float diff_mat[4][4], GP_BrushApplyCb apply) { GP_SpaceConversion *gsc = &gso->gsc; @@ -1246,14 +1411,9 @@ static bool gpsculpt_brush_do_stroke( bool changed = false; if (gps->totpoints == 1) { - if (!parented) { - gp_point_to_xy(gsc, gps, gps->points, &pc1[0], &pc1[1]); - } - else { - bGPDspoint pt_temp; - gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); - gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]); - } + bGPDspoint pt_temp; + gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); + gp_point_to_xy(gsc, gps, &pt_temp, &pc1[0], &pc1[1]); /* do boundbox check first */ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { @@ -1280,19 +1440,12 @@ static bool gpsculpt_brush_do_stroke( continue; } } - if (!parented) { - gp_point_to_xy(gsc, gps, pt1, &pc1[0], &pc1[1]); - gp_point_to_xy(gsc, gps, pt2, &pc2[0], &pc2[1]); - } - else { - bGPDspoint npt; - gp_point_to_parent_space(pt1, diff_mat, &npt); - gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]); - - gp_point_to_parent_space(pt2, diff_mat, &npt); - gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]); - } + bGPDspoint npt; + gp_point_to_parent_space(pt1, diff_mat, &npt); + gp_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]); + gp_point_to_parent_space(pt2, diff_mat, &npt); + gp_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]); /* Check that point segment of the boundbox of the selection stroke */ if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) || @@ -1342,9 +1495,114 @@ static bool gpsculpt_brush_do_stroke( return changed; } +/* Apply sculpt brushes to strokes in the given frame */ +static bool gpsculpt_brush_do_frame( + bContext *C, tGP_BrushEditData *gso, + bGPDlayer *gpl, bGPDframe *gpf, + float diff_mat[4][4]) +{ + bool changed = false; + Object *ob = CTX_data_active_object(C); + + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + + switch (gso->brush_type) { + case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_smooth_apply); + break; + } + + case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_thickness_apply); + break; + } + + case GP_EDITBRUSH_TYPE_STRENGTH: /* Adjust stroke color strength */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_strength_apply); + break; + } + + case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */ + { + if (gso->first) { + /* First time this brush stroke is being applied: + * 1) Prepare data buffers (init/clear) for this stroke + * 2) Use the points now under the cursor + */ + gp_brush_grab_stroke_init(gso, gps); + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_grab_store_points); + } + else { + /* Apply effect to the stored points */ + gp_brush_grab_apply_cached(gso, gps, diff_mat); + changed |= true; + } + break; + } + + case GP_EDITBRUSH_TYPE_PUSH: /* Push points */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_push_apply); + break; + } + + case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_pinch_apply); + break; + } + + case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_twist_apply); + break; + } + + case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_randomize_apply); + break; + } + + case GP_EDITBRUSH_TYPE_WEIGHT: /* Adjust vertex group weight */ + { + changed |= gpsculpt_brush_do_stroke(gso, gps, diff_mat, gp_brush_weight_apply); + break; + } + + + default: + printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type); + break; + } + /* Triangulation must be calculated if changed */ + if (changed) { + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; + } + } + + return changed; +} + /* Perform two-pass brushes which modify the existing strokes */ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso) { + ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + Object *obact = gso->object; + bGPdata *gpd = gso->gpd; bool changed = false; /* Calculate brush-specific data which applies equally to all points */ @@ -1378,104 +1636,53 @@ static bool gpsculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *gso) /* Find visible strokes, and perform operations on those if hit */ - float diff_mat[4][4]; - bool parented = false; - CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - if (gpf == NULL) + /* If no active frame, don't do anything... */ + if (gpl->actframe == NULL) { continue; - - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - parented = true; } - else { - parented = false; - } - - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) - continue; - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { - continue; - } - switch (gso->brush_type) { - case GP_EDITBRUSH_TYPE_SMOOTH: /* Smooth strokes */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_smooth_apply); - break; - } + /* calculate difference matrix */ + float diff_mat[4][4]; + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); - case GP_EDITBRUSH_TYPE_THICKNESS: /* Adjust stroke thickness */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_thickness_apply); - break; - } + /* Active Frame or MultiFrame? */ + if (gso->is_multiframe) { + /* init multiframe falloff options */ + int f_init = 0; + int f_end = 0; - case GP_EDITBRUSH_TYPE_STRENGTH: /* Adjust stroke color strength */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_strength_apply); - break; - } + if (gso->use_multiframe_falloff) { + BKE_gpencil_get_range_selected(gpl, &f_init, &f_end); + } - case GP_EDITBRUSH_TYPE_GRAB: /* Grab points */ - { - if (gso->first) { - /* First time this brush stroke is being applied: - * 1) Prepare data buffers (init/clear) for this stroke - * 2) Use the points now under the cursor - */ - gp_brush_grab_stroke_init(gso, gps); - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_grab_store_points); + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* Always do active frame; Otherwise, only include selected frames */ + if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) { + /* compute multiframe falloff factor */ + if (gso->use_multiframe_falloff) { + /* Faloff depends on distance to active frame (relative to the overall frame range) */ + gso->mf_falloff = BKE_gpencil_multiframe_falloff_calc( + gpf, gpl->actframe->framenum, + f_init, f_end, + ts->gp_sculpt.cur_falloff); } else { - /* Apply effect to the stored points */ - gp_brush_grab_apply_cached(gso, gps, parented, diff_mat); - changed |= true; + /* No falloff */ + gso->mf_falloff = 1.0f; } - break; - } - - case GP_EDITBRUSH_TYPE_PUSH: /* Push points */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_push_apply); - break; - } - - case GP_EDITBRUSH_TYPE_PINCH: /* Pinch points */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_pinch_apply); - break; - } - case GP_EDITBRUSH_TYPE_TWIST: /* Twist points around midpoint */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_twist_apply); - break; + /* affect strokes in this frame */ + changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpf, diff_mat); } - - case GP_EDITBRUSH_TYPE_RANDOMIZE: /* Apply jitter */ - { - changed |= gpsculpt_brush_do_stroke(gso, gps, parented, diff_mat, gp_brush_randomize_apply); - break; - } - - default: - printf("ERROR: Unknown type of GPencil Sculpt brush - %u\n", gso->brush_type); - break; - } - /* Triangulation must be calculated if changed */ - if (changed) { - gps->flag |= GP_STROKE_RECALC_CACHES; - gps->tot_triangles = 0; } } + else { + /* Apply to active frame's strokes */ + gso->mf_falloff = 1.0f; + changed |= gpsculpt_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat); + } } CTX_DATA_END; @@ -1529,6 +1736,7 @@ static void gpsculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA *itempt /* Updates */ if (changed) { + DEG_id_tag_update(&gso->gpd->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } @@ -1852,6 +2060,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even /* Redraw toolsettings (brush settings)? */ if (redraw_toolsettings) { + DEG_id_tag_update(&gso->gpd->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); } @@ -1860,6 +2069,19 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even /* Operator --------------------------------------------- */ +static const EnumPropertyItem prop_gpencil_sculpt_brush_items[] = { + {GP_EDITBRUSH_TYPE_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth stroke points" }, + {GP_EDITBRUSH_TYPE_THICKNESS, "THICKNESS", 0, "Thickness", "Adjust thickness of strokes" }, + {GP_EDITBRUSH_TYPE_STRENGTH, "STRENGTH", 0, "Strength", "Adjust color strength of strokes" }, + {GP_EDITBRUSH_TYPE_GRAB, "GRAB", 0, "Grab", "Translate the set of points initially within the brush circle" }, + {GP_EDITBRUSH_TYPE_PUSH, "PUSH", 0, "Push", "Move points out of the way, as if combing them" }, + {GP_EDITBRUSH_TYPE_TWIST, "TWIST", 0, "Twist", "Rotate points around the midpoint of the brush" }, + {GP_EDITBRUSH_TYPE_PINCH, "PINCH", 0, "Pinch", "Pull points towards the midpoint of the brush" }, + {GP_EDITBRUSH_TYPE_RANDOMIZE, "RANDOMIZE", 0, "Randomize", "Introduce jitter/randomness into strokes" }, + {GP_EDITBRUSH_TYPE_CLONE, "CLONE", 0, "Clone", "Paste copies of the strokes stored on the clipboard" }, + {GP_EDITBRUSH_TYPE_WEIGHT, "WEIGHT", 0, "Weight", "Weight Paint" }, + {0, NULL, 0, NULL, NULL } +}; void GPENCIL_OT_brush_paint(wmOperatorType *ot) { @@ -1879,13 +2101,20 @@ void GPENCIL_OT_brush_paint(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* properties */ + ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_sculpt_brush_items, 0, "Mode", "Brush mode"); + RNA_def_property_flag(ot->prop, PROP_HIDDEN | PROP_SKIP_SAVE); + PropertyRNA *prop; prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Enter a mini 'sculpt-mode' if enabled, otherwise, exit after drawing a single stroke"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + prop = RNA_def_boolean(ot->srna, "keep_brush", false, "Keep Brush", + "Keep current brush activated"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } /* ************************************************ */ diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 79bfc5149ba..f662e9b42be 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -56,7 +56,6 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "DNA_gpencil_types.h" -#include "DNA_workspace_types.h" #include "BKE_collection.h" #include "BKE_context.h" @@ -74,6 +73,7 @@ #include "BKE_tracking.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "UI_interface.h" @@ -149,28 +149,24 @@ static const EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C), Poi * - assumes that the active space is the 3D-View */ static void gp_strokepoint_convertcoords( - bContext *C, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt, + bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, bGPDspoint *source_pt, float p3d[3], const rctf *subrect) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + Object *obact = CTX_data_active_object(C); bGPDspoint mypt, *pt; float diff_mat[4][4]; pt = &mypt; - /* calculate difference matrix if parent object */ - if (gpl->parent == NULL) { - copy_v3_v3(&pt->x, &source_pt->x); - } - else { - /* apply parent transform */ - float fpt[3]; - ED_gpencil_parent_location(gpl, diff_mat); - mul_v3_m4v3(fpt, diff_mat, &source_pt->x); - copy_v3_v3(&pt->x, fpt); - } + /* apply parent transform */ + float fpt[3]; + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); + mul_v3_m4v3(fpt, diff_mat, &source_pt->x); + copy_v3_v3(&pt->x, fpt); if (gps->flag & GP_STROKE_3DSPACE) { @@ -591,7 +587,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl } } -static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, +static void gp_stroke_to_path(bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, const bool add_end_point, tGpTimingData *gtd) { @@ -655,7 +651,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv bp = &nu->bp[old_nbp - 1]; /* First point */ - gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect); if (prev_bp) { interp_v3_v3v3(p1, bp->vec, prev_bp->vec, -GAP_DFAC); if (do_gtd) { @@ -676,7 +672,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv /* Second point */ /* Note dt2 is always negative, which marks the gap. */ if (gps->totpoints > 1) { - gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect); interp_v3_v3v3(p2, p, next_p, -GAP_DFAC); if (do_gtd) { dt2 = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); @@ -697,9 +693,9 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv float p[3], next_p[3]; float dt = 0.0f; - gp_strokepoint_convertcoords(C, gpl, gps, gps->points, p, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points, p, subrect); if (gps->totpoints > 1) { - gp_strokepoint_convertcoords(C, gpl, gps, gps->points + 1, next_p, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, gps->points + 1, next_p, subrect); interp_v3_v3v3(p, p, next_p, -GAP_DFAC); if (do_gtd) { dt = interpf(gps->points[1].time, gps->points[0].time, -GAP_DFAC); @@ -728,10 +724,10 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv i++, pt++, bp++) { float p[3]; - float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC; + float width = pt->pressure * (gps->thickness + gpl->line_change) * WIDTH_CORR_FAC; /* get coordinates to add at */ - gp_strokepoint_convertcoords(C, gpl, gps, pt, p, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, p, subrect); gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time, width, rad_fac, minmax_weights); @@ -801,7 +797,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt, } } -static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, +static void gp_stroke_to_bezier(bContext *C, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu, float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point, const bool add_end_point, tGpTimingData *gtd) { @@ -843,12 +839,12 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu /* get initial coordinates */ pt = gps->points; if (tot) { - gp_strokepoint_convertcoords(C, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt, (stitch) ? p3d_prev : p3d_cur, subrect); if (tot > 1) { - gp_strokepoint_convertcoords(C, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 1, (stitch) ? p3d_cur : p3d_next, subrect); } if (stitch && tot > 2) { - gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect); } } @@ -967,7 +963,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu /* add points */ for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) { - float width = pt->pressure * (gps->thickness + gpl->thickness) * WIDTH_CORR_FAC; + float width = pt->pressure * (gps->thickness + gpl->line_change) * WIDTH_CORR_FAC; if (i || old_nbezt) { interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC); @@ -991,7 +987,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu copy_v3_v3(p3d_cur, p3d_next); if (i + 2 < tot) { - gp_strokepoint_convertcoords(C, gpl, gps, pt + 2, p3d_next, subrect); + gp_strokepoint_convertcoords(C, gpd, gpl, gps, pt + 2, p3d_next, subrect); } prev_bezt = bezt; @@ -1130,10 +1126,12 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG const bool norm_weights, const float rad_fac, const bool link_strokes, tGpTimingData *gtd) { struct Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); Collection *collection = CTX_data_collection(C); - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); bGPDstroke *gps, *prev_gps = NULL; Object *ob; Curve *cu; @@ -1192,12 +1190,12 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG switch (mode) { case GP_STROKECONVERT_PATH: - gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, + gp_stroke_to_path(C, gpd, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, add_start_point, add_end_point, gtd); break; case GP_STROKECONVERT_CURVE: case GP_STROKECONVERT_POLY: /* convert after */ - gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, + gp_stroke_to_bezier(C, gpd, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch, add_start_point, add_end_point, gtd); break; default: @@ -1238,7 +1236,9 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG */ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bGPDframe *gpf = NULL; bGPDstroke *gps = NULL; bGPDspoint *pt; @@ -1246,7 +1246,7 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe int i; bool valid = true; - if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) || !(gps = gpf->strokes.first)) + if (!gpl || !(gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0)) || !(gps = gpf->strokes.first)) return false; do { @@ -1294,10 +1294,12 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN static bool gp_convert_poll(bContext *C) { bGPdata *gpd = ED_gpencil_data_get_active(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bGPDlayer *gpl = NULL; bGPDframe *gpf = NULL; ScrArea *sa = CTX_wm_area(C); - Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); /* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!), @@ -1305,7 +1307,7 @@ static bool gp_convert_poll(bContext *C) */ return ((sa && sa->spacetype == SPACE_VIEW3D) && (gpl = BKE_gpencil_layer_getactive(gpd)) && - (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) && + (gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0)) && (gpf->strokes.first) && (OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL)); } diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index c28fea0fc41..dd1852ca8ce 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -46,18 +46,32 @@ #include "BLT_translation.h" +#include "DNA_anim_types.h" +#include "DNA_brush_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" -#include "DNA_gpencil_types.h" -#include "BKE_colortools.h" +#include "BKE_main.h" +#include "BKE_brush.h" +#include "BKE_animsys.h" #include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" #include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_object.h" +#include "BKE_material.h" +#include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" @@ -72,8 +86,13 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "ED_object.h" #include "ED_gpencil.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + #include "gpencil_intern.h" /* ************************************************ */ @@ -84,9 +103,9 @@ /* add new datablock - wrapper around API */ static int gp_data_add_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); - ToolSettings *ts = CTX_data_tool_settings(C); + PointerRNA gpd_owner = {{NULL}}; + bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, &gpd_owner); + bool is_annotation = ED_gpencil_data_owner_is_annotation(&gpd_owner); if (gpd_ptr == NULL) { BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go"); @@ -94,19 +113,36 @@ static int gp_data_add_exec(bContext *C, wmOperator *op) } else { /* decrement user count and add new datablock */ - bGPdata *gpd = (*gpd_ptr); + /* TODO: if a datablock exists, we should make a copy of it instead of starting fresh (as in other areas) */ + Main *bmain = CTX_data_main(C); - id_us_min(&gpd->id); - *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); + /* decrement user count of old GP datablock */ + if (*gpd_ptr) { + bGPdata *gpd = (*gpd_ptr); + id_us_min(&gpd->id); + } - /* if not exist brushes, create a new set */ - if (ts) { - if (BLI_listbase_is_empty(&ts->gp_brushes)) { - /* create new brushes */ - BKE_gpencil_brush_init_presets(ts); - } + /* add new datablock, with a single layer ready to use (so users don't have to perform an extra step) */ + if (is_annotation) { + bGPdata *gpd = BKE_gpencil_data_addnew(bmain, DATA_("Annotations")); + *gpd_ptr = gpd; + + /* tag for annotations */ + gpd->flag |= GP_DATA_ANNOTATIONS; + + /* add new layer (i.e. a "note") */ + BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("Note"), true); } + else { + /* GP Object Case - This shouldn't happen! */ + *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); + + /* add default sets of colors and brushes */ + ED_gpencil_add_defaults(C); + /* add new layer */ + BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true); + } } /* notifiers */ @@ -185,28 +221,42 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot) /* add new layer - wrapper around API */ static int gp_layer_add_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); - ToolSettings *ts = CTX_data_tool_settings(C); + PointerRNA gpd_owner = {{NULL}}; + bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, &gpd_owner); + bool is_annotation = ED_gpencil_data_owner_is_annotation(&gpd_owner); /* if there's no existing Grease-Pencil data there, add some */ if (gpd_ptr == NULL) { BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go"); return OPERATOR_CANCELLED; } - if (*gpd_ptr == NULL) - *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); - /* if not exist brushes, create a new set */ - if (ts) { - if (BLI_listbase_is_empty(&ts->gp_brushes)) { - /* create new brushes */ - BKE_gpencil_brush_init_presets(ts); + if (*gpd_ptr == NULL) { + Main *bmain = CTX_data_main(C); + if (is_annotation) { + /* Annotations */ + *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("Annotations")); + + /* mark as annotation */ + (*gpd_ptr)->flag |= GP_DATA_ANNOTATIONS; + } + else { + /* GP Object */ + /* NOTE: This shouldn't actually happen in practice */ + *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); + + /* add default sets of colors and brushes */ + ED_gpencil_add_defaults(C); } } /* add new layer now */ - BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true); + if (is_annotation) { + BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("Note"), true); + } + else { + BKE_gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), true); + } /* notifiers */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); @@ -219,7 +269,7 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot) /* identifiers */ ot->name = "Add New Layer"; ot->idname = "GPENCIL_OT_layer_add"; - ot->description = "Add new Grease Pencil layer for the active Grease Pencil data-block"; + ot->description = "Add new layer or note for the active data-block"; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -257,6 +307,7 @@ static int gp_layer_remove_exec(bContext *C, wmOperator *op) BKE_gpencil_layer_delete(gpd, gpl); /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -296,6 +347,7 @@ static int gp_layer_move_exec(bContext *C, wmOperator *op) BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */ if (BLI_listbase_link_move(&gpd->layers, gpl, direction)) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } @@ -346,6 +398,7 @@ static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op)) BKE_gpencil_layer_setactive(gpd, new_layer); /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -366,6 +419,154 @@ void GPENCIL_OT_layer_duplicate(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ********************* Duplicate Frame ************************** */ +enum { + GP_FRAME_DUP_ACTIVE = 0, + GP_FRAME_DUP_ALL = 1 +}; + +static int gp_frame_duplicate_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + int mode = RNA_enum_get(op->ptr, "mode"); + + /* sanity checks */ + if (ELEM(NULL, gpd, gpl)) + return OPERATOR_CANCELLED; + + if (mode == 0) { + BKE_gpencil_frame_addcopy(gpl, cfra_eval); + } + else { + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & GP_LAYER_LOCKED) == 0) { + BKE_gpencil_frame_addcopy(gpl, cfra_eval); + } + } + + } + /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_frame_duplicate(wmOperatorType *ot) +{ + static const EnumPropertyItem duplicate_mode[] = { + { GP_FRAME_DUP_ACTIVE, "ACTIVE", 0, "Active", "Duplicate frame in active layer only" }, + { GP_FRAME_DUP_ALL, "ALL", 0, "All", "Duplicate active frames in all layers" }, + { 0, NULL, 0, NULL, NULL } + }; + + + /* identifiers */ + ot->name = "Duplicate Frame"; + ot->idname = "GPENCIL_OT_frame_duplicate"; + ot->description = "Make a copy of the active Grease Pencil Frame"; + + /* callbacks */ + ot->exec = gp_frame_duplicate_exec; + ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", ""); +} + +/* ********************* Clean Fill Boundaries on Frame ************************** */ +enum { + GP_FRAME_CLEAN_FILL_ACTIVE = 0, + GP_FRAME_CLEAN_FILL_ALL = 1 +}; + +static int gp_frame_clean_fill_exec(bContext *C, wmOperator *op) +{ + bool changed = false; + bGPdata *gpd = ED_gpencil_data_get_active(C); + int mode = RNA_enum_get(op->ptr, "mode"); + + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *init_gpf = gpl->actframe; + if (mode == GP_FRAME_CLEAN_FILL_ALL) { + init_gpf = gpl->frames.first; + } + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || (mode == GP_FRAME_CLEAN_FILL_ALL)) { + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) + continue; + + /* simply delete strokes which are no fill */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + + /* free stroke */ + if (gps->flag & GP_STROKE_NOFILL) { + /* free stroke memory arrays, then stroke itself */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + MEM_SAFE_FREE(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); + + changed = true; + } + } + } + } + } + CTX_DATA_END; + + /* notifiers */ + if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + } + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_frame_clean_fill(wmOperatorType *ot) +{ + static const EnumPropertyItem duplicate_mode[] = { + { GP_FRAME_CLEAN_FILL_ACTIVE, "ACTIVE", 0, "Active Frame Only", "Clean active frame only" }, + { GP_FRAME_CLEAN_FILL_ALL, "ALL", 0, "All Frames", "Clean all frames in all layers" }, + { 0, NULL, 0, NULL, NULL } + }; + + /* identifiers */ + ot->name = "Clean Fill Boundaries"; + ot->idname = "GPENCIL_OT_frame_clean_fill"; + ot->description = "Remove 'no fill' boundary strokes"; + + /* callbacks */ + ot->exec = gp_frame_clean_fill_exec; + ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "mode", duplicate_mode, GP_FRAME_DUP_ACTIVE, "Mode", ""); +} + /* *********************** Hide Layers ******************************** */ static int gp_hide_exec(bContext *C, wmOperator *op) @@ -394,6 +595,7 @@ static int gp_hide_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -481,6 +683,7 @@ static int gp_reveal_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -521,6 +724,7 @@ static int gp_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -558,6 +762,7 @@ static int gp_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -630,6 +835,7 @@ static int gp_isolate_layer_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -673,22 +879,28 @@ static int gp_merge_layer_exec(bContext *C, wmOperator *op) BLI_ghash_insert(gh_frames_cur, SET_INT_IN_POINTER(gpf->framenum), gpf); } - /* read all frames from next layer */ + /* read all frames from next layer and add any missing in current layer */ for (bGPDframe *gpf = gpl_next->frames.first; gpf; gpf = gpf->next) { - /* try to find frame in active layer */ + /* try to find frame in current layer */ bGPDframe *frame = BLI_ghash_lookup(gh_frames_cur, SET_INT_IN_POINTER(gpf->framenum)); if (!frame) { - /* nothing found, create new */ + bGPDframe *actframe = BKE_gpencil_layer_getframe(gpl_current, gpf->framenum, GP_GETFRAME_USE_PREV); frame = BKE_gpencil_frame_addnew(gpl_current, gpf->framenum); + /* duplicate strokes of current active frame */ + if (actframe) { + BKE_gpencil_frame_copy_strokes(actframe, frame); + } } /* add to tail all strokes */ BLI_movelisttolist(&frame->strokes, &gpf->strokes); } + /* Now delete next layer */ BKE_gpencil_layer_delete(gpd, gpl_next); BLI_ghash_free(gh_frames_cur, NULL, NULL); /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -750,6 +962,7 @@ static int gp_layer_change_exec(bContext *C, wmOperator *op) BKE_gpencil_layer_setactive(gpd, gpl); /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -788,6 +1001,7 @@ enum { static int gp_stroke_arrange_exec(bContext *C, wmOperator *op) { + Object *ob = CTX_data_active_object(C); bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); bGPDstroke *gps; @@ -797,79 +1011,95 @@ static int gp_stroke_arrange_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - bGPDframe *gpf = gpl->actframe; - /* temp listbase to store selected strokes */ - ListBase selected = {NULL}; const int direction = RNA_enum_get(op->ptr, "direction"); - /* verify if any selected stroke is in the extreme of the stack and select to move */ - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* only if selected */ - if (gps->flag & GP_STROKE_SELECT) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { - continue; - } - /* some stroke is already at front*/ - if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) { - if (gps == gpf->strokes.last) { - return OPERATOR_CANCELLED; + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* temp listbase to store selected strokes by layer */ + ListBase selected = { NULL }; + bGPDframe *gpf = gpl->actframe; + if (gpl->flag & GP_LAYER_LOCKED) { + continue; + } + + if (gpf == NULL) { + continue; + } + bool gpf_lock = false; + /* verify if any selected stroke is in the extreme of the stack and select to move */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + /* only if selected */ + if (gps->flag & GP_STROKE_SELECT) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; } - } - /* some stroke is already at botom */ - if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) { - if (gps == gpf->strokes.first) { - return OPERATOR_CANCELLED; + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + /* some stroke is already at front*/ + if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) { + if (gps == gpf->strokes.last) { + gpf_lock = true; + continue; + } + } + /* some stroke is already at botom */ + if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) { + if (gps == gpf->strokes.first) { + gpf_lock = true; + continue; + } + } + /* add to list (if not locked) */ + if (!gpf_lock) { + BLI_addtail(&selected, BLI_genericNodeN(gps)); } } - /* add to list */ - BLI_addtail(&selected, BLI_genericNodeN(gps)); } - } - - /* Now do the movement of the stroke */ - switch (direction) { - /* Bring to Front */ - case GP_STROKE_MOVE_TOP: - for (LinkData *link = selected.first; link; link = link->next) { - gps = link->data; - BLI_remlink(&gpf->strokes, gps); - BLI_addtail(&gpf->strokes, gps); - } - break; - /* Bring Forward */ - case GP_STROKE_MOVE_UP: - for (LinkData *link = selected.last; link; link = link->prev) { - gps = link->data; - BLI_listbase_link_move(&gpf->strokes, gps, 1); - } - break; - /* Send Backward */ - case GP_STROKE_MOVE_DOWN: - for (LinkData *link = selected.first; link; link = link->next) { - gps = link->data; - BLI_listbase_link_move(&gpf->strokes, gps, -1); - } - break; - /* Send to Back */ - case GP_STROKE_MOVE_BOTTOM: - for (LinkData *link = selected.last; link; link = link->prev) { - gps = link->data; - BLI_remlink(&gpf->strokes, gps); - BLI_addhead(&gpf->strokes, gps); + /* Now do the movement of the stroke */ + if (!gpf_lock) { + switch (direction) { + /* Bring to Front */ + case GP_STROKE_MOVE_TOP: + for (LinkData *link = selected.first; link; link = link->next) { + gps = link->data; + BLI_remlink(&gpf->strokes, gps); + BLI_addtail(&gpf->strokes, gps); + } + break; + /* Bring Forward */ + case GP_STROKE_MOVE_UP: + for (LinkData *link = selected.last; link; link = link->prev) { + gps = link->data; + BLI_listbase_link_move(&gpf->strokes, gps, 1); + } + break; + /* Send Backward */ + case GP_STROKE_MOVE_DOWN: + for (LinkData *link = selected.first; link; link = link->next) { + gps = link->data; + BLI_listbase_link_move(&gpf->strokes, gps, -1); + } + break; + /* Send to Back */ + case GP_STROKE_MOVE_BOTTOM: + for (LinkData *link = selected.last; link; link = link->prev) { + gps = link->data; + BLI_remlink(&gpf->strokes, gps); + BLI_addhead(&gpf->strokes, gps); + } + break; + default: + BLI_assert(0); + break; } - break; - default: - BLI_assert(0); - break; + } + BLI_freelistN(&selected); } - BLI_freelistN(&selected); /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -890,58 +1120,70 @@ void GPENCIL_OT_stroke_arrange(wmOperatorType *ot) ot->idname = "GPENCIL_OT_stroke_arrange"; ot->description = "Arrange selected strokes up/down in the drawing order of the active layer"; - /* api callbacks */ + /* callbacks */ ot->exec = gp_stroke_arrange_exec; ot->poll = gp_active_layer_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* properties */ ot->prop = RNA_def_enum(ot->srna, "direction", slot_move, GP_STROKE_MOVE_UP, "Direction", ""); } + /* ******************* Move Stroke to new color ************************** */ static int gp_stroke_change_color_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette; - bGPDpalettecolor *color; + Object *ob = CTX_data_active_object(C); + Material *ma = give_current_material(ob, ob->actcol); + int idx = BKE_object_material_slot_find_index(ob, ma) - 1; /* sanity checks */ if (ELEM(NULL, gpd)) { return OPERATOR_CANCELLED; } - palette = BKE_gpencil_palette_getactive(gpd); - color = BKE_gpencil_palettecolor_getactive(palette); - if (ELEM(NULL, palette, color)) { + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + if (ELEM(NULL, ma)) { return OPERATOR_CANCELLED; } /* loop all strokes */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* only editable and visible layers are considered */ - if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { - for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) { - /* only if selected */ - if (gps->flag & GP_STROKE_SELECT) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) - continue; - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) - continue; + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) + continue; - /* asign new color (only if different) */ - if ((STREQ(gps->colorname, color->info) == false) || (gps->palcolor != color)) { - BLI_strncpy(gps->colorname, color->info, sizeof(gps->colorname)); - gps->palcolor = color; + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* only if selected */ + if (gps->flag & GP_STROKE_SELECT) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) + continue; + + /* asign new color */ + gps->mat_nr = idx; } } } } } + CTX_DATA_END; + /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -954,9 +1196,12 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot) ot->idname = "GPENCIL_OT_stroke_change_color"; ot->description = "Move selected strokes to active color"; - /* api callbacks */ + /* callbacks */ ot->exec = gp_stroke_change_color_exec; ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* ******************* Lock color of non selected Strokes colors ************************** */ @@ -964,19 +1209,21 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot) static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette; + + Object *ob = CTX_data_active_object(C); + + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); /* sanity checks */ if (ELEM(NULL, gpd)) return OPERATOR_CANCELLED; - palette = BKE_gpencil_palette_getactive(gpd); - if (ELEM(NULL, palette)) - return OPERATOR_CANCELLED; - /* first lock all colors */ - for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag |= PC_COLOR_LOCKED; + for (short i = 0; i < *totcol; i++) { + Material *tmp_ma = (*matar)[i]; + tmp_ma->gp_style->flag |= GP_STYLE_COLOR_LOCKED; + } /* loop all selected strokes and unlock any color */ @@ -991,14 +1238,14 @@ static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op)) continue; } /* unlock color */ - if (gps->palcolor != NULL) { - gps->palcolor->flag &= ~PC_COLOR_LOCKED; - } + Material *tmp_ma = (*matar)[gps->mat_nr]; + tmp_ma->gp_style->flag &= ~GP_STYLE_COLOR_LOCKED; } } } } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -1014,25 +1261,18 @@ void GPENCIL_OT_stroke_lock_color(wmOperatorType *ot) /* api callbacks */ ot->exec = gp_stroke_lock_color_exec; ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* ************************************************ */ /* Drawing Brushes Operators */ -/* ******************* Add New Brush ************************ */ - -/* add new brush - wrapper around API */ -static int gp_brush_add_exec(bContext *C, wmOperator *op) +/* ******************* Brush create presets ************************** */ +static int gp_brush_presets_create_exec(bContext *C, wmOperator *UNUSED(op)) { - ToolSettings *ts = CTX_data_tool_settings(C); - - /* if there's no existing container */ - if (ts == NULL) { - BKE_report(op->reports, RPT_ERROR, "Nowhere for brush data to go"); - return OPERATOR_CANCELLED; - } - /* add new brush now */ - BKE_gpencil_brush_addnew(ts, DATA_("GP_Brush"), true); + BKE_brush_gpencil_presets(C); /* notifiers */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); @@ -1040,513 +1280,760 @@ static int gp_brush_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_add(wmOperatorType *ot) +void GPENCIL_OT_brush_presets_create(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Brush"; - ot->idname = "GPENCIL_OT_brush_add"; - ot->description = "Add new Grease Pencil drawing brush for the active Grease Pencil data-block"; + ot->name = "Create Preset Brushes"; + ot->idname = "GPENCIL_OT_brush_presets_create"; + ot->description = "Create a set of predefined Grease Pencil drawing brushes"; + /* api callbacks */ + ot->exec = gp_brush_presets_create_exec; + + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* callbacks */ - ot->exec = gp_brush_add_exec; - ot->poll = gp_add_poll; } -/* ******************* Remove Active Brush ************************* */ +/* ***************** Select Brush ************************ */ -static int gp_brush_remove_exec(bContext *C, wmOperator *op) +static int gp_brush_select_exec(bContext *C, wmOperator *op) { ToolSettings *ts = CTX_data_tool_settings(C); - bGPDbrush *brush = BKE_gpencil_brush_getactive(ts); - - /* sanity checks */ - if (ELEM(NULL, ts, brush)) - return OPERATOR_CANCELLED; + Main *bmain = CTX_data_main(C); - if (BLI_listbase_count_at_most(&ts->gp_brushes, 2) < 2) { - BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a brush, unable to delete the last one"); + /* if there's no existing container */ + if (ts == NULL) { + BKE_report(op->reports, RPT_ERROR, "Nowhere to go"); return OPERATOR_CANCELLED; } + const int index = RNA_int_get(op->ptr, "index"); - /* make the brush before this the new active brush - * - use the one after if this is the first - * - if this is the only brush, this naturally becomes NULL - */ - if (brush->prev) - BKE_gpencil_brush_setactive(ts, brush->prev); - else - BKE_gpencil_brush_setactive(ts, brush->next); - - /* delete the brush now... */ - BKE_gpencil_brush_delete(ts, brush); + Paint *paint = BKE_brush_get_gpencil_paint(ts); + int i = 0; + for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) { + if (brush->ob_mode == OB_MODE_GPENCIL_PAINT) { + if (i == index) { + BKE_paint_brush_set(paint, brush); - /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + /* notifiers */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + return OPERATOR_FINISHED; + } + i++; + } + } - return OPERATOR_FINISHED; + return OPERATOR_CANCELLED; } -void GPENCIL_OT_brush_remove(wmOperatorType *ot) +void GPENCIL_OT_brush_select(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove Brush"; - ot->idname = "GPENCIL_OT_brush_remove"; - ot->description = "Remove active Grease Pencil drawing brush"; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->name = "Select Brush"; + ot->idname = "GPENCIL_OT_brush_select"; + ot->description = "Select a Grease Pencil drawing brush"; /* callbacks */ - ot->exec = gp_brush_remove_exec; + ot->exec = gp_brush_select_exec; ot->poll = gp_active_brush_poll; -} - -/* ********************** Change Brush ***************************** */ - -static int gp_brush_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt)) -{ - uiPopupMenu *pup; - uiLayout *layout; - /* call the menu, which will call this operator again, hence the canceled */ - pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); - layout = UI_popup_menu_layout(pup); - uiItemsEnumO(layout, "GPENCIL_OT_brush_change", "brush"); - UI_popup_menu_end(C, pup); + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - return OPERATOR_INTERFACE; + /* properties */ + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Drawing Brush", 0, INT_MAX); } -static int gp_brush_change_exec(bContext *C, wmOperator *op) +/* ***************** Select Sculpt Brush ************************ */ + +static int gp_sculpt_select_exec(bContext *C, wmOperator *op) { ToolSettings *ts = CTX_data_tool_settings(C); - bGPDbrush *brush = NULL; - int brush_num = RNA_enum_get(op->ptr, "brush"); - /* Get brush or create new one */ - if (brush_num == -1) { - /* Create brush */ - brush = BKE_gpencil_brush_addnew(ts, DATA_("GP_Brush"), true); + /* if there's no existing container */ + if (ts == NULL) { + BKE_report(op->reports, RPT_ERROR, "Nowhere to go"); + return OPERATOR_CANCELLED; } - else { - /* Try to get brush */ - brush = BLI_findlink(&ts->gp_brushes, brush_num); - if (brush == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent brush (index = %d)", brush_num); - return OPERATOR_CANCELLED; - } + const int index = RNA_int_get(op->ptr, "index"); + GP_BrushEdit_Settings *gp_sculpt = &ts->gp_sculpt; + /* sanity checks */ + if (ELEM(NULL, gp_sculpt)) { + return OPERATOR_CANCELLED; } - /* Set active brush */ - BKE_gpencil_brush_setactive(ts, brush); - - /* updates */ + if (index < TOT_GP_EDITBRUSH_TYPES - 1) { + gp_sculpt->brushtype = index; + } + /* notifiers */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_change(wmOperatorType *ot) +void GPENCIL_OT_sculpt_select(wmOperatorType *ot) { /* identifiers */ - ot->name = "Change Brush"; - ot->idname = "GPENCIL_OT_brush_change"; - ot->description = "Change active Grease Pencil drawing brush"; + ot->name = "Select Sculpt Brush"; + ot->idname = "GPENCIL_OT_sculpt_select"; + ot->description = "Select a Grease Pencil sculpt brush"; /* callbacks */ - ot->invoke = gp_brush_change_invoke; - ot->exec = gp_brush_change_exec; - ot->poll = gp_active_brush_poll; + ot->exec = gp_sculpt_select_exec; + ot->poll = gp_add_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* gp brush to use (dynamic enum) */ - ot->prop = RNA_def_enum(ot->srna, "brush", DummyRNA_DEFAULT_items, 0, "Grease Pencil Brush", ""); - RNA_def_enum_funcs(ot->prop, ED_gpencil_brushes_enum_itemf); + /* properties */ + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Sculpt Brush", 0, INT_MAX); } -/* ******************* Move Brush Up/Down ************************** */ +/*********************** Vertex Groups ***********************************/ -enum { - GP_BRUSH_MOVE_UP = -1, - GP_BRUSH_MOVE_DOWN = 1 -}; +static bool gpencil_vertex_group_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + + if ((ob) && (ob->type == OB_GPENCIL)) { + if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) { + if (ELEM(ob->mode, + OB_MODE_GPENCIL_EDIT, + OB_MODE_GPENCIL_SCULPT)) + { + return true; + } + } + } -static int gp_brush_move_exec(bContext *C, wmOperator *op) + return false; +} + +static bool gpencil_vertex_group_weight_poll(bContext *C) { - ToolSettings *ts = CTX_data_tool_settings(C); - bGPDbrush *brush = BKE_gpencil_brush_getactive(ts); + Object *ob = CTX_data_active_object(C); - int direction = RNA_enum_get(op->ptr, "type"); + if ((ob) && (ob->type == OB_GPENCIL)) { + if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) { + if (ob->mode == OB_MODE_GPENCIL_WEIGHT) + { + return true; + } + } + } + + return false; +} + +static int gpencil_vertex_group_assign_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ToolSettings *ts = CTX_data_tool_settings(C); + Object *ob = CTX_data_active_object(C); /* sanity checks */ - if (ELEM(NULL, ts, brush)) { + if (ELEM(NULL, ts, ob, ob->data)) return OPERATOR_CANCELLED; - } - /* up or down? */ - if (direction == GP_BRUSH_MOVE_UP) { - /* up */ - BLI_remlink(&ts->gp_brushes, brush); - BLI_insertlinkbefore(&ts->gp_brushes, brush->prev, brush); - } - else if (direction == GP_BRUSH_MOVE_DOWN) { - /* down */ - BLI_remlink(&ts->gp_brushes, brush); - BLI_insertlinkafter(&ts->gp_brushes, brush->next, brush); - } - else { - BLI_assert(0); - } + ED_gpencil_vgroup_assign(C, ob, ts->vgroup_weight); /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_move(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_assign(wmOperatorType *ot) { - static const EnumPropertyItem slot_move[] = { - {GP_BRUSH_MOVE_UP, "UP", 0, "Up", ""}, - {GP_BRUSH_MOVE_DOWN, "DOWN", 0, "Down", ""}, - {0, NULL, 0, NULL, NULL } - }; - /* identifiers */ - ot->name = "Move Brush"; - ot->idname = "GPENCIL_OT_brush_move"; - ot->description = "Move the active Grease Pencil drawing brush up/down in the list"; + ot->name = "Assign to Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_assign"; + ot->description = "Assign the selected vertices to the active vertex group"; /* api callbacks */ - ot->exec = gp_brush_move_exec; - ot->poll = gp_active_brush_poll; + ot->poll = gpencil_vertex_group_poll; + ot->exec = gpencil_vertex_group_assign_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - ot->prop = RNA_def_enum(ot->srna, "type", slot_move, GP_BRUSH_MOVE_UP, "Type", ""); } -/* ******************* Brush create presets ************************** */ - -static int gp_brush_presets_create_exec(bContext *C, wmOperator *UNUSED(op)) +/* remove point from vertex group */ +static int gpencil_vertex_group_remove_from_exec(bContext *C, wmOperator *UNUSED(op)) { - ToolSettings *ts = CTX_data_tool_settings(C); - BKE_gpencil_brush_init_presets(ts); + Object *ob = CTX_data_active_object(C); + + /* sanity checks */ + if (ELEM(NULL, ob, ob->data)) + return OPERATOR_CANCELLED; + + ED_gpencil_vgroup_remove(C, ob); /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_presets_create(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_remove_from(wmOperatorType *ot) { /* identifiers */ - ot->name = "Create Preset Brushes"; - ot->idname = "GPENCIL_OT_brush_presets_create"; - ot->description = "Create a set of predefined Grease Pencil drawing brushes"; + ot->name = "Remove from Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_remove_from"; + ot->description = "Remove the selected vertices from active or all vertex group(s)"; /* api callbacks */ - ot->exec = gp_brush_presets_create_exec; + ot->poll = gpencil_vertex_group_poll; + ot->exec = gpencil_vertex_group_remove_from_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ***************** Copy Brush ************************ */ - -static int gp_brush_copy_exec(bContext *C, wmOperator *op) +static int gpencil_vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op)) { - ToolSettings *ts = CTX_data_tool_settings(C); - - /* if there's no existing container */ - if (ts == NULL) { - BKE_report(op->reports, RPT_ERROR, "Nowhere for brush data to go"); - return OPERATOR_CANCELLED; - } - - bGPDbrush *brush = BKE_gpencil_brush_getactive(ts); - bGPDbrush *newbrush; + Object *ob = CTX_data_active_object(C); /* sanity checks */ - if (ELEM(NULL, brush)) + if (ELEM(NULL, ob, ob->data)) return OPERATOR_CANCELLED; - /* create a brush and duplicate data */ - newbrush = BKE_gpencil_brush_addnew(ts, brush->info, true); - newbrush->thickness = brush->thickness; - newbrush->draw_smoothfac = brush->draw_smoothfac; - newbrush->draw_smoothlvl = brush->draw_smoothlvl; - newbrush->sublevel = brush->sublevel; - newbrush->flag = brush->flag; - newbrush->draw_sensitivity = brush->draw_sensitivity; - newbrush->draw_strength = brush->draw_strength; - newbrush->draw_jitter = brush->draw_jitter; - newbrush->draw_angle = brush->draw_angle; - newbrush->draw_angle_factor = brush->draw_angle_factor; - newbrush->draw_random_press = brush->draw_random_press; - newbrush->draw_random_sub = brush->draw_random_sub; - - /* free automatic curves created by default (replaced by copy) */ - curvemapping_free(newbrush->cur_sensitivity); - curvemapping_free(newbrush->cur_strength); - curvemapping_free(newbrush->cur_jitter); - - /* make a copy of curves */ - newbrush->cur_sensitivity = curvemapping_copy(brush->cur_sensitivity); - newbrush->cur_strength = curvemapping_copy(brush->cur_strength); - newbrush->cur_jitter = curvemapping_copy(brush->cur_jitter); - - BKE_gpencil_brush_setactive(ts, newbrush); + ED_gpencil_vgroup_select(C, ob); + /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_copy(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_select(wmOperatorType *ot) { /* identifiers */ - ot->name = "Copy Brush"; - ot->idname = "GPENCIL_OT_brush_copy"; - ot->description = "Copy current Grease Pencil drawing brush"; + ot->name = "Select Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_select"; + ot->description = "Select all the vertices assigned to the active vertex group"; - /* callbacks */ - ot->exec = gp_brush_copy_exec; - ot->poll = gp_active_brush_poll; + /* api callbacks */ + ot->poll = gpencil_vertex_group_poll; + ot->exec = gpencil_vertex_group_select_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ***************** Select Brush ************************ */ - -static int gp_brush_select_exec(bContext *C, wmOperator *op) +static int gpencil_vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op)) { - ToolSettings *ts = CTX_data_tool_settings(C); - - /* if there's no existing container */ - if (ts == NULL) { - BKE_report(op->reports, RPT_ERROR, "Nowhere to go"); - return OPERATOR_CANCELLED; - } + Object *ob = CTX_data_active_object(C); - const int index = RNA_int_get(op->ptr, "index"); - bGPDbrush *brush = BLI_findlink(&ts->gp_brushes, index); /* sanity checks */ - if (ELEM(NULL, brush)) { + if (ELEM(NULL, ob, ob->data)) return OPERATOR_CANCELLED; - } - BKE_gpencil_brush_setactive(ts, brush); + ED_gpencil_vgroup_deselect(C, ob); /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_brush_select(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_deselect(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Brush"; - ot->idname = "GPENCIL_OT_brush_select"; - ot->description = "Select a Grease Pencil drawing brush"; + ot->name = "Deselect Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_deselect"; + ot->description = "Deselect all selected vertices assigned to the active vertex group"; - /* callbacks */ - ot->exec = gp_brush_select_exec; - ot->poll = gp_active_brush_poll; + /* api callbacks */ + ot->poll = gpencil_vertex_group_poll; + ot->exec = gpencil_vertex_group_deselect_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of Drawing Brush", 0, INT_MAX); } -/* ************************************************ */ -/* Palette Operators */ - -/* ******************* Add New Palette ************************ */ - -/* add new palette - wrapper around API */ -static int gp_palette_add_exec(bContext *C, wmOperator *op) +/* invert */ +static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); - bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); + ToolSettings *ts = CTX_data_tool_settings(C); + Object *ob = CTX_data_active_object(C); - /* if there's no existing Grease-Pencil data there, add some */ - if (gpd_ptr == NULL) { - BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go"); + /* sanity checks */ + if (ELEM(NULL, ts, ob, ob->data)) return OPERATOR_CANCELLED; - } - if (*gpd_ptr == NULL) - *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); - /* add new palette now */ - BKE_gpencil_palette_addnew(*gpd_ptr, DATA_("GP_Palette"), true); + MDeformVert *dvert; + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return OPERATOR_CANCELLED; + + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + for (int i = 0; i < gps->totpoints; i++) { + dvert = &gps->dvert[i]; + if (dvert->dw == NULL) { + BKE_gpencil_vgroup_add_point_weight(dvert, def_nr, 1.0f); + } + else if (dvert->dw->weight == 1.0f) { + BKE_gpencil_vgroup_remove_point_weight(dvert, def_nr); + } + else { + dvert->dw->weight = 1.0f - dvert->dw->weight; + } + } + } + CTX_DATA_END; /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_palette_add(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_invert(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add Palette"; - ot->idname = "GPENCIL_OT_palette_add"; - ot->description = "Add new Grease Pencil palette for the active Grease Pencil data-block"; + ot->name = "Invert Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_invert"; + ot->description = "Invert weights to the active vertex group"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* api callbacks */ + ot->poll = gpencil_vertex_group_weight_poll; + ot->exec = gpencil_vertex_group_invert_exec; - /* callbacks */ - ot->exec = gp_palette_add_exec; - ot->poll = gp_add_poll; + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************* Remove Active Palette ************************* */ - -static int gp_palette_remove_exec(bContext *C, wmOperator *op) +/* smooth */ +static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); + const float fac = RNA_float_get(op->ptr, "factor"); + const int repeat = RNA_int_get(op->ptr, "repeat"); + + ToolSettings *ts = CTX_data_tool_settings(C); + Object *ob = CTX_data_active_object(C); /* sanity checks */ - if (ELEM(NULL, gpd, palette)) + if (ELEM(NULL, ts, ob, ob->data)) return OPERATOR_CANCELLED; - if (BLI_listbase_count_at_most(&gpd->palettes, 2) < 2) { - BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a palette, unable to delete the last one"); - return OPERATOR_CANCELLED; - } + bGPDspoint *pta, *ptb, *ptc; + MDeformVert *dverta, *dvertb; + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return OPERATOR_CANCELLED; - /* make the palette before this the new active palette - * - use the one after if this is the first - * - if this is the only palette, this naturally becomes NULL - */ - if (palette->prev) - BKE_gpencil_palette_setactive(gpd, palette->prev); - else - BKE_gpencil_palette_setactive(gpd, palette->next); + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + for (int s = 0; s < repeat; s++) { + for (int i = 0; i < gps->totpoints; i++) { + /* previous point */ + if (i > 0) { + pta = &gps->points[i - 1]; + dverta = &gps->dvert[i - 1]; + } + else { + pta = &gps->points[i]; + dverta = &gps->dvert[i]; + } + /* current */ + ptb = &gps->points[i]; + dvertb = &gps->dvert[i]; + /* next point */ + if (i + 1 < gps->totpoints) { + ptc = &gps->points[i + 1]; + } + else { + ptc = &gps->points[i]; + } - /* delete the palette now... */ - BKE_gpencil_palette_delete(gpd, palette); + float wa = BKE_gpencil_vgroup_use_index(dverta, def_nr); + float wb = BKE_gpencil_vgroup_use_index(dvertb, def_nr); + CLAMP_MIN(wa, 0.0f); + CLAMP_MIN(wb, 0.0f); + + /* the optimal value is the corresponding to the interpolation of the weight + * at the distance of point b + */ + const float opfac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); + const float optimal = interpf(wa, wb, opfac); + /* Based on influence factor, blend between original and optimal */ + wb = interpf(wb, optimal, fac); + BKE_gpencil_vgroup_add_point_weight(dvertb, def_nr, wb); + } + } + } + CTX_DATA_END; /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_palette_remove(wmOperatorType *ot) +void GPENCIL_OT_vertex_group_smooth(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove palette"; - ot->idname = "GPENCIL_OT_palette_remove"; - ot->description = "Remove active Grease Pencil palette"; + ot->name = "Smooth Vertex Group"; + ot->idname = "GPENCIL_OT_vertex_group_smooth"; + ot->description = "Smooth weights to the active vertex group"; + + /* api callbacks */ + ot->poll = gpencil_vertex_group_weight_poll; + ot->exec = gpencil_vertex_group_smooth_exec; + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* callbacks */ - ot->exec = gp_palette_remove_exec; - ot->poll = gp_active_palette_poll; + RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 1.0, "Factor", "", 0.0f, 1.0f); + RNA_def_int(ot->srna, "repeat", 1, 1, 10000, "Iterations", "", 1, 200); } -/* ********************** Change Palette ***************************** */ +/****************************** Join ***********************************/ -static int gp_palette_change_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt)) +/* userdata for joined_gpencil_fix_animdata_cb() */ +typedef struct tJoinGPencil_AdtFixData { + bGPdata *src_gpd; + bGPdata *tar_gpd; + + GHash *names_map; +} tJoinGPencil_AdtFixData; + +/* Callback to pass to BKE_fcurves_main_cb() for RNA Paths attached to each F-Curve used in the AnimData */ +static void joined_gpencil_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data) { - uiPopupMenu *pup; - uiLayout *layout; + tJoinGPencil_AdtFixData *afd = (tJoinGPencil_AdtFixData *)user_data; + ID *src_id = &afd->src_gpd->id; + ID *dst_id = &afd->tar_gpd->id; - /* call the menu, which will call this operator again, hence the canceled */ - pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE); - layout = UI_popup_menu_layout(pup); - uiItemsEnumO(layout, "GPENCIL_OT_palette_change", "palette"); - UI_popup_menu_end(C, pup); + GHashIterator gh_iter; - return OPERATOR_INTERFACE; + /* Fix paths - If this is the target datablock, it will have some "dirty" paths */ + if ((id == src_id) && fcu->rna_path && strstr(fcu->rna_path, "layers[")) { + GHASH_ITER(gh_iter, afd->names_map) { + const char *old_name = BLI_ghashIterator_getKey(&gh_iter); + const char *new_name = BLI_ghashIterator_getValue(&gh_iter); + + /* only remap if changed; this still means there will be some waste if there aren't many drivers/keys */ + if (!STREQ(old_name, new_name) && strstr(fcu->rna_path, old_name)) { + fcu->rna_path = BKE_animsys_fix_rna_path_rename(id, fcu->rna_path, "layers", + old_name, new_name, 0, 0, false); + + /* we don't want to apply a second remapping on this F-Curve now, + * so stop trying to fix names names + */ + break; + } + } + } + + /* Fix driver targets */ + if (fcu->driver) { + /* Fix driver references to invalid ID's */ + for (DriverVar *dvar = fcu->driver->variables.first; dvar; dvar = dvar->next) { + /* only change the used targets, since the others will need fixing manually anyway */ + DRIVER_TARGETS_USED_LOOPER(dvar) + { + /* change the ID's used... */ + if (dtar->id == src_id) { + dtar->id = dst_id; + + /* also check on the subtarget... + * XXX: We duplicate the logic from drivers_path_rename_fix() here, with our own + * little twists so that we know that it isn't going to clobber the wrong data + */ + if (dtar->rna_path && strstr(dtar->rna_path, "layers[")) { + GHASH_ITER(gh_iter, afd->names_map) { + const char *old_name = BLI_ghashIterator_getKey(&gh_iter); + const char *new_name = BLI_ghashIterator_getValue(&gh_iter); + + /* only remap if changed */ + if (!STREQ(old_name, new_name)) { + if ((dtar->rna_path) && strstr(dtar->rna_path, old_name)) { + /* Fix up path */ + dtar->rna_path = BKE_animsys_fix_rna_path_rename(id, dtar->rna_path, "layers", + old_name, new_name, 0, 0, false); + break; /* no need to try any more names for layer path */ + } + } + } + } + } + } + DRIVER_TARGETS_LOOPER_END + } + } } -static int gp_palette_change_exec(bContext *C, wmOperator *op) +/* join objects called from OBJECT_OT_join */ +int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) { - bGPdata *gpd = CTX_data_gpencil_data(C); - bGPDpalette *palette = NULL; - int palette_num = RNA_enum_get(op->ptr, "palette"); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Object *obact = CTX_data_active_object(C); + bGPdata *gpd_dst = NULL; + bool ok = false; + + /* Ensure we're in right mode and that the active object is correct */ + if (!obact || obact->type != OB_GPENCIL) + return OPERATOR_CANCELLED; - /* Get palette or create new one */ - if (palette_num == -1) { - /* Create palette */ - palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true); + bGPdata *gpd = (bGPdata *)obact->data; + if ((!gpd) || GPENCIL_ANY_MODE(gpd)) { + return OPERATOR_CANCELLED; } - else { - /* Try to get palette */ - palette = BLI_findlink(&gpd->palettes, palette_num); - if (palette == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Cannot change to non-existent palette (index = %d)", palette_num); - return OPERATOR_CANCELLED; + /* Ensure all rotations are applied before */ + // XXX: Why don't we apply them here instead of warning? + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) + { + if (base->object->type == OB_GPENCIL) { + if ((base->object->rot[0] != 0) || + (base->object->rot[1] != 0) || + (base->object->rot[2] != 0)) + { + BKE_report(op->reports, RPT_ERROR, "Apply all rotations before join objects"); + return OPERATOR_CANCELLED; + } } } + CTX_DATA_END; - /* Set active palette */ - BKE_gpencil_palette_setactive(gpd, palette); + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) + { + if (base->object == obact) { + ok = true; + break; + } + } + CTX_DATA_END; - /* updates */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + /* that way the active object is always selected */ + if (ok == false) { + BKE_report(op->reports, RPT_WARNING, "Active object is not a selected grease pencil"); + return OPERATOR_CANCELLED; + } - return OPERATOR_FINISHED; -} + gpd_dst = obact->data; + Object *ob_dst = obact; + + /* loop and join all data */ + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) + { + if ((base->object->type == OB_GPENCIL) && (base->object != obact)) { + /* we assume that each datablock is not already used in active object */ + if (obact->data != base->object->data) { + Object *ob_src = base->object; + bGPdata *gpd_src = base->object->data; + + /* Apply all GP modifiers before */ + for (GpencilModifierData *md = base->object->greasepencil_modifiers.first; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + if (mti->bakeModifier) { + mti->bakeModifier(bmain, depsgraph, md, base->object); + } + } -void GPENCIL_OT_palette_change(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Change Palette"; - ot->idname = "GPENCIL_OT_palette_change"; - ot->description = "Change active Grease Pencil palette"; + /* copy vertex groups to the base one's */ + int old_idx = 0; + for (bDeformGroup *dg = base->object->defbase.first; dg; dg = dg->next) { + bDeformGroup *vgroup = MEM_dupallocN(dg); + int idx = BLI_listbase_count(&obact->defbase); + defgroup_unique_name(vgroup, obact); + BLI_addtail(&obact->defbase, vgroup); + /* update vertex groups in strokes in original data */ + for (bGPDlayer *gpl_src = gpd->layers.first; gpl_src; gpl_src = gpl_src->next) { + for (bGPDframe *gpf = gpl_src->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + MDeformVert *dvert; + int i; + for (i = 0, dvert = gps->dvert; i < gps->totpoints; i++, dvert++) { + if ((dvert->dw) && (dvert->dw->def_nr == old_idx)) { + dvert->dw->def_nr = idx; + } + } + } + } + } + old_idx++; + } + if (obact->defbase.first && obact->actdef == 0) + obact->actdef = 1; + + /* add missing materials reading source materials and checking in destination object */ + Material ***matar = give_matarar(ob_src); + short *totcol = give_totcolp(ob_src); + + for (short i = 0; i < *totcol; i++) { + Material *tmp_ma = (*matar)[i]; + if (BKE_object_material_slot_find_index(ob_dst, tmp_ma) == 0) { + BKE_object_material_slot_add(bmain, ob_dst); + assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_EXISTING); + } + } - /* callbacks */ - ot->invoke = gp_palette_change_invoke; - ot->exec = gp_palette_change_exec; - ot->poll = gp_active_palette_poll; + /* duplicate bGPDlayers */ + tJoinGPencil_AdtFixData afd = {0}; + afd.src_gpd = gpd_src; + afd.tar_gpd = gpd_dst; + afd.names_map = BLI_ghash_str_new("joined_gp_layers_map"); + + float imat[3][3], bmat[3][3]; + float offset_global[3]; + float offset_local[3]; + + sub_v3_v3v3(offset_global, obact->loc, base->object->obmat[3]); + copy_m3_m4(bmat, obact->obmat); + invert_m3_m3(imat, bmat); + mul_m3_v3(imat, offset_global); + mul_v3_m3v3(offset_local, imat, offset_global); + + + for (bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) { + bGPDlayer *gpl_new = BKE_gpencil_layer_duplicate(gpl_src); + float diff_mat[4][4]; + float inverse_diff_mat[4][4]; + + /* recalculate all stroke points */ + ED_gpencil_parent_location(depsgraph, base->object, gpd_src, gpl_src, diff_mat); + invert_m4_m4(inverse_diff_mat, diff_mat); + + Material *ma_src = NULL; + int idx; + for (bGPDframe *gpf = gpl_new->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + + /* reasign material. Look old material and try to find in dst */ + ma_src = give_current_material(ob_src, gps->mat_nr + 1); + if (ma_src != NULL) { + idx = BKE_object_material_slot_find_index(ob_dst, ma_src); + if (idx > 0) { + gps->mat_nr = idx - 1; + } + else { + gps->mat_nr = 0; + } + } + else { + gps->mat_nr = 0; + } + + bGPDspoint *pt; + int i; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + float mpt[3]; + mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x); + sub_v3_v3(mpt, offset_local); + mul_v3_m4v3(&pt->x, diff_mat, mpt); + } + } + } - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + /* be sure name is unique in new object */ + BLI_uniquename(&gpd_dst->layers, gpl_new, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl_new->info)); + BLI_ghash_insert(afd.names_map, BLI_strdup(gpl_src->info), gpl_new->info); + + /* add to destination datablock */ + BLI_addtail(&gpd_dst->layers, gpl_new); + } + + /* Fix all the animation data */ + BKE_fcurves_main_cb(bmain, joined_gpencil_fix_animdata_cb, &afd); + BLI_ghash_free(afd.names_map, MEM_freeN, NULL); + + /* Only copy over animdata now, after all the remapping has been done, + * so that we don't have to worry about ambiguities re which datablock + * a layer came from! + */ + if (base->object->adt) { + if (obact->adt == NULL) { + /* no animdata, so just use a copy of the whole thing */ + obact->adt = BKE_animdata_copy(bmain, base->object->adt, false, true); + } + else { + /* merge in data - we'll fix the drivers manually */ + BKE_animdata_merge_copy(bmain, &obact->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, false); + } + } + + if (gpd_src->adt) { + if (gpd_dst->adt == NULL) { + /* no animdata, so just use a copy of the whole thing */ + gpd_dst->adt = BKE_animdata_copy(bmain, gpd_src->adt, false, true); + } + else { + /* merge in data - we'll fix the drivers manually */ + BKE_animdata_merge_copy(bmain, &gpd_dst->id, &gpd_src->id, ADT_MERGECOPY_KEEP_DST, false); + } + } + } + + /* Free the old object */ + ED_object_base_free_and_unlink(bmain, scene, base->object); + } + } + CTX_DATA_END; + + DEG_relations_tag_update(bmain); /* because we removed object(s) */ - /* gp palette to use (dynamic enum) */ - ot->prop = RNA_def_enum(ot->srna, "palette", DummyRNA_DEFAULT_items, 0, "Grease Pencil Palette", ""); - RNA_def_enum_funcs(ot->prop, ED_gpencil_palettes_enum_itemf); + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + + return OPERATOR_FINISHED; } -/* ******************* Lock and hide any color non used in current layer ************************** */ +/* Color Handle operator */ +static bool gpencil_active_color_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + if (ob && ob->data && (ob->type == OB_GPENCIL)) { + short *totcolp = give_totcolp(ob); + return *totcolp > 0; + } + return false; +} -static int gp_palette_lock_layer_exec(bContext *C, wmOperator *UNUSED(op)) + +/* ******************* Lock and hide any color non used in current layer ************************** */ +static int gpencil_lock_layer_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette; + Object *ob = CTX_data_active_object(C); + MaterialGPencilStyle *gp_style = NULL; /* sanity checks */ if (ELEM(NULL, gpd)) return OPERATOR_CANCELLED; - palette = BKE_gpencil_palette_getactive(gpd); - if (ELEM(NULL, palette)) + /* first lock and hide all colors */ + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + if ((totcol == 0) || (matar == NULL)) return OPERATOR_CANCELLED; - /* first lock and hide all colors */ - for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag |= PC_COLOR_LOCKED; - palcolor->flag |= PC_COLOR_HIDE; + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + gp_style->flag |= GP_STYLE_COLOR_LOCKED; + gp_style->flag |= GP_STYLE_COLOR_HIDE; } /* loop all selected strokes and unlock any color used in active layer */ @@ -1558,140 +2045,49 @@ static int gp_palette_lock_layer_exec(bContext *C, wmOperator *UNUSED(op)) if (ED_gpencil_stroke_can_use(C, gps) == false) continue; + gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); /* unlock/unhide color if not unlocked before */ - if (gps->palcolor != NULL) { - gps->palcolor->flag &= ~PC_COLOR_LOCKED; - gps->palcolor->flag &= ~PC_COLOR_HIDE; + if (gp_style != NULL) { + gp_style->flag &= ~GP_STYLE_COLOR_LOCKED; + gp_style->flag &= ~GP_STYLE_COLOR_HIDE; } } } } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_palette_lock_layer(wmOperatorType *ot) +void GPENCIL_OT_lock_layer(wmOperatorType *ot) { /* identifiers */ ot->name = "Disable Unused Layer Colors"; - ot->idname = "GPENCIL_OT_palette_lock_layer"; + ot->idname = "GPENCIL_OT_lock_layer"; ot->description = "Lock and hide any color not used in any layer"; /* api callbacks */ - ot->exec = gp_palette_lock_layer_exec; + ot->exec = gpencil_lock_layer_exec; ot->poll = gp_active_layer_poll; } -/* ************************************************ */ -/* Palette Colors Operators */ - -/* ******************* Add New Palette ************************ */ - -/* add new palette - wrapper around API */ -static int gp_palettecolor_add_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); - - /* if there's no existing Grease-Pencil data there, add some */ - if (gpd_ptr == NULL) { - BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go"); - return OPERATOR_CANCELLED; - } - if (*gpd_ptr == NULL) - *gpd_ptr = BKE_gpencil_data_addnew(bmain, DATA_("GPencil")); - - /* verify palette */ - bGPDpalette *palette = BKE_gpencil_palette_getactive(*gpd_ptr); - if (palette == NULL) - palette = BKE_gpencil_palette_addnew(*gpd_ptr, DATA_("GP_Palette"), true); - - /* add new palette color now */ - BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true); - - /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_palettecolor_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Palette Color"; - ot->idname = "GPENCIL_OT_palettecolor_add"; - ot->description = "Add new Grease Pencil palette color for the active Grease Pencil data-block"; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* callbacks */ - ot->exec = gp_palettecolor_add_exec; - ot->poll = gp_add_poll; -} - -/* ******************* Remove Active Palette color ************************* */ - -static int gp_palettecolor_remove_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *color = BKE_gpencil_palettecolor_getactive(palette); - - /* sanity checks */ - if (ELEM(NULL, gpd, palette, color)) - return OPERATOR_CANCELLED; - - /* make the palette color before this the new active color - * - use the one after if this is the first - * - if this is the only color, this naturally becomes NULL - */ - if (color->prev) - BKE_gpencil_palettecolor_setactive(palette, color->prev); - else - BKE_gpencil_palettecolor_setactive(palette, color->next); - - /* delete the strokes */ - BKE_gpencil_palettecolor_delete_strokes(gpd, color->info); - - /* delete the palette color now... */ - BKE_gpencil_palettecolor_delete(palette, color); - - /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_palettecolor_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Remove palette color"; - ot->idname = "GPENCIL_OT_palettecolor_remove"; - ot->description = "Remove active Grease Pencil palette color"; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* callbacks */ - ot->exec = gp_palettecolor_remove_exec; - ot->poll = gp_active_palettecolor_poll; -} - -/* ********************** Isolate palette color **************************** */ +/* ********************** Isolate gpencil_ color **************************** */ -static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op) +static int gpencil_color_isolate_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *active_color = BKE_gpencil_palettecolor_getactive(palette); - bGPDpalettecolor *palcolor; + Object *ob = CTX_data_active_object(C); + Material *active_ma = give_current_material(ob, ob->actcol); + MaterialGPencilStyle *active_color = BKE_material_gpencil_settings_get(ob, ob->actcol); + MaterialGPencilStyle *gp_style; - int flags = PC_COLOR_LOCKED; + int flags = GP_STYLE_COLOR_LOCKED; bool isolate = false; if (RNA_boolean_get(op->ptr, "affect_visibility")) - flags |= PC_COLOR_HIDE; + flags |= GP_STYLE_COLOR_HIDE; if (ELEM(NULL, gpd, active_color)) { BKE_report(op->reports, RPT_ERROR, "No active color to isolate"); @@ -1699,15 +2095,20 @@ static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op) } /* Test whether to isolate or clear all flags */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; /* Skip if this is the active one */ - if (palcolor == active_color) + if (ma == active_ma) continue; /* If the flags aren't set, that means that the color is - * not alone, so we have some colors to isolate still - */ - if ((palcolor->flag & flags) == 0) { + * not alone, so we have some colors to isolate still + */ + gp_style = ma->gp_style; + if ((gp_style->flag & flags) == 0) { isolate = true; break; } @@ -1716,72 +2117,79 @@ static int gp_isolate_palettecolor_exec(bContext *C, wmOperator *op) /* Set/Clear flags as appropriate */ if (isolate) { /* Set flags on all "other" colors */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - if (palcolor == active_color) + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + if (gp_style == active_color) continue; else - palcolor->flag |= flags; + gp_style->flag |= flags; } } else { /* Clear flags - Restore everything else */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag &= ~flags; + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + gp_style->flag &= ~flags; } } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_isolate(wmOperatorType *ot) +void GPENCIL_OT_color_isolate(wmOperatorType *ot) { /* identifiers */ - ot->name = "Isolate Palette Color"; - ot->idname = "GPENCIL_OT_palettecolor_isolate"; + ot->name = "Isolate Color"; + ot->idname = "GPENCIL_OT_color_isolate"; ot->description = "Toggle whether the active color is the only one that is editable and/or visible"; /* callbacks */ - ot->exec = gp_isolate_palettecolor_exec; - ot->poll = gp_active_palettecolor_poll; + ot->exec = gpencil_color_isolate_exec; + ot->poll = gpencil_active_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "affect_visibility", false, "Affect Visibility", "In addition to toggling " - "the editability, also affect the visibility"); + "the editability, also affect the visibility"); } -/* *********************** Hide Palette colors ******************************** */ +/* *********************** Hide colors ******************************** */ -static int gp_palettecolor_hide_exec(bContext *C, wmOperator *op) +static int gpencil_color_hide_exec(bContext *C, wmOperator *op) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); + Object *ob = CTX_data_active_object(C); + MaterialGPencilStyle *active_color = BKE_material_gpencil_settings_get(ob, ob->actcol); bool unselected = RNA_boolean_get(op->ptr, "unselected"); - /* sanity checks */ - if (ELEM(NULL, gpd, palette, palcolor)) + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + if ((totcol == 0) || (matar == NULL)) return OPERATOR_CANCELLED; if (unselected) { - bGPDpalettecolor *color; - /* hide unselected */ - for (color = palette->colors.first; color; color = color->next) { - if (color != palcolor) { - color->flag |= PC_COLOR_HIDE; + MaterialGPencilStyle *color = NULL; + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + color = ma->gp_style; + if (active_color != color) { + color->flag |= GP_STYLE_COLOR_HIDE; } } } else { /* hide selected/active */ - palcolor->flag |= PC_COLOR_HIDE; + active_color->flag |= GP_STYLE_COLOR_HIDE; } /* notifiers */ @@ -1790,18 +2198,18 @@ static int gp_palettecolor_hide_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_hide(wmOperatorType *ot) +void GPENCIL_OT_color_hide(wmOperatorType *ot) { /* identifiers */ ot->name = "Hide Color(s)"; - ot->idname = "GPENCIL_OT_palettecolor_hide"; + ot->idname = "GPENCIL_OT_color_hide"; ot->description = "Hide selected/unselected Grease Pencil colors"; /* callbacks */ - ot->exec = gp_palettecolor_hide_exec; - ot->poll = gp_active_palettecolor_poll; /* NOTE: we need an active color to play with */ + ot->exec = gpencil_color_hide_exec; + ot->poll = gpencil_active_color_poll; /* NOTE: we need an active color to play with */ - /* flags */ + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ @@ -1810,25 +2218,23 @@ void GPENCIL_OT_palettecolor_hide(wmOperatorType *ot) /* ********************** Show All Colors ***************************** */ -/* poll callback for showing colors */ -static bool gp_palettecolor_reveal_poll(bContext *C) -{ - return ED_gpencil_data_get_active(C) != NULL; -} - -static int gp_palettecolor_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +static int gpencil_color_reveal_exec(bContext *C, wmOperator *UNUSED(op)) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor; + Object *ob = CTX_data_active_object(C); + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); - /* sanity checks */ - if (ELEM(NULL, gpd, palette)) + if ((totcol == 0) || (matar == NULL)) return OPERATOR_CANCELLED; /* make all colors visible */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag &= ~PC_COLOR_HIDE; + MaterialGPencilStyle *gp_style = NULL; + + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + gp_style->flag &= ~GP_STYLE_COLOR_HIDE; } /* notifiers */ @@ -1837,36 +2243,41 @@ static int gp_palettecolor_reveal_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_reveal(wmOperatorType *ot) +void GPENCIL_OT_color_reveal(wmOperatorType *ot) { /* identifiers */ ot->name = "Show All Colors"; - ot->idname = "GPENCIL_OT_palettecolor_reveal"; - ot->description = "Unhide all hidden Grease Pencil palette colors"; + ot->idname = "GPENCIL_OT_color_reveal"; + ot->description = "Unhide all hidden Grease Pencil gpencil_ colors"; /* callbacks */ - ot->exec = gp_palettecolor_reveal_exec; - ot->poll = gp_palettecolor_reveal_poll; + ot->exec = gpencil_color_reveal_exec; + ot->poll = gpencil_active_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ***************** Lock/Unlock All Palette colors ************************ */ +/* ***************** Lock/Unlock All colors ************************ */ -static int gp_palettecolor_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) +static int gpencil_color_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor; - /* sanity checks */ - if (ELEM(NULL, gpd, palette)) + Object *ob = CTX_data_active_object(C); + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + + if ((totcol == 0) || (matar == NULL)) return OPERATOR_CANCELLED; /* make all layers non-editable */ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag |= PC_COLOR_LOCKED; + MaterialGPencilStyle *gp_style = NULL; + + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + gp_style->flag |= GP_STYLE_COLOR_LOCKED; } /* notifiers */ @@ -1875,16 +2286,16 @@ static int gp_palettecolor_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_lock_all(wmOperatorType *ot) +void GPENCIL_OT_color_lock_all(wmOperatorType *ot) { /* identifiers */ ot->name = "Lock All Colors"; - ot->idname = "GPENCIL_OT_palettecolor_lock_all"; + ot->idname = "GPENCIL_OT_color_lock_all"; ot->description = "Lock all Grease Pencil colors to prevent them from being accidentally modified"; /* callbacks */ - ot->exec = gp_palettecolor_lock_all_exec; - ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */ + ot->exec = gpencil_color_lock_all_exec; + ot->poll = gpencil_active_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1892,19 +2303,23 @@ void GPENCIL_OT_palettecolor_lock_all(wmOperatorType *ot) /* -------------------------- */ -static int gp_palettecolor_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) +static int gpencil_color_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor; + Object *ob = CTX_data_active_object(C); + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); - /* sanity checks */ - if (ELEM(NULL, gpd, palette)) + if ((totcol == 0) || (matar == NULL)) return OPERATOR_CANCELLED; /* make all layers editable again*/ - for (palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { - palcolor->flag &= ~PC_COLOR_LOCKED; + MaterialGPencilStyle *gp_style = NULL; + + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + gp_style = ma->gp_style; + gp_style->flag &= ~GP_STYLE_COLOR_LOCKED; } /* notifiers */ @@ -1913,94 +2328,32 @@ static int gp_palettecolor_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_unlock_all(wmOperatorType *ot) +void GPENCIL_OT_color_unlock_all(wmOperatorType *ot) { /* identifiers */ ot->name = "Unlock All Colors"; - ot->idname = "GPENCIL_OT_palettecolor_unlock_all"; + ot->idname = "GPENCIL_OT_color_unlock_all"; ot->description = "Unlock all Grease Pencil colors so that they can be edited"; /* callbacks */ - ot->exec = gp_palettecolor_unlock_all_exec; - ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */ + ot->exec = gpencil_color_unlock_all_exec; + ot->poll = gpencil_active_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************* Move Color Up/Down ************************** */ - -enum { - GP_COLOR_MOVE_UP = -1, - GP_COLOR_MOVE_DOWN = 1 -}; - -static int gp_palettecolor_move_exec(bContext *C, wmOperator *op) -{ - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); - - int direction = RNA_enum_get(op->ptr, "direction"); - - /* sanity checks */ - if (ELEM(NULL, gpd, palette, palcolor)) - return OPERATOR_CANCELLED; - - /* up or down? */ - if (direction == GP_COLOR_MOVE_UP) { - /* up */ - BLI_remlink(&palette->colors, palcolor); - BLI_insertlinkbefore(&palette->colors, palcolor->prev, palcolor); - } - else if (direction == GP_COLOR_MOVE_DOWN) { - /* down */ - BLI_remlink(&palette->colors, palcolor); - BLI_insertlinkafter(&palette->colors, palcolor->next, palcolor); - } - else { - BLI_assert(0); - } - - /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_palettecolor_move(wmOperatorType *ot) -{ - static const EnumPropertyItem slot_move[] = { - {GP_COLOR_MOVE_UP, "UP", 0, "Up", ""}, - {GP_COLOR_MOVE_DOWN, "DOWN", 0, "Down", ""}, - {0, NULL, 0, NULL, NULL} - }; - /* identifiers */ - ot->name = "Move Palette color"; - ot->idname = "GPENCIL_OT_palettecolor_move"; - ot->description = "Move the active Grease Pencil palette color up/down in the list"; +/* ***************** Select all strokes using color ************************ */ - /* api callbacks */ - ot->exec = gp_palettecolor_move_exec; - ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */ - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - ot->prop = RNA_def_enum(ot->srna, "direction", slot_move, GP_COLOR_MOVE_UP, "Direction", ""); -} - -/* ***************** Select all strokes using Palette color ************************ */ - -static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op)) +static int gpencil_color_select_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); + Object *ob = CTX_data_active_object(C); + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol); /* sanity checks */ - if (ELEM(NULL, gpd, palette, palcolor)) + if (ELEM(NULL, gpd, gp_style)) return OPERATOR_CANCELLED; /* read all strokes and select*/ @@ -2013,11 +2366,11 @@ static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op)) if (ED_gpencil_stroke_can_use(C, gps) == false) continue; /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) continue; /* select */ - if (strcmp(palcolor->info, gps->colorname) == 0) { + if (ob->actcol == gps->mat_nr) { bGPDspoint *pt; int i; @@ -2035,56 +2388,16 @@ static int gp_palettecolor_select_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GPENCIL_OT_palettecolor_select(wmOperatorType *ot) +void GPENCIL_OT_color_select(wmOperatorType *ot) { /* identifiers */ ot->name = "Select Color"; - ot->idname = "GPENCIL_OT_palettecolor_select"; + ot->idname = "GPENCIL_OT_color_select"; ot->description = "Select all Grease Pencil strokes using current color"; /* callbacks */ - ot->exec = gp_palettecolor_select_exec; - ot->poll = gp_palettecolor_reveal_poll; /* XXX: could use dedicated poll later */ - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ***************** Copy Palette color ************************ */ - -static int gp_palettecolor_copy_exec(bContext *C, wmOperator *UNUSED(op)) -{ - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); - bGPDpalettecolor *newcolor; - - /* sanity checks */ - if (ELEM(NULL, gpd, palette, palcolor)) - return OPERATOR_CANCELLED; - - /* create a new color and duplicate data */ - newcolor = BKE_gpencil_palettecolor_addnew(palette, palcolor->info, true); - copy_v4_v4(newcolor->color, palcolor->color); - copy_v4_v4(newcolor->fill, palcolor->fill); - newcolor->flag = palcolor->flag; - - /* notifiers */ - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_palettecolor_copy(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Copy Color"; - ot->idname = "GPENCIL_OT_palettecolor_copy"; - ot->description = "Copy current Grease Pencil palette color"; - - /* callbacks */ - ot->exec = gp_palettecolor_copy_exec; - ot->poll = gp_active_palettecolor_poll; + ot->exec = gpencil_color_select_exec; + ot->poll = gpencil_active_color_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index ec67b2da161..4264645b52e 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -47,6 +47,7 @@ #include "BLT_translation.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -54,12 +55,19 @@ #include "DNA_view3d_types.h" #include "DNA_gpencil_types.h" +#include "BKE_main.h" #include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_brush.h" #include "BKE_gpencil.h" +#include "BKE_paint.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_object.h" #include "BKE_report.h" #include "BKE_screen.h" +#include "BKE_workspace.h" #include "UI_interface.h" #include "UI_resources.h" @@ -80,31 +88,70 @@ #include "ED_space_api.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" #include "gpencil_intern.h" /* ************************************************ */ /* Stroke Edit Mode Management */ - static bool gpencil_editmode_toggle_poll(bContext *C) { + /* if using gpencil object, use this gpd */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + return ob->data != NULL; + } return ED_gpencil_data_get_active(C) != NULL; } -static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *op) { + const int back = RNA_boolean_get(op->ptr, "back"); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_object = false; + short mode; + /* if using a gpencil object, use this datablock */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + gpd = ob->data; + is_object = true; + } - if (gpd == NULL) + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No active GP data"); return OPERATOR_CANCELLED; + } /* Just toggle editmode flag... */ gpd->flag ^= GP_DATA_STROKE_EDITMODE; /* recalculate parent matrix */ if (gpd->flag & GP_DATA_STROKE_EDITMODE) { - ED_gpencil_reset_layers_parent(gpd); + ED_gpencil_reset_layers_parent(depsgraph, ob, gpd); + } + /* set mode */ + if (gpd->flag & GP_DATA_STROKE_EDITMODE) { + mode = OB_MODE_GPENCIL_EDIT; + } + else { + mode = OB_MODE_OBJECT; } + if (is_object) { + /* try to back previous mode */ + if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_EDITMODE) == 0) && (back == 1)) { + mode = ob->restore_mode; + } + ob->restore_mode = ob->mode; + ob->mode = mode; + } + + /* setup other modes */ + ED_gpencil_setup_modes(C, gpd, mode); + /* set cache as dirty */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); WM_event_add_notifier(C, NC_GPENCIL | ND_GPENCIL_EDITMODE, NULL); WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); @@ -114,6 +161,8 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) void GPENCIL_OT_editmode_toggle(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Strokes Edit Mode Toggle"; ot->idname = "GPENCIL_OT_editmode_toggle"; @@ -125,6 +174,259 @@ void GPENCIL_OT_editmode_toggle(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); +} + +/* Stroke Paint Mode Management */ + +static bool gpencil_paintmode_toggle_poll(bContext *C) +{ + /* if using gpencil object, use this gpd */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + return ob->data != NULL; + } + return ED_gpencil_data_get_active(C) != NULL; +} + +static int gpencil_paintmode_toggle_exec(bContext *C, wmOperator *op) +{ + const bool back = RNA_boolean_get(op->ptr, "back"); + + bGPdata *gpd = ED_gpencil_data_get_active(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + bool is_object = false; + short mode; + /* if using a gpencil object, use this datablock */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + gpd = ob->data; + is_object = true; + } + + if (gpd == NULL) + return OPERATOR_CANCELLED; + + /* Just toggle paintmode flag... */ + gpd->flag ^= GP_DATA_STROKE_PAINTMODE; + /* set mode */ + if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { + mode = OB_MODE_GPENCIL_PAINT; + } + else { + mode = OB_MODE_OBJECT; + } + + if (is_object) { + /* try to back previous mode */ + if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0) && (back == 1)) { + mode = ob->restore_mode; + } + ob->restore_mode = ob->mode; + ob->mode = mode; + } + + /* be sure we have brushes */ + Paint *paint = BKE_brush_get_gpencil_paint(ts); + /* if not exist, create a new one */ + if (paint->brush == NULL) { + BKE_brush_gpencil_presets(C); + } + + /* setup other modes */ + ED_gpencil_setup_modes(C, gpd, mode); + /* set cache as dirty */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_paintmode_toggle(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Strokes Paint Mode Toggle"; + ot->idname = "GPENCIL_OT_paintmode_toggle"; + ot->description = "Enter/Exit paint mode for Grease Pencil strokes"; + + /* callbacks */ + ot->exec = gpencil_paintmode_toggle_exec; + ot->poll = gpencil_paintmode_toggle_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); +} + +/* Stroke Sculpt Mode Management */ + +static bool gpencil_sculptmode_toggle_poll(bContext *C) +{ + /* if using gpencil object, use this gpd */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + return ob->data != NULL; + } + return ED_gpencil_data_get_active(C) != NULL; +} + +static int gpencil_sculptmode_toggle_exec(bContext *C, wmOperator *op) +{ + const bool back = RNA_boolean_get(op->ptr, "back"); + + bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_object = false; + short mode; + /* if using a gpencil object, use this datablock */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + gpd = ob->data; + is_object = true; + } + + if (gpd == NULL) + return OPERATOR_CANCELLED; + + /* Just toggle sculptmode flag... */ + gpd->flag ^= GP_DATA_STROKE_SCULPTMODE; + /* set mode */ + if (gpd->flag & GP_DATA_STROKE_SCULPTMODE) { + mode = OB_MODE_GPENCIL_SCULPT; + } + else { + mode = OB_MODE_OBJECT; + } + + if (is_object) { + /* try to back previous mode */ + if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_SCULPTMODE) == 0) && (back == 1)) { + mode = ob->restore_mode; + } + ob->restore_mode = ob->mode; + ob->mode = mode; + } + + /* setup other modes */ + ED_gpencil_setup_modes(C, gpd, mode); + /* set cache as dirty */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_sculptmode_toggle(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Strokes Sculpt Mode Toggle"; + ot->idname = "GPENCIL_OT_sculptmode_toggle"; + ot->description = "Enter/Exit sculpt mode for Grease Pencil strokes"; + + /* callbacks */ + ot->exec = gpencil_sculptmode_toggle_exec; + ot->poll = gpencil_sculptmode_toggle_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); +} + +/* Stroke Weight Paint Mode Management */ + +static bool gpencil_weightmode_toggle_poll(bContext *C) +{ + /* if using gpencil object, use this gpd */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + return ob->data != NULL; + } + return ED_gpencil_data_get_active(C) != NULL; +} + +static int gpencil_weightmode_toggle_exec(bContext *C, wmOperator *op) +{ + const bool back = RNA_boolean_get(op->ptr, "back"); + + bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_object = false; + short mode; + /* if using a gpencil object, use this datablock */ + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + gpd = ob->data; + is_object = true; + } + + if (gpd == NULL) + return OPERATOR_CANCELLED; + + /* Just toggle weightmode flag... */ + gpd->flag ^= GP_DATA_STROKE_WEIGHTMODE; + /* set mode */ + if (gpd->flag & GP_DATA_STROKE_WEIGHTMODE) { + mode = OB_MODE_GPENCIL_WEIGHT; + } + else { + mode = OB_MODE_OBJECT; + } + + if (is_object) { + /* try to back previous mode */ + if ((ob->restore_mode) && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && (back == 1)) { + mode = ob->restore_mode; + } + ob->restore_mode = ob->mode; + ob->mode = mode; + } + + /* setup other modes */ + ED_gpencil_setup_modes(C, gpd, mode); + /* set cache as dirty */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_weightmode_toggle(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Strokes Weight Mode Toggle"; + ot->idname = "GPENCIL_OT_weightmode_toggle"; + ot->description = "Enter/Exit weight paint mode for Grease Pencil strokes"; + + /* callbacks */ + ot->exec = gpencil_weightmode_toggle_exec; + ot->poll = gpencil_weightmode_toggle_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ + prop = RNA_def_boolean(ot->srna, "back", 0, "Return to Previous Mode", "Return to previous mode"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } /* ************************************************ */ @@ -137,21 +439,30 @@ static bool gp_stroke_edit_poll(bContext *C) return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0; } +/* poll callback to verify edit mode in 3D view only */ +static bool gp_strokes_edit3d_poll(bContext *C) +{ + /* 2 Requirements: + * - 1) Editable GP data + * - 2) 3D View only + */ + return (gp_stroke_edit_poll(C) && ED_operator_view3d_active(C)); +} + /* ************ Stroke Hide selection Toggle ************** */ static int gpencil_hideselect_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { - ToolSettings *ts = CTX_data_tool_settings(C); - - if (ts == NULL) + View3D *v3d = CTX_wm_view3d(C); + if (v3d == NULL) return OPERATOR_CANCELLED; /* Just toggle alpha... */ - if (ts->gp_sculpt.alpha > 0.0f) { - ts->gp_sculpt.alpha = 0.0f; + if (v3d->vertex_opacity > 0.0f) { + v3d->vertex_opacity = 0.0f; } else { - ts->gp_sculpt.alpha = 1.0f; + v3d->vertex_opacity = 1.0f; } WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); @@ -176,6 +487,44 @@ void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot) ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; } +/* toggle multi edit strokes support */ +static int gpencil_multiedit_toggle_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + const bool lines = RNA_boolean_get(op->ptr, "lines"); + + /* Just toggle value */ + if (lines == 0) { + v3d->flag3 ^= V3D_GP_SHOW_EDIT_LINES; + } + else { + v3d->flag3 ^= V3D_GP_SHOW_MULTIEDIT_LINES; + } + + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL); + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_multiedit_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Edit Lines Toggle"; + ot->idname = "GPENCIL_OT_multiedit_toggle"; + ot->description = "Enable/disable edit lines support"; + + /* callbacks */ + ot->exec = gpencil_multiedit_toggle_exec; + ot->poll = gp_stroke_edit_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ + RNA_def_boolean(ot->srna, "toggle_visibility", 0, "Toggle Visibility Only", "Toggle visibility of edit lines only"); +} + /* ************** Duplicate Selected Strokes **************** */ /* Make copies of selected point segments in a selected stroke */ @@ -220,7 +569,7 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co /* make a stupid copy first of the entire stroke (to get the flags too) */ gpsd = MEM_dupallocN(gps); - BLI_strncpy(gpsd->tmp_layerinfo, layername, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */ + BLI_strncpy(gpsd->runtime.tmp_layerinfo, layername, sizeof(gpsd->runtime.tmp_layerinfo)); /* saves original layer name */ /* initialize triangle memory - will be calculated on next redraw */ gpsd->triangles = NULL; @@ -232,6 +581,20 @@ static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes, co memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len); gpsd->totpoints = len; + if (gps->dvert != NULL) { + gpsd->dvert = MEM_callocN(sizeof(MDeformVert) * len, "gps stroke weights copy"); + memcpy(gpsd->dvert, gps->dvert + start_idx, sizeof(MDeformVert) * len); + + /* Copy weights */ + int e = start_idx; + for (int j = 0; j < gpsd->totpoints; j++) { + MDeformVert *dvert_dst = &gps->dvert[e]; + MDeformVert *dvert_src = &gps->dvert[j]; + dvert_dst->dw = MEM_dupallocN(dvert_src->dw); + e++; + } + } + /* add to temp buffer */ gpsd->next = gpsd->prev = NULL; BLI_addtail(new_strokes, gpsd); @@ -252,6 +615,11 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { + BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); + return OPERATOR_CANCELLED; + } + /* for each visible (and editable) layer's selected strokes, * copy the strokes into a temporary buffer, then append * once all done @@ -279,8 +647,12 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op) /* make direct copies of the stroke and its points */ gpsd = MEM_dupallocN(gps); - BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo)); + BLI_strncpy(gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo)); gpsd->points = MEM_dupallocN(gps->points); + if (gps->dvert != NULL) { + gpsd->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, gpsd); + } /* triangle information - will be calculated on next redraw */ gpsd->flag |= GP_STROKE_RECALC_CACHES; @@ -309,6 +681,7 @@ static int gp_duplicate_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -342,7 +715,7 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot) /* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */ ListBase gp_strokes_copypastebuf = {NULL, NULL}; -/* Hash for hanging on to all the palette colors used by strokes in the buffer +/* Hash for hanging on to all the colors used by strokes in the buffer * * This is needed to prevent dangling and unsafe pointers when pasting across datablocks, * or after a color used by a stroke in the buffer gets deleted (via user action or undo). @@ -354,11 +727,11 @@ void ED_gpencil_strokes_copybuf_free(void) { bGPDstroke *gps, *gpsn; - /* Free the palettes buffer - * NOTE: This is done before the strokes so that the name ptrs (keys) are still safe + /* Free the colors buffer + * NOTE: This is done before the strokes so that the ptrs are still safe */ if (gp_strokes_copypastebuf_colors) { - BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN); + BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, NULL); gp_strokes_copypastebuf_colors = NULL; } @@ -366,8 +739,15 @@ void ED_gpencil_strokes_copybuf_free(void) for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) { gpsn = gps->next; - if (gps->points) MEM_freeN(gps->points); - if (gps->triangles) MEM_freeN(gps->triangles); + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + + MEM_SAFE_FREE(gps->triangles); BLI_freelinkN(&gp_strokes_copypastebuf, gps); } @@ -378,38 +758,26 @@ void ED_gpencil_strokes_copybuf_free(void) /* Ensure that destination datablock has all the colours the pasted strokes need * Helper function for copy-pasting strokes */ -GHash *gp_copybuf_validate_colormap(bGPdata *gpd) +GHash *gp_copybuf_validate_colormap(bContext *C) { + Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors"); GHashIterator gh_iter; - /* If there's no active palette yet (i.e. new datablock), add one */ - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - if (palette == NULL) { - palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true); - } - - /* For each color, figure out what to map to... */ + /* For each color, check if exist and add if not */ GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) { - bGPDpalettecolor *palcolor; - char *name = BLI_ghashIterator_getKey(&gh_iter); - /* Look for existing color to map to */ - /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */ - palcolor = BKE_gpencil_palettecolor_getbyname(palette, name); - if (palcolor == NULL) { - /* Doesn't Exist - Create new matching color for this palette */ - /* XXX: This still doesn't fix the pasting across file boundaries problem... */ - bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter); + int *key = BLI_ghashIterator_getKey(&gh_iter); + Material *ma = BLI_ghashIterator_getValue(&gh_iter); - palcolor = MEM_dupallocN(src_color); - BLI_addtail(&palette->colors, palcolor); - - BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info)); + if (BKE_object_material_slot_find_index(ob, ma) == 0) { + BKE_object_material_slot_add(bmain, ob); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); } /* Store this mapping (for use later when pasting) */ - BLI_ghash_insert(new_colors, name, palcolor); + BLI_ghash_insert(new_colors, key, ma); } return new_colors; @@ -420,6 +788,7 @@ GHash *gp_copybuf_validate_colormap(bGPdata *gpd) static int gp_strokes_copy_exec(bContext *C, wmOperator *op) { + Object *ob = CTX_data_active_object(C); bGPdata *gpd = ED_gpencil_data_get_active(C); if (gpd == NULL) { @@ -427,6 +796,11 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { + BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); + return OPERATOR_CANCELLED; + } + /* clear the buffer first */ ED_gpencil_strokes_copybuf_free(); @@ -455,8 +829,12 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) /* make direct copies of the stroke and its points */ gpsd = MEM_dupallocN(gps); - BLI_strncpy(gpsd->tmp_layerinfo, gpl->info, sizeof(gpsd->tmp_layerinfo)); /* saves original layer name */ + BLI_strncpy(gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo)); /* saves original layer name */ gpsd->points = MEM_dupallocN(gps->points); + if (gps->dvert != NULL) { + gpsd->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, gpsd); + } /* triangles cache - will be recalculated on next redraw */ gpsd->flag |= GP_STROKE_RECALC_CACHES; @@ -476,17 +854,16 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - /* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */ + /* Build up hash of material colors used in these strokes */ if (gp_strokes_copypastebuf.first) { gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors"); - + Material *ma = NULL; for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use(C, gps)) { - if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) { - bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor); - - BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color); - gps->palcolor = color; + ma = give_current_material(ob, gps->mat_nr + 1); + if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, &gps->mat_nr) == false) + { + BLI_ghash_insert(gp_strokes_copypastebuf_colors, &gps->mat_nr, ma); } } } @@ -534,9 +911,11 @@ typedef enum eGP_PasteMode { static int gp_strokes_paste_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); /* only use active for copy merge */ + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); bGPDframe *gpf; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); @@ -547,6 +926,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); return OPERATOR_CANCELLED; } + else if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { + BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); + return OPERATOR_CANCELLED; + } else if (BLI_listbase_is_empty(&gp_strokes_copypastebuf)) { BKE_report(op->reports, RPT_ERROR, "No strokes to paste, select and copy some points before trying again"); return OPERATOR_CANCELLED; @@ -599,14 +982,14 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* Ensure that all the necessary colors exist */ - new_colors = gp_copybuf_validate_colormap(gpd); + new_colors = gp_copybuf_validate_colormap(C); /* Copy over the strokes from the buffer (and adjust the colors) */ for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use(C, gps)) { /* Need to verify if layer exists */ if (type != GP_COPY_MERGE) { - gpl = BLI_findstring(&gpd->layers, gps->tmp_layerinfo, offsetof(bGPDlayer, info)); + gpl = BLI_findstring(&gpd->layers, gps->runtime.tmp_layerinfo, offsetof(bGPDlayer, info)); if (gpl == NULL) { /* no layer - use active (only if layer deleted before paste) */ gpl = CTX_data_active_gpencil_layer(C); @@ -618,28 +1001,33 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) * we are obliged to add a new frame if one * doesn't exist already */ - gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); + gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, true); if (gpf) { /* Create new stroke */ bGPDstroke *new_stroke = MEM_dupallocN(gps); - new_stroke->tmp_layerinfo[0] = '\0'; + new_stroke->runtime.tmp_layerinfo[0] = '\0'; new_stroke->points = MEM_dupallocN(gps->points); - + if (gps->dvert != NULL) { + new_stroke->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, new_stroke); + } new_stroke->flag |= GP_STROKE_RECALC_CACHES; new_stroke->triangles = NULL; new_stroke->next = new_stroke->prev = NULL; BLI_addtail(&gpf->strokes, new_stroke); - /* Fix color references */ - BLI_assert(new_stroke->colorname[0] != '\0'); - new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname); - - BLI_assert(new_stroke->palcolor != NULL); - BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname)); + /* Remap material */ + Material *ma = BLI_ghash_lookup(new_colors, &new_stroke->mat_nr); + if ((ma) && (BKE_object_material_slot_find_index(ob, ma) > 0)) { + gps->mat_nr = BKE_object_material_slot_find_index(ob, ma) - 1; + CLAMP_MIN(gps->mat_nr, 0); + } + else { + gps->mat_nr = 0; /* only if the color is not found */ + } - /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */ } } } @@ -648,6 +1036,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) BLI_ghash_free(new_colors, NULL, NULL); /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -697,10 +1086,17 @@ static int gp_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *U static int gp_move_to_layer_exec(bContext *C, wmOperator *op) { bGPdata *gpd = CTX_data_gpencil_data(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); bGPDlayer *target_layer = NULL; ListBase strokes = {NULL, NULL}; int layer_num = RNA_enum_get(op->ptr, "layer"); + if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { + BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); + return OPERATOR_CANCELLED; + } + /* Get layer or create new one */ if (layer_num == -1) { /* Create layer */ @@ -748,14 +1144,14 @@ static int gp_move_to_layer_exec(bContext *C, wmOperator *op) /* Paste them all in one go */ if (strokes.first) { - Scene *scene = CTX_data_scene(C); - bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, CFRA, true); + bGPDframe *gpf = BKE_gpencil_layer_getframe(target_layer, cfra_eval, true); BLI_movelisttolist(&gpf->strokes, &strokes); BLI_assert((strokes.first == strokes.last) && (strokes.first == NULL)); } /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -804,8 +1200,10 @@ static bool UNUSED_FUNCTION(gp_blank_frame_add_poll)(bContext *C) static int gp_blank_frame_add_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); bGPdata *gpd = ED_gpencil_data_get_active(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bGPDlayer *active_gpl = BKE_gpencil_layer_getactive(gpd); const bool all_layers = RNA_boolean_get(op->ptr, "all_layers"); @@ -826,7 +1224,7 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op) } /* 1) Check for an existing frame on the current frame */ - bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, CFRA); + bGPDframe *gpf = BKE_gpencil_layer_find_frame(gpl, cfra_eval); if (gpf) { /* Shunt all frames after (and including) the existing one later by 1-frame */ for (; gpf; gpf = gpf->next) { @@ -835,11 +1233,12 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op) } /* 2) Now add a new frame, with nothing in it */ - gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_NEW); + gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_NEW); } CTX_DATA_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -876,10 +1275,13 @@ static bool gp_actframe_delete_poll(bContext *C) /* delete active frame - wrapper around API calls */ static int gp_actframe_delete_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0); + + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); /* if there's no existing Grease-Pencil data there, add some */ if (gpd == NULL) { @@ -895,6 +1297,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op) BKE_gpencil_layer_delframe(gpl, gpf); /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -928,13 +1331,16 @@ static bool gp_actframe_delete_all_poll(bContext *C) static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); + bGPdata *gpd = ED_gpencil_data_get_active(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bool success = false; CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { /* try to get the "active" frame - but only if it actually occurs on this frame */ - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0); + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); if (gpf == NULL) continue; @@ -949,6 +1355,7 @@ static int gp_actframe_delete_all_exec(bContext *C, wmOperator *op) /* updates */ if (success) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -983,43 +1390,69 @@ typedef enum eGP_DeleteMode { GP_DELETEOP_FRAME = 2, } eGP_DeleteMode; +typedef enum eGP_DissolveMode { + /* dissolve all selected points */ + GP_DISSOLVE_POINTS = 0, + /* dissolve between selected points */ + GP_DISSOLVE_BETWEEN = 1, + /* dissolve unselected points */ + GP_DISSOLVE_UNSELECT = 2, +} eGP_DissolveMode; + /* ----------------------------------- */ /* Delete selected strokes */ static int gp_delete_selected_strokes(bContext *C) { bool changed = false; + bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - bGPDstroke *gps, *gpsn; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } - if (gpf == NULL) - continue; + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + bGPDstroke *gps, *gpsn; - /* simply delete strokes which are selected */ - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; + if (gpf == NULL) + continue; - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) - continue; + /* simply delete strokes which are selected */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; - /* free stroke if selected */ - if (gps->flag & GP_STROKE_SELECT) { - /* free stroke memory arrays, then stroke itself */ - if (gps->points) MEM_freeN(gps->points); - if (gps->triangles) MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + + /* free stroke if selected */ + if (gps->flag & GP_STROKE_SELECT) { + /* free stroke memory arrays, then stroke itself */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + MEM_SAFE_FREE(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); - changed = true; + changed = true; + } + } } } } CTX_DATA_END; if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -1031,88 +1464,238 @@ static int gp_delete_selected_strokes(bContext *C) /* ----------------------------------- */ /* Delete selected points but keep the stroke */ -static int gp_dissolve_selected_points(bContext *C) +static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode) { + Object *ob = CTX_data_active_object(C); + bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); bool changed = false; + int first = 0; + int last = 0; CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - bGPDstroke *gps, *gpsn; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } - if (gpf == NULL) - continue; + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { - /* simply delete points from selected strokes - * NOTE: we may still have to remove the stroke if it ends up having no points! - */ - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; + bGPDstroke *gps, *gpsn; - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) - continue; - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) - continue; + if (gpf == NULL) + continue; - if (gps->flag & GP_STROKE_SELECT) { - bGPDspoint *pt; - int i; + /* simply delete points from selected strokes + * NOTE: we may still have to remove the stroke if it ends up having no points! + */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) + continue; + + /* the stroke must have at least one point selected for any operator */ + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + MDeformVert *dvert = NULL; + int i; + + int tot = gps->totpoints; /* number of points in new buffer */ + + /* first pass: count points to remove */ + switch (mode) { + case GP_DISSOLVE_POINTS: + /* Count how many points are selected (i.e. how many to remove) */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* selected point - one of the points to remove */ + tot--; + } + } + break; + case GP_DISSOLVE_BETWEEN: + /* need to find first and last point selected */ + first = -1; + last = 0; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + if (first < 0) { + first = i; + } + last = i; + } + } + /* count unselected points in the range */ + for (i = first, pt = gps->points + first; i < last; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + tot--; + } + } + break; + case GP_DISSOLVE_UNSELECT: + /* count number of unselected points */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + tot--; + } + } + break; + default: + return false; + break; + } - int tot = gps->totpoints; /* number of points in new buffer */ + /* if no points are left, we simply delete the entire stroke */ + if (tot <= 0) { + /* remove the entire stroke */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + if (gps->triangles) { + MEM_freeN(gps->triangles); + } + BLI_freelinkN(&gpf->strokes, gps); + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + else { + /* just copy all points to keep into a smaller buffer */ + bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy"); + bGPDspoint *npt = new_points; - /* First Pass: Count how many points are selected (i.e. how many to remove) */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - /* selected point - one of the points to remove */ - tot--; - } - } + MDeformVert *new_dvert = NULL; + MDeformVert *ndvert = NULL; - /* if no points are left, we simply delete the entire stroke */ - if (tot <= 0) { - /* remove the entire stroke */ - MEM_freeN(gps->points); - if (gps->triangles) { - MEM_freeN(gps->triangles); - } - BLI_freelinkN(&gpf->strokes, gps); - } - else { - /* just copy all unselected into a smaller buffer */ - bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy"); - bGPDspoint *npt = new_points; + if (gps->dvert != NULL) { + new_dvert = MEM_callocN(sizeof(MDeformVert) * tot, "new gp stroke weights copy"); + ndvert = new_dvert; + } - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) == 0) { - *npt = *pt; - npt++; - } - } + switch (mode) { + case GP_DISSOLVE_POINTS: + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; + } + } + } + break; + case GP_DISSOLVE_BETWEEN: + /* copy first segment */ + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < first; i++, pt++) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; + } + } + /* copy segment (selected points) */ + (gps->dvert != NULL) ? dvert = gps->dvert + first : NULL; + for (i = first, pt = gps->points + first; i < last; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; + } + } + } + /* copy last segment */ + (gps->dvert != NULL) ? dvert = gps->dvert + last : NULL; + for (i = last, pt = gps->points + last; i < gps->totpoints; i++, pt++) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; + } + } + + break; + case GP_DISSOLVE_UNSELECT: + /* copy any selected point */ + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; + } + } + } + break; + } - /* free the old buffer */ - MEM_freeN(gps->points); + /* free the old buffer */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } - /* save the new buffer */ - gps->points = new_points; - gps->totpoints = tot; + /* save the new buffer */ + gps->points = new_points; + gps->dvert = new_dvert; + gps->totpoints = tot; - /* triangles cache needs to be recalculated */ - gps->flag |= GP_STROKE_RECALC_CACHES; - gps->tot_triangles = 0; + /* triangles cache needs to be recalculated */ + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; - /* deselect the stroke, since none of its selected points will still be selected */ - gps->flag &= ~GP_STROKE_SELECT; - } + /* deselect the stroke, since none of its selected points will still be selected */ + gps->flag &= ~GP_STROKE_SELECT; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; + } + } - changed = true; + changed = true; + } + } } } } CTX_DATA_END; if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -1146,17 +1729,17 @@ typedef struct tGPDeleteIsland { * becomes much less * 2) Each island gets converted to a new stroke */ -void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags) +void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, + int tag_flags, bool select) { tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands"); bool in_island = false; int num_islands = 0; - bGPDspoint *pt; - int i; /* First Pass: Identify start/end of islands */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + bGPDspoint *pt = gps->points; + for (int i = 0; i < gps->totpoints; i++, pt++) { if (pt->flag & tag_flags) { /* selected - stop accumulating to island */ in_island = false; @@ -1198,11 +1781,26 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke /* Compute new buffer size (+ 1 needed as the endpoint index is "inclusive") */ new_stroke->totpoints = island->end_idx - island->start_idx + 1; - new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment"); - /* Copy over the relevant points */ + /* Copy over the relevant point data */ + new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment"); memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints); - + + /* Copy over vertex weight data (if available) */ + if (new_stroke->dvert != NULL) { + /* Copy over the relevant vertex-weight points */ + new_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * new_stroke->totpoints, "gp delete stroke fragment weight"); + memcpy(new_stroke->dvert, gps->dvert + island->start_idx, sizeof(MDeformVert) * new_stroke->totpoints); + + /* Copy weights */ + int e = island->start_idx; + for (int i = 0; i < new_stroke->totpoints; i++) { + MDeformVert *dvert_dst = &gps->dvert[e]; + MDeformVert *dvert_src = &new_stroke->dvert[i]; + dvert_dst->dw = MEM_dupallocN(dvert_src->dw); + e++; + } + } /* Each island corresponds to a new stroke. We must adjust the * timings of these new strokes: @@ -1222,6 +1820,11 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke pts = new_stroke->points; for (j = 0; j < new_stroke->totpoints; j++, pts++) { pts->time -= delta; + /* set flag for select again later */ + if (select == true) { + pts->flag &= ~GP_SPOINT_SELECT; + pts->flag |= GP_SPOINT_TAG; + } } } @@ -1239,53 +1842,70 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke MEM_freeN(islands); /* Delete the old stroke */ - MEM_freeN(gps->points); + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } if (gps->triangles) { MEM_freeN(gps->triangles); } BLI_freelinkN(&gpf->strokes, gps); } - /* Split selected strokes into segments, splitting on selected points */ static int gp_delete_selected_points(bContext *C) { + Object *ob = CTX_data_active_object(C); + bGPdata *gpd = ED_gpencil_data_get_active(C); + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); bool changed = false; CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - bGPDstroke *gps, *gpsn; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } - if (gpf == NULL) - continue; + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + bGPDstroke *gps, *gpsn; - /* simply delete strokes which are selected */ - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; + if (gpf == NULL) + continue; - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) - continue; - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) - continue; + /* simply delete strokes which are selected */ + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) + continue; - if (gps->flag & GP_STROKE_SELECT) { - /* deselect old stroke, since it will be used as template for the new strokes */ - gps->flag &= ~GP_STROKE_SELECT; - /* delete unwanted points by splitting stroke into several smaller ones */ - gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT); + if (gps->flag & GP_STROKE_SELECT) { + /* deselect old stroke, since it will be used as template for the new strokes */ + gps->flag &= ~GP_STROKE_SELECT; + + /* delete unwanted points by splitting stroke into several smaller ones */ + gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false); - changed = true; + changed = true; + } + } } } } CTX_DATA_END; if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -1294,6 +1914,12 @@ static int gp_delete_selected_points(bContext *C) } } +/* simple wrapper to external call */ +int gp_delete_selected_point_wrap(bContext *C) +{ + return gp_delete_selected_points(C); +} + /* ----------------------------------- */ static int gp_delete_exec(bContext *C, wmOperator *op) @@ -1344,24 +1970,37 @@ void GPENCIL_OT_delete(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data"); } -static int gp_dissolve_exec(bContext *C, wmOperator *UNUSED(op)) +static int gp_dissolve_exec(bContext *C, wmOperator *op) { - return gp_dissolve_selected_points(C); + eGP_DissolveMode mode = RNA_enum_get(op->ptr, "type"); + + return gp_dissolve_selected_points(C, mode); } void GPENCIL_OT_dissolve(wmOperatorType *ot) { + static EnumPropertyItem prop_gpencil_dissolve_types[] = { + { GP_DISSOLVE_POINTS, "POINTS", 0, "Dissolve", "Dissolve selected points" }, + { GP_DISSOLVE_BETWEEN, "BETWEEN", 0, "Dissolve Between", "Dissolve points between selected points" }, + { GP_DISSOLVE_UNSELECT, "UNSELECT", 0, "Dissolve Unselect", "Dissolve all unselected points" }, + { 0, NULL, 0, NULL, NULL } + }; + /* identifiers */ ot->name = "Dissolve"; ot->idname = "GPENCIL_OT_dissolve"; ot->description = "Delete selected points without splitting strokes"; /* callbacks */ + ot->invoke = WM_menu_invoke; ot->exec = gp_dissolve_exec; ot->poll = gp_stroke_edit_poll; /* flags */ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* props */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_dissolve_types, 0, "Type", "Method used for disolving Stroke points"); } /* ****************** Snapping - Strokes <-> Cursor ************************ */ @@ -1384,6 +2023,8 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); RegionView3D *rv3d = CTX_wm_region_data(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + Object *obact = CTX_data_active_object(C); const float gridf = rv3d->gridview; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { @@ -1392,10 +2033,8 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op)) bGPDframe *gpf = gpl->actframe; float diff_mat[4][4]; - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - } + /* calculate difference matrix object */ + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { bGPDspoint *pt; @@ -1405,37 +2044,32 @@ static int gp_snap_to_grid(bContext *C, wmOperator *UNUSED(op)) if (ED_gpencil_stroke_can_use(C, gps) == false) continue; /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) continue; // TODO: if entire stroke is selected, offset entire stroke by same amount? for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { /* only if point is selected */ if (pt->flag & GP_SPOINT_SELECT) { - if (gpl->parent == NULL) { - pt->x = gridf * floorf(0.5f + pt->x / gridf); - pt->y = gridf * floorf(0.5f + pt->y / gridf); - pt->z = gridf * floorf(0.5f + pt->z / gridf); - } - else { - /* apply parent transformations */ - float fpt[3]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); + /* apply parent transformations */ + float fpt[3]; + mul_v3_m4v3(fpt, diff_mat, &pt->x); - fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf); - fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf); - fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf); + fpt[0] = gridf * floorf(0.5f + fpt[0] / gridf); + fpt[1] = gridf * floorf(0.5f + fpt[1] / gridf); + fpt[2] = gridf * floorf(0.5f + fpt[2] / gridf); - /* return data */ - copy_v3_v3(&pt->x, fpt); - gp_apply_parent_point(gpl, pt); - } + /* return data */ + copy_v3_v3(&pt->x, fpt); + gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt); } } } } } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -1463,6 +2097,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + Object *obact = CTX_data_active_object(C); \ const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d)->location; @@ -1473,10 +2109,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) bGPDframe *gpf = gpl->actframe; float diff_mat[4][4]; - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - } + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { bGPDspoint *pt; @@ -1486,7 +2120,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) if (ED_gpencil_stroke_can_use(C, gps) == false) continue; /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) continue; /* only continue if this stroke is selected (editable doesn't guarantee this)... */ if ((gps->flag & GP_STROKE_SELECT) == 0) @@ -1509,9 +2143,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { if (pt->flag & GP_SPOINT_SELECT) { copy_v3_v3(&pt->x, cursor_global); - if (gpl->parent != NULL) { - gp_apply_parent_point(gpl, pt); - } + gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt); } } } @@ -1520,6 +2152,8 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) } } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -1551,6 +2185,8 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ + Object *obact = CTX_data_active_object(C); \ float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; float centroid[3] = {0.0f}; @@ -1566,10 +2202,8 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) bGPDframe *gpf = gpl->actframe; float diff_mat[4][4]; - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - } + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { bGPDspoint *pt; @@ -1579,7 +2213,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) if (ED_gpencil_stroke_can_use(C, gps) == false) continue; /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) continue; /* only continue if this stroke is selected (editable doesn't guarantee this)... */ if ((gps->flag & GP_STROKE_SELECT) == 0) @@ -1587,18 +2221,13 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { if (pt->flag & GP_SPOINT_SELECT) { - if (gpl->parent == NULL) { - add_v3_v3(centroid, &pt->x); - minmax_v3v3_v3(min, max, &pt->x); - } - else { - /* apply parent transformations */ - float fpt[3]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); + /* apply parent transformations */ + float fpt[3]; + mul_v3_m4v3(fpt, diff_mat, &pt->x); add_v3_v3(centroid, fpt); - minmax_v3v3_v3(min, max, fpt); - } + minmax_v3v3_v3(min, max, fpt); + count++; } } @@ -1616,7 +2245,9 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) } - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); + return OPERATOR_FINISHED; } @@ -1650,13 +2281,20 @@ static int gp_stroke_apply_thickness_exec(bContext *C, wmOperator *UNUSED(op)) for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { /* Apply thickness */ - gps->thickness = gps->thickness + gpl->thickness; + if ((gps->thickness == 0) && (gpl->line_change == 0)) { + gps->thickness = gpl->thickness; + } + else { + gps->thickness = gps->thickness + gpl->line_change; + } } } /* clear value */ gpl->thickness = 0.0f; + gpl->line_change = 0; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -1685,6 +2323,8 @@ enum { static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); + Object *ob = CTX_data_active_object(C); + const int type = RNA_enum_get(op->ptr, "type"); /* sanity checks */ @@ -1698,13 +2338,13 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op) continue; for (bGPDstroke *gps = gpl->actframe->strokes.last; gps; gps = gps->prev) { - bGPDpalettecolor *palcolor = gps->palcolor; + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); /* skip strokes that are not selected or invalid for current view */ if (((gps->flag & GP_STROKE_SELECT) == 0) || ED_gpencil_stroke_can_use(C, gps) == false) continue; /* skip hidden or locked colors */ - if (!palcolor || (palcolor->flag & PC_COLOR_HIDE) || (palcolor->flag & PC_COLOR_LOCKED)) + if (!gp_style || (gp_style->flag & GP_STYLE_COLOR_HIDE) || (gp_style->flag & GP_STYLE_COLOR_LOCKED)) continue; switch (type) { @@ -1729,6 +2369,7 @@ static int gp_stroke_cyclical_set_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -1809,15 +2450,24 @@ static void gpencil_flip_stroke(bGPDstroke *gps) } /* Helper: copy point between strokes */ -static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, float delta[3], +static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, int idx, float delta[3], float pressure, float strength, float deltatime) { bGPDspoint *newpoint; + MDeformVert *dvert, *newdvert; gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1)); + if (gps->dvert != NULL) { + gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1)); + } gps->totpoints++; - newpoint = &gps->points[gps->totpoints - 1]; + + if (gps->dvert != NULL) { + dvert = &gps->dvert[idx]; + newdvert = &gps->dvert[gps->totpoints - 1]; + } + newpoint->x = point->x * delta[0]; newpoint->y = point->y * delta[1]; newpoint->z = point->z * delta[2]; @@ -1825,6 +2475,9 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, float newpoint->pressure = pressure; newpoint->strength = strength; newpoint->time = point->time + deltatime; + + newdvert->totweight = dvert->totweight; + newdvert->dw = MEM_dupallocN(dvert->dw); } /* Helper: join two strokes using the shortest distance (reorder stroke if necessary ) */ @@ -1870,18 +2523,18 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, bGPDstroke *gps_b, co /* 1st: add one tail point to start invisible area */ point = gps_a->points[gps_a->totpoints - 1]; deltatime = point.time; - gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, 0.0f); + gpencil_stroke_copy_point(gps_a, &point, gps_a->totpoints - 1, delta, 0.0f, 0.0f, 0.0f); /* 2nd: add one head point to finish invisible area */ point = gps_b->points[0]; - gpencil_stroke_copy_point(gps_a, &point, delta, 0.0f, 0.0f, deltatime); + gpencil_stroke_copy_point(gps_a, &point, 0, delta, 0.0f, 0.0f, deltatime); } /* 3rd: add all points */ for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) { /* check if still room in buffer */ if (gps_a->totpoints <= GP_STROKE_BUFFER_MAX - 2) { - gpencil_stroke_copy_point(gps_a, pt, delta, pt->pressure, pt->strength, deltatime); + gpencil_stroke_copy_point(gps_a, pt, i, delta, pt->pressure, pt->strength, deltatime); } } } @@ -1891,8 +2544,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op) bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *activegpl = BKE_gpencil_layer_getactive(gpd); bGPDstroke *gps, *gpsn; - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); + Object *ob = CTX_data_active_object(C); bGPDframe *gpf_a = NULL; bGPDstroke *stroke_a = NULL; @@ -1928,7 +2580,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { continue; } @@ -1948,15 +2600,17 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op) if (new_stroke == NULL) { new_stroke = MEM_dupallocN(stroke_a); new_stroke->points = MEM_dupallocN(stroke_a->points); + if (stroke_a->dvert != NULL) { + new_stroke->dvert = MEM_dupallocN(stroke_a->dvert); + BKE_gpencil_stroke_weights_duplicate(stroke_a, new_stroke); + } new_stroke->triangles = NULL; new_stroke->tot_triangles = 0; new_stroke->flag |= GP_STROKE_RECALC_CACHES; /* if new, set current color */ if (type == GP_STROKE_JOINCOPY) { - new_stroke->palcolor = palcolor; - BLI_strncpy(new_stroke->colorname, palcolor->info, sizeof(new_stroke->colorname)); - new_stroke->flag |= GP_STROKE_RECALC_COLOR; + new_stroke->mat_nr = stroke_a->mat_nr; } } @@ -1995,6 +2649,7 @@ static int gp_stroke_join_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -2030,6 +2685,7 @@ void GPENCIL_OT_stroke_join(wmOperatorType *ot) static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); + Object *ob = CTX_data_active_object(C); /* sanity checks */ if (ELEM(NULL, gpd)) @@ -2049,7 +2705,7 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op)) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { continue; } @@ -2061,6 +2717,7 @@ static int gp_stroke_flip_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -2084,33 +2741,42 @@ void GPENCIL_OT_stroke_flip(wmOperatorType *ot) /* ***************** Reproject Strokes ********************** */ typedef enum eGP_ReprojectModes { + /* Axis (equal to lock axis) */ + GP_REPROJECT_AXIS = 0, /* On same plane, parallel to viewplane */ - GP_REPROJECT_PLANAR = 0, + GP_REPROJECT_PLANAR, /* Reprojected on to the scene geometry */ GP_REPROJECT_SURFACE, } eGP_ReprojectModes; -static bool gp_strokes_reproject_poll(bContext *C) -{ - /* 2 Requirements: - * - 1) Editable GP data - * - 2) 3D View only (2D editors don't have projection issues) - */ - return (gp_stroke_edit_poll(C) && ED_operator_view3d_active(C)); -} - static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); Scene *scene = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Object *ob = CTX_data_active_object(C); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + RegionView3D *rv3d = ar->regiondata; + View3D *v3d = sa->spacedata.first; + GP_SpaceConversion gsc = {NULL}; - eGP_ReprojectModes mode = RNA_boolean_get(op->ptr, "type"); + eGP_ReprojectModes mode = RNA_enum_get(op->ptr, "type"); + + int lock_axis = ts->gp_sculpt.lock_axis; + float origin[3]; + + if ((mode == GP_REPROJECT_AXIS) && (lock_axis == GP_LOCKAXIS_NONE)) { + BKE_report(op->reports, RPT_ERROR, "To reproject by axis, a lock axis must be set before"); + return OPERATOR_CANCELLED; + } /* init space conversion stuff */ gp_point_conversion_init(C, &gsc); /* init autodist for geometry projection */ if (mode == GP_REPROJECT_SURFACE) { - struct Depsgraph *depsgraph = CTX_data_depsgraph(C); view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar); ED_view3d_autodist_init(depsgraph, gsc.ar, CTX_wm_view3d(C), 0); } @@ -2127,9 +2793,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) /* Compute inverse matrix for unapplying parenting once instead of doing per-point */ /* TODO: add this bit to the iteration macro? */ - if (gpl->parent) { - invert_m4_m4(inverse_diff_mat, diff_mat); - } + invert_m4_m4(inverse_diff_mat, diff_mat); /* Adjust each point */ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { @@ -2140,19 +2804,28 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) * coordinates, resulting in lost precision, which in turn causes stairstepping * artifacts in the final points. */ - if (gpl->parent == NULL) { - gp_point_to_xy_fl(&gsc, gps, pt, &xy[0], &xy[1]); - } - else { - bGPDspoint pt2; - gp_point_to_parent_space(pt, diff_mat, &pt2); - gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]); + bGPDspoint pt2; + gp_point_to_parent_space(pt, diff_mat, &pt2); + gp_point_to_xy_fl(&gsc, gps, &pt2, &xy[0], &xy[1]); + + /* Project stroke in the axis locked */ + if (mode == GP_REPROJECT_AXIS) { + if (lock_axis > GP_LOCKAXIS_NONE) { + ED_gp_get_drawing_reference(v3d, scene, ob, gpl, + ts->gpencil_v3d_align, origin); + ED_gp_project_point_to_plane(ob, rv3d, origin, + lock_axis - 1, &pt2); + + copy_v3_v3(&pt->x, &pt2.x); + + /* apply parent again */ + gp_apply_parent_point(depsgraph, ob, gpd, gpl, pt); + } } - /* Project screenspace back to 3D space (from current perspective) * so that all points have been treated the same way */ - if (mode == GP_REPROJECT_PLANAR) { + else if (mode == GP_REPROJECT_PLANAR) { /* Planar - All on same plane parallel to the viewplane */ gp_point_xy_to_3d(&gsc, scene, xy, &pt->x); } @@ -2175,7 +2848,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) } /* Unapply parent corrections */ - if (gpl->parent) { + if (mode != GP_REPROJECT_AXIS) { mul_m4_v3(inverse_diff_mat, &pt->x); } } @@ -2183,6 +2856,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) } GP_EDITABLE_STROKES_END; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -2190,6 +2864,9 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) void GPENCIL_OT_reproject(wmOperatorType *ot) { static const EnumPropertyItem reproject_type[] = { + { GP_REPROJECT_AXIS, "AXIS", 0, "Axis", + "Reproject the strokes using the current lock axis configuration. This is the same projection using while" + "drawing new strokes" }, {GP_REPROJECT_PLANAR, "PLANAR", 0, "Planar", "Reproject the strokes to end up on the same plane, as if drawn from the current viewpoint " "using 'Cursor' Stroke Placement"}, @@ -2208,7 +2885,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot) /* callbacks */ ot->invoke = WM_menu_invoke; ot->exec = gp_strokes_reproject_exec; - ot->poll = gp_strokes_reproject_poll; + ot->poll = gp_strokes_edit3d_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2229,7 +2906,7 @@ static int gp_count_subdivision_cuts(bGPDstroke *gps) if (pt->flag & GP_SPOINT_SELECT) { if (i + 1 < gps->totpoints) { if (gps->points[i + 1].flag & GP_SPOINT_SELECT) { - ++totnewpoints; + totnewpoints++; } } } @@ -2237,6 +2914,7 @@ static int gp_count_subdivision_cuts(bGPDstroke *gps) return totnewpoints; } + static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); @@ -2267,6 +2945,9 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) /* resize the points arrys */ gps->totpoints += totnewpoints; gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints); + if (gps->dvert != NULL) { + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints); + } gps->flag |= GP_STROKE_RECALC_CACHES; /* loop and interpolate */ @@ -2275,19 +2956,27 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) bGPDspoint *pt = &temp_points[i]; bGPDspoint *pt_final = &gps->points[i2]; + MDeformVert *dvert_final = &gps->dvert[i2]; + /* copy current point */ copy_v3_v3(&pt_final->x, &pt->x); pt_final->pressure = pt->pressure; pt_final->strength = pt->strength; pt_final->time = pt->time; pt_final->flag = pt->flag; - ++i2; + + dvert_final->totweight = 0; + dvert_final->dw = NULL; + i2++; /* if next point is selected add a half way point */ if (pt->flag & GP_SPOINT_SELECT) { if (i + 1 < oldtotpoints) { if (temp_points[i + 1].flag & GP_SPOINT_SELECT) { pt_final = &gps->points[i2]; + if (gps->dvert != NULL) { + dvert_final = &gps->dvert[i2]; + } /* Interpolate all values */ bGPDspoint *next = &temp_points[i + 1]; interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); @@ -2296,7 +2985,11 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt_final->time = interpf(pt->time, next->time, 0.5f); pt_final->flag |= GP_SPOINT_SELECT; - ++i2; + + dvert_final->totweight = 0; + dvert_final->dw = NULL; + + i2++; } } } @@ -2309,6 +3002,7 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) GP_EDITABLE_STROKES_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -2328,7 +3022,7 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot) ot->poll = gp_active_layer_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, 5); @@ -2336,3 +3030,414 @@ void GPENCIL_OT_stroke_subdivide(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } + +/* ** simplify stroke *** */ +static int gp_stroke_simplify_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + float factor = RNA_float_get(op->ptr, "factor"); + + /* sanity checks */ + if (ELEM(NULL, gpd)) + return OPERATOR_CANCELLED; + + /* Go through each editable + selected stroke */ + GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) + { + if (gps->flag & GP_STROKE_SELECT) { + /* simplify stroke using Ramer-Douglas-Peucker algorithm */ + BKE_gpencil_simplify_stroke(gps, factor); + } + } + GP_EDITABLE_STROKES_END; + + /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_stroke_simplify(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Simplify Stroke"; + ot->idname = "GPENCIL_OT_stroke_simplify"; + ot->description = "Simplify selected stroked reducing number of points"; + + /* api callbacks */ + ot->exec = gp_stroke_simplify_exec; + ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, 100.0f, "Factor", "", 0.0f, 100.0f); + /* avoid re-using last var */ + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +/* ** simplify stroke using fixed algorith *** */ +static int gp_stroke_simplify_fixed_exec(bContext *C, wmOperator *op) +{ + bGPdata *gpd = ED_gpencil_data_get_active(C); + int steps = RNA_int_get(op->ptr, "step"); + + /* sanity checks */ + if (ELEM(NULL, gpd)) + return OPERATOR_CANCELLED; + + /* Go through each editable + selected stroke */ + GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) + { + if (gps->flag & GP_STROKE_SELECT) { + for (int i = 0; i < steps; i++) { + BKE_gpencil_simplify_fixed(gps); + } + } + } + GP_EDITABLE_STROKES_END; + + /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Simplify Fixed Stroke"; + ot->idname = "GPENCIL_OT_stroke_simplify_fixed"; + ot->description = "Simplify selected stroked reducing number of points using fixed algorithm"; + + /* api callbacks */ + ot->exec = gp_stroke_simplify_fixed_exec; + ot->poll = gp_active_layer_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Steps", "Number of simplify steps", 1, 10); + + /* avoid re-using last var */ + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + +} + +/* ***************** Separate Strokes ********************** */ +typedef enum eGP_SeparateModes { + /* Points */ + GP_SEPARATE_POINT = 0, + /* Selected Strokes */ + GP_SEPARATE_STROKE, + /* Current Layer */ + GP_SEPARATE_LAYER, +} eGP_SeparateModes; + +static int gp_stroke_separate_exec(bContext *C, wmOperator *op) +{ + Base *base_new; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Base *base_old = CTX_data_active_base(C); + bGPdata *gpd_src = ED_gpencil_data_get_active(C); + Object *ob = CTX_data_active_object(C); + + Object *ob_dst = NULL; + bGPdata *gpd_dst = NULL; + bGPDlayer *gpl_dst = NULL; + bGPDframe *gpf_dst = NULL; + bGPDspoint *pt; + Material *ma = NULL; + int i, idx; + + eGP_SeparateModes mode = RNA_enum_get(op->ptr, "mode"); + + /* sanity checks */ + if (ELEM(NULL, gpd_src)) { + return OPERATOR_CANCELLED; + } + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_src); + + /* create a new object */ + base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, 0); + ob_dst = base_new->object; + + /* create new grease pencil datablock */ + // XXX: check usercounts + gpd_dst = BKE_gpencil_data_addnew(bmain, "GPencil"); + ob_dst->data = (bGPdata *)gpd_dst; + + int totslots = ob_dst->totcol; + int totadd = 0; + + /* loop old datablock and separate parts */ + if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) { + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + gpl_dst = NULL; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) { + continue; + } + + gpf_dst = NULL; + + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + /* separate selected strokes */ + if (gps->flag & GP_STROKE_SELECT) { + /* add layer if not created before */ + if (gpl_dst == NULL) { + gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, gpl->info, false); + } + + /* add frame if not created before */ + if (gpf_dst == NULL) { + gpf_dst = BKE_gpencil_layer_getframe(gpl_dst, gpf->framenum, GP_GETFRAME_ADD_NEW); + } + + /* add duplicate materials */ + ma = give_current_material(ob, gps->mat_nr + 1); + idx = BKE_object_material_slot_find_index(ob_dst, ma); + if (idx == 0) { + + totadd++; + ob_dst->actcol = totadd; + ob_dst->totcol = totadd; + + if (totadd > totslots) { + BKE_object_material_slot_add(bmain, ob_dst); + } + + assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_EXISTING); + idx = totadd; + } + + /* selected points mode */ + if (mode == GP_SEPARATE_POINT) { + /* make copy of source stroke */ + bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps); + + /* reasign material */ + gps_dst->mat_nr = idx - 1; + + /* link to destination frame */ + BLI_addtail(&gpf_dst->strokes, gps_dst); + + /* Invert selection status of all points in destination stroke */ + for (i = 0, pt = gps_dst->points; i < gps_dst->totpoints; i++, pt++) { + pt->flag ^= GP_SPOINT_SELECT; + } + + /* delete selected points from destination stroke */ + gp_stroke_delete_tagged_points(gpf_dst, gps_dst, NULL, GP_SPOINT_SELECT, false); + + /* delete selected points from origin stroke */ + gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false); + } + /* selected strokes mode */ + else if (mode == GP_SEPARATE_STROKE) { + /* deselect old stroke */ + gps->flag &= ~GP_STROKE_SELECT; + /* unlink from source frame */ + BLI_remlink(&gpf->strokes, gps); + gps->prev = gps->next = NULL; + /* relink to destination frame */ + BLI_addtail(&gpf_dst->strokes, gps); + /* reasign material */ + gps->mat_nr = idx - 1; + } + } + } + } + + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } + } + } + CTX_DATA_END; + } + else if (mode == GP_SEPARATE_LAYER) { + bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + if (gpl) { + /* try to set a new active layer in source datablock */ + if (gpl->prev) { + BKE_gpencil_layer_setactive(gpd_src, gpl->prev); + } + else if (gpl->next) { + BKE_gpencil_layer_setactive(gpd_src, gpl->next); + } + /* unlink from source datablock */ + BLI_remlink(&gpd_src->layers, gpl); + gpl->prev = gpl->next = NULL; + /* relink to destination datablock */ + BLI_addtail(&gpd_dst->layers, gpl); + } + } + DEG_id_tag_update(&gpd_src->id, OB_RECALC_OB | OB_RECALC_DATA); + DEG_id_tag_update(&gpd_dst->id, OB_RECALC_OB | OB_RECALC_DATA); + + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_stroke_separate(wmOperatorType *ot) +{ + static const EnumPropertyItem separate_type[] = { + {GP_SEPARATE_POINT, "POINT", 0, "Selected Points", "Separate the selected points" }, + {GP_SEPARATE_STROKE, "STROKE", 0, "Selected Strokes", "Separate the selected strokes"}, + {GP_SEPARATE_LAYER, "LAYER", 0, "Active Layer", "Separate the strokes of the current layer" }, + { 0, NULL, 0, NULL, NULL } + }; + + /* identifiers */ + ot->name = "Separate Strokes"; + ot->idname = "GPENCIL_OT_stroke_separate"; + ot->description = "Separate the selected strokes or layer in a new grease pencil object"; + + /* callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = gp_stroke_separate_exec; + ot->poll = gp_strokes_edit3d_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "mode", separate_type, GP_SEPARATE_POINT, "Mode", ""); +} + +/* ***************** Split Strokes ********************** */ +static int gp_stroke_split_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob = CTX_data_active_object(C); + bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDspoint *pt; + int i; + + /* sanity checks */ + if (ELEM(NULL, gpd)) { + return OPERATOR_CANCELLED; + } + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + + /* loop strokes and split parts */ + CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) + { + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + bGPDstroke *gps, *gpsn; + + if (gpf == NULL) { + continue; + } + + for (gps = gpf->strokes.first; gps; gps = gpsn) { + gpsn = gps->next; + + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + /* split selected strokes */ + if (gps->flag & GP_STROKE_SELECT) { + /* make copy of source stroke */ + bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps); + + /* link to same frame */ + BLI_addtail(&gpf->strokes, gps_dst); + + /* invert selection status of all points in destination stroke */ + for (i = 0, pt = gps_dst->points; i < gps_dst->totpoints; i++, pt++) { + pt->flag ^= GP_SPOINT_SELECT; + } + + /* delete selected points from destination stroke */ + gp_stroke_delete_tagged_points(gpf, gps_dst, NULL, GP_SPOINT_SELECT, true); + + /* delete selected points from origin stroke */ + gp_stroke_delete_tagged_points(gpf, gps, gpsn, GP_SPOINT_SELECT, false); + } + } + /* select again tagged points */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + bGPDspoint *ptn = gps->points; + for (int i2 = 0; i2 < gps->totpoints; i2++, ptn++) { + if (ptn->flag & GP_SPOINT_TAG) { + ptn->flag |= GP_SPOINT_SELECT; + ptn->flag &= ~GP_SPOINT_TAG; + } + } + } + } + + /* if not multiedit, exit loop*/ + if (!is_multiedit) { + break; + } + } + } + CTX_DATA_END; + + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_stroke_split(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Split Strokes"; + ot->idname = "GPENCIL_OT_stroke_split"; + ot->description = "Split selected points as new stroke on same frame"; + + /* callbacks */ + ot->exec = gp_stroke_split_exec; + ot->poll = gp_strokes_edit3d_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c new file mode 100644 index 00000000000..b768ac2c44f --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -0,0 +1,1246 @@ +/* + * ***** 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) 2017, Blender Foundation, Joshua Leung + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/gpencil_fill.c + * \ingroup edgpencil + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_stack.h" + +#include "BLT_translation.h" + +#include "DNA_brush_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_image_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_windowmanager_types.h" + +#include "BKE_main.h" +#include "BKE_brush.h" +#include "BKE_image.h" +#include "BKE_gpencil.h" +#include "BKE_material.h" +#include "BKE_context.h" +#include "BKE_screen.h" +#include "BKE_paint.h" + +#include "ED_gpencil.h" +#include "ED_screen.h" +#include "ED_space_api.h" +#include "ED_view3d.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "GPU_immediate.h" +#include "GPU_draw.h" +#include "GPU_matrix.h" +#include "GPU_framebuffer.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "gpencil_intern.h" + +#define LEAK_HORZ 0 +#define LEAK_VERT 1 + + +/* Temporary fill operation data (op->customdata) */ +typedef struct tGPDfill { + struct Main *bmain; + struct Depsgraph *depsgraph; + struct wmWindow *win; /* window where painting originated */ + struct Scene *scene; /* current scene from context */ + struct Object *ob; /* current active gp object */ + struct ScrArea *sa; /* area where painting originated */ + struct RegionView3D *rv3d; /* region where painting originated */ + struct View3D *v3d; /* view3 where painting originated */ + struct ARegion *ar; /* region where painting originated */ + struct bGPdata *gpd; /* current GP datablock */ + struct Material *mat; /* current material */ + struct bGPDlayer *gpl; /* layer */ + struct bGPDframe *gpf; /* frame */ + + short flag; /* flags */ + short oldkey; /* avoid too fast events */ + bool on_back; /* send to back stroke */ + + int center[2]; /* mouse fill center position */ + int sizex; /* windows width */ + int sizey; /* window height */ + int lock_axis; /* lock to viewport axis */ + + short fill_leak; /* number of pixel to consider the leak is too small (x 2) */ + float fill_threshold; /* factor for transparency */ + int fill_simplylvl; /* number of simplify steps */ + int fill_draw_mode; /* boundary limits drawing mode */ + + short sbuffer_size; /* number of elements currently in cache */ + void *sbuffer; /* temporary points */ + float *depth_arr; /* depth array for reproject */ + + Image *ima; /* temp image */ + BLI_Stack *stack; /* temp points data */ + void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */ +} tGPDfill; + + + /* draw a given stroke using same thickness and color for all points */ +static void gp_draw_basic_stroke(tGPDfill *tgpf, bGPDstroke *gps, const float diff_mat[4][4], + bool cyclic, float ink[4], int flag, float thershold) +{ + bGPDspoint *points = gps->points; + + Material *ma = tgpf->mat; + MaterialGPencilStyle *gp_style = ma->gp_style; + + int totpoints = gps->totpoints; + float fpt[3]; + float col[4]; + + copy_v4_v4(col, ink); + + /* if cyclic needs more vertex */ + int cyclic_add = (cyclic) ? 1 : 0; + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); + + /* draw stroke curve */ + glLineWidth(1.0f); + immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints + cyclic_add); + const bGPDspoint *pt = points; + + for (int i = 0; i < totpoints; i++, pt++) { + + if (flag & GP_BRUSH_FILL_HIDE) { + float alpha = gp_style->stroke_rgba[3] * pt->strength; + CLAMP(alpha, 0.0f, 1.0f); + col[3] = alpha <= thershold ? 0.0f : 1.0f; + } + else { + col[3] = 1.0f; + } + /* set point */ + immAttrib4fv(color, col); + mul_v3_m4v3(fpt, diff_mat, &pt->x); + immVertex3fv(pos, fpt); + } + + if (cyclic && totpoints > 2) { + /* draw line to first point to complete the cycle */ + immAttrib4fv(color, col); + mul_v3_m4v3(fpt, diff_mat, &points->x); + immVertex3fv(pos, fpt); + } + + immEnd(); + immUnbindProgram(); +} + +/* loop all layers */ +static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) +{ + /* duplicated: etempFlags */ + enum { + GP_DRAWFILLS_NOSTATUS = (1 << 0), /* don't draw status info */ + GP_DRAWFILLS_ONLY3D = (1 << 1), /* only draw 3d-strokes */ + }; + + Object *ob = tgpf->ob; + bGPdata *gpd = tgpf->gpd; + int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph); + + tGPDdraw tgpw; + tgpw.rv3d = tgpf->rv3d; + tgpw.depsgraph = tgpf->depsgraph; + tgpw.ob = ob; + tgpw.gpd = gpd; + tgpw.offsx = 0; + tgpw.offsy = 0; + tgpw.winx = tgpf->ar->winx; + tgpw.winy = tgpf->ar->winy; + tgpw.dflag = 0; + tgpw.disable_fill = 1; + tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS); + + glEnable(GL_BLEND); + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* calculate parent position */ + ED_gpencil_parent_location(tgpw.depsgraph, ob, gpd, gpl, tgpw.diff_mat); + + /* do not draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; + + /* get frame to draw */ + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); + if (gpf == NULL) + continue; + + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* check if stroke can be drawn */ + if ((gps->points == NULL) || (gps->totpoints < 2)) { + continue; + } + /* check if the color is visible */ + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE)) + { + continue; + } + + tgpw.gps = gps; + tgpw.gpl = gpl; + tgpw.gpf = gpf; + tgpw.t_gpf = gpf; + + /* reduce thickness to avoid gaps */ + tgpw.lthick = gpl->line_change - 4; + tgpw.opacity = 1.0; + copy_v4_v4(tgpw.tintcolor, ink); + tgpw.onion = true; + tgpw.custonion = true; + + /* normal strokes */ + if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) || + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + { + ED_gp_draw_fill(&tgpw); + + } + + /* 3D Lines with basic shapes and invisible lines */ + if ((tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) || + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + { + gp_draw_basic_stroke(tgpf, gps, tgpw.diff_mat, gps->flag & GP_STROKE_CYCLIC, ink, + tgpf->flag, tgpf->fill_threshold); + } + } + } + + glDisable(GL_BLEND); +} + + /* draw strokes in offscreen buffer */ +static void gp_render_offscreen(tGPDfill *tgpf) +{ + bool is_ortho = false; + float winmat[4][4]; + + if (!tgpf->gpd) { + return; + } + + char err_out[256] = "unknown"; + GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, 0, true, false, err_out); + GPU_offscreen_bind(offscreen, true); + uint flag = IB_rect | IB_rectfloat; + ImBuf *ibuf = IMB_allocImBuf(tgpf->sizex, tgpf->sizey, 32, flag); + + rctf viewplane; + float clipsta, clipend; + + is_ortho = ED_view3d_viewplane_get(tgpf->depsgraph, tgpf->v3d, tgpf->rv3d, tgpf->sizex, tgpf->sizey, &viewplane, &clipsta, &clipend, NULL); + if (is_ortho) { + orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend); + } + else { + perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); + } + + /* set temporary new size */ + int bwinx = tgpf->ar->winx; + int bwiny = tgpf->ar->winy; + rcti brect = tgpf->ar->winrct; + + tgpf->ar->winx = (short) tgpf->sizex; + tgpf->ar->winy = (short) tgpf->sizey; + tgpf->ar->winrct.xmin = 0; + tgpf->ar->winrct.ymin = 0; + tgpf->ar->winrct.xmax = tgpf->sizex; + tgpf->ar->winrct.ymax = tgpf->sizey; + + GPU_matrix_push_projection(); + GPU_matrix_identity_set(); + GPU_matrix_push(); + GPU_matrix_identity_set(); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + ED_view3d_update_viewmat(tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, + NULL, winmat, NULL); + /* set for opengl */ + GPU_matrix_projection_set(tgpf->rv3d->winmat); + GPU_matrix_set(tgpf->rv3d->viewmat); + + /* draw strokes */ + float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; + gp_draw_datablock(tgpf, ink); + + /* restore size */ + tgpf->ar->winx = (short)bwinx; + tgpf->ar->winy = (short)bwiny; + tgpf->ar->winrct = brect; + + GPU_matrix_pop_projection(); + GPU_matrix_pop(); + + /* create a image to see result of template */ + if (ibuf->rect_float) { + GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float); + } + else if (ibuf->rect) { + GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect); + } + if (ibuf->rect_float && ibuf->rect) { + IMB_rect_from_float(ibuf); + } + + tgpf->ima = BKE_image_add_from_imbuf(tgpf->bmain, ibuf, "GP_fill"); + tgpf->ima->id.tag |= LIB_TAG_DOIT; + + BKE_image_release_ibuf(tgpf->ima, ibuf, NULL); + + /* switch back to window-system-provided framebuffer */ + GPU_offscreen_unbind(offscreen, true); + GPU_offscreen_free(offscreen); +} + +/* return pixel data (rgba) at index */ +static void get_pixel(ImBuf *ibuf, int idx, float r_col[4]) +{ + if (ibuf->rect_float) { + float *frgba = &ibuf->rect_float[idx * 4]; + copy_v4_v4(r_col, frgba); + } + else { + /* XXX: This case probably doesn't happen, as we only write to the float buffer, + * but we get compiler warnings about uninitialised vars otherwise + */ + BLI_assert(!"gpencil_fill.c - get_pixel() non-float case is used!"); + zero_v4(r_col); + } +} + +/* set pixel data (rgba) at index */ +static void set_pixel(ImBuf *ibuf, int idx, const float col[4]) +{ + if (ibuf->rect) { + uint *rrect = &ibuf->rect[idx]; + uchar ccol[4]; + + rgba_float_to_uchar(ccol, col); + *rrect = *((uint *)ccol); + } + + if (ibuf->rect_float) { + float *rrectf = &ibuf->rect_float[idx * 4]; + copy_v4_v4(rrectf, col); + } +} + +/* check if the size of the leak is narrow to determine if the stroke is closed + * this is used for strokes with small gaps between them to get a full fill + * and do not get a full screen fill. + * + * \param ibuf Image pixel data + * \param maxpixel Maximum index + * \param limit Limit of pixels to analize + * \param index Index of current pixel + * \param type 0-Horizontal 1-Vertical + */ +static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index, int type) +{ + float rgba[4]; + int i; + int pt; + bool t_a = false; + bool t_b = false; + + /* Horizontal leak (check vertical pixels) + * X + * X + * xB7 + * X + * X + */ + if (type == LEAK_HORZ) { + /* pixels on top */ + for (i = 1; i <= limit; i++) { + pt = index + (ibuf->x * i); + if (pt <= maxpixel) { + get_pixel(ibuf, pt, rgba); + if (rgba[0] == 1.0f) { + t_a = true; + break; + } + } + else { + t_a = true; /* edge of image*/ + break; + } + } + /* pixels on bottom */ + for (i = 1; i <= limit; i++) { + pt = index - (ibuf->x * i); + if (pt >= 0) { + get_pixel(ibuf, pt, rgba); + if (rgba[0] == 1.0f) { + t_b = true; + break; + } + } + else { + t_b = true; /* edge of image*/ + break; + } + } + } + + /* Vertical leak (check horizontal pixels) + * + * XXXxB7XX + * + */ + if (type == LEAK_VERT) { + /* get pixel range of the row */ + int row = index / ibuf->x; + int lowpix = row * ibuf->x; + int higpix = lowpix + ibuf->x - 1; + + /* pixels to right */ + for (i = 0; i < limit; i++) { + pt = index - (limit - i); + if (pt >= lowpix) { + get_pixel(ibuf, pt, rgba); + if (rgba[0] == 1.0f) { + t_a = true; + break; + } + } + else { + t_a = true; /* edge of image*/ + break; + } + } + /* pixels to left */ + for (i = 0; i < limit; i++) { + pt = index + (limit - i); + if (pt <= higpix) { + get_pixel(ibuf, pt, rgba); + if (rgba[0] == 1.0f) { + t_b = true; + break; + } + } + else { + t_b = true; /* edge of image */ + break; + } + } + } + return (bool)(t_a && t_b); +} + +/* Boundary fill inside strokes + * Fills the space created by a set of strokes using the stroke color as the boundary + * of the shape to fill. + * + * \param tgpf Temporary fill data + */ +static void gpencil_boundaryfill_area(tGPDfill *tgpf) +{ + ImBuf *ibuf; + float rgba[4]; + void *lock; + const float fill_col[4] = { 0.0f, 1.0f, 0.0f, 1.0f }; + ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock); + const int maxpixel = (ibuf->x * ibuf->y) - 1; + + BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__); + + /* calculate index of the seed point using the position of the mouse */ + int index = (tgpf->sizex * tgpf->center[1]) + tgpf->center[0]; + if ((index >= 0) && (index < maxpixel)) { + BLI_stack_push(stack, &index); + } + + /* the fill use a stack to save the pixel list instead of the common recursive + * 4-contact point method. + * The problem with recursive calls is that for big fill areas, we can get max limit + * of recursive calls and STACK_OVERFLOW error. + * + * The 4-contact point analyze the pixels to the left, right, bottom and top + * ----------- + * | X | + * | XoX | + * | X | + * ----------- + */ + while (!BLI_stack_is_empty(stack)) { + int v; + BLI_stack_pop(stack, &v); + + get_pixel(ibuf, v, rgba); + + if (true) { /* Was: 'rgba' */ + /* check if no border(red) or already filled color(green) */ + if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) + { + /* fill current pixel */ + set_pixel(ibuf, v, fill_col); + + /* add contact pixels */ + /* pixel left */ + if (v - 1 >= 0) { + index = v - 1; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { + BLI_stack_push(stack, &index); + } + } + /* pixel right */ + if (v + 1 < maxpixel) { + index = v + 1; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_HORZ)) { + BLI_stack_push(stack, &index); + } + } + /* pixel top */ + if (v + tgpf->sizex < maxpixel) { + index = v + tgpf->sizex; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { + BLI_stack_push(stack, &index); + } + } + /* pixel bottom */ + if (v - tgpf->sizex >= 0) { + index = v - tgpf->sizex; + if (!is_leak_narrow(ibuf, maxpixel, tgpf->fill_leak, v, LEAK_VERT)) { + BLI_stack_push(stack, &index); + } + } + } + } + } + + /* release ibuf */ + if (ibuf) { + BKE_image_release_ibuf(tgpf->ima, ibuf, lock); + } + + tgpf->ima->id.tag |= LIB_TAG_DOIT; + /* free temp stack data */ + BLI_stack_free(stack); +} + +/* clean external border of image to avoid infinite loops */ +static void gpencil_clean_borders(tGPDfill *tgpf) +{ + ImBuf *ibuf; + void *lock; + const float fill_col[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock); + int idx; + + /* horizontal lines */ + for (idx = 0; idx < ibuf->x; idx++) { + /* bottom line */ + set_pixel(ibuf, idx, fill_col); + /* top line */ + set_pixel(ibuf, idx + (ibuf->x * (ibuf->y - 1)), fill_col); + } + /* vertical lines */ + for (idx = 0; idx < ibuf->y; idx++) { + /* left line */ + set_pixel(ibuf, ibuf->x * idx, fill_col); + /* right line */ + set_pixel(ibuf, ibuf->x * idx + (ibuf->x - 1), fill_col); + } + + /* release ibuf */ + if (ibuf) { + BKE_image_release_ibuf(tgpf->ima, ibuf, lock); + } + + tgpf->ima->id.tag |= LIB_TAG_DOIT; +} + +/* Get the outline points of a shape using Moore Neighborhood algorithm + * + * This is a Blender customized version of the general algorithm described + * in https://en.wikipedia.org/wiki/Moore_neighborhood + */ +static void gpencil_get_outline_points(tGPDfill *tgpf) +{ + ImBuf *ibuf; + float rgba[4]; + void *lock; + int v[2]; + int boundary_co[2]; + int start_co[2]; + int backtracked_co[2]; + int current_check_co[2]; + int prev_check_co[2]; + int backtracked_offset[1][2] = { { 0,0 } }; + // bool boundary_found = false; + bool start_found = false; + const int NEIGHBOR_COUNT = 8; + + int offset[8][2] = { + { -1, -1 }, + { 0, -1 }, + { 1, -1 }, + { 1, 0 }, + { 1, 1 }, + { 0, 1 }, + { -1, 1 }, + { -1, 0 } + }; + + tgpf->stack = BLI_stack_new(sizeof(int[2]), __func__); + + ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock); + int imagesize = ibuf->x * ibuf->y; + + /* find the initial point to start outline analysis */ + for (int idx = imagesize; idx >= 0; idx--) { + get_pixel(ibuf, idx, rgba); + if (rgba[1] == 1.0f) { + boundary_co[0] = idx % ibuf->x; + boundary_co[1] = idx / ibuf->x; + copy_v2_v2_int(start_co, boundary_co); + backtracked_co[0] = (idx - 1) % ibuf->x; + backtracked_co[1] = (idx - 1) / ibuf->x; + backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0]; + backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1]; + copy_v2_v2_int(prev_check_co, start_co); + + BLI_stack_push(tgpf->stack, &boundary_co); + start_found = true; + break; + } + } + + while (true && start_found) + { + int cur_back_offset = -1; + for (int i = 0; i < NEIGHBOR_COUNT; i++) { + if (backtracked_offset[0][0] == offset[i][0] && + backtracked_offset[0][1] == offset[i][1]) + { + /* Finding the bracktracked pixel offset index */ + cur_back_offset = i; + break; + } + } + + int loop = 0; + while (loop < (NEIGHBOR_COUNT - 1) && cur_back_offset != -1) { + int offset_idx = (cur_back_offset + 1) % NEIGHBOR_COUNT; + current_check_co[0] = boundary_co[0] + offset[offset_idx][0]; + current_check_co[1] = boundary_co[1] + offset[offset_idx][1]; + + int image_idx = ibuf->x * current_check_co[1] + current_check_co[0]; + get_pixel(ibuf, image_idx, rgba); + + /* find next boundary pixel */ + if (rgba[1] == 1.0f) { + copy_v2_v2_int(boundary_co, current_check_co); + copy_v2_v2_int(backtracked_co, prev_check_co); + backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0]; + backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1]; + + BLI_stack_push(tgpf->stack, &boundary_co); + + break; + } + copy_v2_v2_int(prev_check_co, current_check_co); + cur_back_offset++; + loop++; + } + /* current pixel is equal to starting pixel */ + if (boundary_co[0] == start_co[0] && + boundary_co[1] == start_co[1]) + { + BLI_stack_pop(tgpf->stack, &v); + // boundary_found = true; + break; + } + } + + /* release ibuf */ + if (ibuf) { + BKE_image_release_ibuf(tgpf->ima, ibuf, lock); + } +} + +/* get z-depth array to reproject on surface */ +static void gpencil_get_depth_array(tGPDfill *tgpf) +{ + tGPspoint *ptc; + ToolSettings *ts = tgpf->scene->toolsettings; + int totpoints = tgpf->sbuffer_size; + int i = 0; + + if (totpoints == 0) { + return; + } + + /* for surface sketching, need to set the right OpenGL context stuff so that + * the conversions will project the values correctly... + */ + if (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) { + /* need to restore the original projection settings before packing up */ + view3d_region_operator_needs_opengl(tgpf->win, tgpf->ar); + ED_view3d_autodist_init(tgpf->depsgraph, tgpf->ar, tgpf->v3d, 0); + + /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */ + int depth_margin = 0; + + /* get an array of depths, far depths are blended */ + int mval[2], mval_prev[2] = { 0 }; + int interp_depth = 0; + int found_depth = 0; + + tgpf->depth_arr = MEM_mallocN(sizeof(float) * totpoints, "depth_points"); + + for (i = 0, ptc = tgpf->sbuffer; i < totpoints; i++, ptc++) { + copy_v2_v2_int(mval, &ptc->x); + + if ((ED_view3d_autodist_depth(tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) && + (i && (ED_view3d_autodist_depth_seg(tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) + { + interp_depth = true; + } + else { + found_depth = true; + } + + copy_v2_v2_int(mval_prev, mval); + } + + if (found_depth == false) { + /* eeh... not much we can do.. :/, ignore depth in this case */ + for (i = totpoints - 1; i >= 0; i--) + tgpf->depth_arr[i] = 0.9999f; + } + else { + if (interp_depth) { + interp_sparse_array(tgpf->depth_arr, totpoints, FLT_MAX); + } + } + } +} + +/* create array of points using stack as source */ +static void gpencil_points_from_stack(tGPDfill *tgpf) +{ + tGPspoint *point2D; + int totpoints = BLI_stack_count(tgpf->stack); + if (totpoints == 0) { + return; + } + + tgpf->sbuffer_size = (short)totpoints; + tgpf->sbuffer = MEM_callocN(sizeof(tGPspoint) * totpoints, __func__); + + point2D = tgpf->sbuffer; + while (!BLI_stack_is_empty(tgpf->stack)) { + int v[2]; + BLI_stack_pop(tgpf->stack, &v); + point2D->x = v[0]; + point2D->y = v[1]; + + point2D->pressure = 1.0f; + point2D->strength = 1.0f;; + point2D->time = 0.0f; + point2D++; + } +} + +/* create a grease pencil stroke using points in buffer */ +static void gpencil_stroke_from_buffer(tGPDfill *tgpf) +{ + ToolSettings *ts = tgpf->scene->toolsettings; + int cfra_eval = (int)DEG_get_ctime(tgpf->depsgraph); + + Brush *brush; + brush = BKE_brush_getactive_gpencil(ts); + if (brush == NULL) { + return; + } + + bGPDspoint *pt; + MDeformVert *dvert; + tGPspoint *point2D; + + if (tgpf->sbuffer_size == 0) { + return; + } + + /* get frame or create a new one */ + tgpf->gpf = BKE_gpencil_layer_getframe(tgpf->gpl, cfra_eval, GP_GETFRAME_ADD_NEW); + + /* create new stroke */ + bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "bGPDstroke"); + gps->thickness = brush->size; + gps->inittime = 0.0f; + + /* the polygon must be closed, so enabled cyclic */ + gps->flag |= GP_STROKE_CYCLIC; + gps->flag |= GP_STROKE_3DSPACE; + + gps->mat_nr = BKE_object_material_slot_find_index(tgpf->ob, tgpf->mat) - 1; + + /* allocate memory for storage points */ + gps->totpoints = tgpf->sbuffer_size; + gps->points = MEM_callocN(sizeof(bGPDspoint) * tgpf->sbuffer_size, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * tgpf->sbuffer_size, "gp_stroke_weights"); + + /* initialize triangle memory to dummy data */ + gps->tot_triangles = 0; + gps->triangles = NULL; + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* add stroke to frame */ + if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) || (tgpf->on_back == true)){ + BLI_addhead(&tgpf->gpf->strokes, gps); + } + else { + BLI_addtail(&tgpf->gpf->strokes, gps); + } + + /* add points */ + pt = gps->points; + dvert = gps->dvert; + point2D = (tGPspoint *)tgpf->sbuffer; + for (int i = 0; i < tgpf->sbuffer_size && point2D; i++, point2D++, pt++, dvert++) { + /* convert screen-coordinates to 3D coordinates */ + gp_stroke_convertcoords_tpoint(tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob, + tgpf->gpl, point2D, + tgpf->depth_arr ? tgpf->depth_arr + i : NULL, + &pt->x); + + pt->pressure = 1.0f; + pt->strength = 1.0f;; + pt->time = 0.0f; + + dvert->totweight = 0; + dvert->dw = NULL; + } + + /* smooth stroke */ + float reduce = 0.0f; + float smoothfac = 1.0f; + for (int r = 0; r < 1; r++) { + for (int i = 0; i < gps->totpoints; i++) { + BKE_gpencil_smooth_stroke(gps, i, smoothfac - reduce); + } + reduce += 0.25f; // reduce the factor + } + + /* if axis locked, reproject to plane locked */ + if ((tgpf->lock_axis > GP_LOCKAXIS_NONE) && ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0)) { + float origin[3]; + ED_gp_get_drawing_reference(tgpf->v3d, tgpf->scene, tgpf->ob, tgpf->gpl, + ts->gpencil_v3d_align, origin); + ED_gp_project_stroke_to_plane(tgpf->ob, tgpf->rv3d, gps, origin, + tgpf->lock_axis - 1); + } + + /* if parented change position relative to parent object */ + for (int a = 0; a < tgpf->sbuffer_size; a++) { + pt = &gps->points[a]; + gp_apply_parent_point(tgpf->depsgraph, tgpf->ob, tgpf->gpd, tgpf->gpl, pt); + } + + /* simplify stroke */ + for (int b = 0; b < tgpf->fill_simplylvl; b++) { + BKE_gpencil_simplify_fixed(gps); + } +} + +/* ----------------------- */ +/* Drawing */ +/* Helper: Draw status message while the user is running the operator */ +static void gpencil_fill_status_indicators(bContext *C, tGPDfill *UNUSED(tgpf)) +{ + char status_str[UI_MAX_DRAW_STR]; + + BLI_snprintf(status_str, sizeof(status_str), IFACE_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back")); + ED_workspace_status_text(C, status_str); +} + +/* draw boundary lines to see fill limits */ +static void gpencil_draw_boundary_lines(const bContext *UNUSED(C), tGPDfill *tgpf) +{ + if (!tgpf->gpd) { + return; + } + float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; + gp_draw_datablock(tgpf, ink); +} + +/* Drawing callback for modal operator in 3d mode */ +static void gpencil_fill_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg) +{ + tGPDfill *tgpf = (tGPDfill *)arg; + /* draw only in the region that originated operator. This is required for multiwindow */ + ARegion *ar = CTX_wm_region(C); + if (ar != tgpf->ar) { + return; + } + + gpencil_draw_boundary_lines(C, tgpf); +} + +/* check if context is suitable for filling */ +static bool gpencil_fill_poll(bContext *C) +{ + if (ED_operator_regionactive(C)) { + ScrArea *sa = CTX_wm_area(C); + if (sa->spacetype == SPACE_VIEW3D) { + return 1; + } + else { + CTX_wm_operator_poll_msg_set(C, "Active region not valid for filling operator"); + return 0; + } + } + else { + CTX_wm_operator_poll_msg_set(C, "Active region not set"); + return 0; + } +} + +/* Allocate memory and initialize values */ +static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op)) +{ + tGPDfill *tgpf = MEM_callocN(sizeof(tGPDfill), "GPencil Fill Data"); + + /* define initial values */ + ToolSettings *ts = CTX_data_tool_settings(C); + bGPdata *gpd = CTX_data_gpencil_data(C); + Main *bmain = CTX_data_main(C); + + /* set current scene and window info */ + tgpf->bmain = CTX_data_main(C); + tgpf->scene = CTX_data_scene(C); + tgpf->ob = CTX_data_active_object(C); + tgpf->sa = CTX_wm_area(C); + tgpf->ar = CTX_wm_region(C); + tgpf->rv3d = tgpf->ar->regiondata; + tgpf->v3d = tgpf->sa->spacedata.first; + tgpf->depsgraph = CTX_data_depsgraph(C); + tgpf->win = CTX_wm_window(C); + + /* set GP datablock */ + tgpf->gpd = gpd; + tgpf->gpl = BKE_gpencil_layer_getactive(gpd); + + tgpf->lock_axis = ts->gp_sculpt.lock_axis; + + tgpf->oldkey = -1; + tgpf->sbuffer_size = 0; + tgpf->sbuffer = NULL; + tgpf->depth_arr = NULL; + + /* save filling parameters */ + Brush *brush = BKE_brush_getactive_gpencil(ts); + tgpf->flag = brush->gpencil_settings->flag; + tgpf->fill_leak = brush->gpencil_settings->fill_leak; + tgpf->fill_threshold = brush->gpencil_settings->fill_threshold; + tgpf->fill_simplylvl = brush->gpencil_settings->fill_simplylvl; + tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode; + + /* get color info */ + Material *ma = BKE_gpencil_get_material_from_brush(brush); + /* if no brush defaults, get material and color info */ + if ((ma == NULL) || (ma->gp_style == NULL)) { + ma = BKE_gpencil_material_ensure(bmain, tgpf->ob); + /* assign always the first material to the brush */ + brush->gpencil_settings->material = give_current_material(tgpf->ob, 1); + } + + tgpf->mat = ma; + + /* init undo */ + gpencil_undo_init(tgpf->gpd); + + /* return context data for running operator */ + return tgpf; +} + +/* end operator */ +static void gpencil_fill_exit(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); + + /* clear undo stack */ + gpencil_undo_finish(); + + /* restore cursor to indicate end of fill */ + WM_cursor_modal_restore(CTX_wm_window(C)); + + tGPDfill *tgpf = op->customdata; + + /* don't assume that operator data exists at all */ + if (tgpf) { + /* clear status message area */ + ED_workspace_status_text(C, NULL); + + MEM_SAFE_FREE(tgpf->sbuffer); + MEM_SAFE_FREE(tgpf->depth_arr); + + /* remove drawing handler */ + if (tgpf->draw_handle_3d) { + ED_region_draw_cb_exit(tgpf->ar->type, tgpf->draw_handle_3d); + } + + /* delete temp image */ + if (tgpf->ima) { + for (Image *ima = bmain->image.first; ima; ima = ima->id.next) { + if (ima == tgpf->ima) { + BLI_remlink(&bmain->image, ima); + BKE_image_free(tgpf->ima); + MEM_SAFE_FREE(tgpf->ima); + break; + } + } + } + + /* finally, free memory used by temp data */ + MEM_freeN(tgpf); + } + + /* clear pointer */ + op->customdata = NULL; + + /* drawing batch cache is dirty now */ + if ((ob) && (ob->type == OB_GPENCIL) && (ob->data)) { + bGPdata *gpd2 = ob->data; + DEG_id_tag_update(&gpd2->id, OB_RECALC_OB | OB_RECALC_DATA); + gpd2->flag |= GP_DATA_CACHE_IS_DIRTY; + } + + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); +} + +static void gpencil_fill_cancel(bContext *C, wmOperator *op) +{ + /* this is just a wrapper around exit() */ + gpencil_fill_exit(C, op); +} + +/* Init: Allocate memory and set init values */ +static int gpencil_fill_init(bContext *C, wmOperator *op) +{ + tGPDfill *tgpf; + + /* check context */ + tgpf = op->customdata = gp_session_init_fill(C, op); + if (tgpf == NULL) { + /* something wasn't set correctly in context */ + gpencil_fill_exit(C, op); + return 0; + } + + /* everything is now setup ok */ + return 1; +} + +/* start of interactive part of operator */ +static int gpencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + tGPDfill *tgpf = NULL; + + /* try to initialize context data needed */ + if (!gpencil_fill_init(C, op)) { + gpencil_fill_exit(C, op); + if (op->customdata) + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + else { + tgpf = op->customdata; + } + + /* Enable custom drawing handlers to show help lines */ + if (tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) { + tgpf->draw_handle_3d = ED_region_draw_cb_activate(tgpf->ar->type, gpencil_fill_draw_3d, tgpf, REGION_DRAW_POST_VIEW); + } + + WM_cursor_modal_set(CTX_wm_window(C), BC_PAINTBRUSHCURSOR); + + gpencil_fill_status_indicators(C, tgpf); + + DEG_id_tag_update(&tgpf->gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + + /* add a modal handler for this operator*/ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +/* events handling during interactive part of operator */ +static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + tGPDfill *tgpf = op->customdata; + + int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */ + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + estate = OPERATOR_CANCELLED; + break; + case LEFTMOUSE: + tgpf->on_back = RNA_boolean_get(op->ptr, "on_back"); + /* first time the event is not enabled to show help lines */ + if ((tgpf->oldkey != -1) || ((tgpf->flag & GP_BRUSH_FILL_SHOW_HELPLINES) == 0)) { + ARegion *ar = BKE_area_find_region_xy(CTX_wm_area(C), RGN_TYPE_ANY, event->x, event->y); + if (ar) { + bool in_bounds = false; + + /* Perform bounds check */ + in_bounds = BLI_rcti_isect_pt(&ar->winrct, event->x, event->y); + + if ((in_bounds) && (ar->regiontype == RGN_TYPE_WINDOW)) { + /* TODO GPXX: Verify the mouse click is right for any window size */ + tgpf->center[0] = event->mval[0]; + tgpf->center[1] = event->mval[1]; + + /* save size */ + tgpf->sizex = ar->winx; + tgpf->sizey = ar->winy; + + /* render screen to temp image */ + gp_render_offscreen(tgpf); + + /* apply boundary fill */ + gpencil_boundaryfill_area(tgpf); + + /* clean borders to avoid infinite loops */ + gpencil_clean_borders(tgpf); + + /* analyze outline */ + gpencil_get_outline_points(tgpf); + + /* create array of points from stack */ + gpencil_points_from_stack(tgpf); + + /* create z-depth array for reproject */ + gpencil_get_depth_array(tgpf); + + /* create stroke and reproject */ + gpencil_stroke_from_buffer(tgpf); + + /* free temp stack data */ + if (tgpf->stack) { + BLI_stack_free(tgpf->stack); + } + + /* push undo data */ + gpencil_undo_push(tgpf->gpd); + + estate = OPERATOR_FINISHED; + } + else { + estate = OPERATOR_CANCELLED; + } + } + else { + estate = OPERATOR_CANCELLED; + } + } + tgpf->oldkey = event->type; + break; + } + /* process last operations before exiting */ + switch (estate) { + case OPERATOR_FINISHED: + gpencil_fill_exit(C, op); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + break; + + case OPERATOR_CANCELLED: + gpencil_fill_exit(C, op); + break; + + case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: + break; + } + + /* return status code */ + return estate; +} + +void GPENCIL_OT_fill(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Grease Pencil Fill"; + ot->idname = "GPENCIL_OT_fill"; + ot->description = "Fill with color the shape formed by strokes"; + + /* api callbacks */ + ot->invoke = gpencil_fill_invoke; + ot->modal = gpencil_fill_modal; + ot->poll = gpencil_fill_poll; + ot->cancel = gpencil_fill_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING; + + prop = RNA_def_boolean(ot->srna, "on_back", false, "Draw On Back", "Send new stroke to Back"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 90ff1e0bb25..0218530be4e 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -34,24 +34,144 @@ #include "DNA_vec_types.h" +#include "ED_numinput.h" + /* internal exports only */ struct bGPdata; struct bGPDstroke; struct bGPDspoint; +struct tGPspoint; +struct Material; struct GHash; struct RNG; +struct Brush; +struct Scene; struct ARegion; +struct View3D; struct View2D; struct wmOperatorType; +struct Depsgraph; + struct PointerRNA; struct PropertyRNA; struct EnumPropertyItem; +/* ***************************************************** */ +/* Modal Operator Geometry Preview + * + * Several modal operators (Fill, Interpolate, Primitive) + * need to run some drawing code to display previews, or + * to perform screen-space/image-based analysis routines. + * The following structs + function prototypes are used + * by these operators so that the operator code + * (in gpencil_.c) can communicate with the drawing + * code (in drawgpencil.c). + * + * NOTE: All this is within the gpencil module, so nothing needs + * to be exported to other modules. + */ + +/* Internal Operator-State Data ------------------------ */ + +/* Temporary draw data (no draw manager mode) */ +typedef struct tGPDdraw { + struct RegionView3D *rv3d; /* region to draw */ + struct Depsgraph *depsgraph; /* depsgraph */ + struct Object *ob; /* GP object */ + struct bGPdata *gpd; /* current GP datablock */ + struct bGPDlayer *gpl; /* layer */ + struct bGPDframe *gpf; /* frame */ + struct bGPDframe *t_gpf; /* temporal frame */ + struct bGPDstroke *gps; /* stroke */ + int disable_fill; /* disable fill */ + int offsx; /* windows offset x */ + int offsy; /* windows offset y */ + int winx; /* windows width */ + int winy; /* windows height */ + int dflag; /* flags datablock */ + short lthick; /* layer thickness */ + float opacity; /* opacity */ + float tintcolor[4]; /* tint color */ + bool onion; /* onion flag */ + bool custonion; /* use custom onion colors */ + float diff_mat[4][4]; /* matrix */ +} tGPDdraw; + + +/* Temporary interpolate operation data */ +typedef struct tGPDinterpolate_layer { + struct tGPDinterpolate_layer *next, *prev; + + struct bGPDlayer *gpl; /* layer */ + struct bGPDframe *prevFrame; /* frame before current frame (interpolate-from) */ + struct bGPDframe *nextFrame; /* frame after current frame (interpolate-to) */ + struct bGPDframe *interFrame; /* interpolated frame */ + float factor; /* interpolate factor */ + +} tGPDinterpolate_layer; + +typedef struct tGPDinterpolate { + struct Scene *scene; /* current scene from context */ + struct ScrArea *sa; /* area where painting originated */ + struct ARegion *ar; /* region where painting originated */ + struct bGPdata *gpd; /* current GP datablock */ + struct Material *mat; /* current material */ + + int cframe; /* current frame number */ + ListBase ilayers; /* (tGPDinterpolate_layer) layers to be interpolated */ + float shift; /* value for determining the displacement influence */ + float init_factor; /* initial interpolation factor for active layer */ + float low_limit; /* shift low limit (-100%) */ + float high_limit; /* shift upper limit (200%) */ + int flag; /* flag from toolsettings */ + + NumInput num; /* numeric input */ + void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */ + void *draw_handle_screen; /* handle for drawing strokes while operator is running screen stuff */ +} tGPDinterpolate; + + +/* Temporary primitive operation data */ +typedef struct tGPDprimitive { + struct Depsgraph *depsgraph; + struct wmWindow *win; /* window where painting originated */ + struct Scene *scene; /* current scene from context */ + struct Object *ob; /* current active gp object */ + struct ScrArea *sa; /* area where painting originated */ + struct RegionView3D *rv3d; /* region where painting originated */ + struct View3D *v3d; /* view3d where painting originated */ + struct ARegion *ar; /* region where painting originated */ + struct bGPdata *gpd; /* current GP datablock */ + struct Material *mat; /* current material */ + struct Brush *brush; /* current brush */ + + int cframe; /* current frame number */ + struct bGPDlayer *gpl; /* layer */ + struct bGPDframe *gpf; /* frame */ + int type; /* type of primitive */ + int tot_edges; /* number of polygon edges */ + int top[2]; /* first box corner */ + int bottom[2]; /* last box corner */ + int flag; /* flag to determine operations in progress */ + + int lock_axis; /* lock to viewport axis */ + + NumInput num; /* numeric input */ + void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */ +} tGPDprimitive; + + +/* Modal Operator Drawing Callbacks ------------------------ */ + +void ED_gp_draw_interpolation(const struct bContext *C, struct tGPDinterpolate *tgpi, const int type); +void ED_gp_draw_primitives(const struct bContext *C, struct tGPDprimitive *tgpi, const int type); +void ED_gp_draw_fill(struct tGPDdraw *tgpw); + /* ***************************************************** */ /* Internal API */ @@ -84,21 +204,29 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt, float *r_x, float *r_y); void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt); - -void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps); - -void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt); +/** + * Change points position relative to parent object + */ +void gp_apply_parent(struct Depsgraph *depsgraph, struct Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps); +/** + * Change point position relative to parent object + */ +void gp_apply_parent_point(struct Depsgraph *depsgraph, struct Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDspoint *pt); bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float screen_co[2], float r_out[3]); +/* helper to convert 2d to 3d */ +void gp_stroke_convertcoords_tpoint(struct Scene *scene, struct ARegion *ar, + struct View3D *v3d, struct Object *ob, + bGPDlayer *gpl, const struct tGPspoint *point2D, + float *depth, float out[3]); + /* Poll Callbacks ------------------------------------ */ /* gpencil_utils.c */ bool gp_add_poll(struct bContext *C); bool gp_active_layer_poll(struct bContext *C); bool gp_active_brush_poll(struct bContext *C); -bool gp_active_palette_poll(struct bContext *C); -bool gp_active_palettecolor_poll(struct bContext *C); bool gp_brush_crt_presets_poll(bContext *C); /* Copy/Paste Buffer --------------------------------- */ @@ -107,18 +235,19 @@ bool gp_brush_crt_presets_poll(bContext *C); extern ListBase gp_strokes_copypastebuf; /* Build a map for converting between old colornames and destination-color-refs */ -struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd); +struct GHash *gp_copybuf_validate_colormap(struct bContext *C); /* Stroke Editing ------------------------------------ */ -void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags); - +void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, + int tag_flags, bool select); +int gp_delete_selected_point_wrap(bContext *C); bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure); bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf); bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf); -void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints); -void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, struct RNG *rng); +void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide); +void gp_randomize_stroke(bGPDstroke *gps, Brush *brush, struct RNG *rng); /* Layers Enums -------------------------------------- */ @@ -129,22 +258,18 @@ const struct EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf( struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free); -/* Enums of GP Brushes */ -const EnumPropertyItem *ED_gpencil_brushes_enum_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), - bool *r_free); - -/* Enums of GP palettes */ -const EnumPropertyItem *ED_gpencil_palettes_enum_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), - bool *r_free); - /* ***************************************************** */ /* Operator Defines */ +/* annotations ------ */ + +void GPENCIL_OT_annotate(struct wmOperatorType *ot); + + /* drawing ---------- */ void GPENCIL_OT_draw(struct wmOperatorType *ot); +void GPENCIL_OT_fill(struct wmOperatorType *ot); /* Paint Modes for operator */ typedef enum eGPencil_PaintModes { @@ -160,7 +285,11 @@ typedef enum eGPencil_PaintModes { /* stroke editing ----- */ void GPENCIL_OT_editmode_toggle(struct wmOperatorType *ot); +void GPENCIL_OT_paintmode_toggle(struct wmOperatorType *ot); +void GPENCIL_OT_sculptmode_toggle(struct wmOperatorType *ot); +void GPENCIL_OT_weightmode_toggle(struct wmOperatorType *ot); void GPENCIL_OT_selection_opacity_toggle(struct wmOperatorType *ot); +void GPENCIL_OT_multiedit_toggle(struct wmOperatorType *ot); void GPENCIL_OT_select(struct wmOperatorType *ot); void GPENCIL_OT_select_all(struct wmOperatorType *ot); @@ -174,6 +303,7 @@ void GPENCIL_OT_select_more(struct wmOperatorType *ot); void GPENCIL_OT_select_less(struct wmOperatorType *ot); void GPENCIL_OT_select_first(struct wmOperatorType *ot); void GPENCIL_OT_select_last(struct wmOperatorType *ot); +void GPENCIL_OT_select_alternate(struct wmOperatorType *ot); void GPENCIL_OT_duplicate(struct wmOperatorType *ot); void GPENCIL_OT_delete(struct wmOperatorType *ot); @@ -218,6 +348,8 @@ void GPENCIL_OT_blank_frame_add(struct wmOperatorType *ot); void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot); void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot); +void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot); +void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot); void GPENCIL_OT_convert(struct wmOperatorType *ot); @@ -226,6 +358,13 @@ enum { GP_STROKE_JOINCOPY = 1 }; +enum { + GP_STROKE_BOX = -1, + GP_STROKE_LINE = 1, + GP_STROKE_CIRCLE = 2 +}; + + void GPENCIL_OT_stroke_arrange(struct wmOperatorType *ot); void GPENCIL_OT_stroke_change_color(struct wmOperatorType *ot); void GPENCIL_OT_stroke_lock_color(struct wmOperatorType *ot); @@ -234,30 +373,15 @@ void GPENCIL_OT_stroke_cyclical_set(struct wmOperatorType *ot); void GPENCIL_OT_stroke_join(struct wmOperatorType *ot); void GPENCIL_OT_stroke_flip(struct wmOperatorType *ot); void GPENCIL_OT_stroke_subdivide(struct wmOperatorType *ot); +void GPENCIL_OT_stroke_simplify(struct wmOperatorType *ot); +void GPENCIL_OT_stroke_simplify_fixed(struct wmOperatorType *ot); +void GPENCIL_OT_stroke_separate(struct wmOperatorType *ot); +void GPENCIL_OT_stroke_split(struct wmOperatorType *ot); -void GPENCIL_OT_brush_add(struct wmOperatorType *ot); -void GPENCIL_OT_brush_remove(struct wmOperatorType *ot); -void GPENCIL_OT_brush_change(struct wmOperatorType *ot); -void GPENCIL_OT_brush_move(struct wmOperatorType *ot); void GPENCIL_OT_brush_presets_create(struct wmOperatorType *ot); -void GPENCIL_OT_brush_copy(struct wmOperatorType *ot); void GPENCIL_OT_brush_select(struct wmOperatorType *ot); -void GPENCIL_OT_palette_add(struct wmOperatorType *ot); -void GPENCIL_OT_palette_remove(struct wmOperatorType *ot); -void GPENCIL_OT_palette_change(struct wmOperatorType *ot); -void GPENCIL_OT_palette_lock_layer(struct wmOperatorType *ot); - -void GPENCIL_OT_palettecolor_add(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_remove(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_isolate(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_hide(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_reveal(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_lock_all(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_unlock_all(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_move(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_select(struct wmOperatorType *ot); -void GPENCIL_OT_palettecolor_copy(struct wmOperatorType *ot); +void GPENCIL_OT_sculpt_select(struct wmOperatorType *ot); /* undo stack ---------- */ @@ -271,6 +395,30 @@ void GPENCIL_OT_interpolate(struct wmOperatorType *ot); void GPENCIL_OT_interpolate_sequence(struct wmOperatorType *ot); void GPENCIL_OT_interpolate_reverse(struct wmOperatorType *ot); +/* primitives ---------- */ + +void GPENCIL_OT_primitive(struct wmOperatorType *ot); + +/* vertex groups ------------ */ +void GPENCIL_OT_vertex_group_assign(struct wmOperatorType *ot); +void GPENCIL_OT_vertex_group_remove_from(struct wmOperatorType *ot); +void GPENCIL_OT_vertex_group_select(struct wmOperatorType *ot); +void GPENCIL_OT_vertex_group_deselect(struct wmOperatorType *ot); +void GPENCIL_OT_vertex_group_invert(struct wmOperatorType *ot); +void GPENCIL_OT_vertex_group_smooth(struct wmOperatorType *ot); + +/* color handle */ +void GPENCIL_OT_lock_layer(struct wmOperatorType *ot); +void GPENCIL_OT_color_isolate(struct wmOperatorType *ot); +void GPENCIL_OT_color_hide(struct wmOperatorType *ot); +void GPENCIL_OT_color_reveal(struct wmOperatorType *ot); +void GPENCIL_OT_color_lock_all(struct wmOperatorType *ot); +void GPENCIL_OT_color_unlock_all(struct wmOperatorType *ot); +void GPENCIL_OT_color_select(struct wmOperatorType *ot); + +/* convert old 2.7 files to 2.8 */ +void GPENCIL_OT_convert_old_files(struct wmOperatorType *ot); + /* ****************************************************** */ /* FILTERED ACTION DATA - TYPES ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */ @@ -331,24 +479,37 @@ typedef enum ACTCONT_TYPES { */ #define GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) \ { \ + Depsgraph *depsgraph_ = CTX_data_depsgraph(C); \ + Object *obact_ = CTX_data_active_object(C); \ + bGPdata *gpd_ = CTX_data_gpencil_data(C); \ + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_); \ CTX_DATA_BEGIN(C, bGPDlayer*, gpl, editable_gpencil_layers) \ { \ - if (gpl->actframe == NULL) \ - continue; \ - /* calculate difference matrix if parent object */ \ - float diff_mat[4][4]; \ - ED_gpencil_parent_location(gpl, diff_mat); \ - /* loop over strokes */ \ - for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { \ - /* skip strokes that are invalid for current view */ \ - if (ED_gpencil_stroke_can_use(C, gps) == false) \ - continue; \ - /* check if the color is editable */ \ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) \ - continue; \ - /* ... Do Stuff With Strokes ... */ + bGPDframe *init_gpf = gpl->actframe; \ + if (is_multiedit) { \ + init_gpf = gpl->frames.first; \ + } \ + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { \ + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { \ + /* calculate difference matrix */ \ + float diff_mat[4][4]; \ + ED_gpencil_parent_location(depsgraph_, obact_, gpd_, gpl, diff_mat); \ + /* loop over strokes */ \ + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { \ + /* skip strokes that are invalid for current view */ \ + if (ED_gpencil_stroke_can_use(C, gps) == false) \ + continue; \ + /* check if the color is editable */ \ + if (ED_gpencil_stroke_color_use(obact_, gpl, gps) == false) \ + continue; \ + /* ... Do Stuff With Strokes ... */ #define GP_EDITABLE_STROKES_END \ + } \ + } \ + if (!is_multiedit) { \ + break; \ + } \ } \ } \ CTX_DATA_END; \ diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index cc30d7ec266..6541e9f012a 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -47,6 +47,7 @@ #include "DNA_color_types.h" #include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -60,6 +61,7 @@ #include "BKE_library.h" #include "BKE_report.h" #include "BKE_screen.h" +#include "BKE_deform.h" #include "UI_interface.h" #include "UI_resources.h" @@ -79,6 +81,9 @@ #include "ED_view3d.h" #include "ED_space_api.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "gpencil_intern.h" /* ************************************************ */ @@ -108,11 +113,13 @@ static bool gpencil_view3d_poll(bContext *C) static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_to, bGPDstroke *new_stroke, float factor) { bGPDspoint *prev, *pt, *next; + MDeformVert *dvert; /* update points */ for (int i = 0; i < new_stroke->totpoints; i++) { prev = &gps_from->points[i]; pt = &new_stroke->points[i]; + dvert = &new_stroke->dvert[i]; next = &gps_to->points[i]; /* Interpolate all values */ @@ -120,6 +127,9 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor); pt->strength = interpf(prev->strength, next->strength, 1.0f - factor); CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); + + dvert->totweight = 0; + dvert->dw = NULL; } } @@ -128,6 +138,7 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t /* Helper: Update all strokes interpolated */ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) { + bGPdata *gpd = tgpi->gpd; tGPDinterpolate_layer *tgpil; const float shift = tgpi->shift; @@ -156,12 +167,14 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) } } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); } /* Helper: Verify valid strokes for interpolation */ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) { + Object *ob = CTX_data_active_object(C); ToolSettings *ts = CTX_data_tool_settings(C); eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag; @@ -190,7 +203,7 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) { continue; } @@ -213,6 +226,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) bGPdata *gpd = tgpi->gpd; bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); bGPDframe *actframe = active_gpl->actframe; + Object *ob = CTX_data_active_object(C); /* save initial factor for active layer to define shift limits */ tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1); @@ -255,7 +269,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) bGPDstroke *gps_to; int fFrame; - bGPDstroke *new_stroke; + bGPDstroke *new_stroke = NULL; bool valid = true; @@ -269,7 +283,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(tgpil->gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) { valid = false; } @@ -281,16 +295,13 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) } /* create new stroke */ - new_stroke = MEM_dupallocN(gps_from); - new_stroke->points = MEM_dupallocN(gps_from->points); - new_stroke->triangles = MEM_dupallocN(gps_from->triangles); - new_stroke->tot_triangles = 0; - new_stroke->flag |= GP_STROKE_RECALC_CACHES; + new_stroke = BKE_gpencil_stroke_duplicate(gps_from); if (valid) { /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints); new_stroke->totpoints = gps_to->totpoints; new_stroke->tot_triangles = 0; new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -302,6 +313,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) /* need an empty stroke to keep index correct for lookup, but resize to smallest size */ new_stroke->totpoints = 0; new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points)); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert)); new_stroke->tot_triangles = 0; new_stroke->triangles = MEM_recallocN(new_stroke->triangles, sizeof(*new_stroke->triangles)); new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -317,17 +329,17 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) /* Drawing Callbacks */ /* Drawing callback for modal operator in screen mode */ -static void gpencil_interpolate_draw_screen(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) +static void gpencil_interpolate_draw_screen(const struct bContext *C, ARegion *UNUSED(ar), void *arg) { tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_PIXEL); + ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_PIXEL); } /* Drawing callback for modal operator in 3d mode */ -static void gpencil_interpolate_draw_3d(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) +static void gpencil_interpolate_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg) { tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_VIEW); + ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_VIEW); } /* ----------------------- */ @@ -392,6 +404,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op) { tGPDinterpolate *tgpi = op->customdata; tGPDinterpolate_layer *tgpil; + bGPdata *gpd = tgpi->gpd; /* don't assume that operator data exists at all */ if (tgpi) { @@ -416,6 +429,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op) BLI_freelistN(&tgpi->ilayers); MEM_freeN(tgpi); } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* clear pointer */ @@ -483,9 +497,10 @@ static int gpencil_interpolate_init(bContext *C, wmOperator *op) static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { wmWindow *win = CTX_wm_window(C); - Scene *scene = CTX_data_scene(C); bGPdata *gpd = CTX_data_gpencil_data(C); bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); bGPDframe *actframe = gpl->actframe; tGPDinterpolate *tgpi = NULL; @@ -496,7 +511,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent } /* cannot interpolate in extremes */ - if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) { + if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) { BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames"); return OPERATOR_CANCELLED; } @@ -529,6 +544,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent /* update shift indicator in header */ gpencil_interpolate_status_indicators(C, tgpi); + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* add a modal handler for this operator */ @@ -571,6 +587,8 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent /* make copy of source stroke, then adjust pointer to points too */ gps_dst = MEM_dupallocN(gps_src); gps_dst->points = MEM_dupallocN(gps_src->points); + gps_dst->dvert = MEM_dupallocN(gps_src->dvert); + BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); gps_dst->triangles = MEM_dupallocN(gps_src->triangles); gps_dst->flag |= GP_STROKE_RECALC_CACHES; BLI_addtail(&gpf_dst->strokes, gps_dst); @@ -902,8 +920,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); bGPDframe *actframe = active_gpl->actframe; - Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate; eGP_Interpolate_SettingsFlag flag = ipo_settings->flag; @@ -913,7 +934,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* cannot interpolate in extremes */ - if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) { + if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) { BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames"); return OPERATOR_CANCELLED; } @@ -961,7 +982,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) /* create new strokes data with interpolated points reading original stroke */ for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { - bGPDstroke *new_stroke; + bGPDstroke *new_stroke = NULL; /* only selected */ if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { @@ -972,7 +993,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) { continue; } @@ -990,15 +1011,15 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* create new stroke */ - new_stroke = MEM_dupallocN(gps_from); - new_stroke->points = MEM_dupallocN(gps_from->points); - new_stroke->triangles = MEM_dupallocN(gps_from->triangles); - new_stroke->tot_triangles = 0; - new_stroke->flag |= GP_STROKE_RECALC_CACHES; + new_stroke = BKE_gpencil_stroke_duplicate(gps_from); /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { + /* free weights of removed points */ + BKE_defvert_array_free_elems(gps_from->dvert + gps_to->totpoints, gps_from->totpoints - gps_to->totpoints); + new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints); new_stroke->totpoints = gps_to->totpoints; new_stroke->tot_triangles = 0; new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -1014,6 +1035,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -1055,6 +1077,8 @@ static bool gpencil_interpolate_reverse_poll(bContext *C) static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op)) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* Go through each layer, deleting the breakdowns around the current frame, * but only if there is a keyframe nearby to stop at */ @@ -1123,6 +1147,7 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/gpencil/gpencil_old.c b/source/blender/editors/gpencil/gpencil_old.c new file mode 100644 index 00000000000..b7af1c80d4c --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_old.c @@ -0,0 +1,219 @@ +/* + * ***** 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) 2018, Blender Foundation, + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + * Use deprecated data to convert old 2.7x files + */ + +/** \file blender/editors/gpencil/gpencil_old.c + * \ingroup edgpencil + */ + + /* allow to use deprecated functionality */ +#define DNA_DEPRECATED_ALLOW + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_main.h" +#include "BKE_brush.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_object.h" +#include "BKE_material.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_object.h" +#include "ED_gpencil.h" + +#include "gpencil_intern.h" + + /* Free all of a gp-colors */ +static void free_gpencil_colors(bGPDpalette *palette) +{ + /* error checking */ + if (palette == NULL) { + return; + } + + /* free colors */ + BLI_freelistN(&palette->colors); +} + +/* Free all of the gp-palettes and colors */ +static void free_palettes(ListBase *list) +{ + bGPDpalette *palette_next; + + /* error checking */ + if (list == NULL) { + return; + } + + /* delete palettes */ + for (bGPDpalette *palette = list->first; palette; palette = palette_next) { + palette_next = palette->next; + /* free palette colors */ + free_gpencil_colors(palette); + + MEM_freeN(palette); + } + BLI_listbase_clear(list); +} + +/* ***************** Convert old 2.7 files to 2.8 ************************ */ +static bool gpencil_convert_old_files_poll(bContext *C) +{ + Scene *scene = CTX_data_scene(C); + + return (int) (scene->gpd != NULL); +} + +static int gpencil_convert_old_files_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + /* Convert grease pencil scene datablock to GP object */ + if ((scene->gpd) && (view_layer != NULL)) { + Object *ob; + ob = BKE_object_add_for_data(bmain, view_layer, OB_GPENCIL, "GP_Scene", &scene->gpd->id, false); + zero_v3(ob->loc); + + Paint *paint = BKE_brush_get_gpencil_paint(ts); + /* if not exist, create a new one */ + if (paint->brush == NULL) { + /* create new brushes */ + BKE_brush_gpencil_presets(C); + } + + /* convert grease pencil palettes (version >= 2.78) to materials and weights */ + bGPdata *gpd = scene->gpd; + for (const bGPDpalette *palette = gpd->palettes.first; palette; palette = palette->next) { + for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) { + + /* create material slot */ + BKE_object_material_slot_add(bmain, ob); + Material *ma = BKE_material_add_gpencil(bmain, palcolor->info); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + + /* copy color settings */ + MaterialGPencilStyle *gp_style = ma->gp_style; + copy_v4_v4(gp_style->stroke_rgba, palcolor->color); + copy_v4_v4(gp_style->fill_rgba, palcolor->fill); + gp_style->flag = palcolor->flag; + + /* fix strokes */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + if ((gps->colorname[0] != '\0') && + (STREQ(gps->colorname, palcolor->info))) + { + gps->mat_nr = ob->totcol - 1; + gps->colorname[0] = '\0'; + /* create weights array */ + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); + } + } + } + } + } + } + + /* free palettes */ + free_palettes(&gpd->palettes); + + /* disable all GP modes */ + ED_gpencil_setup_modes(C, gpd, 0); + + /* set cache as dirty */ + BKE_gpencil_batch_cache_dirty(ob->data); + + scene->gpd = NULL; + } + +#if 0 /* GPXX */ + /* Handle object-linked grease pencil datablocks */ + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->gpd) { + if (ob->type == OB_GPENCIL) { + /* GP Object - remap the links */ + ob->data = ob->gpd; + ob->gpd = NULL; + } + else if (ob->type == OB_EMPTY) { + /* Empty with GP data - This should be able to be converted + * to a GP object with little data loss + */ + ob->data = ob->gpd; + ob->gpd = NULL; + ob->type = OB_GPENCIL; + } + else { + /* FIXME: What to do in this case? + * + * We cannot create new objects for these, as we don't have a scene & scene layer + * to put them into from here... + */ + printf("WARNING: Old Grease Pencil data ('%s') still exists on Object '%s'\n", + ob->gpd->id.name + 2, ob->id.name + 2); + } + } + } +#endif + + /* notifiers */ + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_convert_old_files(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Convert 2.7 Grease Pencil File"; + ot->idname = "GPENCIL_OT_convert_old_files"; + ot->description = "Convert 2.7x grease pencil files to 2.8"; + + /* callbacks */ + ot->exec = gpencil_convert_old_files_exec; + ot->poll = gpencil_convert_old_files_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 3f114a4dd4a..991bfb622b7 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -35,8 +35,14 @@ #include "BLI_sys_types.h" #include "BKE_context.h" +#include "BKE_brush.h" +#include "BKE_gpencil.h" +#include "DNA_brush_types.h" #include "DNA_gpencil_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "WM_api.h" #include "WM_types.h" @@ -52,7 +58,7 @@ /* ****************************************** */ /* Grease Pencil Keymaps */ -/* Generic Drawing Keymap */ +/* Generic Drawing Keymap - Annotations */ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf) { wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil", 0, 0); @@ -60,36 +66,22 @@ static void ed_keymap_gpencil_general(wmKeyConfig *keyconf) /* Draw --------------------------------------- */ /* draw */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, 0, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); RNA_boolean_set(kmi->ptr, "wait_for_input", false); /* draw - straight lines */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, KM_ALT, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT); RNA_boolean_set(kmi->ptr, "wait_for_input", false); /* draw - poly lines */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY); RNA_boolean_set(kmi->ptr, "wait_for_input", false); /* erase */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY); - RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); - RNA_boolean_set(kmi->ptr, "wait_for_input", false); - - /* Tablet Mappings for Drawing ------------------ */ - /* For now, only support direct drawing using the eraser, as most users using a tablet - * may still want to use that as their primary pointing device! - */ -#if 0 - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_STYLUS, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); - RNA_boolean_set(kmi->ptr, "wait_for_input", false); -#endif - - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_annotate", RIGHTMOUSE, KM_PRESS, 0, DKEY); RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); RNA_boolean_set(kmi->ptr, "wait_for_input", false); @@ -121,67 +113,85 @@ static bool gp_stroke_editmode_poll(bContext *C) return (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE)); } -/* Stroke Editing Keymap - Only when editmode is enabled */ -static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) +/* Poll callback for stroke painting mode */ +static bool gp_stroke_paintmode_poll(bContext *C) { - wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0); - wmKeyMapItem *kmi; - - /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */ - keymap->poll = gp_stroke_editmode_poll; - - /* ----------------------------------------------- */ - - /* Exit EditMode */ - WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0); - - /* Pie Menu - For settings/tools easy access */ - WM_keymap_add_menu_pie(keymap, "GPENCIL_MT_pie_sculpt", EKEY, KM_PRESS, 0, DKEY); - - /* Brush Settings */ - /* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys - * in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain - * that the only data being edited is that of the Grease Pencil strokes - */ - - /* CTRL + FKEY = Eraser Radius */ - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0); - RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius"); - - /* Interpolation */ - WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate", EKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); - WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate_sequence", EKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); + /* TODO: limit this to mode, but review 2D editors */ + bGPdata *gpd = CTX_data_gpencil_data(C); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE)); +} - /* Sculpting ------------------------------------- */ +/* Poll callback for stroke painting (draw brush) */ +static bool gp_stroke_paintmode_draw_poll(bContext *C) +{ + /* TODO: limit this to mode, but review 2D editors */ + bGPdata *gpd = CTX_data_gpencil_data(C); + ToolSettings *ts = CTX_data_tool_settings(C); + Brush *brush = BKE_brush_getactive_gpencil(ts); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) + && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)); +} - /* Brush-Based Editing: - * EKEY + LMB = Single stroke, draw immediately - * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc. - * - * For the modal version, use D+E -> Sculpt - */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, EKEY); - RNA_boolean_set(kmi->ptr, "wait_for_input", false); +/* Poll callback for stroke painting (erase brush) */ +static bool gp_stroke_paintmode_erase_poll(bContext *C) +{ + /* TODO: limit this to mode, but review 2D editors */ + bGPdata *gpd = CTX_data_gpencil_data(C); + ToolSettings *ts = CTX_data_tool_settings(C); + Brush *brush = BKE_brush_getactive_gpencil(ts); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) + && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)); +} - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, EKEY); - RNA_boolean_set(kmi->ptr, "wait_for_input", false); - /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/ +/* Poll callback for stroke painting (fill) */ +static bool gp_stroke_paintmode_fill_poll(bContext *C) +{ + /* TODO: limit this to mode, but review 2D editors */ + bGPdata *gpd = CTX_data_gpencil_data(C); + ToolSettings *ts = CTX_data_tool_settings(C); + Brush *brush = BKE_brush_getactive_gpencil(ts); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) + && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_FILL)); +} - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, EKEY); - RNA_boolean_set(kmi->ptr, "wait_for_input", false); - /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/ +/* Poll callback for stroke sculpting mode */ +static bool gp_stroke_sculptmode_poll(bContext *C) +{ + bGPdata *gpd = CTX_data_gpencil_data(C); + Object *ob = CTX_data_active_object(C); + ScrArea *sa = CTX_wm_area(C); + + /* if not gpencil object and not view3d, need sculpt keys if edit mode */ + if (sa->spacetype != SPACE_VIEW3D) { + return ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)); + } + else { + /* weight paint is a submode of sculpt */ + if ((ob) && (ob->type == OB_GPENCIL)) { + return GPENCIL_SCULPT_OR_WEIGHT_MODE(gpd); + } + } + + return 0; +} +/* Poll callback for stroke weight paint mode */ +static bool gp_stroke_weightmode_poll(bContext *C) +{ + bGPdata *gpd = CTX_data_gpencil_data(C); + Object *ob = CTX_data_active_object(C); - /* Shift-FKEY = Sculpt Strength */ - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength"); + if ((ob) && (ob->type == OB_GPENCIL)) { + return (gpd && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE)); + } - /* FKEY = Sculpt Brush Size */ - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size"); + return 0; +} +static void ed_keymap_gpencil_selection(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; - /* Selection ------------------------------------- */ /* select all */ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", AKEY, KM_PRESS, 0, 0); RNA_enum_set(kmi->ptr, "action", SEL_SELECT); @@ -204,17 +214,14 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "deselect", true); /* In the Node Editor, lasso select needs ALT modifier too (as somehow CTRL+LMB drag gets taken for "cut" quite early) - * There probably isn't too much harm adding this for other editors too as part of standard GP editing keymap. This hotkey - * combo doesn't seem to see much use under standard scenarios? - */ + * There probably isn't too much harm adding this for other editors too as part of standard GP editing keymap. This hotkey + * combo doesn't seem to see much use under standard scenarios? + */ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", false); kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", true); - /* normal select */ - WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", true); RNA_boolean_set(kmi->ptr, "toggle", true); @@ -223,11 +230,18 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "entire_strokes", true); + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT | KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "entire_strokes", true); + RNA_boolean_set(kmi->ptr, "extend", true); + /* select linked */ /* NOTE: While LKEY is redundant, not having it breaks the mode illusion too much */ WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); + /* select alternate */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_alternate", LKEY, KM_PRESS, KM_SHIFT, 0); + /* select grouped */ WM_keymap_add_item(keymap, "GPENCIL_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); @@ -235,6 +249,102 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); +} + +static void ed_keymap_gpencil_sculpt(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + /* Pie Menu - For settings/tools easy access */ + WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_sculpt", EKEY, KM_PRESS, 0, DKEY); + + /* Sculpting ------------------------------------- */ + + /* Brush-Based Editing: + * EKEY + LMB = Single stroke, draw immediately + * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc. + * + * For the modal version, use D+E -> Sculpt + */ + /* GPXX: disabled to make toolsystem works */ + //kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, 0); + //RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + RNA_boolean_set(kmi->ptr, "keep_brush", true); + /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/ + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + RNA_boolean_set(kmi->ptr, "keep_brush", true); + /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/ + + /* Shift-FKEY = Sculpt Strength */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.strength"); + + /* FKEY = Sculpt Brush Size */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size"); + + /* menu sculpt specials */ + WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_sculpt_specials", WKEY, KM_PRESS, 0, 0); +} + +static void ed_keymap_gpencil_weight(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + + /* Brush-Based Editing: + * EKEY + LMB = Single stroke, draw immediately + * + Other Modifiers (Ctrl/Shift) = Invert, Smooth, etc. + * + * For the modal version, use D+E -> Sculpt + */ + /* GPXX: disabled to make toolsystem works */ + //kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, 0, 0); + //RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + RNA_boolean_set(kmi->ptr, "keep_brush", true); + /*RNA_boolean_set(kmi->ptr, "use_invert", true);*/ + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_paint", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + RNA_boolean_set(kmi->ptr, "keep_brush", true); + /*RNA_boolean_set(kmi->ptr, "use_smooth", true);*/ +} + +/* Stroke Editing Keymap - Only when editmode is enabled */ +static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */ + keymap->poll = gp_stroke_editmode_poll; + + /* ----------------------------------------------- */ + + /* Brush Settings */ + /* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys + * in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain + * that the only data being edited is that of the Grease Pencil strokes + */ + + /* Interpolation */ + WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate", EKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); + WM_keymap_add_item(keymap, "GPENCIL_OT_interpolate_sequence", EKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); + + /* normal select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + + /* Selection */ + ed_keymap_gpencil_selection(keymap); + /* Editing ----------------------------------------- */ /* duplicate and move selected points */ @@ -253,6 +363,12 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) /* menu edit specials */ WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0); + /* menu separate */ + WM_keymap_add_menu(keymap, "GPENCIL_MT_separate", PKEY, KM_PRESS, 0, 0); + + /* split strokes */ + WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_split", VKEY, KM_PRESS, 0, 0); + /* join strokes */ WM_keymap_add_item(keymap, "GPENCIL_OT_stroke_join", JKEY, KM_PRESS, KM_CTRL, 0); @@ -271,7 +387,6 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) /* snap */ WM_keymap_add_menu(keymap, "GPENCIL_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); - /* convert to geometry */ WM_keymap_add_item(keymap, "GPENCIL_OT_convert", CKEY, KM_PRESS, KM_ALT, 0); @@ -288,6 +403,13 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0); + /* toogle multiedit support */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); + /* Isolate Layer */ WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0); @@ -317,28 +439,246 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) /* Proportional Editing */ ED_keymap_proportional_cycle(keyconf, keymap); ED_keymap_proportional_editmode(keyconf, keymap, true); + + /* menu - add GP object (3d view only) */ + WM_keymap_add_item(keymap, "OBJECT_OT_gpencil_add", AKEY, KM_PRESS, KM_SHIFT, 0); + + /* menu vertex group */ + WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_vertex_group", GKEY, KM_PRESS, KM_CTRL, 0); + + /* toggle edit mode */ + WM_keymap_add_item(keymap, "GPENCIL_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0); +} + +/* keys for draw with a drawing brush (no fill) */ +static void ed_keymap_gpencil_painting_draw(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback */ + keymap->poll = gp_stroke_paintmode_draw_poll; + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* draw - straight lines */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* draw - poly lines */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* erase */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* Tablet Mappings for Drawing ------------------ */ + /* For now, only support direct drawing using the eraser, as most users using a tablet + * may still want to use that as their primary pointing device! + */ +#if 0 + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_STYLUS, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); +#endif + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* Selection (used by eraser) */ + /* border select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0); + + /* lasso select */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", false); +} + +/* keys for draw with a eraser brush (erase) */ +static void ed_keymap_gpencil_painting_erase(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Erase)", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback */ + keymap->poll = gp_stroke_paintmode_erase_poll; + + /* erase */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", TABLET_ERASER, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + + /* Selection (used by eraser) */ + /* border select */ + WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0); + + /* lasso select */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", false); +} + +/* keys for draw with a fill brush */ +static void ed_keymap_gpencil_painting_fill(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint (Fill)", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback */ + keymap->poll = gp_stroke_paintmode_fill_poll; + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_fill", LEFTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "on_back", false); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_fill", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "on_back", true); + + /* if press alternative key, the brush now it's for drawing areas */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + /* disable straight lines */ + RNA_boolean_set(kmi->ptr, "disable_straight", true); + + /* if press alternative key, the brush now it's for drawing lines */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW); + RNA_boolean_set(kmi->ptr, "wait_for_input", false); + /* disable straight lines */ + RNA_boolean_set(kmi->ptr, "disable_straight", true); + /* enable special stroke with no fill flag */ + RNA_boolean_set(kmi->ptr, "disable_fill", true); +} + +/* Stroke Painting Keymap - Only when paintmode is enabled */ +static void ed_keymap_gpencil_painting(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Paint Mode", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback - so that this keymap only gets enabled when stroke paintmode is enabled */ + keymap->poll = gp_stroke_paintmode_poll; + + /* FKEY = Brush Size */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_paint.brush.size"); + + /* CTRL + FKEY = Eraser Radius */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius"); + + /* menu draw specials */ + WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_specials", WKEY, KM_PRESS, 0, 0); + + /* menu draw delete */ + WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_draw_delete", XKEY, KM_PRESS, 0, 0); + } +/* Stroke Sculpting Keymap - Only when sculptmode is enabled */ +static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Sculpt Mode", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */ + keymap->poll = gp_stroke_sculptmode_poll; + + /* Selection */ + ed_keymap_gpencil_selection(keymap); + + /* sculpt */ + ed_keymap_gpencil_sculpt(keymap); + + /* toogle multiedit support */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); + +} + +/* Stroke Weight Paint Keymap - Only when weight is enabled */ +static void ed_keymap_gpencil_weightpainting(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Weight Mode", 0, 0); + wmKeyMapItem *kmi; + + /* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */ + keymap->poll = gp_stroke_weightmode_poll; + + /* Selection */ + ed_keymap_gpencil_selection(keymap); + + /* sculpt */ + ed_keymap_gpencil_weight(keymap); + + /* Shift-FKEY = Sculpt Strength */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.strength"); + + /* FKEY = Sculpt Brush Size */ + kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.size"); + + /* toogle multiedit support */ + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); + + kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); + +} /* ==================== */ void ED_keymap_gpencil(wmKeyConfig *keyconf) { ed_keymap_gpencil_general(keyconf); ed_keymap_gpencil_editing(keyconf); + ed_keymap_gpencil_painting(keyconf); + ed_keymap_gpencil_painting_draw(keyconf); + ed_keymap_gpencil_painting_erase(keyconf); + ed_keymap_gpencil_painting_fill(keyconf); + ed_keymap_gpencil_sculpting(keyconf); + ed_keymap_gpencil_weightpainting(keyconf); } /* ****************************************** */ void ED_operatortypes_gpencil(void) { + /* Annotations -------------------- */ + + WM_operatortype_append(GPENCIL_OT_annotate); + /* Drawing ----------------------- */ WM_operatortype_append(GPENCIL_OT_draw); + WM_operatortype_append(GPENCIL_OT_fill); /* Editing (Strokes) ------------ */ WM_operatortype_append(GPENCIL_OT_editmode_toggle); + WM_operatortype_append(GPENCIL_OT_paintmode_toggle); + WM_operatortype_append(GPENCIL_OT_sculptmode_toggle); + WM_operatortype_append(GPENCIL_OT_weightmode_toggle); WM_operatortype_append(GPENCIL_OT_selection_opacity_toggle); + WM_operatortype_append(GPENCIL_OT_multiedit_toggle); WM_operatortype_append(GPENCIL_OT_select); WM_operatortype_append(GPENCIL_OT_select_all); @@ -352,6 +692,7 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_select_less); WM_operatortype_append(GPENCIL_OT_select_first); WM_operatortype_append(GPENCIL_OT_select_last); + WM_operatortype_append(GPENCIL_OT_select_alternate); WM_operatortype_append(GPENCIL_OT_duplicate); WM_operatortype_append(GPENCIL_OT_delete); @@ -391,6 +732,8 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_active_frame_delete); WM_operatortype_append(GPENCIL_OT_active_frames_delete_all); + WM_operatortype_append(GPENCIL_OT_frame_duplicate); + WM_operatortype_append(GPENCIL_OT_frame_clean_fill); WM_operatortype_append(GPENCIL_OT_convert); @@ -402,36 +745,46 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_stroke_join); WM_operatortype_append(GPENCIL_OT_stroke_flip); WM_operatortype_append(GPENCIL_OT_stroke_subdivide); + WM_operatortype_append(GPENCIL_OT_stroke_simplify); + WM_operatortype_append(GPENCIL_OT_stroke_simplify_fixed); + WM_operatortype_append(GPENCIL_OT_stroke_separate); + WM_operatortype_append(GPENCIL_OT_stroke_split); - WM_operatortype_append(GPENCIL_OT_palette_add); - WM_operatortype_append(GPENCIL_OT_palette_remove); - WM_operatortype_append(GPENCIL_OT_palette_change); - WM_operatortype_append(GPENCIL_OT_palette_lock_layer); - WM_operatortype_append(GPENCIL_OT_palettecolor_add); - WM_operatortype_append(GPENCIL_OT_palettecolor_remove); - WM_operatortype_append(GPENCIL_OT_palettecolor_isolate); - WM_operatortype_append(GPENCIL_OT_palettecolor_hide); - WM_operatortype_append(GPENCIL_OT_palettecolor_reveal); - WM_operatortype_append(GPENCIL_OT_palettecolor_lock_all); - WM_operatortype_append(GPENCIL_OT_palettecolor_unlock_all); - WM_operatortype_append(GPENCIL_OT_palettecolor_move); - WM_operatortype_append(GPENCIL_OT_palettecolor_select); - WM_operatortype_append(GPENCIL_OT_palettecolor_copy); - - WM_operatortype_append(GPENCIL_OT_brush_add); - WM_operatortype_append(GPENCIL_OT_brush_remove); - WM_operatortype_append(GPENCIL_OT_brush_change); - WM_operatortype_append(GPENCIL_OT_brush_move); WM_operatortype_append(GPENCIL_OT_brush_presets_create); - WM_operatortype_append(GPENCIL_OT_brush_copy); WM_operatortype_append(GPENCIL_OT_brush_select); + WM_operatortype_append(GPENCIL_OT_sculpt_select); + + /* vertex groups */ + WM_operatortype_append(GPENCIL_OT_vertex_group_assign); + WM_operatortype_append(GPENCIL_OT_vertex_group_remove_from); + WM_operatortype_append(GPENCIL_OT_vertex_group_select); + WM_operatortype_append(GPENCIL_OT_vertex_group_deselect); + WM_operatortype_append(GPENCIL_OT_vertex_group_invert); + WM_operatortype_append(GPENCIL_OT_vertex_group_smooth); + + /* color handle */ + WM_operatortype_append(GPENCIL_OT_lock_layer); + WM_operatortype_append(GPENCIL_OT_color_isolate); + WM_operatortype_append(GPENCIL_OT_color_hide); + WM_operatortype_append(GPENCIL_OT_color_reveal); + WM_operatortype_append(GPENCIL_OT_color_lock_all); + WM_operatortype_append(GPENCIL_OT_color_unlock_all); + WM_operatortype_append(GPENCIL_OT_color_select); + /* Editing (Time) --------------- */ /* Interpolation */ WM_operatortype_append(GPENCIL_OT_interpolate); WM_operatortype_append(GPENCIL_OT_interpolate_sequence); WM_operatortype_append(GPENCIL_OT_interpolate_reverse); + + /* Primitives */ + WM_operatortype_append(GPENCIL_OT_primitive); + + /* convert old 2.7 files to 2.8 */ + WM_operatortype_append(GPENCIL_OT_convert_old_files); + } void ED_operatormacros_gpencil(void) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 789e9865ae4..995ab91ff8b 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -46,26 +46,34 @@ #include "PIL_time.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_material_types.h" +#include "DNA_brush_types.h" +#include "DNA_windowmanager_types.h" + #include "BKE_colortools.h" +#include "BKE_main.h" +#include "BKE_brush.h" +#include "BKE_paint.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_main.h" #include "BKE_paint.h" #include "BKE_report.h" +#include "BKE_layer.h" +#include "BKE_material.h" #include "BKE_screen.h" #include "BKE_tracking.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_gpencil_types.h" -#include "DNA_brush_types.h" -#include "DNA_windowmanager_types.h" - #include "UI_view2d.h" #include "ED_gpencil.h" #include "ED_screen.h" +#include "ED_object.h" #include "ED_view3d.h" #include "ED_clip.h" @@ -82,6 +90,7 @@ #include "WM_types.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "gpencil_intern.h" @@ -110,6 +119,8 @@ typedef enum eGPencil_PaintFlags { GP_PAINTFLAG_STROKEADDED = (1 << 1), GP_PAINTFLAG_V3D_ERASER_DEPTH = (1 << 2), GP_PAINTFLAG_SELECTMASK = (1 << 3), + GP_PAINTFLAG_HARD_ERASER = (1 << 4), + GP_PAINTFLAG_STROKE_ERASER = (1 << 5), } eGPencil_PaintFlags; @@ -117,10 +128,13 @@ typedef enum eGPencil_PaintFlags { * "p" = op->customdata */ typedef struct tGPsdata { - Main *bmain; + bContext *C; + + Main *bmain; /* main database pointer */ Scene *scene; /* current scene from context */ struct Depsgraph *depsgraph; + Object *ob; /* current object */ wmWindow *win; /* window where painting originated */ ScrArea *sa; /* area where painting originated */ ARegion *ar; /* region where painting originated */ @@ -165,14 +179,23 @@ typedef struct tGPsdata { void *erasercursor; /* radial cursor data for drawing eraser */ - bGPDpalettecolor *palettecolor; /* current palette color */ - bGPDbrush *brush; /* current drawing brush */ + /* mat settings are only used for 3D view */ + Material *material; /* current material */ + + Brush *brush; /* current drawing brush */ + Brush *eraser; /* default eraser brush */ short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */ int lock_axis; /* lock drawing to one axis */ + bool disable_fill; /* the stroke is no fill mode */ RNG *rng; short keymodifier; /* key used for invoking the operator */ + short shift; /* shift modifier flag */ + + float totpixlen; /* size in pixels for uv calculation */ + + ReportList *reports; } tGPsdata; /* ------ */ @@ -183,6 +206,14 @@ typedef struct tGPsdata { /* minimum length of new segment before new point can be added */ #define MIN_EUCLIDEAN_PX (U.gp_euclideandist) +static void gp_update_cache(bGPdata *gpd) +{ + if (gpd) { + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + } +} + static bool gp_stroke_added_check(tGPsdata *p) { return (p->gpf && p->gpf->strokes.last && p->flags & GP_PAINTFLAG_STROKEADDED); @@ -192,6 +223,9 @@ static void gp_stroke_added_enable(tGPsdata *p) { BLI_assert(p->gpf->strokes.last != NULL); p->flags |= GP_PAINTFLAG_STROKEADDED; + + /* drawing batch cache is dirty now */ + gp_update_cache(p->gpd); } /* ------ */ @@ -206,30 +240,42 @@ static void gp_session_validatebuffer(tGPsdata *p); static bool gpencil_draw_poll(bContext *C) { if (ED_operator_regionactive(C)) { - /* check if current context can support GPencil data */ - if (ED_gpencil_data_get_pointers(C, NULL) != NULL) { - /* check if Grease Pencil isn't already running */ - if (ED_gpencil_session_active() == 0) - return 1; - else - CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active"); + ScrArea *sa = CTX_wm_area(C); + if (!ELEM(sa->spacetype, SPACE_VIEW3D)) { + /* check if current context can support GPencil data */ + if (ED_gpencil_data_get_pointers(C, NULL) != NULL) { + /* check if Grease Pencil isn't already running */ + if (ED_gpencil_session_active() == 0) + return 1; + else + CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active"); + } + else { + CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into"); + } + return 0; } + /* 3D Viewport */ else { - CTX_wm_operator_poll_msg_set(C, "Failed to find Grease Pencil data to draw into"); + if (ED_gpencil_session_active() == 0) { + return 1; + } + else { + return 0; + } } } else { CTX_wm_operator_poll_msg_set(C, "Active region not set"); + return 0; } - - return 0; } /* check if projecting strokes into 3d-geometry in the 3D-View */ static bool gpencil_project_check(tGPsdata *p) { bGPdata *gpd = p->gpd; - return ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE))); + return ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) && (*p->align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE))); } /* ******************************************* */ @@ -241,38 +287,39 @@ static bool gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location; - - /* the reference point used depends on the owner... */ -#if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ + Object *ob = NULL; if (p->ownerPtr.type == &RNA_Object) { - Object *ob = (Object *)p->ownerPtr.data; - - /* active Object - * - use relative distance of 3D-cursor from object center - */ - sub_v3_v3v3(vec, fp, ob->loc); - } - else -#endif - { - /* use 3D-cursor */ - copy_v3_v3(vec, fp); + ob = (Object *)p->ownerPtr.data; } + ED_gp_get_drawing_reference(v3d, p->scene, ob, p->gpl, *p->align_flag, vec); } /* Stroke Editing ---------------------------- */ - /* check if the current mouse position is suitable for adding a new point */ static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2]) { + Brush *brush = p->brush; int dx = abs(mval[0] - pmval[0]); int dy = abs(mval[1] - pmval[1]); + brush->gpencil_settings->flag &= ~GP_BRUSH_STABILIZE_MOUSE_TEMP; /* if buffer is empty, just let this go through (i.e. so that dots will work) */ - if (p->gpd->sbuffer_size == 0) + if (p->gpd->runtime.sbuffer_size == 0) { return true; - + } + /* if lazy mouse, check minimum distance */ + else if (GPENCIL_LAZY_MODE(brush, p->shift)) { + brush->gpencil_settings->flag |= GP_BRUSH_STABILIZE_MOUSE_TEMP; + if ((dx * dx + dy * dy) > (brush->smooth_stroke_radius * brush->smooth_stroke_radius)) { + return true; + } + else { + /* If the mouse is moving within the radius of the last move, + * don't update the mouse position. This allows sharp turns. */ + copy_v2_v2_int(p->mval, p->mvalo); + return false; + } + } /* check if mouse moved at least certain distance on both axes (best case) * - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand */ @@ -291,47 +338,17 @@ static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2]) return false; } -/* reproject the points of the stroke to a plane locked to axis to avoid stroke offset */ -static void gp_project_points_to_plane(RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis) -{ - float plane_normal[3]; - float vn[3]; - - float ray[3]; - float rpoint[3]; - - /* normal vector for a plane locked to axis */ - zero_v3(plane_normal); - plane_normal[axis] = 1.0f; - - /* Reproject the points in the plane */ - for (int i = 0; i < gps->totpoints; i++) { - bGPDspoint *pt = &gps->points[i]; - - /* get a vector from the point with the current view direction of the viewport */ - ED_view3d_global_to_vector(rv3d, &pt->x, vn); - - /* calculate line extrem point to create a ray that cross the plane */ - mul_v3_fl(vn, -50.0f); - add_v3_v3v3(ray, &pt->x, vn); - - /* if the line never intersect, the point is not changed */ - if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) { - copy_v3_v3(&pt->x, rpoint); - } - } -} - /* reproject stroke to plane locked to axis in 3d cursor location */ static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps) { bGPdata *gpd = p->gpd; + Object *obact = (Object *)p->ownerPtr.data; + float origin[3]; - float cursor[3]; RegionView3D *rv3d = p->ar->regiondata; /* verify the stroke mode is CURSOR 3d space mode */ - if ((gpd->sbuffer_sflag & GP_STROKE_3DSPACE) == 0) { + if ((gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) == 0) { return; } if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { @@ -341,12 +358,9 @@ static void gp_reproject_toplane(tGPsdata *p, bGPDstroke *gps) return; } - /* get 3d cursor and set origin for locked axis only. Uses axis-1 because the enum for XYZ start with 1 */ - gp_get_3d_reference(p, cursor); - zero_v3(origin); - origin[p->lock_axis - 1] = cursor[p->lock_axis - 1]; - - gp_project_points_to_plane(rv3d, gps, origin, p->lock_axis - 1); + /* get drawing origin */ + gp_get_3d_reference(p, origin); + ED_gp_project_stroke_to_plane(obact, rv3d, gps, origin, p->lock_axis - 1); } /* convert screen-coordinates to buffer-coordinates */ @@ -356,7 +370,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] bGPdata *gpd = p->gpd; /* in 3d-space - pt->x/y/z are 3 side-by-side floats */ - if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) { + if (gpd->runtime.sbuffer_sflag & GP_STROKE_3DSPACE) { if (gpencil_project_check(p) && (ED_view3d_autodist_simple(p->ar, mval, out, 0, depth))) { /* projecting onto 3D-Geometry * - nothing more needs to be done here, since view_autodist_simple() has already done it @@ -365,7 +379,8 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] else { float mval_prj[2]; float rvec[3], dvec[3]; - float mval_f[2] = {UNPACK2(mval)}; + float mval_f[2]; + copy_v2fl_v2i(mval_f, mval); float zfac; /* Current method just converts each point in screen-coordinates to @@ -390,42 +405,23 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] } } } - - /* 2d - on 'canvas' (assume that p->v2d is set) */ - else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) { - UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]); - mul_v3_m4v3(out, p->imat, out); - } - - /* 2d - relative to screen (viewport area) */ - else { - if (p->subrect == NULL) { /* normal 3D view */ - out[0] = (float)(mval[0]) / (float)(p->ar->winx) * 100; - out[1] = (float)(mval[1]) / (float)(p->ar->winy) * 100; - } - else { /* camera view, use subrect */ - out[0] = ((mval[0] - p->subrect->xmin) / BLI_rctf_size_x(p->subrect)) * 100; - out[1] = ((mval[1] - p->subrect->ymin) / BLI_rctf_size_y(p->subrect)) * 100; - } - } } /* apply jitter to stroke */ -static void gp_brush_jitter( - bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2], int r_mval[2], RNG *rng) +static void gp_brush_jitter(bGPdata *gpd, Brush *brush, tGPspoint *pt, const int mval[2], int r_mval[2], RNG *rng) { float pressure = pt->pressure; float tmp_pressure = pt->pressure; - if (brush->draw_jitter > 0.0f) { - float curvef = curvemapping_evaluateF(brush->cur_jitter, 0, pressure); - tmp_pressure = curvef * brush->draw_sensitivity; + if (brush->gpencil_settings->draw_jitter > 0.0f) { + float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_jitter, 0, pressure); + tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity; } - const float exfactor = (brush->draw_jitter + 2.0f) * (brush->draw_jitter + 2.0f); /* exponential value */ + const float exfactor = (brush->gpencil_settings->draw_jitter + 2.0f) * (brush->gpencil_settings->draw_jitter + 2.0f); /* exponential value */ const float fac = BLI_rng_get_float(rng) * exfactor * tmp_pressure; /* Jitter is applied perpendicular to the mouse movement vector (2D space) */ float mvec[2], svec[2]; /* mouse movement in ints -> floats */ - if (gpd->sbuffer_size > 1) { + if (gpd->runtime.sbuffer_size > 1) { mvec[0] = (float)(mval[0] - (pt - 1)->x); mvec[1] = (float)(mval[1] - (pt - 1)->y); normalize_v2(mvec); @@ -451,18 +447,18 @@ static void gp_brush_jitter( } /* apply pressure change depending of the angle of the stroke to simulate a pen with shape */ -static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2]) +static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const int mval[2]) { float mvec[2]; - float sen = brush->draw_angle_factor; /* sensitivity */; + float sen = brush->gpencil_settings->draw_angle_factor; /* sensitivity */; float fac; float mpressure; - float angle = brush->draw_angle; /* default angle of brush in radians */; + float angle = brush->gpencil_settings->draw_angle; /* default angle of brush in radians */; float v0[2] = { cos(angle), sin(angle) }; /* angle vector of the brush with full thickness */ /* Apply to first point (only if there are 2 points because before no data to do it ) */ - if (gpd->sbuffer_size == 1) { + if (gpd->runtime.sbuffer_size == 1) { mvec[0] = (float)(mval[0] - (pt - 1)->x); mvec[1] = (float)(mval[1] - (pt - 1)->y); normalize_v2(mvec); @@ -475,7 +471,7 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const } /* apply from second point */ - if (gpd->sbuffer_size >= 1) { + if (gpd->runtime.sbuffer_size >= 1) { mvec[0] = (float)(mval[0] - (pt - 1)->x); mvec[1] = (float)(mval[1] - (pt - 1)->y); normalize_v2(mvec); @@ -490,21 +486,83 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const } +/* Apply smooth to buffer while drawing +* to smooth point C, use 2 before (A, B) and current point (D): +* +* A----B-----C------D +* +* \param p Temp data +* \param inf Influence factor +* \param idx Index of the last point (need minimum 3 points in the array) +*/ +static void gp_smooth_buffer(tGPsdata *p, float inf, int idx) +{ + bGPdata *gpd = p->gpd; + short num_points = gpd->runtime.sbuffer_size; + + /* Do nothing if not enough points to smooth out */ + if ((num_points < 3) || (idx < 3) || (inf == 0.0f)) { + return; + } + + tGPspoint *points = (tGPspoint *)gpd->runtime.sbuffer; + float steps = 4.0f; + if (idx < 4) { + steps--; + } + + tGPspoint *pta = idx >= 4 ? &points[idx - 4] : NULL; + tGPspoint *ptb = idx >= 3 ? &points[idx - 3] : NULL; + tGPspoint *ptc = idx >= 2 ? &points[idx - 2] : NULL; + tGPspoint *ptd = &points[idx - 1]; + + float sco[2] = { 0.0f }; + float a[2], b[2], c[2], d[2]; + const float average_fac = 1.0f / steps; + + /* Compute smoothed coordinate by taking the ones nearby */ + if (pta) { + copy_v2fl_v2i(a, &pta->x); + madd_v2_v2fl(sco, a, average_fac); + } + if (ptb) { + copy_v2fl_v2i(b, &ptb->x); + madd_v2_v2fl(sco, b, average_fac); + } + if (ptc) { + copy_v2fl_v2i(c, &ptc->x); + madd_v2_v2fl(sco, c, average_fac); + } + if (ptd) { + copy_v2fl_v2i(d, &ptd->x); + madd_v2_v2fl(sco, d, average_fac); + } + + /* Based on influence factor, blend between original and optimal smoothed coordinate */ + interp_v2_v2v2(c, c, sco, inf); + round_v2i_v2fl(&ptc->x, c); +} + /* add current stroke-point to buffer (returns whether point was successfully added) */ static short gp_stroke_addpoint( tGPsdata *p, const int mval[2], float pressure, double curtime) { bGPdata *gpd = p->gpd; - bGPDbrush *brush = p->brush; + Brush *brush = p->brush; tGPspoint *pt; ToolSettings *ts = p->scene->toolsettings; + Object *obact = (Object *)p->ownerPtr.data; + Depsgraph *depsgraph = p->depsgraph; \ + RegionView3D *rv3d = p->ar->regiondata; + View3D *v3d = p->sa->spacedata.first; + MaterialGPencilStyle *gp_style = p->material->gp_style; /* check painting mode */ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { /* straight lines only - i.e. only store start and end point in buffer */ - if (gpd->sbuffer_size == 0) { + if (gpd->runtime.sbuffer_size == 0) { /* first point in buffer (start point) */ - pt = (tGPspoint *)(gpd->sbuffer); + pt = (tGPspoint *)(gpd->runtime.sbuffer); /* store settings */ copy_v2_v2_int(&pt->x, mval); @@ -513,13 +571,13 @@ static short gp_stroke_addpoint( pt->time = (float)(curtime - p->inittime); /* increment buffer size */ - gpd->sbuffer_size++; + gpd->runtime.sbuffer_size++; } else { /* just reset the endpoint to the latest value * - assume that pointers for this are always valid... */ - pt = ((tGPspoint *)(gpd->sbuffer) + 1); + pt = ((tGPspoint *)(gpd->runtime.sbuffer) + 1); /* store settings */ copy_v2_v2_int(&pt->x, mval); @@ -528,31 +586,35 @@ static short gp_stroke_addpoint( pt->time = (float)(curtime - p->inittime); /* now the buffer has 2 points (and shouldn't be allowed to get any larger) */ - gpd->sbuffer_size = 2; + gpd->runtime.sbuffer_size = 2; } + /* tag depsgraph to update object */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + /* can keep carrying on this way :) */ return GP_STROKEADD_NORMAL; } else if (p->paintmode == GP_PAINTMODE_DRAW) { /* normal drawing */ /* check if still room in buffer */ - if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) + if (gpd->runtime.sbuffer_size >= GP_STROKE_BUFFER_MAX) return GP_STROKEADD_OVERFLOW; /* get pointer to destination point */ - pt = ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); + pt = ((tGPspoint *)(gpd->runtime.sbuffer) + gpd->runtime.sbuffer_size); /* store settings */ /* pressure */ - if (brush->flag & GP_BRUSH_USE_PRESSURE) { - float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure); - pt->pressure = curvef * brush->draw_sensitivity; + if (brush->gpencil_settings->flag & GP_BRUSH_USE_PRESSURE) { + float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure); + pt->pressure = curvef * brush->gpencil_settings->draw_sensitivity; } else { pt->pressure = 1.0f; } + /* Apply jitter to position */ - if (brush->draw_jitter > 0.0f) { + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && (brush->gpencil_settings->draw_jitter > 0.0f)) { int r_mval[2]; gp_brush_jitter(gpd, brush, pt, mval, r_mval, p->rng); copy_v2_v2_int(&pt->x, r_mval); @@ -561,42 +623,62 @@ static short gp_stroke_addpoint( copy_v2_v2_int(&pt->x, mval); } /* apply randomness to pressure */ - if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_PRESSURE)) { - float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure); - float tmp_pressure = curvef * brush->draw_sensitivity; + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && + (brush->gpencil_settings->draw_random_press > 0.0f)) + { + float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure); + float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity; if (BLI_rng_get_float(p->rng) > 0.5f) { - pt->pressure -= tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng); + pt->pressure -= tmp_pressure * brush->gpencil_settings->draw_random_press * BLI_rng_get_float(p->rng); } else { - pt->pressure += tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng); + pt->pressure += tmp_pressure * brush->gpencil_settings->draw_random_press * BLI_rng_get_float(p->rng); } CLAMP(pt->pressure, GPENCIL_STRENGTH_MIN, 1.0f); } + /* apply randomness to uv texture rotation */ + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && (brush->gpencil_settings->uv_random > 0.0f)) { + if (BLI_rng_get_float(p->rng) > 0.5f) { + pt->uv_rot = (BLI_rng_get_float(p->rng) * M_PI * -1) * brush->gpencil_settings->uv_random; + } + else { + pt->uv_rot = (BLI_rng_get_float(p->rng) * M_PI) * brush->gpencil_settings->uv_random; + } + CLAMP(pt->uv_rot, -M_PI_2, M_PI_2); + } + else { + pt->uv_rot = 0.0f; + } + /* apply angle of stroke to brush size */ - if (brush->draw_angle_factor > 0.0f) { + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && + (brush->gpencil_settings->draw_angle_factor > 0.0f)) + { gp_brush_angle(gpd, brush, pt, mval); } /* color strength */ - if (brush->flag & GP_BRUSH_USE_STENGTH_PRESSURE) { - float curvef = curvemapping_evaluateF(brush->cur_strength, 0, pressure); - float tmp_pressure = curvef * brush->draw_sensitivity; + if (brush->gpencil_settings->flag & GP_BRUSH_USE_STENGTH_PRESSURE) { + float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_strength, 0, pressure); + float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity; - pt->strength = tmp_pressure * brush->draw_strength; + pt->strength = tmp_pressure * brush->gpencil_settings->draw_strength; } else { - pt->strength = brush->draw_strength; + pt->strength = brush->gpencil_settings->draw_strength; } CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); /* apply randomness to color strength */ - if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_STRENGTH)) { + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && + (brush->gpencil_settings->draw_random_strength > 0.0f)) + { if (BLI_rng_get_float(p->rng) > 0.5f) { - pt->strength -= pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng); + pt->strength -= pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng); } else { - pt->strength += pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng); + pt->strength += pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng); } CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); } @@ -604,11 +686,49 @@ static short gp_stroke_addpoint( /* point time */ pt->time = (float)(curtime - p->inittime); + /* point uv (only 3d view) */ + if ((p->sa->spacetype == SPACE_VIEW3D) && (gpd->runtime.sbuffer_size > 1)) { + float pixsize = gp_style->texture_pixsize / 1000000.0f; + tGPspoint *ptb = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 2; + bGPDspoint spt, spt2; + + /* get origin to reproject point */ + float origin[3]; + gp_get_3d_reference(p, origin); + /* reproject current */ + ED_gpencil_tpoint_to_point(p->ar, origin, pt, &spt); + ED_gp_project_point_to_plane(obact, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &spt); + + /* reproject previous */ + ED_gpencil_tpoint_to_point(p->ar, origin, ptb, &spt2); + ED_gp_project_point_to_plane(obact, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &spt2); + + p->totpixlen += len_v3v3(&spt.x, &spt2.x) / pixsize; + pt->uv_fac = p->totpixlen; + if ((gp_style) && (gp_style->sima)) { + pt->uv_fac /= gp_style->sima->gen_x; + } + } + else { + p->totpixlen = 0.0f; + pt->uv_fac = 0.0f; + } + /* increment counters */ - gpd->sbuffer_size++; + gpd->runtime.sbuffer_size++; + + /* smooth while drawing previous points with a reduction factor for previous */ + if (brush->gpencil_settings->active_smooth > 0.0f) { + for (int s = 0; s < 3; s++) { + gp_smooth_buffer(p, brush->gpencil_settings->active_smooth * ((3.0f - s) / 3.0f), gpd->runtime.sbuffer_size - s); + } + } + + /* tag depsgraph to update object */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); /* check if another operation can still occur */ - if (gpd->sbuffer_size == GP_STROKE_BUFFER_MAX) + if (gpd->runtime.sbuffer_size == GP_STROKE_BUFFER_MAX) return GP_STROKEADD_FULL; else return GP_STROKEADD_NORMAL; @@ -617,7 +737,7 @@ static short gp_stroke_addpoint( bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); /* get pointer to destination point */ - pt = (tGPspoint *)(gpd->sbuffer); + pt = (tGPspoint *)(gpd->runtime.sbuffer); /* store settings */ copy_v2_v2_int(&pt->x, mval); @@ -632,14 +752,17 @@ static short gp_stroke_addpoint( if (gp_stroke_added_check(p)) { bGPDstroke *gps = p->gpf->strokes.last; bGPDspoint *pts; + MDeformVert *dvert; /* first time point is adding to temporary buffer -- need to allocate new point in stroke */ - if (gpd->sbuffer_size == 0) { + if (gpd->runtime.sbuffer_size == 0) { gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1)); + gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * (gps->totpoints + 1)); gps->totpoints++; } pts = &gps->points[gps->totpoints - 1]; + dvert = &gps->dvert[gps->totpoints - 1]; /* special case for poly lines: normally, * depth is needed only when creating new stroke from buffer, @@ -647,8 +770,6 @@ static short gp_stroke_addpoint( * so initialize depth buffer before converting coordinates */ if (gpencil_project_check(p)) { - View3D *v3d = p->sa->spacedata.first; - view3d_region_operator_needs_opengl(p->win, p->ar); ED_view3d_autodist_init( p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); @@ -656,25 +777,32 @@ static short gp_stroke_addpoint( /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &pt->x, &pts->x, NULL); - /* if axis locked, reproject to plane locked (only in 3d space) */ - if (p->lock_axis > GP_LOCKAXIS_NONE) { - gp_reproject_toplane(p, gps); - } + /* reproject to plane (only in 3d space) */ + gp_reproject_toplane(p, gps); /* if parented change position relative to parent object */ - if (gpl->parent != NULL) { - gp_apply_parent_point(gpl, pts); - } + gp_apply_parent_point(depsgraph, obact, gpd, gpl, pts); /* copy pressure and time */ pts->pressure = pt->pressure; pts->strength = pt->strength; pts->time = pt->time; + pts->uv_fac = pt->uv_fac; + pts->uv_rot = pt->uv_rot; + + dvert->totweight = 0; + dvert->dw = NULL; + /* force fill recalc */ gps->flag |= GP_STROKE_RECALC_CACHES; + /* drawing batch cache is dirty now */ + gp_update_cache(p->gpd); } /* increment counters */ - if (gpd->sbuffer_size == 0) - gpd->sbuffer_size++; + if (gpd->runtime.sbuffer_size == 0) + gpd->runtime.sbuffer_size++; + + /* tag depsgraph to update object */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); return GP_STROKEADD_NORMAL; } @@ -690,9 +818,9 @@ static short gp_stroke_addpoint( static void gp_stroke_simplify(tGPsdata *p) { bGPdata *gpd = p->gpd; - tGPspoint *old_points = (tGPspoint *)gpd->sbuffer; - short num_points = gpd->sbuffer_size; - short flag = gpd->sbuffer_sflag; + tGPspoint *old_points = (tGPspoint *)gpd->runtime.sbuffer; + short num_points = gpd->runtime.sbuffer_size; + short flag = gpd->runtime.sbuffer_sflag; short i, j; /* only simplify if simplification is enabled, and we're not doing a straight line */ @@ -707,9 +835,9 @@ static void gp_stroke_simplify(tGPsdata *p) * - firstly set sbuffer to NULL, so a new one is allocated * - secondly, reset flag after, as it gets cleared auto */ - gpd->sbuffer = NULL; + gpd->runtime.sbuffer = NULL; gp_session_validatebuffer(p); - gpd->sbuffer_sflag = flag; + gpd->runtime.sbuffer_sflag = flag; /* macro used in loop to get position of new point * - used due to the mixture of datatypes in use here @@ -766,8 +894,11 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) bGPDstroke *gps; bGPDspoint *pt; tGPspoint *ptc; - bGPDbrush *brush = p->brush; + MDeformVert *dvert; + Brush *brush = p->brush; ToolSettings *ts = p->scene->toolsettings; + Depsgraph *depsgraph = p->depsgraph; + Object *obact = (Object *)p->ownerPtr.data; int i, totelem; /* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */ @@ -777,14 +908,14 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) * - drawing straight-lines only requires the endpoints */ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) - totelem = (gpd->sbuffer_size >= 2) ? 2 : gpd->sbuffer_size; + totelem = (gpd->runtime.sbuffer_size >= 2) ? 2 : gpd->runtime.sbuffer_size; else - totelem = gpd->sbuffer_size; + totelem = gpd->runtime.sbuffer_size; /* exit with error if no valid points from this stroke */ if (totelem == 0) { if (G.debug & G_DEBUG) - printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->sbuffer_size); + printf("Error: No valid points in stroke buffer to convert (tot=%d)\n", gpd->runtime.sbuffer_size); return; } @@ -793,6 +924,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) * interactive behavior */ if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { + /* be sure to hide any lazy cursor */ + ED_gpencil_toggle_brush_cursor(p->C, true, NULL); + if (gp_stroke_added_check(p)) { return; } @@ -803,95 +937,94 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) /* copy appropriate settings for stroke */ gps->totpoints = totelem; - gps->thickness = brush->thickness; - gps->flag = gpd->sbuffer_sflag; + gps->thickness = brush->size; + gps->flag = gpd->runtime.sbuffer_sflag; gps->inittime = p->inittime; /* enable recalculation flag by default (only used if hq fill) */ gps->flag |= GP_STROKE_RECALC_CACHES; /* allocate enough memory for a continuous array for storage points */ - int sublevel = brush->sublevel; - int new_totpoints = gps->totpoints; + const int subdivide = brush->gpencil_settings->draw_subdivide; + + gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); - for (i = 0; i < sublevel; i++) { - new_totpoints += new_totpoints - 1; - } - gps->points = MEM_callocN(sizeof(bGPDspoint) * new_totpoints, "gp_stroke_points"); /* initialize triangle memory to dummy data */ gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation"); gps->flag |= GP_STROKE_RECALC_CACHES; gps->tot_triangles = 0; + /* drawing batch cache is dirty now */ + gp_update_cache(p->gpd); /* set pointer to first non-initialized point */ pt = gps->points + (gps->totpoints - totelem); + dvert = gps->dvert + (gps->totpoints - totelem); /* copy points from the buffer to the stroke */ if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) { /* straight lines only -> only endpoints */ { /* first point */ - ptc = gpd->sbuffer; + ptc = gpd->runtime.sbuffer; /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); - /* if axis locked, reproject to plane locked (only in 3d space) */ - if (p->lock_axis > GP_LOCKAXIS_NONE) { - gp_reproject_toplane(p, gps); - } - /* if parented change position relative to parent object */ - if (gpl->parent != NULL) { - gp_apply_parent_point(gpl, pt); - } /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; + dvert->totweight = 0; + dvert->dw = NULL; + pt++; + dvert++; } if (totelem == 2) { /* last point if applicable */ - ptc = ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1); + ptc = ((tGPspoint *)gpd->runtime.sbuffer) + (gpd->runtime.sbuffer_size - 1); /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); - /* if axis locked, reproject to plane locked (only in 3d space) */ - if (p->lock_axis > GP_LOCKAXIS_NONE) { - gp_reproject_toplane(p, gps); - } - /* if parented change position relative to parent object */ - if (gpl->parent != NULL) { - gp_apply_parent_point(gpl, pt); - } - /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; + + dvert->totweight = 0; + dvert->dw = NULL; + } + + /* reproject to plane (only in 3d space) */ + gp_reproject_toplane(p, gps); + pt = gps->points; + for (i = 0; i < gps->totpoints; i++, pt++) { + /* if parented change position relative to parent object */ + gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt); } } else if (p->paintmode == GP_PAINTMODE_DRAW_POLY) { /* first point */ - ptc = gpd->sbuffer; + ptc = gpd->runtime.sbuffer; /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &ptc->x, &pt->x, NULL); - /* if axis locked, reproject to plane locked (only in 3d space) */ - if (p->lock_axis > GP_LOCKAXIS_NONE) { - gp_reproject_toplane(p, gps); - } + /* reproject to plane (only in 3d space) */ + gp_reproject_toplane(p, gps); /* if parented change position relative to parent object */ - if (gpl->parent != NULL) { - gp_apply_parent_point(gpl, pt); - } + gp_apply_parent_point(depsgraph, obact, gpd, gpl, pt); /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; + + dvert->totweight = 0; + dvert->dw = NULL; + } else { float *depth_arr = NULL; @@ -902,9 +1035,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) int interp_depth = 0; int found_depth = 0; - depth_arr = MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points"); + depth_arr = MEM_mallocN(sizeof(float) * gpd->runtime.sbuffer_size, "depth_points"); - for (i = 0, ptc = gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) { + for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size; i++, ptc++, pt++) { copy_v2_v2_int(mval, &ptc->x); if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) && @@ -921,7 +1054,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) if (found_depth == false) { /* eeh... not much we can do.. :/, ignore depth in this case, use the 3D cursor */ - for (i = gpd->sbuffer_size - 1; i >= 0; i--) + for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) depth_arr[i] = 0.9999f; } else { @@ -930,13 +1063,13 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) int first_valid = 0; int last_valid = 0; - for (i = 0; i < gpd->sbuffer_size; i++) { + for (i = 0; i < gpd->runtime.sbuffer_size; i++) { if (depth_arr[i] != FLT_MAX) break; } first_valid = i; - for (i = gpd->sbuffer_size - 1; i >= 0; i--) { + for (i = gpd->runtime.sbuffer_size - 1; i >= 0; i--) { if (depth_arr[i] != FLT_MAX) break; } @@ -950,16 +1083,15 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } if (interp_depth) { - interp_sparse_array(depth_arr, gpd->sbuffer_size, FLT_MAX); + interp_sparse_array(depth_arr, gpd->runtime.sbuffer_size, FLT_MAX); } } } - pt = gps->points; /* convert all points (normal behavior) */ - for (i = 0, ptc = gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++, pt++) { + for (i = 0, ptc = gpd->runtime.sbuffer; i < gpd->runtime.sbuffer_size && ptc; i++, ptc++, pt++) { /* convert screen-coordinates to appropriate coordinates (and store them) */ gp_stroke_convertcoords(p, &ptc->x, &pt->x, depth_arr ? depth_arr + i : NULL); @@ -968,20 +1100,18 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) pt->strength = ptc->strength; CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); pt->time = ptc->time; + pt->uv_fac = ptc->uv_fac; + pt->uv_rot = ptc->uv_rot; } - /* subdivide the stroke */ - if (sublevel > 0) { - int totpoints = gps->totpoints; - for (i = 0; i < sublevel; i++) { - /* we're adding one new point between each pair of verts on each step */ - totpoints += totpoints - 1; - - gp_subdivide_stroke(gps, totpoints); - } + /* subdivide and smooth the stroke */ + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && (subdivide > 0)) { + gp_subdivide_stroke(gps, subdivide); } /* apply randomness to stroke */ - if (brush->draw_random_sub > 0.0f) { + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && + (brush->gpencil_settings->draw_random_sub > 0.0f)) + { gp_randomize_stroke(gps, brush, p->rng); } @@ -989,34 +1119,43 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) * for each iteration, the factor is reduced to get a better smoothing without changing too much * the original stroke */ - if (brush->draw_smoothfac > 0.0f) { + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && + (brush->gpencil_settings->draw_smoothfac > 0.0f)) + { float reduce = 0.0f; - for (int r = 0; r < brush->draw_smoothlvl; ++r) { + for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) { for (i = 0; i < gps->totpoints; i++) { - /* NOTE: No pressure smoothing, or else we get annoying thickness changes while drawing... */ - gp_smooth_stroke(gps, i, brush->draw_smoothfac - reduce, false); + BKE_gpencil_smooth_stroke(gps, i, brush->gpencil_settings->draw_smoothfac - reduce); + BKE_gpencil_smooth_stroke_strength(gps, i, brush->gpencil_settings->draw_smoothfac); } reduce += 0.25f; // reduce the factor } } - - /* if axis locked, reproject to plane locked (only in 3d space) */ - if (p->lock_axis > GP_LOCKAXIS_NONE) { - gp_reproject_toplane(p, gps); - } - /* if parented change position relative to parent object */ - if (gpl->parent != NULL) { - gp_apply_parent(gpl, gps); + /* smooth thickness */ + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && + (brush->gpencil_settings->thick_smoothfac > 0.0f)) + { + for (int r = 0; r < brush->gpencil_settings->thick_smoothlvl * 2; r++) { + for (i = 0; i < gps->totpoints; i++) { + BKE_gpencil_smooth_stroke_thickness(gps, i, brush->gpencil_settings->thick_smoothfac); + } + } } + /* reproject to plane (only in 3d space) */ + gp_reproject_toplane(p, gps); + /* change position relative to parent object */ + gp_apply_parent(depsgraph, obact, gpd, gpl, gps); + if (depth_arr) MEM_freeN(depth_arr); } - /* Save palette color */ - bGPDpalette *palette = BKE_gpencil_palette_getactive(p->gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); - gps->palcolor = palcolor; - BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname)); + + /* Save material index */ + gps->mat_nr = BKE_object_material_slot_find_index(p->ob, p->material) - 1; + + /* calculate UVs along the stroke */ + ED_gpencil_calc_stroke_uv(obact, gps); /* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke is added on listbase head * because the drawing order is inverse and the head stroke is the first to draw. This is very useful for artist @@ -1047,6 +1186,8 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3]) /* only erase stroke points that are visible */ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, const int x, const int y) { + Object *obact = (Object *)p->ownerPtr.data; + if ((p->sa->spacetype == SPACE_VIEW3D) && (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH)) { @@ -1059,7 +1200,7 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, cons float diff_mat[4][4]; /* calculate difference matrix if parent object */ - ED_gpencil_parent_location(gpl, diff_mat); + ED_gpencil_parent_location(p->depsgraph, obact, p->gpd, gpl, diff_mat); if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) { const float depth_mval = view3d_point_depth(rv3d, mval_3d); @@ -1092,6 +1233,24 @@ static float gp_stroke_eraser_calc_influence(tGPsdata *p, const int mval[2], con return fac; } +/* helper to free a stroke */ +static void gp_free_stroke(bGPdata *gpd, bGPDframe *gpf, bGPDstroke *gps) +{ + if (gps->points) { + MEM_freeN(gps->points); + } + + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } + + if (gps->triangles) + MEM_freeN(gps->triangles); + BLI_freelinkN(&gpf->strokes, gps); + gp_update_cache(gpd); +} + /* eraser tool - evaluation per stroke */ /* TODO: this could really do with some optimization (KD-Tree/BVH?) */ static void gp_stroke_eraser_dostroke(tGPsdata *p, @@ -1099,46 +1258,58 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, const int mval[2], const int mvalo[2], const int radius, const rcti *rect) { + Depsgraph *depsgraph = p->depsgraph; + Object *obact = (Object *)p->ownerPtr.data; + Brush *eraser = p->eraser; bGPDspoint *pt1, *pt2; int pc1[2] = {0}; int pc2[2] = {0}; int i; float diff_mat[4][4]; - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - } + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, obact, p->gpd, gpl, diff_mat); if (gps->totpoints == 0) { /* just free stroke */ - if (gps->points) - MEM_freeN(gps->points); - if (gps->triangles) - MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); + gp_free_stroke(p->gpd, gpf, gps); } else if (gps->totpoints == 1) { /* only process if it hasn't been masked out... */ if (!(p->flags & GP_PAINTFLAG_SELECTMASK) || (gps->points->flag & GP_SPOINT_SELECT)) { - if (gpl->parent == NULL) { - gp_point_to_xy(&p->gsc, gps, gps->points, &pc1[0], &pc1[1]); - } - else { - bGPDspoint pt_temp; - gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); - gp_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]); + bGPDspoint pt_temp; + gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); + gp_point_to_xy(&p->gsc, gps, &pt_temp, &pc1[0], &pc1[1]); + /* do boundbox check first */ + if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { + /* only check if point is inside */ + if (len_v2v2_int(mval, pc1) <= radius) { + /* free stroke */ + gp_free_stroke(p->gpd, gpf, gps); + } } + } + } + else if ((p->flags & GP_PAINTFLAG_STROKE_ERASER) || (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_STROKE)) { + for (i = 0; (i + 1) < gps->totpoints; i++) { + + /* only process if it hasn't been masked out... */ + if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT)) + continue; + + /* get points to work with */ + pt1 = gps->points + i; + bGPDspoint npt; + gp_point_to_parent_space(pt1, diff_mat, &npt); + gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]); + /* do boundbox check first */ if ((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) { /* only check if point is inside */ if (len_v2v2_int(mval, pc1) <= radius) { /* free stroke */ - // XXX: pressure sensitive eraser should apply here too? - MEM_freeN(gps->points); - if (gps->triangles) - MEM_freeN(gps->triangles); - BLI_freelinkN(&gpf->strokes, gps); + gp_free_stroke(p->gpd, gpf, gps); + return; } } } @@ -1181,18 +1352,12 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, if ((p->flags & GP_PAINTFLAG_SELECTMASK) && !(gps->points->flag & GP_SPOINT_SELECT)) continue; - if (gpl->parent == NULL) { - gp_point_to_xy(&p->gsc, gps, pt1, &pc1[0], &pc1[1]); - gp_point_to_xy(&p->gsc, gps, pt2, &pc2[0], &pc2[1]); - } - else { - bGPDspoint npt; - gp_point_to_parent_space(pt1, diff_mat, &npt); - gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]); + bGPDspoint npt; + gp_point_to_parent_space(pt1, diff_mat, &npt); + gp_point_to_xy(&p->gsc, gps, &npt, &pc1[0], &pc1[1]); - gp_point_to_parent_space(pt2, diff_mat, &npt); - gp_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]); - } + gp_point_to_parent_space(pt2, diff_mat, &npt); + gp_point_to_xy(&p->gsc, gps, &npt, &pc2[0], &pc2[1]); /* Check that point segment of the boundbox of the eraser stroke */ if (((!ELEM(V2D_IS_CLIPPED, pc1[0], pc1[1])) && BLI_rcti_isect_pt(rect, pc1[0], pc1[1])) || @@ -1215,11 +1380,15 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, pt2->pressure -= gp_stroke_eraser_calc_influence(p, mval, radius, pc2) * strength / 2.0f; /* 2) Tag any point with overly low influence for removal in the next pass */ - if (pt1->pressure < cull_thresh) { + if ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + { pt1->flag |= GP_SPOINT_TAG; do_cull = true; } - if (pt2->pressure < cull_thresh) { + if ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + { pt2->flag |= GP_SPOINT_TAG; do_cull = true; } @@ -1230,8 +1399,9 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* Second Pass: Remove any points that are tagged */ if (do_cull) { - gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG); + gp_stroke_delete_tagged_points(gpf, gps, gps->next, GP_SPOINT_TAG, false); } + gp_update_cache(p->gpd); } } @@ -1275,7 +1445,7 @@ static void gp_stroke_doeraser(tGPsdata *p) for (gps = gpf->strokes.first; gps; gps = gpn) { gpn = gps->next; /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { + if (ED_gpencil_stroke_color_use(p->ob, gpl, gps) == false) { continue; } /* Not all strokes in the datablock may be valid in the current editor/context @@ -1295,107 +1465,178 @@ static void gp_stroke_doeraser(tGPsdata *p) static void gp_session_validatebuffer(tGPsdata *p) { bGPdata *gpd = p->gpd; + Brush *brush = p->brush; /* clear memory of buffer (or allocate it if starting a new session) */ - if (gpd->sbuffer) { + if (gpd->runtime.sbuffer) { /* printf("\t\tGP - reset sbuffer\n"); */ - memset(gpd->sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX); + memset(gpd->runtime.sbuffer, 0, sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX); } else { /* printf("\t\tGP - allocate sbuffer\n"); */ - gpd->sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); + gpd->runtime.sbuffer = MEM_callocN(sizeof(tGPspoint) * GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); } /* reset indices */ - gpd->sbuffer_size = 0; + gpd->runtime.sbuffer_size = 0; /* reset flags */ - gpd->sbuffer_sflag = 0; + gpd->runtime.sbuffer_sflag = 0; /* reset inittime */ p->inittime = 0.0; + + /* reset lazy */ + if (brush) { + brush->gpencil_settings->flag &= ~GP_BRUSH_STABILIZE_MOUSE_TEMP; + } } -/* create a new palette color */ -static bGPDpalettecolor *gp_create_new_color(bGPDpalette *palette) +/* helper to get default eraser and create one if no eraser brush */ +static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts) { - bGPDpalettecolor *palcolor; + Brush *brush_dft = NULL; + Paint *paint = BKE_brush_get_gpencil_paint(ts); + Brush *brush_old = paint->brush; + for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) { + if ((brush->ob_mode == OB_MODE_GPENCIL_PAINT) && + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + { + /* save first eraser to use later if no default */ + if (brush_dft == NULL) { + brush_dft = brush; + } + /* found default */ + if(brush->gpencil_settings->flag & GP_BRUSH_DEFAULT_ERASER) { + return brush; + } + } + } + /* if no default, but exist eraser brush, return this and set as default */ + if (brush_dft) { + brush_dft->gpencil_settings->flag |= GP_BRUSH_DEFAULT_ERASER; + return brush_dft; + } + /* create a new soft eraser brush */ + else { + brush_dft = BKE_brush_add_gpencil(bmain, ts, "Soft Eraser"); + brush_dft->size = 30.0f; + brush_dft->gpencil_settings->flag |= (GP_BRUSH_ENABLE_CURSOR | GP_BRUSH_DEFAULT_ERASER); + brush_dft->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT; + brush_dft->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE; + brush_dft->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT; - palcolor = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true); + /* reset current brush */ + BKE_paint_brush_set(paint, brush_old); - return palcolor; + return brush_dft; + } } /* initialize a drawing brush */ -static void gp_init_drawing_brush(ToolSettings *ts, tGPsdata *p) +static void gp_init_drawing_brush(bContext *C, tGPsdata *p) { - bGPDbrush *brush; + Brush *brush; + Scene *scene = CTX_data_scene(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + Paint *paint = BKE_brush_get_gpencil_paint(ts); /* if not exist, create a new one */ - if (BLI_listbase_is_empty(&ts->gp_brushes)) { + if (paint->brush == NULL) { /* create new brushes */ - BKE_gpencil_brush_init_presets(ts); - brush = BKE_gpencil_brush_getactive(ts); + BKE_brush_gpencil_presets(C); + brush = BKE_brush_getactive_gpencil(ts); } else { /* Use the current */ - brush = BKE_gpencil_brush_getactive(ts); + brush = BKE_brush_getactive_gpencil(ts); } /* be sure curves are initializated */ - curvemapping_initialize(brush->cur_sensitivity); - curvemapping_initialize(brush->cur_strength); - curvemapping_initialize(brush->cur_jitter); + curvemapping_initialize(brush->gpencil_settings->curve_sensitivity); + curvemapping_initialize(brush->gpencil_settings->curve_strength); + curvemapping_initialize(brush->gpencil_settings->curve_jitter); /* asign to temp tGPsdata */ p->brush = brush; + if (brush->gpencil_settings->brush_type != GP_BRUSH_TYPE_ERASE) { + p->eraser = gp_get_default_eraser(p->bmain, ts); + } + else { + p->eraser = brush; + } + /* use radius of eraser */ + p->radius = (short)p->eraser->size; + + /* GPXX: Need this update to synchronize brush with draw manager. + * Maybe this update can be removed when the new tool system + * will be in place, but while, we need this to keep drawing working. + * + */ + DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE); } -/* initialize a paint palette brush and a default color if not exist */ -static void gp_init_palette(tGPsdata *p) +/* initialize a paint brush and a default color if not exist */ +static void gp_init_colors(tGPsdata *p) { - bGPdata *gpd; - bGPDpalette *palette; - bGPDpalettecolor *palcolor; + bGPdata *gpd = p->gpd; + Brush *brush = p->brush; - gpd = p->gpd; + Material *ma = NULL; + MaterialGPencilStyle *gp_style = NULL; + + /* use brush material */ + ma = BKE_gpencil_get_material_from_brush(brush); + + /* if no brush defaults, get material and color info + * NOTE: Ensures that everything we need will exist... + */ + if ((ma == NULL) || (ma->gp_style == NULL)) { + BKE_gpencil_material_ensure(p->bmain, p->ob); - /* if not exist, create a new palette */ - if (BLI_listbase_is_empty(&gpd->palettes)) { - /* create new palette */ - palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true); - /* now create a default color */ - palcolor = gp_create_new_color(palette); + /* assign always the first material to the brush */ + p->material = give_current_material(p->ob, 1); + brush->gpencil_settings->material = p->material; } else { - /* Use the current palette and color */ - palette = BKE_gpencil_palette_getactive(gpd); - /* the palette needs one color */ - if (BLI_listbase_is_empty(&palette->colors)) { - palcolor = gp_create_new_color(palette); - } - else { - palcolor = BKE_gpencil_palettecolor_getactive(palette); - } - /* in some situations can be null, so use first */ - if (palcolor == NULL) { - BKE_gpencil_palettecolor_setactive(palette, palette->colors.first); - palcolor = palette->colors.first; - } + p->material = ma; } - /* asign to temp tGPsdata */ - p->palettecolor = palcolor; + /* check if the material is already on object material slots and add it if missing */ + if (BKE_object_material_slot_find_index(p->ob, p->material) == 0) { + BKE_object_material_slot_add(p->bmain, p->ob); + assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_EXISTING); + } + + /* assign color information to temp tGPsdata */ + gp_style = p->material->gp_style; + if (gp_style) { + + /* set colors */ + copy_v4_v4(gpd->runtime.scolor, gp_style->stroke_rgba); + copy_v4_v4(gpd->runtime.sfill, gp_style->fill_rgba); + /* add some alpha to make easy the filling without hide strokes */ + if (gpd->runtime.sfill[3] > 0.8f) { + gpd->runtime.sfill[3] = 0.8f; + } + + gpd->runtime.mode = (short)gp_style->mode; + gpd->runtime.bstroke_style = gp_style->stroke_style; + gpd->runtime.bfill_style = gp_style->fill_style; + } } /* (re)init new painting data */ -static bool gp_session_initdata(bContext *C, tGPsdata *p) +static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p) { Main *bmain = CTX_data_main(C); bGPdata **gpd_ptr = NULL; ScrArea *curarea = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); ToolSettings *ts = CTX_data_tool_settings(C); + Object *obact = CTX_data_active_object(C); + View3D *v3d = curarea->spacedata.first; /* make sure the active view (at the starting time) is a 3d-view */ if (curarea == NULL) { @@ -1406,10 +1647,12 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) } /* pass on current scene and window */ + p->C = C; p->bmain = CTX_data_main(C); p->scene = CTX_data_scene(C); p->depsgraph = CTX_data_depsgraph(C); p->win = CTX_wm_window(C); + p->disable_fill = RNA_boolean_get(op->ptr, "disable_fill"); unit_m4(p->imat); unit_m4(p->mat); @@ -1424,7 +1667,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) /* set current area * - must verify that region data is 3D-view (and not something else) */ - /* CAUTION: If this is the "toolbar", then this will change on the first stroke */ + /* CAUTION: If this is the "toolbar", then this will change on the first stroke */ p->sa = curarea; p->ar = ar; p->align_flag = &ts->gpencil_v3d_align; @@ -1435,92 +1678,19 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n"); return 0; } - break; - } - case SPACE_NODE: - { - /* SpaceNode *snode = curarea->spacedata.first; */ - /* set current area */ - p->sa = curarea; - p->ar = ar; - p->v2d = &ar->v2d; - p->align_flag = &ts->gpencil_v2d_align; - break; - } - case SPACE_SEQ: - { - SpaceSeq *sseq = curarea->spacedata.first; - - /* set current area */ - p->sa = curarea; - p->ar = ar; - p->v2d = &ar->v2d; - p->align_flag = &ts->gpencil_seq_align; - - /* check that gpencil data is allowed to be drawn */ - if (sseq->mainb == SEQ_DRAW_SEQUENCE) { - p->status = GP_STATUS_ERROR; - if (G.debug & G_DEBUG) - printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n"); - return 0; + /* if active object doesn't exist or isn't a GP Object, create one */ + float *cur = ED_view3d_cursor3d_get(p->scene, v3d)->location; + if ((!obact) || (obact->type != OB_GPENCIL)) { + /* create new default object */ + obact = ED_add_gpencil_object(C, p->scene, cur); } - break; - } - case SPACE_IMAGE: - { - /* SpaceImage *sima = curarea->spacedata.first; */ + /* assign object after all checks to be sure we have one active */ + p->ob = obact; - /* set the current area */ - p->sa = curarea; - p->ar = ar; - p->v2d = &ar->v2d; - p->align_flag = &ts->gpencil_ima_align; - break; - } - case SPACE_CLIP: - { - SpaceClip *sc = curarea->spacedata.first; - MovieClip *clip = ED_space_clip_get_clip(sc); - - if (clip == NULL) { - p->status = GP_STATUS_ERROR; - return false; - } - - /* set the current area */ - p->sa = curarea; - p->ar = ar; - p->v2d = &ar->v2d; - p->align_flag = &ts->gpencil_v2d_align; - - invert_m4_m4(p->imat, sc->unistabmat); - - /* custom color for new layer */ - p->custom_color[0] = 1.0f; - p->custom_color[1] = 0.0f; - p->custom_color[2] = 0.5f; - p->custom_color[3] = 0.9f; - - if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { - int framenr = ED_space_clip_get_clip_frame_number(sc); - MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking); - MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL; - - if (marker) { - p->imat[3][0] -= marker->pos[0]; - p->imat[3][1] -= marker->pos[1]; - } - else { - p->status = GP_STATUS_ERROR; - return false; - } - } - - invert_m4_m4(p->mat, p->imat); - copy_m4_m4(p->gsc.mat, p->mat); break; } + /* unsupported views */ default: { @@ -1533,7 +1703,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) /* get gp-data */ gpd_ptr = ED_gpencil_data_get_pointers(C, &p->ownerPtr); - if (gpd_ptr == NULL) { + if ((gpd_ptr == NULL) || ED_gpencil_data_owner_is_annotation(&p->ownerPtr)) { p->status = GP_STATUS_ERROR; if (G.debug & G_DEBUG) printf("Error: Current context doesn't allow for any Grease Pencil data\n"); @@ -1555,16 +1725,18 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) /* clear out buffer (stored in gp-data), in case something contaminated it */ gp_session_validatebuffer(p); + /* set brush and create a new one if null */ - gp_init_drawing_brush(ts, p); - /* set palette info and create a new one if null */ - gp_init_palette(p); - /* set palette colors */ - bGPDpalettecolor *palcolor = p->palettecolor; - bGPdata *pdata = p->gpd; - copy_v4_v4(pdata->scolor, palcolor->color); - copy_v4_v4(pdata->sfill, palcolor->fill); - pdata->sflag = palcolor->flag; + gp_init_drawing_brush(C, p); + + /* setup active color */ + if (curarea->spacetype == SPACE_VIEW3D) { + /* NOTE: This is only done for 3D view, as Materials aren't used for + * annotations in 2D editors + */ + gp_init_colors(p); + } + /* lock axis */ p->lock_axis = ts->gp_sculpt.lock_axis; @@ -1572,20 +1744,22 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) } /* init new painting session */ -static tGPsdata *gp_session_initpaint(bContext *C) +static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op) { tGPsdata *p = NULL; /* create new context data */ p = MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data"); - gp_session_initdata(C, p); + gp_session_initdata(C, op, p); +#if 0 /* radius for eraser circle is defined in userprefs now */ /* NOTE: we do this here, so that if we exit immediately, * erase size won't get lost */ p->radius = U.gp_eraser; +#endif /* Random generator, only init once. */ uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); @@ -1606,15 +1780,15 @@ static void gp_session_cleanup(tGPsdata *p) return; /* free stroke buffer */ - if (gpd->sbuffer) { + if (gpd->runtime.sbuffer) { /* printf("\t\tGP - free sbuffer\n"); */ - MEM_freeN(gpd->sbuffer); - gpd->sbuffer = NULL; + MEM_freeN(gpd->runtime.sbuffer); + gpd->runtime.sbuffer = NULL; } /* clear flags */ - gpd->sbuffer_size = 0; - gpd->sbuffer_sflag = 0; + gpd->runtime.sbuffer_size = 0; + gpd->runtime.sbuffer_sflag = 0; p->inittime = 0.0; } @@ -1632,11 +1806,12 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps { Scene *scene = p->scene; ToolSettings *ts = scene->toolsettings; + int cfra_eval = (int)DEG_get_ctime(p->depsgraph); /* get active layer (or add a new one if non-existent) */ p->gpl = BKE_gpencil_layer_getactive(p->gpd); if (p->gpl == NULL) { - p->gpl = BKE_gpencil_layer_addnew(p->gpd, "GP_Layer", true); + p->gpl = BKE_gpencil_layer_addnew(p->gpd, DATA_("GP_Layer"), true); if (p->custom_color[3]) copy_v3_v3(p->gpl->color, p->custom_color); @@ -1670,7 +1845,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps * -> If there are no strokes in that frame, don't add a new empty frame */ if (gpl->actframe && gpl->actframe->strokes.first) { - gpl->actframe = BKE_gpencil_layer_getframe(gpl, CFRA, GP_GETFRAME_ADD_COPY); + gpl->actframe = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_ADD_COPY); has_layer_to_erase = true; } @@ -1708,7 +1883,9 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps else add_frame_mode = GP_GETFRAME_ADD_NEW; - p->gpf = BKE_gpencil_layer_getframe(p->gpl, CFRA, add_frame_mode); + p->gpf = BKE_gpencil_layer_getframe(p->gpl, cfra_eval, add_frame_mode); + /* set as dirty draw manager cache */ + gp_update_cache(p->gpd); if (p->gpf == NULL) { p->status = GP_STATUS_ERROR; @@ -1724,7 +1901,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps /* set 'eraser' for this stroke if using eraser */ p->paintmode = paintmode; if (p->paintmode == GP_PAINTMODE_ERASER) { - p->gpd->sbuffer_sflag |= GP_STROKE_ERASER; + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_ERASER; /* check if we should respect depth while erasing */ if (p->sa->spacetype == SPACE_VIEW3D) { @@ -1735,7 +1912,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps } else { /* disable eraser flags - so that we can switch modes during a session */ - p->gpd->sbuffer_sflag &= ~GP_STROKE_ERASER; + p->gpd->runtime.sbuffer_sflag &= ~GP_STROKE_ERASER; if (p->sa->spacetype == SPACE_VIEW3D) { if (p->gpl->flag & GP_LAYER_NO_XRAY) { @@ -1744,10 +1921,16 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps } } + /* set special fill stroke mode */ + if (p->disable_fill == true) { + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_NOFILL; + /* replace stroke color with fill color */ + copy_v4_v4(p->gpd->runtime.scolor, p->gpd->runtime.sfill); + } + /* set 'initial run' flag, which is only used to denote when a new stroke is starting */ p->flags |= GP_PAINTFLAG_FIRSTRUN; - /* when drawing in the camera view, in 2D space, set the subrect */ p->subrect = NULL; if ((*p->align_flag & GP_PROJECT_VIEWSPACE) == 0) { @@ -1782,41 +1965,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps switch (p->sa->spacetype) { case SPACE_VIEW3D: { - p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE; - break; - } - case SPACE_NODE: - { - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; - break; - } - case SPACE_SEQ: - { - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; - break; - } - case SPACE_IMAGE: - { - SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first; - - /* only set these flags if the image editor doesn't have an image active, - * otherwise user will be confused by strokes not appearing after they're drawn - * - * Admittedly, this is a bit hacky, but it works much nicer from an ergonomic standpoint! - */ - if (ELEM(NULL, sima, sima->image)) { - /* make strokes be drawn in screen space */ - p->gpd->sbuffer_sflag &= ~GP_STROKE_2DSPACE; - *(p->align_flag) &= ~GP_PROJECT_VIEWSPACE; - } - else { - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; - } - break; - } - case SPACE_CLIP: - { - p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + p->gpd->runtime.sbuffer_sflag |= GP_STROKE_3DSPACE; break; } } @@ -1839,7 +1988,7 @@ static void gp_paint_strokeend(tGPsdata *p) } /* check if doing eraser or not */ - if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) { + if ((p->gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) { /* simplify stroke before transferring? */ gp_stroke_simplify(p); @@ -1920,10 +2069,12 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en p->erasercursor = NULL; } else if (enable && !p->erasercursor) { + ED_gpencil_toggle_brush_cursor(p->C, false, NULL); /* enable cursor */ - p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C), - NULL, /* XXX */ - gpencil_draw_eraser, p); + p->erasercursor = WM_paint_cursor_activate( + CTX_wm_manager(C), + NULL, /* XXX */ + gpencil_draw_eraser, p); } } @@ -1943,13 +2094,26 @@ static bool gpencil_is_tablet_eraser_active(const wmEvent *event) static void gpencil_draw_exit(bContext *C, wmOperator *op) { tGPsdata *p = op->customdata; + bGPdata *gpd = CTX_data_gpencil_data(C); /* clear undo stack */ gpencil_undo_finish(); /* restore cursor to indicate end of drawing */ - WM_cursor_modal_restore(CTX_wm_window(C)); + if (p->sa->spacetype != SPACE_VIEW3D) { + WM_cursor_modal_restore(CTX_wm_window(C)); + } + else { + /* or restore paint if 3D view */ + if ((p) && (p->paintmode == GP_PAINTMODE_ERASER)) { + WM_cursor_modal_set(p->win, CURSOR_STD); + } + /* drawing batch cache is dirty now */ + if (gpd) { + gp_update_cache(gpd); + } + } /* don't assume that operator data exists at all */ if (p) { /* check size of buffer before cleanup, to determine if anything happened here */ @@ -1962,11 +2126,16 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) * NOTE: Do this even when not in eraser mode, as eraser may * have been toggled at some point. */ - U.gp_eraser = p->radius; + if (p->eraser) { + p->eraser->size = p->radius; + } /* cleanup */ gp_paint_cleanup(p); gp_session_cleanup(p); + ED_gpencil_toggle_brush_cursor(C, true, NULL); + + /* finally, free the temp data */ gp_session_free(p); } @@ -1986,9 +2155,18 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) { tGPsdata *p; eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode"); + ToolSettings *ts = CTX_data_tool_settings(C); + Brush *brush = BKE_brush_getactive_gpencil(ts); + + /* if mode is draw and the brush is eraser, cancel */ + if (paintmode != GP_PAINTMODE_ERASER) { + if ((brush) && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { + return 0; + } + } /* check context */ - p = op->customdata = gp_session_initpaint(C); + p = op->customdata = gp_session_initpaint(C, op); if ((p == NULL) || (p->status == GP_STATUS_ERROR)) { /* something wasn't set correctly in context */ gpencil_draw_exit(C, op); @@ -2009,6 +2187,8 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) p->keymodifier = -1; } + p->reports = op->reports; + /* everything is now setup ok */ return 1; } @@ -2019,10 +2199,15 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) /* ensure that the correct cursor icon is set */ static void gpencil_draw_cursor_set(tGPsdata *p) { - if (p->paintmode == GP_PAINTMODE_ERASER) + Brush *brush = p->brush; + if ((p->paintmode == GP_PAINTMODE_ERASER) || + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + { WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */ - else - WM_cursor_modal_set(p->win, BC_PAINTBRUSHCURSOR); + } + else { + WM_cursor_modal_set(p->win, CURSOR_STD); + } } /* update UI indicators of status, including cursor and header prints */ @@ -2030,11 +2215,21 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) { /* header prints */ switch (p->status) { - case GP_STATUS_PAINTING: - /* only print this for paint-sessions, otherwise it gets annoying */ - if (GPENCIL_SKETCH_SESSIONS_ON(p->scene)) - ED_workspace_status_text(C, IFACE_("Grease Pencil: Drawing/erasing stroke... Release to end stroke")); - break; + +#if 0 /* FIXME, this never runs! */ + switch (p->paintmode) { + case GP_PAINTMODE_DRAW_POLY: + /* Provide usage tips, since this is modal, and unintuitive without hints */ + ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | " + "ESC/Enter to end (or click outside this area)")); + break; + default: + /* Do nothing - the others are self explanatory, exit quickly once the mouse is released + * Showing any text would just be annoying as it would flicker. + */ + break; + } +#endif case GP_STATUS_IDLING: /* print status info */ @@ -2048,12 +2243,11 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) "ESC/Enter to end (or click outside this area)")); break; case GP_PAINTMODE_DRAW: - ED_workspace_status_text(C, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw | " - "E/ESC/Enter to end (or click outside this area)")); + ED_workspace_status_text(C, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw")); break; case GP_PAINTMODE_DRAW_POLY: ED_workspace_status_text(C, IFACE_("Grease Pencil Poly Session: LMB click to place next stroke vertex | " - "ESC/Enter to end (or click outside this area)")); + "Release Shift/ESC/Enter to end (or click outside this area)")); break; default: /* unhandled future cases */ @@ -2067,14 +2261,19 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) /* clear status string */ ED_workspace_status_text(C, NULL); break; + case GP_STATUS_PAINTING: + break; } } /* ------------------------------- */ /* create a new stroke point at the point indicated by the painting context */ -static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph) +static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgraph *depsgraph) { + bGPdata *gpd = p->gpd; + tGPspoint *pt = NULL; + /* handle drawing/erasing -> test for erasing first */ if (p->paintmode == GP_PAINTMODE_ERASER) { /* do 'live' erasing now */ @@ -2087,6 +2286,17 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph } /* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */ else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) { + + /* if lazy mouse, interpolate the last and current mouse positions */ + if (GPENCIL_LAZY_MODE(p->brush, p->shift)) { + float now_mouse[2]; + float last_mouse[2]; + copy_v2fl_v2i(now_mouse, p->mval); + copy_v2fl_v2i(last_mouse, p->mvalo); + interp_v2_v2v2(now_mouse, now_mouse, last_mouse, p->brush->smooth_stroke_factor); + round_v2i_v2fl(p->mval, now_mouse); + } + /* try to add point */ short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime); @@ -2124,11 +2334,24 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph p->mvalo[1] = p->mval[1]; p->opressure = p->pressure; p->ocurtime = p->curtime; + + pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1; + if (p->paintmode != GP_PAINTMODE_ERASER) { + ED_gpencil_toggle_brush_cursor(C, true, &pt->x); + } + } + else if ((p->brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) && + (gpd->runtime.sbuffer_size > 0)) + { + pt = (tGPspoint *)gpd->runtime.sbuffer + gpd->runtime.sbuffer_size - 1; + if (p->paintmode != GP_PAINTMODE_ERASER) { + ED_gpencil_toggle_brush_cursor(C, true, &pt->x); + } } } /* handle draw event */ -static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsgraph *depsgraph) +static void gpencil_draw_apply_event(bContext *C, wmOperator *op, const wmEvent *event, Depsgraph *depsgraph, int x, int y) { tGPsdata *p = op->customdata; PointerRNA itemptr; @@ -2136,13 +2359,15 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg int tablet = 0; /* convert from window-space to area-space mouse coordinates + * add any x,y override position for fake events * NOTE: float to ints conversions, +1 factor is probably used to ensure a bit more accurate rounding... */ - p->mval[0] = event->mval[0] + 1; - p->mval[1] = event->mval[1] + 1; + p->mval[0] = event->mval[0] + 1 - x; + p->mval[1] = event->mval[1] + 1 - y; + p->shift = event->shift; /* verify key status for straight lines */ - if ((event->ctrl > 0) || (event->alt > 0)) { + if ((event->alt > 0) && (RNA_boolean_get(op->ptr, "disable_straight") == false)) { if (p->straight[0] == 0) { int dx = abs(p->mval[0] - p->mvalo[0]); int dy = abs(p->mval[1] - p->mvalo[1]); @@ -2151,12 +2376,12 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg if (dx >= dy) { /* horizontal */ p->straight[0] = 1; - p->straight[1] = p->mval[1]; /* save y */ + p->straight[1] = (short)p->mval[1]; /* save y */ } else { /* vertical */ p->straight[0] = 2; - p->straight[1] = p->mval[0]; /* save x */ + p->straight[1] = (short)p->mval[0]; /* save x */ } } } @@ -2191,6 +2416,22 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg p->pressure = 1.0f; } + /* special eraser modes */ + if (p->paintmode == GP_PAINTMODE_ERASER) { + if (event->shift > 0) { + p->flags |= GP_PAINTFLAG_HARD_ERASER; + } + else { + p->flags &= ~GP_PAINTFLAG_HARD_ERASER; + } + if (event->alt > 0) { + p->flags |= GP_PAINTFLAG_STROKE_ERASER; + } + else { + p->flags &= ~GP_PAINTFLAG_STROKE_ERASER; + } + } + /* special exception for start of strokes (i.e. maybe for just a dot) */ if (p->flags & GP_PAINTFLAG_FIRSTRUN) { p->flags &= ~GP_PAINTFLAG_FIRSTRUN; @@ -2233,7 +2474,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsg RNA_float_set(&itemptr, "time", p->curtime - p->inittime); /* apply the current latest drawing point */ - gpencil_draw_apply(op, p, depsgraph); + gpencil_draw_apply(C, op, p, depsgraph); /* force refresh */ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ @@ -2251,7 +2492,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) /* try to initialize context data needed while drawing */ if (!gpencil_draw_init(C, op, NULL)) { - if (op->customdata) MEM_freeN(op->customdata); + MEM_SAFE_FREE(op->customdata); /* printf("\tGP - no valid data\n"); */ return OPERATOR_CANCELLED; } @@ -2298,7 +2539,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) } /* apply this data as necessary now (as per usual) */ - gpencil_draw_apply(op, p, depsgraph); + gpencil_draw_apply(C, op, p, depsgraph); } RNA_END; @@ -2324,6 +2565,11 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event if (G.debug & G_DEBUG) printf("GPencil - Starting Drawing\n"); + /* support for tablets eraser pen */ + if (gpencil_is_tablet_eraser_active(event)) { + RNA_enum_set(op->ptr, "mode", GP_PAINTMODE_ERASER); + } + /* try to initialize context data needed while drawing */ if (!gpencil_draw_init(C, op, event)) { if (op->customdata) @@ -2344,6 +2590,9 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event if (p->paintmode == GP_PAINTMODE_ERASER) { gpencil_draw_toggle_eraser_cursor(C, p, true); } + else { + ED_gpencil_toggle_brush_cursor(C, true, NULL); + } /* set cursor * NOTE: This may change later (i.e. intentionally via brush toggle, * or unintentionally if the user scrolls outside the area)... @@ -2357,7 +2606,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event p->status = GP_STATUS_PAINTING; /* handle the initial drawing - i.e. for just doing a simple dot */ - gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); + gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), 0, 0); op->flag |= OP_IS_MODAL_CURSOR_REGION; } else { @@ -2366,9 +2615,29 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event op->flag |= OP_IS_MODAL_CURSOR_REGION; } + /* enable paint mode */ + if (p->sa->spacetype == SPACE_VIEW3D) { + Object *ob = CTX_data_active_object(C); + if (ob && (ob->type == OB_GPENCIL) && ((p->gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0)) { + /* Just set paintmode flag... */ + p->gpd->flag |= GP_DATA_STROKE_PAINTMODE; + /* disable other GP modes */ + p->gpd->flag &= ~GP_DATA_STROKE_EDITMODE; + p->gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; + p->gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; + /* set workspace mode */ + ob->restore_mode = ob->mode; + ob->mode = OB_MODE_GPENCIL_PAINT; + /* redraw mode on screen */ + WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); + } + } + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + /* add a modal handler for this operator, so that we can then draw continuous strokes */ WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; } @@ -2397,7 +2666,7 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) /* XXX: watch it with the paintmode! in future, * it'd be nice to allow changing paint-mode when in sketching-sessions */ - if (gp_session_initdata(C, p)) + if (gp_session_initdata(C, op, p)) gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C)); if (p->status != GP_STATUS_ERROR) { @@ -2448,6 +2717,76 @@ static void gpencil_move_last_stroke_to_back(bContext *C) BLI_insertlinkbefore(&gpf->strokes, gpf->strokes.first, gps); } +/* add events for missing mouse movements when the artist draw very fast */ +static void gpencil_add_missing_events(bContext *C, wmOperator *op, const wmEvent *event, tGPsdata *p) +{ + Brush *brush = p->brush; + if (brush->gpencil_settings->input_samples == 0) { + return; + } + RegionView3D *rv3d = p->ar->regiondata; + float defaultpixsize = rv3d->pixsize * 1000.0f; + int samples = (GP_MAX_INPUT_SAMPLES - brush->gpencil_settings->input_samples + 1); + float thickness = (float)brush->size; + + float pt[2], a[2], b[2]; + float vec[3]; + float scale = 1.0f; + + /* get pixel scale */ + gp_get_3d_reference(p, vec); + mul_m4_v3(rv3d->persmat, vec); + if (rv3d->is_persp) { + scale = vec[2] * defaultpixsize; + } + else { + scale = defaultpixsize; + } + + /* The thickness of the brush is reduced of thickness to get overlap dots */ + float dot_factor = 0.50f; + if (samples < 2) { + dot_factor = 0.05f; + } + else if (samples < 4) { + dot_factor = 0.10f; + } + else if (samples < 7) { + dot_factor = 0.3f; + } + else if (samples < 10) { + dot_factor = 0.4f; + } + float factor = ((thickness * dot_factor) / scale) * samples; + + copy_v2fl_v2i(a, p->mvalo); + b[0] = event->mval[0] + 1; + b[1] = event->mval[1] + 1; + + /* get distance in pixels */ + float dist = len_v2v2(a, b); + + /* for very small distances, add a half way point */ + if (dist <= 2.0f) { + interp_v2_v2v2(pt, a, b, 0.5f); + sub_v2_v2v2(pt, b, pt); + /* create fake event */ + gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), + (int)pt[0], (int)pt[1]); + } + else if (dist >= factor) { + int slices = 2 + (int)((dist - 1.0) / factor); + float n = 1.0f / slices; + for (int i = 1; i < slices; i++) { + interp_v2_v2v2(pt, a, b, n * i); + sub_v2_v2v2(pt, b, pt); + /* create fake event */ + gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), + (int)pt[0], (int)pt[1]); + } + } +} + /* events handling during interactive drawing part of operator */ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) { @@ -2488,10 +2827,6 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) * is essential for ensuring that they can quickly return to that view */ } - else if ((ELEM(event->type, p->keymodifier)) && (event->val == KM_RELEASE)) { - /* enable continuous if release D key in mid drawing */ - p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON; - } else if ((event->type == BKEY) && (event->val == KM_RELEASE)) { /* Add Blank Frame * - Since this operator is non-modal, we can just call it here, and keep going... @@ -2510,7 +2845,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) /* exit painting mode (and/or end current stroke) * NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647] */ - if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) { + /* if polyline and release shift must cancel */ + if ((ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY, EKEY)) || + ((p->paintmode == GP_PAINTMODE_DRAW_POLY) && (event->shift == 0))) + { /* exit() ends the current stroke before cleaning up */ /* printf("\t\tGP - end of paint op + end of stroke\n"); */ /* if drawing polygon and enable on back, must move stroke */ @@ -2537,10 +2875,8 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) int sketch = 0; /* basically, this should be mouse-button up = end stroke - * BUT what happens next depends on whether we 'painting sessions' is enabled + * BUT, polyline drawing is an exception -- all knots should be added during one session */ - sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene); - /* polyline drawing is also 'sketching' -- all knots should be added during one session */ sketch |= (p->paintmode == GP_PAINTMODE_DRAW_POLY); if (sketch) { @@ -2585,6 +2921,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) } } } + /* drawing batch cache is dirty now */ + gp_update_cache(p->gpd); + p->status = GP_STATUS_DONE; estate = OPERATOR_FINISHED; } @@ -2689,7 +3028,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { /* handle drawing event */ /* printf("\t\tGP - add point\n"); */ - gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); + gpencil_add_missing_events(C, op, event, p); + + gpencil_draw_apply_event(C, op, event, CTX_data_depsgraph(C), 0, 0); /* finish painting operation if anything went wrong just now */ if (p->status == GP_STATUS_ERROR) { @@ -2791,7 +3132,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot) /* identifiers */ ot->name = "Grease Pencil Draw"; ot->idname = "GPENCIL_OT_draw"; - ot->description = "Make annotations on the active data"; + ot->description = "Draw a new stroke in the active Grease Pencil Object"; /* api callbacks */ ot->exec = gpencil_draw_exec; @@ -2811,5 +3152,11 @@ void GPENCIL_OT_draw(wmOperatorType *ot) /* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */ prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + prop = RNA_def_boolean(ot->srna, "disable_straight", false, "No Straight lines", "Disable key for straight lines"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + + prop = RNA_def_boolean(ot->srna, "disable_fill", false, "No Fill Areas", "Disable fill to use stroke as fill boundary"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c new file mode 100644 index 00000000000..ef09c5c3f76 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -0,0 +1,712 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + * Operators for creating new Grease Pencil primitives (boxes, circles, ...) + */ + +/** \file blender/editors/gpencil/gpencil_primitive.c + * \ingroup edgpencil + */ + + +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BLT_translation.h" + +#include "DNA_brush_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_main.h" +#include "BKE_brush.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_library.h" +#include "BKE_material.h" +#include "BKE_paint.h" +#include "BKE_report.h" + +#include "UI_interface.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "ED_gpencil.h" +#include "ED_object.h" +#include "ED_screen.h" +#include "ED_view3d.h" +#include "ED_space_api.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "gpencil_intern.h" + +#define MIN_EDGES 2 +#define MAX_EDGES 100 + +#define IDLE 0 +#define IN_PROGRESS 1 + +/* ************************************************ */ +/* Core/Shared Utilities */ + +/* Poll callback for primitive operators */ +static bool gpencil_primitive_add_poll(bContext *C) +{ + /* only 3D view */ + ScrArea *sa = CTX_wm_area(C); + if (sa && sa->spacetype != SPACE_VIEW3D) { + return 0; + } + + /* need data to create primitive */ + bGPdata *gpd = CTX_data_gpencil_data(C); + if (gpd == NULL) { + return 0; + } + + /* only in edit and paint modes + * - paint as it's the "drawing/creation mode" + * - edit as this is more of an atomic editing operation + * (similar to copy/paste), and also for consistency + */ + if ((gpd->flag & (GP_DATA_STROKE_PAINTMODE | GP_DATA_STROKE_EDITMODE)) == 0) { + CTX_wm_operator_poll_msg_set(C, "Primitives can only be added in Draw or Edit modes"); + return 0; + } + + /* don't allow operator to function if the active layer is locked/hidden + * (BUT, if there isn't an active layer, we are free to add new layer when the time comes) + */ + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + if ((gpl) && (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_HIDE))) { + CTX_wm_operator_poll_msg_set(C, "Primitives cannot be added as active layer is locked or hidden"); + return 0; + } + + return 1; +} + + +/* ****************** Primitive Interactive *********************** */ + +/* Helper: Create internal strokes primitives data */ +static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi) +{ + ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + Brush *brush; + + /* if brush doesn't exist, create a new one */ + Paint *paint = BKE_brush_get_gpencil_paint(ts); + /* if not exist, create a new one */ + if (paint->brush == NULL) { + /* create new brushes */ + BKE_brush_gpencil_presets(C); + brush = BKE_brush_getactive_gpencil(ts); + } + else { + /* Use the current */ + brush = BKE_brush_getactive_gpencil(ts); + } + tgpi->brush = brush; + + /* if layer doesn't exist, create a new one */ + if (gpl == NULL) { + gpl = BKE_gpencil_layer_addnew(tgpi->gpd, DATA_("Primitives"), true); + } + tgpi->gpl = gpl; + + /* create a new temporary frame */ + tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe"); + tgpi->gpf->framenum = tgpi->cframe = cfra_eval; + + /* create new temp stroke */ + bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "Temp bGPDstroke"); + gps->thickness = 2.0f; + gps->inittime = 0.0f; + + /* enable recalculation flag by default */ + gps->flag |= GP_STROKE_RECALC_CACHES; + /* the polygon must be closed, so enabled cyclic */ + gps->flag |= GP_STROKE_CYCLIC; + gps->flag |= GP_STROKE_3DSPACE; + + gps->mat_nr = BKE_object_material_slot_find_index(tgpi->ob, tgpi->mat) - 1; + + /* allocate memory for storage points, but keep empty */ + gps->totpoints = 0; + gps->points = MEM_callocN(sizeof(bGPDspoint), "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert), "gp_stroke_weights"); + /* initialize triangle memory to dummy data */ + gps->tot_triangles = 0; + gps->triangles = NULL; + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* add to strokes */ + BLI_addtail(&tgpi->gpf->strokes, gps); +} + +/* ----------------------- */ +/* Drawing Callbacks */ + +/* Drawing callback for modal operator in 3d mode */ +static void gpencil_primitive_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg) +{ + tGPDprimitive *tgpi = (tGPDprimitive *)arg; + ED_gp_draw_primitives(C, tgpi, REGION_DRAW_POST_VIEW); +} + +/* ----------------------- */ + +/* Helper: Draw status message while the user is running the operator */ +static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi) +{ + Scene *scene = tgpi->scene; + char status_str[UI_MAX_DRAW_STR]; + char msg_str[UI_MAX_DRAW_STR]; + + if (tgpi->type == GP_STROKE_BOX) { + BLI_strncpy(msg_str, IFACE_("Rectangle: ESC/RMB to cancel, LMB set origin, Enter/LMB to confirm, Shift to square"), UI_MAX_DRAW_STR); + } + else if (tgpi->type == GP_STROKE_LINE) { + BLI_strncpy(msg_str, IFACE_("Line: ESC/RMB to cancel, LMB set origin, Enter/LMB to confirm"), UI_MAX_DRAW_STR); + } + else { + BLI_strncpy(msg_str, IFACE_("Circle: ESC/RMB to cancel, Enter/LMB to confirm, WHEEL to adjust edge number, Shift to square"), UI_MAX_DRAW_STR); + } + + if (tgpi->type == GP_STROKE_CIRCLE) { + if (hasNumInput(&tgpi->num)) { + char str_offs[NUM_STR_REP_LEN]; + + outputNumInput(&tgpi->num, str_offs, &scene->unit); + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", msg_str, str_offs); + } + else { + if (tgpi->flag == IN_PROGRESS) { + BLI_snprintf(status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + } + else { + BLI_snprintf(status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->bottom[0], tgpi->bottom[1]); + } + } + } + else { + if (tgpi->flag == IN_PROGRESS) { + BLI_snprintf(status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + } + else { + BLI_snprintf(status_str, sizeof(status_str), "%s: (%d, %d)", msg_str, + tgpi->bottom[0], tgpi->bottom[1]); + } + } + ED_workspace_status_text(C, status_str); +} + +/* ----------------------- */ + +/* create a rectangle */ +static void gp_primitive_rectangle(tGPDprimitive *tgpi, tGPspoint *points2D) +{ + BLI_assert(tgpi->tot_edges == 4); + + points2D[0].x = tgpi->top[0]; + points2D[0].y = tgpi->top[1]; + + points2D[1].x = tgpi->bottom[0]; + points2D[1].y = tgpi->top[1]; + + points2D[2].x = tgpi->bottom[0]; + points2D[2].y = tgpi->bottom[1]; + + points2D[3].x = tgpi->top[0]; + points2D[3].y = tgpi->bottom[1]; +} + +/* create a line */ +static void gp_primitive_line(tGPDprimitive *tgpi, tGPspoint *points2D) +{ + BLI_assert(tgpi->tot_edges == 2); + + points2D[0].x = tgpi->top[0]; + points2D[0].y = tgpi->top[1]; + + points2D[1].x = tgpi->bottom[0]; + points2D[1].y = tgpi->bottom[1]; +} + +/* create a circle */ +static void gp_primitive_circle(tGPDprimitive *tgpi, tGPspoint *points2D) +{ + const int totpoints = tgpi->tot_edges; + const float step = (2.0f * M_PI) / (float)(totpoints); + float center[2]; + float radius[2]; + float a = 0.0f; + + /* TODO: Use math-lib functions for these? */ + center[0] = tgpi->top[0] + ((tgpi->bottom[0] - tgpi->top[0]) / 2.0f); + center[1] = tgpi->top[1] + ((tgpi->bottom[1] - tgpi->top[1]) / 2.0f); + radius[0] = fabsf(((tgpi->bottom[0] - tgpi->top[0]) / 2.0f)); + radius[1] = fabsf(((tgpi->bottom[1] - tgpi->top[1]) / 2.0f)); + + for (int i = 0; i < totpoints; i++) { + tGPspoint *p2d = &points2D[i]; + + p2d->x = (int)(center[0] + cosf(a) * radius[0]); + p2d->y = (int)(center[1] + sinf(a) * radius[1]); + a += step; + } +} + +/* Helper: Update shape of the stroke */ +static void gp_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) +{ + ToolSettings *ts = tgpi->scene->toolsettings; + bGPdata *gpd = tgpi->gpd; + bGPDstroke *gps = tgpi->gpf->strokes.first; + + /* realloc points to new size */ + /* TODO: only do this if the size has changed? */ + gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * tgpi->tot_edges); + gps->dvert = MEM_reallocN(gps->dvert, sizeof(MDeformVert) * tgpi->tot_edges); + gps->totpoints = tgpi->tot_edges; + + /* compute screen-space coordinates for points */ + tGPspoint *points2D = MEM_callocN(sizeof(tGPspoint) * tgpi->tot_edges, "gp primitive points2D"); + switch (tgpi->type) { + case GP_STROKE_BOX: + gp_primitive_rectangle(tgpi, points2D); + break; + case GP_STROKE_LINE: + gp_primitive_line(tgpi, points2D); + break; + case GP_STROKE_CIRCLE: + gp_primitive_circle(tgpi, points2D); + break; + default: + break; + } + + /* convert screen-coordinates to 3D coordinates */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + tGPspoint *p2d = &points2D[i]; + + + /* convert screen-coordinates to 3D coordinates */ + gp_stroke_convertcoords_tpoint(tgpi->scene, tgpi->ar, tgpi->v3d, tgpi->ob, tgpi->gpl, p2d, NULL, &pt->x); + + pt->pressure = 1.0f; + pt->strength = tgpi->brush->gpencil_settings->draw_strength; + pt->time = 0.0f; + + dvert->totweight = 0; + dvert->dw = NULL; + } + + /* if axis locked, reproject to plane locked */ + if (tgpi->lock_axis > GP_LOCKAXIS_NONE) { + bGPDspoint *tpt = gps->points; + float origin[3]; + ED_gp_get_drawing_reference(tgpi->v3d, tgpi->scene, tgpi->ob, tgpi->gpl, + ts->gpencil_v3d_align, origin); + + for (int i = 0; i < gps->totpoints; i++, tpt++) { + ED_gp_project_point_to_plane(tgpi->ob, tgpi->rv3d, origin, + ts->gp_sculpt.lock_axis - 1, + tpt); + } + } + + /* if parented change position relative to parent object */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + gp_apply_parent_point(tgpi->depsgraph, tgpi->ob, tgpi->gpd, tgpi->gpl, pt); + } + + /* force fill recalc */ + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* free temp data */ + MEM_SAFE_FREE(points2D); + + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); +} + +/* Update screen and stroke */ +static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive *tgpi) +{ + /* update indicator in header */ + gpencil_primitive_status_indicators(C, tgpi); + /* apply... */ + tgpi->type = RNA_enum_get(op->ptr, "type"); + tgpi->tot_edges = RNA_int_get(op->ptr, "edges"); + /* update points position */ + gp_primitive_update_strokes(C, tgpi); +} + +/* ----------------------- */ + +/* Exit and free memory */ +static void gpencil_primitive_exit(bContext *C, wmOperator *op) +{ + tGPDprimitive *tgpi = op->customdata; + bGPdata *gpd = tgpi->gpd; + + /* don't assume that operator data exists at all */ + if (tgpi) { + /* remove drawing handler */ + if (tgpi->draw_handle_3d) { + ED_region_draw_cb_exit(tgpi->ar->type, tgpi->draw_handle_3d); + } + + /* clear status message area */ + ED_workspace_status_text(C, NULL); + + /* finally, free memory used by temp data */ + BKE_gpencil_free_strokes(tgpi->gpf); + MEM_freeN(tgpi->gpf); + MEM_freeN(tgpi); + } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + + /* clear pointer */ + op->customdata = NULL; +} + +/* Init new temporary primitive data */ +static void gpencil_primitive_init(bContext *C, wmOperator *op) +{ + ToolSettings *ts = CTX_data_tool_settings(C); + bGPdata *gpd = CTX_data_gpencil_data(C); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + + /* create temporary operator data */ + tGPDprimitive *tgpi = MEM_callocN(sizeof(tGPDprimitive), "GPencil Primitive Data"); + op->customdata = tgpi; + + /* set current scene and window info */ + tgpi->scene = scene; + tgpi->ob = CTX_data_active_object(C); + tgpi->sa = CTX_wm_area(C); + tgpi->ar = CTX_wm_region(C); + tgpi->rv3d = tgpi->ar->regiondata; + tgpi->v3d = tgpi->sa->spacedata.first; + tgpi->depsgraph = CTX_data_depsgraph(C); + tgpi->win = CTX_wm_window(C); + + /* set current frame number */ + tgpi->cframe = cfra_eval; + + /* set GP datablock */ + tgpi->gpd = gpd; + + /* getcolor info */ + tgpi->mat = BKE_gpencil_material_ensure(bmain, tgpi->ob); + + /* set parameters */ + tgpi->type = RNA_enum_get(op->ptr, "type"); + + /* if circle set default to 32 */ + if (tgpi->type == GP_STROKE_CIRCLE) { + RNA_int_set(op->ptr, "edges", 32); + } + else if(tgpi->type == GP_STROKE_BOX) { + RNA_int_set(op->ptr, "edges", 4); + } + else { /* LINE */ + RNA_int_set(op->ptr, "edges", 2); + } + + tgpi->tot_edges = RNA_int_get(op->ptr, "edges"); + tgpi->flag = IDLE; + + tgpi->lock_axis = ts->gp_sculpt.lock_axis; + + /* set temp layer, frame and stroke */ + gp_primitive_set_initdata(C, tgpi); +} + +/* ----------------------- */ + +/* Invoke handler: Initialize the operator */ +static int gpencil_primitive_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + wmWindow *win = CTX_wm_window(C); + bGPdata *gpd = CTX_data_gpencil_data(C); + tGPDprimitive *tgpi = NULL; + + /* initialize operator runtime data */ + gpencil_primitive_init(C, op); + tgpi = op->customdata; + + /* if in tools region, wait till we get to the main (3d-space) + * region before allowing drawing to take place. + */ + op->flag |= OP_IS_MODAL_CURSOR_REGION; + + /* Enable custom drawing handlers */ + tgpi->draw_handle_3d = ED_region_draw_cb_activate(tgpi->ar->type, gpencil_primitive_draw_3d, tgpi, REGION_DRAW_POST_VIEW); + + /* set cursor to indicate modal */ + WM_cursor_modal_set(win, BC_CROSSCURSOR); + + /* update sindicator in header */ + gpencil_primitive_status_indicators(C, tgpi); + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + + /* add a modal handler for this operator */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +/* Helper to complete a primitive */ +static void gpencil_primitive_done(bContext *C, wmOperator *op, wmWindow *win, tGPDprimitive *tgpi) +{ + bGPDframe *gpf; + bGPDstroke *gps; + + /* return to normal cursor and header status */ + ED_workspace_status_text(C, NULL); + WM_cursor_modal_restore(win); + + /* insert keyframes as required... */ + gpf = BKE_gpencil_layer_getframe(tgpi->gpl, tgpi->cframe, GP_GETFRAME_ADD_NEW); + + /* prepare stroke to get transfered */ + gps = tgpi->gpf->strokes.first; + if (gps) { + gps->thickness = tgpi->brush->size; + gps->flag |= GP_STROKE_RECALC_CACHES; + } + + /* transfer stroke from temporary buffer to the actual frame */ + BLI_movelisttolist(&gpf->strokes, &tgpi->gpf->strokes); + BLI_assert(BLI_listbase_is_empty(&tgpi->gpf->strokes)); + + /* clean up temp data */ + gpencil_primitive_exit(C, op); +} + +/* Modal handler: Events handling during interactive part */ +static int gpencil_primitive_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + tGPDprimitive *tgpi = op->customdata; + wmWindow *win = CTX_wm_window(C); + const bool has_numinput = hasNumInput(&tgpi->num); + + switch (event->type) { + case LEFTMOUSE: + if ((event->val == KM_PRESS) && (tgpi->flag == IDLE)) { + /* start drawing primitive */ + /* TODO: Ignore if not in main region yet */ + tgpi->flag = IN_PROGRESS; + + tgpi->top[0] = event->mval[0]; + tgpi->top[1] = event->mval[1]; + + tgpi->bottom[0] = event->mval[0]; + tgpi->bottom[1] = event->mval[1]; + } + else if ((event->val == KM_RELEASE) && (tgpi->flag == IN_PROGRESS)) { + /* stop drawing primitive */ + tgpi->flag = IDLE; + gpencil_primitive_done(C, op, win, tgpi); + /* done! */ + return OPERATOR_FINISHED; + } + else { + if (G.debug & G_DEBUG) { + printf("GP Add Primitive Modal: LEFTMOUSE %d, Status = %d\n", event->val, tgpi->flag); + } + } + break; + case RETKEY: /* confirm */ + { + tgpi->flag = IDLE; + gpencil_primitive_done(C, op, win, tgpi); + /* done! */ + return OPERATOR_FINISHED; + } + + case ESCKEY: /* cancel */ + case RIGHTMOUSE: + { + /* return to normal cursor and header status */ + ED_workspace_status_text(C, NULL); + WM_cursor_modal_restore(win); + + /* clean up temp data */ + gpencil_primitive_exit(C, op); + + /* canceled! */ + return OPERATOR_CANCELLED; + } + + case WHEELUPMOUSE: + { + if (tgpi->type == GP_STROKE_CIRCLE) { + tgpi->tot_edges = tgpi->tot_edges + 1; + CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES); + RNA_int_set(op->ptr, "edges", tgpi->tot_edges); + + /* update screen */ + gpencil_primitive_update(C, op, tgpi); + } + break; + } + case WHEELDOWNMOUSE: + { + if (tgpi->type == GP_STROKE_CIRCLE) { + tgpi->tot_edges = tgpi->tot_edges - 1; + CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES); + RNA_int_set(op->ptr, "edges", tgpi->tot_edges); + + /* update screen */ + gpencil_primitive_update(C, op, tgpi); + } + break; + } + case MOUSEMOVE: /* calculate new position */ + { + /* only handle mousemove if not doing numinput */ + if (has_numinput == false) { + /* update position of mouse */ + tgpi->bottom[0] = event->mval[0]; + tgpi->bottom[1] = event->mval[1]; + if (tgpi->flag == IDLE) { + tgpi->top[0] = event->mval[0]; + tgpi->top[1] = event->mval[1]; + } + /* Keep square if shift key */ + if (event->shift) { + tgpi->bottom[1] = tgpi->top[1] - (tgpi->bottom[0] - tgpi->top[0]); + } + /* update screen */ + gpencil_primitive_update(C, op, tgpi); + } + break; + } + default: + { + if ((event->val == KM_PRESS) && handleNumInput(C, &tgpi->num, event)) { + float value; + + /* Grab data from numeric input, and store this new value (the user see an int) */ + value = tgpi->tot_edges; + applyNumInput(&tgpi->num, &value); + tgpi->tot_edges = value; + + CLAMP(tgpi->tot_edges, MIN_EDGES, MAX_EDGES); + RNA_int_set(op->ptr, "edges", tgpi->tot_edges); + + /* update screen */ + gpencil_primitive_update(C, op, tgpi); + + break; + } + else { + /* unhandled event - allow to pass through */ + return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; + } + } + } + + /* still running... */ + return OPERATOR_RUNNING_MODAL; +} + +/* Cancel handler */ +static void gpencil_primitive_cancel(bContext *C, wmOperator *op) +{ + /* this is just a wrapper around exit() */ + gpencil_primitive_exit(C, op); +} + +void GPENCIL_OT_primitive(wmOperatorType *ot) +{ + static EnumPropertyItem primitive_type[] = { + { GP_STROKE_BOX, "BOX", 0, "Box", "" }, + { GP_STROKE_LINE, "LINE", 0, "Line", "" }, + { GP_STROKE_CIRCLE, "CIRCLE", 0, "Circle", "" }, + { 0, NULL, 0, NULL, NULL } + }; + + /* identifiers */ + ot->name = "Grease Pencil Shapes"; + ot->idname = "GPENCIL_OT_primitive"; + ot->description = "Create predefined grease pencil stroke shapes"; + + /* callbacks */ + ot->invoke = gpencil_primitive_invoke; + ot->modal = gpencil_primitive_modal; + ot->cancel = gpencil_primitive_cancel; + ot->poll = gpencil_primitive_add_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING; + + /* properties */ + RNA_def_int(ot->srna, "edges", 4, MIN_EDGES, MAX_EDGES, "Edges", "Number of polygon edges", MIN_EDGES, MAX_EDGES); + RNA_def_enum(ot->srna, "type", primitive_type, GP_STROKE_BOX, "Type", "Type of shape"); +} + +/* *************************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index dd556e99264..9386bfb3333 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -43,6 +43,7 @@ #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" +#include "DNA_space_types.h" #include "DNA_screen_types.h" #include "DNA_object_types.h" @@ -62,6 +63,9 @@ #include "ED_gpencil.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "gpencil_intern.h" /* ********************************************** */ @@ -71,8 +75,8 @@ static bool gpencil_select_poll(bContext *C) { bGPdata *gpd = ED_gpencil_data_get_active(C); - /* we just need some visible strokes, and to be in editmode */ - if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) { + /* we just need some visible strokes, and to be in editmode or other modes only to catch event */ + if (GPENCIL_ANY_MODE(gpd)) { /* TODO: include a check for visible strokes? */ if (gpd->layers.first) return true; @@ -94,6 +98,11 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + /* for "toggle", test for existing selected strokes */ if (action == SEL_TOGGLE) { action = SEL_SELECT; @@ -180,6 +189,11 @@ static int gpencil_select_all_exec(bContext *C, wmOperator *op) } /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -213,6 +227,11 @@ static int gpencil_select_linked_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + /* select all points in selected strokes */ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) { @@ -228,6 +247,11 @@ static int gpencil_select_linked_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -247,6 +271,86 @@ void GPENCIL_OT_select_linked(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ********************************************** */ +/* Select Alternate */ + +static int gpencil_select_alternate_exec(bContext *C, wmOperator *op) +{ + const bool unselect_ends = RNA_boolean_get(op->ptr, "unselect_ends"); + bGPdata *gpd = ED_gpencil_data_get_active(C); + + if (gpd == NULL) { + BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); + return OPERATOR_CANCELLED; + } + + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + + /* select all points in selected strokes */ + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if ((gps->flag & GP_STROKE_SELECT) && (gps->totpoints > 1)) { + bGPDspoint *pt; + int row = 0; + int start = 0; + if (unselect_ends) { + start = 1; + } + + for (int i = start; i < gps->totpoints; i++) { + pt = &gps->points[i]; + if ((row % 2) == 0) { + pt->flag |= GP_SPOINT_SELECT; + } + else { + pt->flag &= ~GP_SPOINT_SELECT; + } + row++; + } + + /* unselect start and end points */ + if (unselect_ends) { + pt = &gps->points[0]; + pt->flag &= ~GP_SPOINT_SELECT; + + pt = &gps->points[gps->totpoints - 1]; + pt->flag &= ~GP_SPOINT_SELECT; + } + } + } + CTX_DATA_END; + + /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); + return OPERATOR_FINISHED; +} + +void GPENCIL_OT_select_alternate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Alternated"; + ot->idname = "GPENCIL_OT_select_alternate"; + ot->description = "Select alternative points in same strokes as already selected points"; + + /* callbacks */ + ot->exec = gpencil_select_alternate_exec; + ot->poll = gpencil_select_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "unselect_ends", true, "Unselect Ends", "Do not select the first and last point of the stroke"); +} + /* ********************************************** */ /* Select Grouped */ @@ -266,11 +370,12 @@ typedef enum eGP_SelectGrouped { /* On each visible layer, check for selected strokes - if found, select all others */ static void gp_select_same_layer(bContext *C) { - Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0); + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); bGPDstroke *gps; bool found = false; @@ -309,10 +414,7 @@ static void gp_select_same_layer(bContext *C) /* Select all strokes with same colors as selected ones */ static void gp_select_same_color(bContext *C) { - /* First, build set containing all the colors of selected strokes - * - We use the palette names, so that we can select all strokes with one - * (potentially missing) color, and remap them to something else - */ + /* First, build set containing all the colors of selected strokes */ GSet *selected_colors = BLI_gset_str_new("GP Selected Colors"); CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) @@ -321,7 +423,7 @@ static void gp_select_same_color(bContext *C) /* add instead of insert here, otherwise the uniqueness check gets skipped, * and we get many duplicate entries... */ - BLI_gset_add(selected_colors, gps->colorname); + BLI_gset_add(selected_colors, &gps->mat_nr); } } CTX_DATA_END; @@ -329,7 +431,7 @@ static void gp_select_same_color(bContext *C) /* Second, select any visible stroke that uses these colors */ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) { - if (BLI_gset_haskey(selected_colors, gps->colorname)) { + if (BLI_gset_haskey(selected_colors, &gps->mat_nr)) { /* select this stroke */ bGPDspoint *pt; int i; @@ -342,6 +444,11 @@ static void gp_select_same_color(bContext *C) } } CTX_DATA_END; + + /* free memomy */ + if (selected_colors != NULL) { + BLI_gset_free(selected_colors, NULL); + } } @@ -350,6 +457,11 @@ static void gp_select_same_color(bContext *C) static int gpencil_select_grouped_exec(bContext *C, wmOperator *op) { eGP_SelectGrouped mode = RNA_enum_get(op->ptr, "type"); + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } switch (mode) { case GP_SEL_SAME_LAYER: @@ -365,6 +477,11 @@ static int gpencil_select_grouped_exec(bContext *C, wmOperator *op) } /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -399,6 +516,12 @@ void GPENCIL_OT_select_grouped(wmOperatorType *ot) static int gpencil_select_first_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); const bool extend = RNA_boolean_get(op->ptr, "extend"); @@ -429,6 +552,11 @@ static int gpencil_select_first_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -459,6 +587,12 @@ void GPENCIL_OT_select_first(wmOperatorType *ot) static int gpencil_select_last_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + const bool only_selected = RNA_boolean_get(op->ptr, "only_selected_strokes"); const bool extend = RNA_boolean_get(op->ptr, "extend"); @@ -489,6 +623,11 @@ static int gpencil_select_last_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -519,6 +658,12 @@ void GPENCIL_OT_select_last(wmOperatorType *ot) static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op)) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) { if (gps->flag & GP_STROKE_SELECT) { @@ -565,6 +710,11 @@ static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -589,6 +739,12 @@ void GPENCIL_OT_select_more(wmOperatorType *ot) static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op)) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) { if (gps->flag & GP_STROKE_SELECT) { @@ -636,6 +792,11 @@ static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* updates */ + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); return OPERATOR_FINISHED; } @@ -665,7 +826,7 @@ void GPENCIL_OT_select_less(wmOperatorType *ot) static bool gp_stroke_do_circle_sel( bGPDstroke *gps, GP_SpaceConversion *gsc, const int mx, const int my, const int radius, - const bool select, rcti *rect, const bool parented, float diff_mat[4][4]) + const bool select, rcti *rect, float diff_mat[4][4]) { bGPDspoint *pt1, *pt2; int x0 = 0, y0 = 0, x1 = 0, y1 = 0; @@ -673,14 +834,9 @@ static bool gp_stroke_do_circle_sel( bool changed = false; if (gps->totpoints == 1) { - if (!parented) { - gp_point_to_xy(gsc, gps, gps->points, &x0, &y0); - } - else { - bGPDspoint pt_temp; - gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); - gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0); - } + bGPDspoint pt_temp; + gp_point_to_parent_space(gps->points, diff_mat, &pt_temp); + gp_point_to_xy(gsc, gps, &pt_temp, &x0, &y0); /* do boundbox check first */ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { @@ -708,18 +864,12 @@ static bool gp_stroke_do_circle_sel( /* get points to work with */ pt1 = gps->points + i; pt2 = gps->points + i + 1; - if (!parented) { - gp_point_to_xy(gsc, gps, pt1, &x0, &y0); - gp_point_to_xy(gsc, gps, pt2, &x1, &y1); - } - else { - bGPDspoint npt; - gp_point_to_parent_space(pt1, diff_mat, &npt); - gp_point_to_xy(gsc, gps, &npt, &x0, &y0); + bGPDspoint npt; + gp_point_to_parent_space(pt1, diff_mat, &npt); + gp_point_to_xy(gsc, gps, &npt, &x0, &y0); - gp_point_to_parent_space(pt2, diff_mat, &npt); - gp_point_to_xy(gsc, gps, &npt, &x1, &y1); - } + gp_point_to_parent_space(pt2, diff_mat, &npt); + gp_point_to_xy(gsc, gps, &npt, &x1, &y1); /* check that point segment of the boundbox of the selection stroke */ if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || @@ -763,6 +913,12 @@ static bool gp_stroke_do_circle_sel( static int gpencil_circle_select_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* if not edit/sculpt mode, the event is catched but not processed */ + if (GPENCIL_NONE_EDIT_MODE(gpd)) { + return OPERATOR_CANCELLED; + } + ScrArea *sa = CTX_wm_area(C); const int mx = RNA_int_get(op->ptr, "x"); @@ -798,13 +954,17 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op) GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) { changed |= gp_stroke_do_circle_sel( - gps, &gsc, mx, my, radius, select, &rect, - (gpl->parent != NULL), diff_mat); + gps, &gsc, mx, my, radius, select, &rect, diff_mat); } GP_EDITABLE_STROKES_END; /* updates */ if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); } @@ -837,10 +997,11 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot) static int gpencil_border_select_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); ScrArea *sa = CTX_wm_area(C); const bool select = !RNA_boolean_get(op->ptr, "deselect"); - const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0); GP_SpaceConversion gsc = {NULL}; rcti rect = {0}; @@ -888,14 +1049,9 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op) int x0, y0; /* convert point coords to screenspace */ - if (gpl->parent == NULL) { - gp_point_to_xy(&gsc, gps, pt, &x0, &y0); - } - else { - bGPDspoint pt2; - gp_point_to_parent_space(pt, diff_mat, &pt2); - gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); - } + bGPDspoint pt2; + gp_point_to_parent_space(pt, diff_mat, &pt2); + gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); /* test if in selection rect */ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) { @@ -915,8 +1071,20 @@ static int gpencil_border_select_exec(bContext *C, wmOperator *op) } GP_EDITABLE_STROKES_END; + /* if paint mode,delete selected points */ + if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { + gp_delete_selected_point_wrap(C); + changed = true; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + /* updates */ if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); } @@ -950,10 +1118,11 @@ void GPENCIL_OT_select_border(wmOperatorType *ot) static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) { + bGPdata *gpd = ED_gpencil_data_get_active(C); GP_SpaceConversion gsc = {NULL}; rcti rect = {0}; - const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend") && ((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0); const bool select = !RNA_boolean_get(op->ptr, "deselect"); int mcords_tot; @@ -997,14 +1166,9 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) int x0, y0; /* convert point coords to screenspace */ - if (gpl->parent == NULL) { - gp_point_to_xy(&gsc, gps, pt, &x0, &y0); - } - else { - bGPDspoint pt2; - gp_point_to_parent_space(pt, diff_mat, &pt2); - gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); - } + bGPDspoint pt2; + gp_point_to_parent_space(pt, diff_mat, &pt2); + gp_point_to_xy(&gsc, gps, &pt2, &x0, &y0); /* test if in lasso boundbox + within the lasso noose */ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) && BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX)) @@ -1028,8 +1192,20 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op) /* cleanup */ MEM_freeN((void *)mcords); + /* if paint mode,delete selected points */ + if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { + gp_delete_selected_point_wrap(C); + changed = true; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + /* updates */ if (changed) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); } @@ -1061,6 +1237,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot) static int gpencil_select_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); + bGPdata *gpd = ED_gpencil_data_get_active(C); /* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */ const float radius = 0.75f * U.widget_unit; @@ -1102,14 +1279,9 @@ static int gpencil_select_exec(bContext *C, wmOperator *op) for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { int xy[2]; - if (gpl->parent == NULL) { - gp_point_to_xy(&gsc, gps, pt, &xy[0], &xy[1]); - } - else { - bGPDspoint pt2; - gp_point_to_parent_space(pt, diff_mat, &pt2); - gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]); - } + bGPDspoint pt2; + gp_point_to_parent_space(pt, diff_mat, &pt2); + gp_point_to_xy(&gsc, gps, &pt2, &xy[0], &xy[1]); /* do boundbox check first */ if (!ELEM(V2D_IS_CLIPPED, xy[0], xy[1])) { @@ -1197,6 +1369,11 @@ static int gpencil_select_exec(bContext *C, wmOperator *op) /* updates */ if (hit_point != NULL) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + + /* copy on write tag is needed, or else no refresh happens */ + DEG_id_tag_update(&gpd->id, DEG_TAG_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL); } diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c index d35df8bc380..708d8f37e58 100644 --- a/source/blender/editors/gpencil/gpencil_undo.c +++ b/source/blender/editors/gpencil/gpencil_undo.c @@ -36,6 +36,7 @@ #include "MEM_guardedalloc.h" #include "DNA_gpencil_types.h" +#include "DNA_object_types.h" #include "DNA_listBase.h" #include "DNA_windowmanager_types.h" @@ -51,6 +52,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "DEG_depsgraph.h" + #include "gpencil_intern.h" typedef struct bGPundonode { @@ -111,6 +114,9 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name) } } } + /* drawing batch cache is dirty now */ + DEG_id_tag_update(&new_gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + new_gpd->flag |= GP_DATA_CACHE_IS_DIRTY; } WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 8b65855f7c4..7262c537321 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -40,7 +40,9 @@ #include "BLT_translation.h" #include "BLI_rand.h" +#include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" +#include "DNA_brush_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -48,9 +50,13 @@ #include "DNA_view3d_types.h" #include "BKE_action.h" +#include "BKE_main.h" +#include "BKE_brush.h" #include "BKE_context.h" #include "BKE_gpencil.h" -#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_material.h" #include "BKE_tracking.h" #include "WM_api.h" @@ -65,8 +71,14 @@ #include "ED_gpencil.h" #include "ED_clip.h" #include "ED_view3d.h" +#include "ED_object.h" +#include "ED_screen.h" + +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "gpencil_intern.h" @@ -76,7 +88,7 @@ /* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it, * when context info is not available. */ -bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob, PointerRNA *ptr) +bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, ScrArea *sa, Scene *scene, Object *ob, PointerRNA *r_ptr) { /* if there's an active area, check if the particular editor may * have defined any special Grease Pencil context for editing... @@ -85,26 +97,37 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr SpaceLink *sl = sa->spacedata.first; switch (sa->spacetype) { - case SPACE_VIEW3D: /* 3D-View */ + /* XXX: Should we reduce reliance on context.gpencil_data for these cases? */ + case SPACE_BUTS: /* properties */ + case SPACE_INFO: /* header info (needed after workspaces merge) */ { - BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src, - GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT)); + if (ob && (ob->type == OB_GPENCIL)) { + /* GP Object */ + if (r_ptr) RNA_id_pointer_create(&ob->id, r_ptr); + return (bGPdata **)&ob->data; + } + else { + return NULL; + } - if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) { - /* legacy behaviour for usage with old addons requiring object-linked to objects */ + break; + } - /* just in case no active/selected object... */ - if (ob && (ob->flag & SELECT)) { - /* for now, as long as there's an object, default to using that in 3D-View */ - if (ptr) RNA_id_pointer_create(&ob->id, ptr); - return &ob->gpd; - } - /* else: defaults to scene... */ + case SPACE_TOPBAR: /* Topbar (needed after topbar merge) */ + case SPACE_VIEW3D: /* 3D-View */ + { + if (ob && (ob->type == OB_GPENCIL)) { + /* GP Object */ + if (r_ptr) RNA_id_pointer_create(&ob->id, r_ptr); + return (bGPdata **)&ob->data; } else { - if (ptr) RNA_id_pointer_create(&scene->id, ptr); + /* Annotations */ + /* XXX: */ + if (r_ptr) RNA_id_pointer_create(&scene->id, r_ptr); return &scene->gpd; } + break; } case SPACE_NODE: /* Nodes Editor */ @@ -114,7 +137,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr /* return the GP data for the active node block/node */ if (snode && snode->nodetree) { /* for now, as long as there's an active node tree, default to using that in the Nodes Editor */ - if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr); + if (r_ptr) RNA_id_pointer_create(&snode->nodetree->id, r_ptr); return &snode->nodetree->gpd; } @@ -127,7 +150,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr /* for now, Grease Pencil data is associated with the space (actually preview region only) */ /* XXX our convention for everything else is to link to data though... */ - if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr); + if (r_ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, r_ptr); return &sseq->gpd; } case SPACE_IMAGE: /* Image/UV Editor */ @@ -136,7 +159,7 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr /* for now, Grease Pencil data is associated with the space... */ /* XXX our convention for everything else is to link to data though... */ - if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr); + if (r_ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, r_ptr); return &sima->gpd; } case SPACE_CLIP: /* Nodes Editor */ @@ -151,15 +174,11 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr if (!track) return NULL; - if (ptr) - RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr); - + if (r_ptr) RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, r_ptr); return &track->gpd; } else { - if (ptr) - RNA_id_pointer_create(&clip->id, ptr); - + if (r_ptr) RNA_id_pointer_create(&clip->id, r_ptr); return &clip->gpd; } } @@ -170,79 +189,102 @@ bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrAr } } - /* just fall back on the scene's GP data */ - if (ptr) RNA_id_pointer_create((ID *)scene, ptr); - return (scene) ? &scene->gpd : NULL; + return NULL; } /* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */ -bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) +bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *r_ptr) { ID *screen_id = (ID *)CTX_wm_screen(C); Scene *scene = CTX_data_scene(C); ScrArea *sa = CTX_wm_area(C); Object *ob = CTX_data_active_object(C); - return ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, ptr); + return ED_gpencil_data_get_pointers_direct(screen_id, sa, scene, ob, r_ptr); } /* -------------------------------------------------------- */ /* Get the active Grease Pencil datablock, when context is not available */ -bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob) +bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, ScrArea *sa, Scene *scene, Object *ob) { - bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, NULL); + bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, sa, scene, ob, NULL); return (gpd_ptr) ? *(gpd_ptr) : NULL; } -/* Get the active Grease Pencil datablock */ +/** + * Get the active Grease Pencil datablock + * \note This is the original (bmain) copy of the datablock, stored in files. + * Do not use for reading evaluated copies of GP Objects data + */ bGPdata *ED_gpencil_data_get_active(const bContext *C) { bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); return (gpd_ptr) ? *(gpd_ptr) : NULL; } +/** + * Get the evaluated copy of the active Grease Pencil datablock (where applicable) + * - For the 3D View (i.e. "GP Objects"), this gives the evaluated copy of the GP datablock + * (i.e. a copy of the active GP datablock for the active object, where modifiers have been + * applied). This is needed to correctly work with "Copy-on-Write" + * - For all other editors (i.e. "GP Annotations"), this just gives the active datablock + * like for ED_gpencil_data_get_active() + */ +bGPdata *ED_gpencil_data_get_active_evaluated(const bContext *C) +{ + ID *screen_id = (ID *)CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + + const Depsgraph *depsgraph = CTX_data_depsgraph(C); + Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); + Object *ob = CTX_data_active_object(C); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + + /* if (ob && ob->type == OB_GPENCIL) BLI_assert(ob_eval->data == DEG_get_evaluated_id(ob->data)); */ + return ED_gpencil_data_get_active_direct(screen_id, sa, scene_eval, ob_eval); +} + +/* -------------------------------------------------------- */ + +/** + * Utility to check whether the r_ptr output of ED_gpencil_data_get_pointers() + * is for annotation usage. + */ +bool ED_gpencil_data_owner_is_annotation(PointerRNA *owner_ptr) +{ + /* Key Assumption: If the pointer is an object, we're dealing with a GP Object's data. + * Otherwise, the GP datablock is being used for annotations (i.e. everywhere else) + */ + return ((owner_ptr) && (owner_ptr->type != &RNA_Object)); +} + /* -------------------------------------------------------- */ // XXX: this should be removed... We really shouldn't duplicate logic like this! -bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, ViewLayer *view_layer) +bGPdata *ED_gpencil_data_get_active_v3d(ViewLayer *view_layer) { Base *base = view_layer->basact; bGPdata *gpd = NULL; + /* We have to make sure active object is actually visible and selected, else we must use default scene gpd, * to be consistent with ED_gpencil_data_get_active's behavior. */ - if (base && TESTBASE(base)) { - gpd = base->object->gpd; + if (base->object->type == OB_GPENCIL) + gpd = base->object->data; } - return gpd ? gpd : scene->gpd; + return gpd ? gpd : NULL; } /* ******************************************************** */ /* Keyframe Indicator Checks */ /* Check whether there's an active GP keyframe on the current frame */ -bool ED_gpencil_has_keyframe_v3d(Scene *scene, Object *ob, int cfra) +bool ED_gpencil_has_keyframe_v3d(Scene *UNUSED(scene), Object *ob, int cfra) { - /* just check both for now... */ - // XXX: this could get confusing (e.g. if only on the object, but other places don't show this) - if (scene->gpd) { - bGPDlayer *gpl = BKE_gpencil_layer_getactive(scene->gpd); - if (gpl) { - if (gpl->actframe) { - // XXX: assumes that frame has been fetched already - return (gpl->actframe->framenum == cfra); - } - else { - /* XXX: disabled as could be too much of a penalty */ - /* return BKE_gpencil_layer_find_frame(gpl, cfra); */ - } - } - } - - if (ob && ob->gpd) { - bGPDlayer *gpl = BKE_gpencil_layer_getactive(ob->gpd); + if (ob && ob->data && (ob->type == OB_GPENCIL)) { + bGPDlayer *gpl = BKE_gpencil_layer_getactive(ob->data); if (gpl) { if (gpl->actframe) { // XXX: assumes that frame has been fetched already @@ -281,28 +323,13 @@ bool gp_active_layer_poll(bContext *C) bool gp_active_brush_poll(bContext *C) { ToolSettings *ts = CTX_data_tool_settings(C); - bGPDbrush *brush = BKE_gpencil_brush_getactive(ts); - - return (brush != NULL); -} - -/* poll callback for checking if there is an active palette */ -bool gp_active_palette_poll(bContext *C) -{ - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - - return (palette != NULL); -} - -/* poll callback for checking if there is an active palette color */ -bool gp_active_palettecolor_poll(bContext *C) -{ - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); - - return (palcolor != NULL); + Paint *paint = &ts->gp_paint->paint; + if (paint) { + return (paint->brush != NULL); + } + else { + return false; + } } /* ******************************************************** */ @@ -360,7 +387,7 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf( /* Create new layer */ /* TODO: have some way of specifying that we don't want this? */ { - /* active Keying Set */ + /* "New Layer" entry */ item_tmp.identifier = "__CREATE__"; item_tmp.name = "New Layer"; item_tmp.value = -1; @@ -392,7 +419,6 @@ const EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf( } - /* ******************************************************** */ /* Brush Tool Core */ @@ -426,7 +452,7 @@ bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]), /* Stroke Validity Testing */ /* Check whether given stroke can be edited given the supplied context */ -// XXX: do we need additional flags for screenspace vs dataspace? +/* TODO: do we need additional flags for screenspace vs dataspace? */ bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps) { /* sanity check */ @@ -436,7 +462,7 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps) /* filter stroke types by flags + spacetype */ if (gps->flag & GP_STROKE_3DSPACE) { /* 3D strokes - only in 3D view */ - return (sa->spacetype == SPACE_VIEW3D); + return ((sa->spacetype == SPACE_VIEW3D) || (sa->spacetype == SPACE_BUTS)); } else if (gps->flag & GP_STROKE_2DIMAGE) { /* Special "image" strokes - only in Image Editor */ @@ -460,59 +486,21 @@ bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps) } /* Check whether given stroke can be edited for the current color */ -bool ED_gpencil_stroke_color_use(const bGPDlayer *gpl, const bGPDstroke *gps) +bool ED_gpencil_stroke_color_use(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps) { /* check if the color is editable */ - bGPDpalettecolor *palcolor = gps->palcolor; - if (palcolor != NULL) { - if (palcolor->flag & PC_COLOR_HIDE) + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + + if (gp_style != NULL) { + if (gp_style->flag & GP_STYLE_COLOR_HIDE) return false; - if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (palcolor->flag & PC_COLOR_LOCKED)) + if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_STYLE_COLOR_LOCKED)) return false; } return true; } -/* Get palette color or create a new one */ -bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps) -{ - bGPDpalette *palette; - bGPDpalettecolor *palcolor; - - if ((gps->palcolor != NULL) && ((gps->flag & GP_STROKE_RECALC_COLOR) == 0)) - return gps->palcolor; - - /* get palette */ - palette = BKE_gpencil_palette_getactive(gpd); - if (palette == NULL) { - palette = BKE_gpencil_palette_addnew(gpd, DATA_("GP_Palette"), true); - } - /* get color */ - palcolor = BKE_gpencil_palettecolor_getbyname(palette, gps->colorname); - if (palcolor == NULL) { - if (gps->palcolor == NULL) { - palcolor = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true); - /* set to a different color */ - ARRAY_SET_ITEMS(palcolor->color, 1.0f, 0.0f, 1.0f, 0.9f); - } - else { - palcolor = BKE_gpencil_palettecolor_addnew(palette, gps->colorname, true); - /* set old color and attributes */ - bGPDpalettecolor *gpscolor = gps->palcolor; - copy_v4_v4(palcolor->color, gpscolor->color); - copy_v4_v4(palcolor->fill, gpscolor->fill); - palcolor->flag = gpscolor->flag; - } - } - - /* clear flag and set pointer */ - gps->flag &= ~GP_STROKE_RECALC_COLOR; - gps->palcolor = palcolor; - - return palcolor; -} - /* ******************************************************** */ /* Space Conversion */ @@ -573,9 +561,9 @@ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint * } /** - * Change points position relative to parent object + * Change position relative to parent object */ -void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps) +void gp_apply_parent(Depsgraph *depsgraph, Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps) { bGPDspoint *pt; int i; @@ -585,7 +573,7 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps) float inverse_diff_mat[4][4]; float fpt[3]; - ED_gpencil_parent_location(gpl, diff_mat); + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); invert_m4_m4(inverse_diff_mat, diff_mat); for (i = 0; i < gps->totpoints; i++) { @@ -598,14 +586,14 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps) /** * Change point position relative to parent object */ -void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt) +void gp_apply_parent_point(Depsgraph *depsgraph, Object *obact, bGPdata *gpd, bGPDlayer *gpl, bGPDspoint *pt) { /* undo matrix */ float diff_mat[4][4]; float inverse_diff_mat[4][4]; float fpt[3]; - ED_gpencil_parent_location(gpl, diff_mat); + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); invert_m4_m4(inverse_diff_mat, diff_mat); mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x); @@ -770,194 +758,259 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen } /** - * Apply smooth to stroke point - * \param gps Stroke to smooth - * \param i Point index - * \param inf Amount of smoothing to apply - * \param affect_pressure Apply smoothing to pressure values too? + * Convert tGPspoint (temporary 2D/screenspace point data used by GP modal operators) + * to 3D coordinates. + * + * \param point2D: The screenspace 2D point data to convert + * \param depth: Depth array (via ED_view3d_autodist_depth()) + * \param[out] r_out: The resulting 2D point data */ -bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure) +void gp_stroke_convertcoords_tpoint( + Scene *scene, ARegion *ar, View3D *v3d, + Object *ob, bGPDlayer *gpl, + const tGPspoint *point2D, float *depth, + float r_out[3]) { - bGPDspoint *pt = &gps->points[i]; - float pressure = 0.0f; - float sco[3] = {0.0f}; - - /* Do nothing if not enough points to smooth out */ - if (gps->totpoints <= 2) { - return false; - } + ToolSettings *ts = scene->toolsettings; + const int mval[2] = {point2D->x, point2D->y}; - /* Only affect endpoints by a fraction of the normal strength, - * to prevent the stroke from shrinking too much - */ - if ((i == 0) || (i == gps->totpoints - 1)) { - inf *= 0.1f; + if ((depth != NULL) && (ED_view3d_autodist_simple(ar, mval, r_out, 0, depth))) { + /* projecting onto 3D-Geometry + * - nothing more needs to be done here, since view_autodist_simple() has already done it + */ } - - /* Compute smoothed coordinate by taking the ones nearby */ - /* XXX: This is potentially slow, and suffers from accumulation error as earlier points are handled before later ones */ - { - // XXX: this is hardcoded to look at 2 points on either side of the current one (i.e. 5 items total) - const int steps = 2; - const float average_fac = 1.0f / (float)(steps * 2 + 1); - int step; - - /* add the point itself */ - madd_v3_v3fl(sco, &pt->x, average_fac); - - if (affect_pressure) { - pressure += pt->pressure * average_fac; + else { + float mval_f[2] = {(float)point2D->x, (float)point2D->y}; + float mval_prj[2]; + float rvec[3], dvec[3]; + float zfac; + + /* Current method just converts each point in screen-coordinates to + * 3D-coordinates using the 3D-cursor as reference. + */ + ED_gp_get_drawing_reference(v3d, scene, ob, gpl, ts->gpencil_v3d_align, rvec); + zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL); + + if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + sub_v2_v2v2(mval_f, mval_prj, mval_f); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); + sub_v3_v3v3(r_out, rvec, dvec); } + else { + zero_v3(r_out); + } + } +} - /* n-steps before/after current point */ - // XXX: review how the endpoints are treated by this algorithm - // XXX: falloff measures should also introduce some weighting variations, so that further-out points get less weight - for (step = 1; step <= steps; step++) { - bGPDspoint *pt1, *pt2; - int before = i - step; - int after = i + step; - - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); - - pt1 = &gps->points[before]; - pt2 = &gps->points[after]; - - /* add both these points to the average-sum (s += p[i]/n) */ - madd_v3_v3fl(sco, &pt1->x, average_fac); - madd_v3_v3fl(sco, &pt2->x, average_fac); - -#if 0 - /* XXX: Disabled because get weird result */ - /* do pressure too? */ - if (affect_pressure) { - pressure += pt1->pressure * average_fac; - pressure += pt2->pressure * average_fac; +/** + * Get drawing reference point for conversion or projection of the stroke + * \param[out] r_vec : Reference point found + */ +void ED_gp_get_drawing_reference( + View3D *v3d, Scene *scene, Object *ob, bGPDlayer *UNUSED(gpl), + char align_flag, float r_vec[3]) +{ + const float *fp = ED_view3d_cursor3d_get(scene, v3d)->location; + + /* if using a gpencil object at cursor mode, can use the location of the object */ + if (align_flag & GP_PROJECT_VIEWSPACE) { + if (ob && (ob->type == OB_GPENCIL)) { + /* fallback (no strokes) - use cursor or object location */ + if (align_flag & GP_PROJECT_CURSOR) { + /* use 3D-cursor */ + copy_v3_v3(r_vec, fp); + } + else { + /* use object location */ + copy_v3_v3(r_vec, ob->obmat[3]); } -#endif } } - - /* Based on influence factor, blend between original and optimal smoothed coordinate */ - interp_v3_v3v3(&pt->x, &pt->x, sco, inf); - -#if 0 - /* XXX: Disabled because get weird result */ - if (affect_pressure) { - pt->pressure = pressure; + else { + /* use 3D-cursor */ + copy_v3_v3(r_vec, fp); } -#endif - - return true; } + /** -* Apply smooth for strength to stroke point -* \param gps Stroke to smooth -* \param i Point index -* \param inf Amount of smoothing to apply -*/ -bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf) + * Reproject all points of the stroke to a plane locked to axis to avoid stroke offset + */ +void ED_gp_project_stroke_to_plane(Object *ob, RegionView3D *rv3d, bGPDstroke *gps, const float origin[3], const int axis) { - bGPDspoint *ptb = &gps->points[i]; - - /* Do nothing if not enough points */ - if (gps->totpoints <= 2) { - return false; + float plane_normal[3]; + float vn[3]; + + float ray[3]; + float rpoint[3]; + + /* normal vector for a plane locked to axis */ + zero_v3(plane_normal); + if (axis < 0) { + /* if the axis is not locked, need a vector to the view direction + * in order to get the right size of the stroke. + */ + ED_view3d_global_to_vector(rv3d, origin, plane_normal); + } + else { + plane_normal[axis] = 1.0f; + /* if object, apply object rotation */ + if (ob && (ob->type == OB_GPENCIL)) { + mul_mat3_m4_v3(ob->obmat, plane_normal); + } } - /* Compute theoretical optimal value using distances */ - bGPDspoint *pta, *ptc; - int before = i - 1; - int after = i + 1; - - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); - - pta = &gps->points[before]; - ptc = &gps->points[after]; + /* Reproject the points in the plane */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; - /* the optimal value is the corresponding to the interpolation of the strength - * at the distance of point b - */ - const float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength; + /* get a vector from the point with the current view direction of the viewport */ + ED_view3d_global_to_vector(rv3d, &pt->x, vn); - /* Based on influence factor, blend between original and optimal */ - ptb->strength = (1.0f - inf) * ptb->strength + inf * optimal; + /* calculate line extreme point to create a ray that cross the plane */ + mul_v3_fl(vn, -50.0f); + add_v3_v3v3(ray, &pt->x, vn); - return true; + /* if the line never intersect, the point is not changed */ + if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) { + copy_v3_v3(&pt->x, rpoint); + } + } } /** -* Apply smooth for thickness to stroke point (use pressure) -* \param gps Stroke to smooth -* \param i Point index -* \param inf Amount of smoothing to apply -*/ -bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf) + * Reproject given point to a plane locked to axis to avoid stroke offset + * \param[in, out] pt : Point to affect + */ +void ED_gp_project_point_to_plane(Object *ob, RegionView3D *rv3d, const float origin[3], const int axis, bGPDspoint *pt) { - bGPDspoint *ptb = &gps->points[i]; - - /* Do nothing if not enough points */ - if (gps->totpoints <= 2) { - return false; + float plane_normal[3]; + float vn[3]; + + float ray[3]; + float rpoint[3]; + + /* normal vector for a plane locked to axis */ + zero_v3(plane_normal); + if (axis < 0) { + /* if the axis is not locked, need a vector to the view direction + * in order to get the right size of the stroke. + */ + ED_view3d_global_to_vector(rv3d, origin, plane_normal); + } + else { + plane_normal[axis] = 1.0f; + /* if object, apply object rotation */ + if (ob && (ob->type == OB_GPENCIL)) { + mul_mat3_m4_v3(ob->obmat, plane_normal); + } } - /* Compute theoretical optimal value using distances */ - bGPDspoint *pta, *ptc; - int before = i - 1; - int after = i + 1; - - CLAMP_MIN(before, 0); - CLAMP_MAX(after, gps->totpoints - 1); - - pta = &gps->points[before]; - ptc = &gps->points[after]; - /* the optimal value is the corresponding to the interpolation of the pressure - * at the distance of point b - */ - float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); - float optimal = (1.0f - fac) * pta->pressure + fac * ptc->pressure; + /* Reproject the points in the plane */ + /* get a vector from the point with the current view direction of the viewport */ + ED_view3d_global_to_vector(rv3d, &pt->x, vn); - /* Based on influence factor, blend between original and optimal */ - ptb->pressure = (1.0f - inf) * ptb->pressure + inf * optimal; + /* calculate line extrem point to create a ray that cross the plane */ + mul_v3_fl(vn, -50.0f); + add_v3_v3v3(ray, &pt->x, vn); - return true; + /* if the line never intersect, the point is not changed */ + if (isect_line_plane_v3(rpoint, &pt->x, ray, origin, plane_normal)) { + copy_v3_v3(&pt->x, rpoint); + } } +/* ******************************************************** */ +/* Stroke Operations */ +// XXX: Check if these functions duplicate stuff in blenkernel, and/or whether we should just deduplicate + /** * Subdivide a stroke once, by adding a point half way between each pair of existing points * \param gps Stroke data - * \param new_totpoints Total number of points (after subdividing) + * \param subdivide Number of times to subdivide */ -void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints) +void gp_subdivide_stroke(bGPDstroke *gps, const int subdivide) { - /* Move points towards end of enlarged points array to leave space for new points */ - int y = 1; - for (int i = gps->totpoints - 1; i > 0; i--) { - gps->points[new_totpoints - y] = gps->points[i]; - y += 2; - } + bGPDspoint *temp_points; + int totnewpoints, oldtotpoints; + int i2; + + /* loop as many times as levels */ + for (int s = 0; s < subdivide; s++) { + totnewpoints = gps->totpoints - 1; + /* duplicate points in a temp area */ + temp_points = MEM_dupallocN(gps->points); + oldtotpoints = gps->totpoints; + + /* resize the points arrys */ + gps->totpoints += totnewpoints; + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints); + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints); + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* move points from last to first to new place */ + i2 = gps->totpoints - 1; + for (int i = oldtotpoints - 1; i > 0; i--) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *pt_final = &gps->points[i2]; + MDeformVert *dvert = &gps->dvert[i]; + MDeformVert *dvert_final = &gps->dvert[i2]; + + copy_v3_v3(&pt_final->x, &pt->x); + pt_final->pressure = pt->pressure; + pt_final->strength = pt->strength; + pt_final->time = pt->time; + pt_final->flag = pt->flag; + pt_final->uv_fac = pt->uv_fac; + pt_final->uv_rot = pt->uv_rot; + + dvert_final->totweight = dvert->totweight; + dvert_final->dw = dvert->dw; + + i2 -= 2; + } + /* interpolate mid points */ + i2 = 1; + for (int i = 0; i < oldtotpoints - 1; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i2]; + MDeformVert *dvert_final = &gps->dvert[i2]; + + /* add a half way point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + pt_final->pressure = interpf(pt->pressure, next->pressure, 0.5f); + pt_final->strength = interpf(pt->strength, next->strength, 0.5f); + CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt_final->time = interpf(pt->time, next->time, 0.5f); + pt_final->uv_fac = interpf(pt->uv_fac, next->uv_fac, 0.5f); + pt_final->uv_rot = interpf(pt->uv_rot, next->uv_rot, 0.5f); + + dvert_final->totweight = 0; + dvert_final->dw = NULL; + + i2 += 2; + } - /* Create interpolated points */ - for (int i = 0; i < new_totpoints - 1; i += 2) { - bGPDspoint *prev = &gps->points[i]; - bGPDspoint *pt = &gps->points[i + 1]; - bGPDspoint *next = &gps->points[i + 2]; + MEM_SAFE_FREE(temp_points); - /* Interpolate all values */ - interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f); + /* move points to smooth stroke */ + /* duplicate points in a temp area with the new subdivide data */ + temp_points = MEM_dupallocN(gps->points); - pt->pressure = interpf(prev->pressure, next->pressure, 0.5f); - pt->strength = interpf(prev->strength, next->strength, 0.5f); - CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); - pt->time = interpf(prev->time, next->time, 0.5f); - } + /* extreme points are not changed */ + for (int i = 0; i < gps->totpoints - 2; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i + 1]; - /* Update to new total number of points */ - gps->totpoints = new_totpoints; + /* move point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + } + /* free temp memory */ + MEM_SAFE_FREE(temp_points); + } } /** @@ -965,7 +1018,7 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints) * \param gps Stroke data * \param brush Brush data */ -void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng) +void gp_randomize_stroke(bGPDstroke *gps, Brush *brush, RNG *rng) { bGPDspoint *pt1, *pt2, *pt3; float v1[3]; @@ -995,10 +1048,10 @@ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng) normalize_v3(ortho); /* Read all points and apply shift vector (first and last point not modified) */ - for (int i = 1; i < gps->totpoints - 1; ++i) { + for (int i = 1; i < gps->totpoints - 1; i++) { bGPDspoint *pt = &gps->points[i]; /* get vector with shift (apply a division because random is too sensitive */ - const float fac = BLI_rng_get_float(rng) * (brush->draw_random_sub / 10.0f); + const float fac = BLI_rng_get_float(rng) * (brush->gpencil_settings->draw_random_sub / 10.0f); float svec[3]; copy_v3_v3(svec, ortho); if (BLI_rng_get_float(rng) > 0.5f) { @@ -1011,31 +1064,46 @@ void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush, RNG *rng) /* apply shift */ add_v3_v3(&pt->x, svec); } - } + +/* ******************************************************** */ +/* Layer Parenting - Compute Parent Transforms */ + /* calculate difference matrix */ -void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4]) +void ED_gpencil_parent_location( + const Depsgraph *depsgraph, Object *obact, bGPdata *UNUSED(gpd), + bGPDlayer *gpl, float diff_mat[4][4]) { - Object *ob = gpl->parent; - - if (ob == NULL) { + Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact; + Object *obparent = gpl->parent; + Object *obparent_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obparent) : obparent; + + /* if not layer parented, try with object parented */ + if (obparent_eval == NULL) { + if (ob_eval != NULL) { + if (ob_eval->type == OB_GPENCIL) { + copy_m4_m4(diff_mat, ob_eval->obmat); + return; + } + } + /* not gpencil object */ unit_m4(diff_mat); return; } else { if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { - mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse); + mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); return; } else if (gpl->partype == PARBONE) { - bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, gpl->parsubstr); + bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr); if (pchan) { float tmp_mat[4][4]; - mul_m4_m4m4(tmp_mat, ob->obmat, pchan->pose_mat); + mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat); mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse); } else { - mul_m4_m4m4(diff_mat, ob->obmat, gpl->inverse); /* if bone not found use object (armature) */ + mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); /* if bone not found use object (armature) */ } return; } @@ -1046,7 +1114,7 @@ void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4]) } /* reset parent matrix for all layers */ -void ED_gpencil_reset_layers_parent(bGPdata *gpd) +void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata *gpd) { bGPDspoint *pt; int i; @@ -1071,7 +1139,7 @@ void ED_gpencil_reset_layers_parent(bGPdata *gpd) /* only redo if any change */ if (!equals_m4m4(gpl->inverse, cur_mat)) { /* first apply current transformation to all strokes */ - ED_gpencil_parent_location(gpl, diff_mat); + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { @@ -1086,90 +1154,580 @@ void ED_gpencil_reset_layers_parent(bGPdata *gpd) } } /* ******************************************************** */ -bool ED_gpencil_stroke_minmax( - const bGPDstroke *gps, const bool use_select, - float r_min[3], float r_max[3]) +/* GP Object Stuff */ + +/* Helper function to create new OB_GPENCIL Object */ +Object *ED_add_gpencil_object(bContext *C, Scene *scene, const float loc[3]) { - const bGPDspoint *pt; - int i; - bool changed = false; + float rot[3] = {0.0f}; + + Object *ob = ED_object_add_type(C, OB_GPENCIL, NULL, loc, rot, false, scene->lay); + + /* define size */ + BKE_object_obdata_size_init(ob, GP_OBGPENCIL_DEFAULT_SIZE); + /* create default brushes and colors */ + ED_gpencil_add_defaults(C); - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((use_select == false) || (pt->flag & GP_SPOINT_SELECT)) {; - minmax_v3v3_v3(r_min, r_max, &pt->x); - changed = true; + return ob; +} + +/* Helper function to create default colors and drawing brushes */ +void ED_gpencil_add_defaults(bContext *C) +{ + Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + /* first try to reuse default material */ + if (ob->actcol > 0) { + Material *ma = give_current_material(ob, ob->actcol); + if ((ma) && (ma->gp_style == NULL)) { + BKE_material_init_gpencil_settings(ma); } } - return changed; + + /* ensure color exist */ + BKE_gpencil_material_ensure(bmain, ob); + + Paint *paint = BKE_brush_get_gpencil_paint(ts); + /* if not exist, create a new one */ + if (paint->brush == NULL) { + /* create new brushes */ + BKE_brush_gpencil_presets(C); + } + } -/* Dynamic Enums of GP Brushes */ -const EnumPropertyItem *ED_gpencil_brushes_enum_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), - bool *r_free) +/* ******************************************************** */ +/* Vertex Groups */ + +/* assign points to vertex group */ +void ED_gpencil_vgroup_assign(bContext *C, Object *ob, float weight) { - ToolSettings *ts = CTX_data_tool_settings(C); - bGPDbrush *brush; - EnumPropertyItem *item = NULL, item_tmp = { 0 }; - int totitem = 0; - int i = 0; + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return; - if (ELEM(NULL, C, ts)) { - return DummyRNA_DEFAULT_items; + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + if (gps->flag & GP_STROKE_SELECT) { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + if (pt->flag & GP_SPOINT_SELECT) { + BKE_gpencil_vgroup_add_point_weight(dvert, def_nr, weight); + } + } + } } + CTX_DATA_END; +} - /* Existing brushes */ - for (brush = ts->gp_brushes.first; brush; brush = brush->next, i++) { - item_tmp.identifier = brush->info; - item_tmp.name = brush->info; - item_tmp.value = i; +/* remove points from vertex group */ +void ED_gpencil_vgroup_remove(bContext *C, Object *ob) +{ + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return; - if (brush->flag & GP_BRUSH_ACTIVE) - item_tmp.icon = ICON_BRUSH_DATA; - else - item_tmp.icon = ICON_NONE; + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; - RNA_enum_item_add(&item, &totitem, &item_tmp); + if ((pt->flag & GP_SPOINT_SELECT) && (dvert->totweight > 0)) { + BKE_gpencil_vgroup_remove_point_weight(dvert, def_nr); + } + } } + CTX_DATA_END; +} - RNA_enum_item_end(&item, &totitem); - *r_free = true; +/* select points of vertex group */ +void ED_gpencil_vgroup_select(bContext *C, Object *ob) +{ + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return; - return item; + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + if (BKE_gpencil_vgroup_use_index(dvert, def_nr) > -1.0f) { + pt->flag |= GP_SPOINT_SELECT; + gps->flag |= GP_STROKE_SELECT; + } + } + } + CTX_DATA_END; } -/* Dynamic Enums of GP Palettes */ -const EnumPropertyItem *ED_gpencil_palettes_enum_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), - bool *r_free) +/* unselect points of vertex group */ +void ED_gpencil_vgroup_deselect(bContext *C, Object *ob) { - bGPdata *gpd = CTX_data_gpencil_data(C); - bGPDpalette *palette; - EnumPropertyItem *item = NULL, item_tmp = { 0 }; - int totitem = 0; - int i = 0; + const int def_nr = ob->actdef - 1; + if (!BLI_findlink(&ob->defbase, def_nr)) + return; - if (ELEM(NULL, C, gpd)) { - return DummyRNA_DEFAULT_items; + CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes) + { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + if (BKE_gpencil_vgroup_use_index(dvert, def_nr) > -1.0f) { + pt->flag &= ~GP_SPOINT_SELECT; + gps->flag |= GP_STROKE_SELECT; + } + } } + CTX_DATA_END; +} - /* Existing palettes */ - for (palette = gpd->palettes.first; palette; palette = palette->next, i++) { - item_tmp.identifier = palette->info; - item_tmp.name = palette->info; - item_tmp.value = i; +/* ******************************************************** */ +/* Cursor drawing */ - if (palette->flag & PL_PALETTE_ACTIVE) - item_tmp.icon = ICON_COLOR; - else - item_tmp.icon = ICON_NONE; +/* check if cursor is in drawing region */ +static bool gp_check_cursor_region(bContext *C, int mval[2]) +{ + ARegion *ar = CTX_wm_region(C); + ScrArea *sa = CTX_wm_area(C); + /* TODO: add more spacetypes */ + if (!ELEM(sa->spacetype, SPACE_VIEW3D)) { + return false; + } + if ((ar) && (ar->regiontype != RGN_TYPE_WINDOW)) { + return false; + } + else if (ar) { + rcti region_rect; - RNA_enum_item_add(&item, &totitem, &item_tmp); + /* Perform bounds check using */ + ED_region_visible_rect(ar, ®ion_rect); + return BLI_rcti_isect_pt_v(®ion_rect, mval); + } + else { + return false; } +} - RNA_enum_item_end(&item, &totitem); - *r_free = true; +/* draw eraser cursor */ +void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) +{ + short radius = (short)brush->size; - return item; + GPUVertFormat *format = immVertexFormat(); + const uint shdr_pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + immUniformColor4ub(255, 100, 100, 20); + imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40); + + immUnbindProgram(); + + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f); + immUniform1i("colors_len", 0); /* "simple" mode */ + immUniform1f("dash_width", 12.0f); + immUniform1f("dash_factor", 0.5f); + + imm_draw_circle_wire_2d(shdr_pos, x, y, radius, + /* XXX Dashed shader gives bad results with sets of small segments currently, + * temp hack around the issue. :( */ + max_ii(8, radius / 2)); /* was fixed 40 */ + + immUnbindProgram(); + + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); +} + +/* Helper callback for drawing the cursor itself */ +static void gp_brush_drawcursor(bContext *C, int x, int y, void *customdata) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + ARegion *ar = CTX_wm_region(C); + + GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; + bGPdata *gpd = ED_gpencil_data_get_active(C); + GP_EditBrush_Data *brush = NULL; + Brush *paintbrush = NULL; + Material *ma = NULL; + MaterialGPencilStyle *gp_style = NULL; + int *last_mouse_position = customdata; + + if ((gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE)) { + brush = &gset->brush[gset->weighttype]; + } + else { + brush = &gset->brush[gset->brushtype]; + } + + /* default radius and color */ + float color[3] = {1.0f, 1.0f, 1.0f}; + float darkcolor[3]; + float radius = 3.0f; + + int mval[2] = {x, y}; + /* check if cursor is in drawing region and has valid datablock */ + if ((!gp_check_cursor_region(C, mval)) || (gpd == NULL)) { + return; + } + + /* for paint use paint brush size and color */ + if (gpd->flag & GP_DATA_STROKE_PAINTMODE) { + paintbrush = BKE_brush_getactive_gpencil(scene->toolsettings); + /* while drawing hide */ + if ((gpd->runtime.sbuffer_size > 0) && + (paintbrush) && ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0)) + { + return; + } + + if (paintbrush) { + if ((paintbrush->gpencil_settings->flag & GP_BRUSH_ENABLE_CURSOR) == 0) { + return; + } + + /* eraser has special shape and use a different shader program */ + if (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE) { + ED_gpencil_brush_draw_eraser(paintbrush, x, y); + return; + } + + /* get current drawing color */ + ma = BKE_gpencil_get_material_from_brush(paintbrush); + if (ma == NULL) { + BKE_gpencil_material_ensure(bmain, ob); + /* assign the first material to the brush */ + ma = give_current_material(ob, 1); + paintbrush->gpencil_settings->material = ma; + } + gp_style = ma->gp_style; + + /* after some testing, display the size of the brush is not practical because + * is too disruptive and the size of cursor does not change with zoom factor. + * The decision was to use a fix size, instead of paintbrush->thickness value. + */ + if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && + (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)) + { + radius = 2.0f; + copy_v3_v3(color, gp_style->stroke_rgba); + } + else { + radius = 5.0f; + copy_v3_v3(color, paintbrush->add_col); + } + } + else { + return; + } + } + + /* for sculpt use sculpt brush size */ + if (GPENCIL_SCULPT_OR_WEIGHT_MODE(gpd)) { + if (brush) { + if ((brush->flag & GP_EDITBRUSH_FLAG_ENABLE_CURSOR) == 0) { + return; + } + + radius = brush->size; + if (brush->flag & (GP_EDITBRUSH_FLAG_INVERT | GP_EDITBRUSH_FLAG_TMP_INVERT)) { + copy_v3_v3(color, brush->curcolor_sub); + } + else { + copy_v3_v3(color, brush->curcolor_add); + } + } + } + + /* draw icon */ + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + + /* Inner Ring: Color from UI panel */ + immUniformColor4f(color[0], color[1], color[2], 0.8f); + if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && + (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)) + { + imm_draw_circle_fill_2d(pos, x, y, radius, 40); + } + else { + imm_draw_circle_wire_2d(pos, x, y, radius, 40); + } + + /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */ + mul_v3_v3fl(darkcolor, color, 0.40f); + immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f); + imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40); + + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + + /* Draw line for lazy mouse */ + if ((last_mouse_position) && + (paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) + { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + + copy_v3_v3(color, paintbrush->add_col); + immUniformColor4f(color[0], color[1], color[2], 0.8f); + + immBegin(GPU_PRIM_LINES, 2); + immVertex2f(pos, x, y); + immVertex2f(pos, last_mouse_position[0] + ar->winrct.xmin, + last_mouse_position[1] + ar->winrct.ymin); + immEnd(); + + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH); + } + + immUnbindProgram(); +} + +/* Turn brush cursor in on/off */ +void ED_gpencil_toggle_brush_cursor(bContext *C, bool enable, void *customdata) +{ + Scene *scene = CTX_data_scene(C); + GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; + int *lastpost = customdata; + + if (gset->paintcursor && !enable) { + /* clear cursor */ + WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor); + gset->paintcursor = NULL; + } + else if (enable) { + /* in some situations cursor could be duplicated, so it is better disable first if exist */ + if (gset->paintcursor) { + /* clear cursor */ + WM_paint_cursor_end(CTX_wm_manager(C), gset->paintcursor); + gset->paintcursor = NULL; + } + /* enable cursor */ + gset->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), + NULL, + gp_brush_drawcursor, + (lastpost) ? customdata : NULL); + } +} + +/* verify if is using the right brush */ +static void gpencil_verify_brush_type(bContext *C, int newmode) +{ + ToolSettings *ts = CTX_data_tool_settings(C); + GP_BrushEdit_Settings *gset = &ts->gp_sculpt; + + switch (newmode) { + case OB_MODE_GPENCIL_SCULPT: + gset->flag &= ~GP_BRUSHEDIT_FLAG_WEIGHT_MODE; + if ((gset->brushtype < 0) || (gset->brushtype >= GP_EDITBRUSH_TYPE_WEIGHT)) { + gset->brushtype = GP_EDITBRUSH_TYPE_PUSH; + } + break; + case OB_MODE_GPENCIL_WEIGHT: + gset->flag |= GP_BRUSHEDIT_FLAG_WEIGHT_MODE; + if ((gset->weighttype < GP_EDITBRUSH_TYPE_WEIGHT) || (gset->weighttype >= TOT_GP_EDITBRUSH_TYPES)) { + gset->weighttype = GP_EDITBRUSH_TYPE_WEIGHT; + } + break; + default: + break; + } +} + +/* set object modes */ +void ED_gpencil_setup_modes(bContext *C, bGPdata *gpd, int newmode) +{ + if (!gpd) { + return; + } + + switch (newmode) { + case OB_MODE_GPENCIL_EDIT: + gpd->flag |= GP_DATA_STROKE_EDITMODE; + gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; + gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; + gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; + ED_gpencil_toggle_brush_cursor(C, false, NULL); + break; + case OB_MODE_GPENCIL_PAINT: + gpd->flag &= ~GP_DATA_STROKE_EDITMODE; + gpd->flag |= GP_DATA_STROKE_PAINTMODE; + gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; + gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; + ED_gpencil_toggle_brush_cursor(C, true, NULL); + break; + case OB_MODE_GPENCIL_SCULPT: + gpd->flag &= ~GP_DATA_STROKE_EDITMODE; + gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; + gpd->flag |= GP_DATA_STROKE_SCULPTMODE; + gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; + gpencil_verify_brush_type(C, OB_MODE_GPENCIL_SCULPT); + ED_gpencil_toggle_brush_cursor(C, true, NULL); + break; + case OB_MODE_GPENCIL_WEIGHT: + gpd->flag &= ~GP_DATA_STROKE_EDITMODE; + gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; + gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; + gpd->flag |= GP_DATA_STROKE_WEIGHTMODE; + gpencil_verify_brush_type(C, OB_MODE_GPENCIL_WEIGHT); + ED_gpencil_toggle_brush_cursor(C, true, NULL); + break; + default: + gpd->flag &= ~GP_DATA_STROKE_EDITMODE; + gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; + gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; + gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; + ED_gpencil_toggle_brush_cursor(C, false, NULL); + break; + } +} + +/* helper to convert 2d to 3d for simple drawing buffer */ +static void gpencil_stroke_convertcoords(ARegion *ar, const tGPspoint *point2D, float origin[3], float out[3]) +{ + float mval_f[2] = { (float)point2D->x, (float)point2D->y }; + float mval_prj[2]; + float rvec[3], dvec[3]; + float zfac; + + copy_v3_v3(rvec, origin); + + zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL); + + if (ED_view3d_project_float_global(ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + sub_v2_v2v2(mval_f, mval_prj, mval_f); + ED_view3d_win_to_delta(ar, mval_f, dvec, zfac); + sub_v3_v3v3(out, rvec, dvec); + } + else { + zero_v3(out); + } +} + +/* convert 2d tGPspoint to 3d bGPDspoint */ +void ED_gpencil_tpoint_to_point(ARegion *ar, float origin[3], const tGPspoint *tpt, bGPDspoint *pt) +{ + float p3d[3]; + /* conversion to 3d format */ + gpencil_stroke_convertcoords(ar, tpt, origin, p3d); + copy_v3_v3(&pt->x, p3d); + + pt->pressure = tpt->pressure; + pt->strength = tpt->strength; + pt->uv_fac = tpt->uv_fac; + pt->uv_rot = tpt->uv_rot; +} + +/* texture coordinate utilities */ +void ED_gpencil_calc_stroke_uv(Object *ob, bGPDstroke *gps) +{ + if (gps == NULL) { + return; + } + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + float pixsize; + if (gp_style) { + pixsize = gp_style->texture_pixsize / 1000000.0f; + } + else { + /* use this value by default */ + pixsize = 0.000100f; + } + pixsize = MAX2(pixsize, 0.0000001f); + + bGPDspoint *pt = NULL; + bGPDspoint *ptb = NULL; + int i; + float totlen = 0; + + /* first read all points and calc distance */ + for (i = 0; i < gps->totpoints; i++) { + pt = &gps->points[i]; + /* first point */ + if (i == 0) { + pt->uv_fac = 0.0f; + continue; + } + + ptb = &gps->points[i - 1]; + totlen += len_v3v3(&pt->x, &ptb->x) / pixsize; + pt->uv_fac = totlen; + } + /* normalize the distance using a factor */ + float factor; + /* if image, use texture width */ + if ((gp_style) && (gp_style->sima)) { + factor = gp_style->sima->gen_x; + } + else { + factor = totlen; + } + for (i = 0; i < gps->totpoints; i++) { + pt = &gps->points[i]; + pt->uv_fac /= factor; + } +} + +/* recalc uv for any stroke using the material */ +void ED_gpencil_update_color_uv(Main *bmain, Material *mat) +{ + Material *gps_ma = NULL; + /* read all strokes */ + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + if (gpd == NULL) { + continue; + } + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* only editable and visible layers are considered */ + if (gpencil_layer_is_editable(gpl)) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* check if it is editable */ + if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { + continue; + } + gps_ma = give_current_material(ob, gps->mat_nr + 1); + /* update */ + if ((gps_ma) && (gps_ma == mat)) { + ED_gpencil_calc_stroke_uv(ob, gps); + } + } + } + } + } + } + } } /* ******************************************************** */ diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 59a54f03e56..ae86e4a5fbf 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -197,6 +197,8 @@ typedef enum eAnim_ChannelType { ANIMTYPE_NLATRACK, ANIMTYPE_NLAACTION, + ANIMTYPE_PALETTE, + /* always as last item, the total number of channel types... */ ANIMTYPE_NUM_TYPES } eAnim_ChannelType; @@ -347,6 +349,9 @@ typedef enum eAnimFilter_Flags { /* Movie clip only */ #define EXPANDED_MCLIP(clip) (clip->flag & MCLIP_DATA_EXPAND) +/* Palette only */ +#define EXPANDED_PALETTE(palette) (palette->flag & PALETTE_DATA_EXPAND) + /* AnimData - NLA mostly... */ #define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED) diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index 7d509d1243a..333e3d72615 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -42,6 +42,9 @@ extern char datatoc_preview_blend[]; extern int datatoc_preview_cycles_blend_size; extern char datatoc_preview_cycles_blend[]; +extern int datatoc_preview_grease_pencil_blend_size; +extern char datatoc_preview_grease_pencil_blend[]; + extern int datatoc_blender_icons16_png_size; extern char datatoc_blender_icons16_png[]; @@ -239,6 +242,66 @@ extern char datatoc_mc23_jpg[]; extern int datatoc_mc24_jpg_size; extern char datatoc_mc24_jpg[]; +/* grease pencil sculpt brushes files */ + +extern int datatoc_gp_brush_smooth_png_size; +extern char datatoc_gp_brush_smooth_png[]; + +extern int datatoc_gp_brush_thickness_png_size; +extern char datatoc_gp_brush_thickness_png[]; + +extern int datatoc_gp_brush_strength_png_size; +extern char datatoc_gp_brush_strength_png[]; + +extern int datatoc_gp_brush_grab_png_size; +extern char datatoc_gp_brush_grab_png[]; + +extern int datatoc_gp_brush_push_png_size; +extern char datatoc_gp_brush_push_png[]; + +extern int datatoc_gp_brush_twist_png_size; +extern char datatoc_gp_brush_twist_png[]; + +extern int datatoc_gp_brush_pinch_png_size; +extern char datatoc_gp_brush_pinch_png[]; + +extern int datatoc_gp_brush_randomize_png_size; +extern char datatoc_gp_brush_randomize_png[]; + +extern int datatoc_gp_brush_clone_png_size; +extern char datatoc_gp_brush_clone_png[]; + +extern int datatoc_gp_brush_weight_png_size; +extern char datatoc_gp_brush_weight_png[]; + +extern int datatoc_gp_brush_pencil_png_size; +extern char datatoc_gp_brush_pencil_png[]; + +extern int datatoc_gp_brush_pen_png_size; +extern char datatoc_gp_brush_pen_png[]; + +extern int datatoc_gp_brush_ink_png_size; +extern char datatoc_gp_brush_ink_png[]; + +extern int datatoc_gp_brush_inknoise_png_size; +extern char datatoc_gp_brush_inknoise_png[]; + +extern int datatoc_gp_brush_block_png_size; +extern char datatoc_gp_brush_block_png[]; + +extern int datatoc_gp_brush_marker_png_size; +extern char datatoc_gp_brush_marker_png[]; + +extern int datatoc_gp_brush_fill_png_size; +extern char datatoc_gp_brush_fill_png[]; + +extern int datatoc_gp_brush_erase_soft_png_size; +extern char datatoc_gp_brush_erase_soft_png[]; + +extern int datatoc_gp_brush_erase_hard_png_size; +extern char datatoc_gp_brush_erase_hard_png[]; +extern int datatoc_gp_brush_erase_stroke_png_size; +extern char datatoc_gp_brush_erase_stroke_png[]; #endif /* __ED_DATAFILES_H__ */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index f1f2ce29e7f..3013b455de4 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -30,64 +30,44 @@ #ifndef __ED_GPENCIL_H__ #define __ED_GPENCIL_H__ -#include "ED_numinput.h" - struct ID; struct ListBase; -struct bContext; -struct Depsgraph; -struct ScrArea; -struct ARegion; -struct View3D; -struct Object; +struct PointerRNA; +struct rcti; + struct bGPdata; struct bGPDlayer; struct bGPDframe; struct bGPDstroke; -struct bGPDpalette; -struct bGPDpalettecolor; -struct bAnimContext; -struct KeyframeEditData; -struct PointerRNA; +struct bGPDspoint; +struct Brush; + +struct Main; +struct bContext; +struct EvaluationContext; +struct Depsgraph; +struct ScrArea; +struct ARegion; +struct RegionView3D; struct Scene; +struct ToolSettings; struct ViewLayer; -struct wmWindowManager; -struct wmKeyConfig; - - -/* ------------- Grease-Pencil Helpers ---------------- */ -typedef struct tGPDinterpolate_layer { - struct tGPDinterpolate_layer *next, *prev; - - struct bGPDlayer *gpl; /* layer */ - struct bGPDframe *prevFrame; /* frame before current frame (interpolate-from) */ - struct bGPDframe *nextFrame; /* frame after current frame (interpolate-to) */ - struct bGPDframe *interFrame; /* interpolated frame */ - float factor; /* interpolate factor */ +struct View3D; -} tGPDinterpolate_layer; +struct Object; +struct Material; -/* Temporary interpolate operation data */ -typedef struct tGPDinterpolate { - struct Scene *scene; /* current scene from context */ - struct ScrArea *sa; /* area where painting originated */ - struct ARegion *ar; /* region where painting originated */ - struct bGPdata *gpd; /* current GP datablock */ +struct bAnimContext; +struct KeyframeEditData; - int cframe; /* current frame number */ - ListBase ilayers; /* (tGPDinterpolate_layer) layers to be interpolated */ - float shift; /* value for determining the displacement influence */ - float init_factor; /* initial interpolation factor for active layer */ - float low_limit; /* shift low limit (-100%) */ - float high_limit; /* shift upper limit (200%) */ - int flag; /* flag from toolsettings */ +struct wmKeyConfig; +struct wmOperator; +struct wmWindow; +struct wmWindowManager; - NumInput num; /* numeric input */ - void *draw_handle_3d; /* handle for drawing strokes while operator is running 3d stuff */ - void *draw_handle_screen; /* handle for drawing strokes while operator is running screen stuff */ -} tGPDinterpolate; +/* ------------- Grease-Pencil Runtime Data ---------------- */ -/* Temporary 'Stroke Point' data +/* Temporary 'Stroke Point' data (2D / screen-space) * * Used as part of the 'stroke cache' used during drawing of new strokes */ @@ -96,27 +76,43 @@ typedef struct tGPspoint { float pressure; /* pressure of tablet at this point */ float strength; /* pressure of tablet at this point for alpha factor */ float time; /* Time relative to stroke start (used when converting to path) */ + float uv_fac; /* factor of uv along the stroke */ + float uv_rot; /* uv rotation for dor mode */ } tGPspoint; - -/* Check if 'sketching sessions' are enabled */ -#define GPENCIL_SKETCH_SESSIONS_ON(scene) ((scene)->toolsettings->gpencil_flags & GP_TOOL_FLAG_PAINTSESSIONS_ON) +/* used to sort by zdepth gpencil objects in viewport */ +/* TODO: this could be a system parameter in userprefs screen */ +#define GP_CACHE_BLOCK_SIZE 16 +typedef struct tGPencilSort { + struct Base *base; + float zdepth; +} tGPencilSort; /* ----------- Grease Pencil Tools/Context ------------- */ /* Context-dependent */ -struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *ptr); +struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *r_ptr); + struct bGPdata *ED_gpencil_data_get_active(const struct bContext *C); +struct bGPdata *ED_gpencil_data_get_active_evaluated(const struct bContext *C); /* Context independent (i.e. each required part is passed in instead) */ -struct bGPdata **ED_gpencil_data_get_pointers_direct(struct ID *screen_id, struct Scene *scene, - struct ScrArea *sa, struct Object *ob, - struct PointerRNA *ptr); -struct bGPdata *ED_gpencil_data_get_active_direct(struct ID *screen_id, struct Scene *scene, - struct ScrArea *sa, struct Object *ob); +struct bGPdata **ED_gpencil_data_get_pointers_direct( + struct ID *screen_id, + struct ScrArea *sa, + struct Scene *scene, + struct Object *ob, + struct PointerRNA *r_ptr); +struct bGPdata *ED_gpencil_data_get_active_direct( + struct ID *screen_id, + struct ScrArea *sa, + struct Scene *scene, + struct Object *ob); + +bool ED_gpencil_data_owner_is_annotation(struct PointerRNA *owner_ptr); /* 3D View */ -struct bGPdata *ED_gpencil_data_get_active_v3d(struct Scene *scene, struct ViewLayer *view_layer); +struct bGPdata *ED_gpencil_data_get_active_v3d(struct ViewLayer *view_layer); bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfra); @@ -124,13 +120,7 @@ bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfr bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *sa, const struct bGPDstroke *gps); bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps); -bool ED_gpencil_stroke_color_use(const struct bGPDlayer *gpl, const struct bGPDstroke *gps); - -struct bGPDpalettecolor *ED_gpencil_stroke_getcolor(struct bGPdata *gpd, struct bGPDstroke *gps); - -bool ED_gpencil_stroke_minmax( - const struct bGPDstroke *gps, const bool use_select, - float r_min[3], float r_max[3]); +bool ED_gpencil_stroke_color_use(struct Object *ob, const struct bGPDlayer *gpl, const struct bGPDstroke *gps); /* ----------- Grease Pencil Operators ----------------- */ @@ -150,16 +140,29 @@ void ED_gpencil_strokes_copybuf_free(void); void ED_gpencil_draw_2dimage(const struct bContext *C); void ED_gpencil_draw_view2d(const struct bContext *C, bool onlyv2d); -void ED_gpencil_draw_view3d(struct wmWindowManager *wm, - struct Scene *scene, - struct ViewLayer *view_layer, - struct Depsgraph *depsgraph, - struct View3D *v3d, - struct ARegion *ar, - bool only3d); -void ED_gpencil_draw_ex(struct Scene *scene, struct bGPdata *gpd, int winx, int winy, - const int cfra, const char spacetype); -void ED_gp_draw_interpolation(struct tGPDinterpolate *tgpi, const int type); +void ED_gpencil_draw_view3d( + struct wmWindowManager *wm, + struct Scene *scene, + struct ViewLayer *view_layer, + struct Depsgraph *depsgraph, + struct View3D *v3d, + struct ARegion *ar, + bool only3d); +void ED_gpencil_draw_view3d_annotations( + struct Scene *scene, struct Depsgraph *depsgraph, + struct View3D *v3d, struct ARegion *ar, + bool only3d); +void ED_gpencil_draw_view3d_object( + struct wmWindowManager *wm, + struct Scene *scene, + struct Depsgraph *depsgraph, + struct Object *ob, + struct View3D *v3d, + struct ARegion *ar, + bool only3d); +void ED_gpencil_draw_ex( + struct RegionView3D *rv3d, struct Scene *scene, struct bGPdata *gpd, int winx, int winy, + const int cfra, const char spacetype); /* ----------- Grease-Pencil AnimEdit API ------------------ */ bool ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, @@ -192,10 +195,45 @@ int ED_undo_gpencil_step(struct bContext *C, int step, const char *name); /* ------------ Transformation Utilities ------------ */ -/* get difference matrix using parent */ -void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]); +/* get difference matrix */ +void ED_gpencil_parent_location( + const struct Depsgraph *depsgraph, struct Object *obact, struct bGPdata *gpd, + struct bGPDlayer *gpl, float diff_mat[4][4]); /* reset parent matrix for all layers */ -void ED_gpencil_reset_layers_parent(struct bGPdata *gpd); +void ED_gpencil_reset_layers_parent(struct Depsgraph *depsgraph, struct Object *obact, struct bGPdata *gpd); + +/* cursor utilities */ +void ED_gpencil_brush_draw_eraser(struct Brush *brush, int x, int y); + +/* ----------- Add Primitive Utilities -------------- */ + +void ED_gpencil_create_monkey(struct bContext *C, float mat[4][4]); + +/* ------------ Object Utilities ------------ */ +struct Object *ED_add_gpencil_object(struct bContext *C, struct Scene *scene, const float loc[3]); +void ED_gpencil_add_defaults(struct bContext *C); +/* set object modes */ +void ED_gpencil_setup_modes(struct bContext *C, struct bGPdata *gpd, int newmode); + +void ED_gp_project_stroke_to_plane(struct Object *ob, struct RegionView3D *rv3d, struct bGPDstroke *gps, const float origin[3], const int axis); +void ED_gp_project_point_to_plane(struct Object *ob, struct RegionView3D *rv3d, const float origin[3], const int axis, struct bGPDspoint *pt); +void ED_gp_get_drawing_reference(struct View3D *v3d, struct Scene *scene, struct Object *ob, struct bGPDlayer *gpl, char align_flag, float vec[3]); + +/* set sculpt cursor */ +void ED_gpencil_toggle_brush_cursor(struct bContext *C, bool enable, void *customdata); + +/* vertex groups */ +void ED_gpencil_vgroup_assign(struct bContext *C, struct Object *ob, float weight); +void ED_gpencil_vgroup_remove(struct bContext *C, struct Object *ob); +void ED_gpencil_vgroup_select(struct bContext *C, struct Object *ob); +void ED_gpencil_vgroup_deselect(struct bContext *C, struct Object *ob); + +/* join objects */ +int ED_gpencil_join_objects_exec(struct bContext *C, struct wmOperator *op); +/* texture coordinate utilities */ +void ED_gpencil_tpoint_to_point(struct ARegion *ar, float origin[3], const struct tGPspoint *tpt, struct bGPDspoint *pt); +void ED_gpencil_calc_stroke_uv(struct Object *ob, struct bGPDstroke *gps); +void ED_gpencil_update_color_uv(struct Main *bmain, struct Material *mat); #endif /* __ED_GPENCIL_H__ */ diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 64dee410526..45a0680e0c1 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -42,6 +42,7 @@ struct bActionGroup; struct Object; struct ListBase; struct bGPDlayer; +struct Palette; struct MaskLayer; struct Scene; struct View2D; @@ -151,9 +152,11 @@ void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tr /* DopeSheet Summary */ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); /* Grease Pencil datablock summary */ -void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys); +void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys, const bool active); /* Grease Pencil Layer */ void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); +/* Palette */ +void palette_to_keylist(struct bDopeSheet *ads, struct Palette *palette, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks); /* Mask */ void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9fd5cc99073..a39523983ba 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -42,6 +42,7 @@ struct ID; struct Main; struct Menu; struct ModifierData; +struct ShaderFxData; struct Object; struct ReportList; struct Scene; @@ -261,6 +262,40 @@ bool ED_object_iter_other( bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); + +/* object_greasepencil_modifier.c */ +struct GpencilModifierData *ED_object_gpencil_modifier_add( + struct ReportList *reports, struct Main *bmain, struct Scene *scene, + struct Object *ob, const char *name, int type); +bool ED_object_gpencil_modifier_remove( + struct ReportList *reports, struct Main *bmain, + struct Object *ob, struct GpencilModifierData *md); +void ED_object_gpencil_modifier_clear( + struct Main *bmain, struct Object *ob); +int ED_object_gpencil_modifier_move_down( + struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md); +int ED_object_gpencil_modifier_move_up( + struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md); +int ED_object_gpencil_modifier_apply( + struct Main *bmain, struct ReportList *reports, struct Depsgraph *depsgraph, + struct Object *ob, struct GpencilModifierData *md, int mode); +int ED_object_gpencil_modifier_copy( + struct ReportList *reports, struct Object *ob, struct GpencilModifierData *md); + +/* object_shader_fx.c */ +struct ShaderFxData *ED_object_shaderfx_add( + struct ReportList *reports, struct Main *bmain, struct Scene *scene, + struct Object *ob, const char *name, int type); +bool ED_object_shaderfx_remove( + struct ReportList *reports, struct Main *bmain, + struct Object *ob, struct ShaderFxData *fx); +void ED_object_shaderfx_clear( + struct Main *bmain, struct Object *ob); +int ED_object_shaderfx_move_down( + struct ReportList *reports, struct Object *ob, struct ShaderFxData *fx); +int ED_object_shaderfx_move_up( + struct ReportList *reports, struct Object *ob, struct ShaderFxData *fx); + /* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index ec4c7dddd4c..dec02faf85c 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -1001,6 +1001,30 @@ DEF_ICON(MATCAP_22) DEF_ICON(MATCAP_23) DEF_ICON(MATCAP_24) +/* grease pencil sculpt */ +DEF_ICON(GPBRUSH_SMOOTH) +DEF_ICON(GPBRUSH_THICKNESS) +DEF_ICON(GPBRUSH_STRENGTH) +DEF_ICON(GPBRUSH_GRAB) +DEF_ICON(GPBRUSH_PUSH) +DEF_ICON(GPBRUSH_TWIST) +DEF_ICON(GPBRUSH_PINCH) +DEF_ICON(GPBRUSH_RANDOMIZE) +DEF_ICON(GPBRUSH_CLONE) +DEF_ICON(GPBRUSH_WEIGHT) + +DEF_ICON(GPBRUSH_PENCIL) +DEF_ICON(GPBRUSH_PEN) +DEF_ICON(GPBRUSH_INK) +DEF_ICON(GPBRUSH_INKNOISE) +DEF_ICON(GPBRUSH_BLOCK) +DEF_ICON(GPBRUSH_MARKER) +DEF_ICON(GPBRUSH_CUSTOM) +DEF_ICON(GPBRUSH_FILL) +DEF_ICON(GPBRUSH_ERASE_SOFT) +DEF_ICON(GPBRUSH_ERASE_HARD) +DEF_ICON(GPBRUSH_ERASE_STROKE) + /* vector icons, VICO_ prefix added */ DEF_VICO(SMALL_TRI_RIGHT_VEC) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b4756eaed0f..fc3dd3f9968 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1022,7 +1022,8 @@ uiLayout *uiLayoutRadial(uiLayout *layout); void uiTemplateHeader(uiLayout *layout, struct bContext *C); void uiTemplateID( uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, - const char *newop, const char *openop, const char *unlinkop, int filter); + const char *newop, const char *openop, const char *unlinkop, + int filter, const bool live_icon); void uiTemplateIDBrowse( uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter); @@ -1052,6 +1053,12 @@ void uiTemplatePathBuilder( uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *root_ptr, const char *text); uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr); +uiLayout *uiTemplateGpencilModifier(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr); +void uiTemplateGpencilColorPreview( + uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, + int rows, int cols, float scale, int filter); + +uiLayout *uiTemplateShaderFx(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr); void uiTemplateOperatorRedoProperties(uiLayout *layout, const struct bContext *C); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 7255640bedc..4f77b797ec0 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -47,6 +47,7 @@ #include "DNA_brush_types.h" #include "DNA_curve_types.h" #include "DNA_dynamicpaint_types.h" +#include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" @@ -109,6 +110,7 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha); #define ICON_TYPE_VECTOR 4 #define ICON_TYPE_GEOM 5 #define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */ +#define ICON_TYPE_GPLAYER 7 typedef struct DrawInfo { int type; @@ -391,6 +393,28 @@ DEF_VICON_COLORSET_DRAW_NTH(20, 19) #undef DEF_VICON_COLORSET_DRAW_NTH +/* Dynamically render icon instead of rendering a plain color to a texture/buffer + * This is mot strictly a "vicon", as it needs access to icon->obj to get the color info, + * but it works in a very similar way. + */ +static void vicon_gplayer_color_draw(Icon *icon, int x, int y, int w, int h) +{ + bGPDlayer *gpl = (bGPDlayer *)icon->obj; + + /* Just draw a colored rect - Like for vicon_colorset_draw() */ + /* TODO: Make this have rounded corners, and maybe be a bit smaller. + * However, UI_draw_roundbox_aa() draws the colors too dark, so can't be used. + */ + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor3fv(gpl->color); + immRecti(pos, x, y, x + w - 1, y + h - 1); + + immUnbindProgram(); +} + + #ifndef WITH_HEADLESS static void init_brush_icons(void) @@ -443,6 +467,30 @@ static void init_brush_icons(void) INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist); INIT_BRUSH_ICON(ICON_BRUSH_VERTEXDRAW, vertexdraw); + /* grease pencil sculpt */ + INIT_BRUSH_ICON(ICON_GPBRUSH_SMOOTH, gp_brush_smooth); + INIT_BRUSH_ICON(ICON_GPBRUSH_THICKNESS, gp_brush_thickness); + INIT_BRUSH_ICON(ICON_GPBRUSH_STRENGTH, gp_brush_strength); + INIT_BRUSH_ICON(ICON_GPBRUSH_GRAB, gp_brush_grab); + INIT_BRUSH_ICON(ICON_GPBRUSH_PUSH, gp_brush_push); + INIT_BRUSH_ICON(ICON_GPBRUSH_TWIST, gp_brush_twist); + INIT_BRUSH_ICON(ICON_GPBRUSH_PINCH, gp_brush_pinch); + INIT_BRUSH_ICON(ICON_GPBRUSH_RANDOMIZE, gp_brush_randomize); + INIT_BRUSH_ICON(ICON_GPBRUSH_CLONE, gp_brush_clone); + INIT_BRUSH_ICON(ICON_GPBRUSH_WEIGHT, gp_brush_weight); + + /* grease pencil drawing brushes */ + INIT_BRUSH_ICON(ICON_GPBRUSH_PENCIL, gp_brush_pencil); + INIT_BRUSH_ICON(ICON_GPBRUSH_PEN, gp_brush_pen); + INIT_BRUSH_ICON(ICON_GPBRUSH_INK, gp_brush_ink); + INIT_BRUSH_ICON(ICON_GPBRUSH_INKNOISE, gp_brush_inknoise); + INIT_BRUSH_ICON(ICON_GPBRUSH_BLOCK, gp_brush_block); + INIT_BRUSH_ICON(ICON_GPBRUSH_MARKER, gp_brush_marker); + INIT_BRUSH_ICON(ICON_GPBRUSH_FILL, gp_brush_fill); + INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_SOFT, gp_brush_erase_soft); + INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_HARD, gp_brush_erase_hard); + INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_STROKE, gp_brush_erase_stroke); + #undef INIT_BRUSH_ICON } @@ -877,6 +925,9 @@ static DrawInfo *icon_create_drawinfo(Icon *icon) else if (icon_data_type == ICON_DATA_STUDIOLIGHT) { di->type = ICON_TYPE_BUFFER; } + else if (icon_data_type == ICON_DATA_GPLAYER) { + di->type = ICON_TYPE_GPLAYER; + } else { BLI_assert(0); } @@ -1484,6 +1535,15 @@ static void icon_draw_size( GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); } } + else if (di->type == ICON_TYPE_GPLAYER) { + BLI_assert(icon->obj != NULL); + + /* We need to flush widget base first to ensure correct ordering. */ + UI_widgetbase_draw_cache_flush(); + + /* Just draw a colored rect - Like for vicon_colorset_draw() */ + vicon_gplayer_color_draw(icon, (int)x, (int)y, w, h); + } } static void ui_id_preview_image_render_size( @@ -1576,7 +1636,45 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) } /* reset the icon */ - if (mode == OB_MODE_SCULPT) { + if (ob->mode & OB_MODE_GPENCIL_PAINT) { + switch (br->gpencil_settings->icon_id) { + case GP_BRUSH_ICON_PENCIL: + br->id.icon_id = ICON_GPBRUSH_PENCIL; + break; + case GP_BRUSH_ICON_PEN: + br->id.icon_id = ICON_GPBRUSH_PEN; + break; + case GP_BRUSH_ICON_INK: + br->id.icon_id = ICON_GPBRUSH_INK; + break; + case GP_BRUSH_ICON_INKNOISE: + br->id.icon_id = ICON_GPBRUSH_INKNOISE; + break; + case GP_BRUSH_ICON_BLOCK: + br->id.icon_id = ICON_GPBRUSH_BLOCK; + break; + case GP_BRUSH_ICON_MARKER: + br->id.icon_id = ICON_GPBRUSH_MARKER; + break; + case GP_BRUSH_ICON_FILL: + br->id.icon_id = ICON_GPBRUSH_FILL; + break; + case GP_BRUSH_ICON_ERASE_SOFT: + br->id.icon_id = ICON_GPBRUSH_ERASE_SOFT; + break; + case GP_BRUSH_ICON_ERASE_HARD: + br->id.icon_id = ICON_GPBRUSH_ERASE_HARD; + break; + case GP_BRUSH_ICON_ERASE_STROKE: + br->id.icon_id = ICON_GPBRUSH_ERASE_STROKE; + break; + default: + br->id.icon_id = ICON_GPBRUSH_PEN; + break; + } + return id->icon_id; + } + else if (mode == OB_MODE_SCULPT) { items = rna_enum_brush_sculpt_tool_items; tool = br->sculpt_tool; } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 82ed4c5acba..89e1a8caec8 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1244,7 +1244,15 @@ void uiItemsFullEnumO( bool free; if (ui_layout_is_radial(layout)) { + /* XXX: While "_all()" guarantees spatial stability, it's bad when an enum has > 8 items total, + * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the + * introduction of GP editing modes) + */ +#if 0 RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free); +#else + RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free); +#endif } else { RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 131ffbca377..513bfd32191 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -39,6 +39,8 @@ #include "DNA_object_force_types.h" #include "DNA_brush_types.h" #include "DNA_texture_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_shader_fx_types.h" #include "BLI_utildefines.h" #include "BLI_alloca.h" @@ -57,6 +59,7 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_gpencil_modifier.h" #include "BKE_idcode.h" #include "BKE_idprop.h" #include "BKE_layer.h" @@ -71,6 +74,7 @@ #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_screen.h" +#include "BKE_shader_fx.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -110,7 +114,7 @@ static void template_add_button_search_menu( const bContext *C, uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, uiBlockCreateFunc block_func, void *block_argN, const char * const tip, - const bool use_previews, const bool editable) + const bool use_previews, const bool editable, const bool live_icon) { PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop); ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL; @@ -146,7 +150,14 @@ static void template_add_button_search_menu( } else { but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip); - ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON); + + if (live_icon) { + int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type); + ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); + } + else { + ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON); + } if (id) { /* default dragging of icon for id browse buttons */ UI_but_drag_set_id(but, id); @@ -162,7 +173,8 @@ static uiBlock *template_common_search_menu( const bContext *C, ARegion *region, uiButSearchFunc search_func, void *search_arg, uiButHandleFunc handle_func, void *active_item, - const int preview_rows, const int preview_cols) + const int preview_rows, const int preview_cols, + float scale) { static char search[256]; wmWindow *win = CTX_wm_window(C); @@ -177,8 +189,8 @@ static uiBlock *template_common_search_menu( /* preview thumbnails */ if (preview_rows > 0 && preview_cols > 0) { - const int w = 4 * U.widget_unit * preview_cols; - const int h = 5 * U.widget_unit * preview_rows; + const int w = 4 * U.widget_unit * preview_cols * scale; + const int h = 5 * U.widget_unit * preview_rows * scale; /* fake button, it holds space for search items */ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL); @@ -237,6 +249,7 @@ typedef struct TemplateID { short filter; int prv_rows, prv_cols; bool preview; + float scale; } TemplateID; /* Search browse menu, assign */ @@ -382,7 +395,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) return template_common_search_menu( C, ar, id_search_cb_p, &template_ui, template_ID_set_property_cb, active_item_ptr.data, - template_ui.prv_rows, template_ui.prv_cols); + template_ui.prv_rows, template_ui.prv_cols, template_ui.scale); } /************************ ID Template ***************************/ @@ -630,7 +643,8 @@ static uiBut *template_id_def_new_but( static void template_ID( bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag, - const char *newop, const char *openop, const char *unlinkop) + const char *newop, const char *openop, const char *unlinkop, + const bool live_icon) { uiBut *but; uiBlock *block; @@ -655,7 +669,7 @@ static void template_ID( template_add_button_search_menu( C, layout, block, &template_ui->ptr, template_ui->prop, id_search_menu, MEM_dupallocN(template_ui), TIP_(template_id_browse_tip(type)), - use_previews, editable); + use_previews, editable, live_icon); } /* text button with name */ @@ -860,7 +874,8 @@ static void ui_template_id( uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, - int flag, int prv_rows, int prv_cols, int filter, bool use_tabs) + int flag, int prv_rows, int prv_cols, int filter, bool use_tabs, + float scale, bool live_icon) { TemplateID *template_ui; PropertyRNA *prop; @@ -879,6 +894,7 @@ static void ui_template_id( template_ui->prop = prop; template_ui->prv_rows = prv_rows; template_ui->prv_cols = prv_cols; + template_ui->scale = scale; if ((flag & UI_ID_PIN) == 0) { template_ui->filter = filter; @@ -907,7 +923,7 @@ static void ui_template_id( } else { uiLayoutRow(layout, true); - template_ID(C, layout, template_ui, type, flag, newop, openop, unlinkop); + template_ID(C, layout, template_ui, type, flag, newop, openop, unlinkop, live_icon); } } @@ -916,13 +932,14 @@ static void ui_template_id( void uiTemplateID( uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, - const char *openop, const char *unlinkop, int filter) + const char *openop, const char *unlinkop, + int filter, const bool live_icon) { ui_template_id( layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, - 0, 0, filter, false); + 0, 0, filter, false, 1.0f, live_icon); } void uiTemplateIDBrowse( @@ -933,7 +950,7 @@ void uiTemplateIDBrowse( layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME, - 0, 0, filter, false); + 0, 0, filter, false, 1.0f, false); } void uiTemplateIDPreview( @@ -944,7 +961,18 @@ void uiTemplateIDPreview( layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS, - rows, cols, filter, false); + rows, cols, filter, false, 1.0f, false); +} + +void uiTemplateGpencilColorPreview( + uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, + int rows, int cols, float scale, int filter) +{ + ui_template_id( + layout, C, ptr, propname, + NULL, NULL, NULL, + UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE, + rows, cols, filter, false, scale < 0.5f ? 0.5f : scale, false); } /** @@ -960,7 +988,7 @@ void uiTemplateIDTabs( layout, C, ptr, propname, newop, openop, unlinkop, UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE, - 0, 0, filter, true); + 0, 0, filter, true, 1.0f, false); } /************************ ID Chooser Template ***************************/ @@ -1057,12 +1085,12 @@ static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_tem return template_common_search_menu( C, region, ui_rna_collection_search_cb, &template_search, template_search_handle_cb, active_ptr.data, - template_search.preview_rows, template_search.preview_cols); + template_search.preview_rows, template_search.preview_cols, 1.0f); } static void template_search_add_button_searchmenu( const bContext *C, uiLayout *layout, uiBlock *block, - TemplateSearch *template_search, const bool editable) + TemplateSearch *template_search, const bool editable, const bool live_icon) { const char *ui_description = RNA_property_ui_description(template_search->search_data.target_prop); @@ -1070,7 +1098,7 @@ static void template_search_add_button_searchmenu( C, layout, block, &template_search->search_data.target_ptr, template_search->search_data.target_prop, template_search_menu, MEM_dupallocN(template_search), ui_description, - template_search->use_previews, editable); + template_search->use_previews, editable, live_icon); } static void template_search_add_button_name( @@ -1116,7 +1144,7 @@ static void template_search_buttons( uiLayoutRow(layout, true); UI_block_align_begin(block); - template_search_add_button_searchmenu(C, layout, block, template_search, editable); + template_search_add_button_searchmenu(C, layout, block, template_search, editable, false); template_search_add_button_name(block, &active_ptr, type); template_search_add_button_operator(block, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, editable); template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable); @@ -1539,6 +1567,246 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) return NULL; } +/************************ Grease Pencil Modifier Template *************************/ + +static uiLayout *gpencil_draw_modifier(uiLayout *layout, Object *ob, + GpencilModifierData *md) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + PointerRNA ptr; + uiBlock *block; + uiLayout *box, *column, *row, *sub; + uiLayout *result = NULL; + + /* create RNA pointer */ + RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr); + + column = uiLayoutColumn(layout, true); + uiLayoutSetContextPointer(column, "modifier", &ptr); + + /* rounded header ------------------------------------------------------------------- */ + box = uiLayoutBox(column); + + row = uiLayoutRow(box, false); + block = uiLayoutGetBlock(row); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + /* Open/Close ................................. */ + uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE); + + /* modifier-type icon */ + uiItemL(row, "", RNA_struct_ui_icon(ptr.type)); + UI_block_emboss_set(block, UI_EMBOSS); + + /* modifier name */ + if (mti->isDisabled && mti->isDisabled(md, 0)) { + uiLayoutSetRedAlert(row, true); + } + uiItemR(row, &ptr, "name", 0, "", ICON_NONE); + uiLayoutSetRedAlert(row, false); + + /* mode enabling buttons */ + UI_block_align_begin(block); + uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE); + uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE); + + if (mti->flags & eGpencilModifierTypeFlag_SupportsEditmode) { + sub = uiLayoutRow(row, true); + uiLayoutSetActive(sub, false); + uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE); + } + + UI_block_align_end(block); + + /* Up/Down + Delete ........................... */ + UI_block_align_begin(block); + uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_gpencil_modifier_move_up"); + uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_gpencil_modifier_move_down"); + UI_block_align_end(block); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiItemO(row, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove"); + UI_block_emboss_set(block, UI_EMBOSS); + + /* modifier settings (under the header) --------------------------------------------------- */ + if (md->mode & eGpencilModifierMode_Expanded) { + /* apply/convert/copy */ + box = uiLayoutBox(column); + row = uiLayoutRow(box, false); + + /* only here obdata, the rest of modifiers is ob level */ + UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT); + uiItemEnumO(row, "OBJECT_OT_gpencil_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"), + 0, "apply_as", MODIFIER_APPLY_DATA); + + uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE, + "OBJECT_OT_gpencil_modifier_copy"); + + /* result is the layout block inside the box, that we return so that modifier settings can be drawn */ + result = uiLayoutColumn(box, false); + block = uiLayoutAbsoluteBlock(box); + } + + /* error messages */ + if (md->error) { + box = uiLayoutBox(column); + row = uiLayoutRow(box, false); + uiItemL(row, md->error, ICON_ERROR); + } + + return result; +} + +uiLayout *uiTemplateGpencilModifier(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + Object *ob; + GpencilModifierData *md, *vmd; + int i; + + /* verify we have valid data */ + if (!RNA_struct_is_a(ptr->type, &RNA_GpencilModifier)) { + RNA_warning("Expected modifier on object"); + return NULL; + } + + ob = ptr->id.data; + md = ptr->data; + + if (!ob || !(GS(ob->id.name) == ID_OB)) { + RNA_warning("Expected modifier on object"); + return NULL; + } + + UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE); + + /* find modifier and draw it */ + vmd = ob->greasepencil_modifiers.first; + for (i = 0; vmd; i++, vmd = vmd->next) { + if (md == vmd) + return gpencil_draw_modifier(layout, ob, md); + } + + return NULL; +} + +/************************ Shader FX Template *************************/ + +static uiLayout *gpencil_draw_shaderfx(uiLayout *layout, Object *ob, + ShaderFxData *md) +{ + const ShaderFxTypeInfo *mti = BKE_shaderfxType_getInfo(md->type); + PointerRNA ptr; + uiBlock *block; + uiLayout *box, *column, *row, *sub; + uiLayout *result = NULL; + + /* create RNA pointer */ + RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr); + + column = uiLayoutColumn(layout, true); + uiLayoutSetContextPointer(column, "shaderfx", &ptr); + + /* rounded header ------------------------------------------------------------------- */ + box = uiLayoutBox(column); + + row = uiLayoutRow(box, false); + block = uiLayoutGetBlock(row); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + /* Open/Close ................................. */ + uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE); + + /* shader-type icon */ + uiItemL(row, "", RNA_struct_ui_icon(ptr.type)); + UI_block_emboss_set(block, UI_EMBOSS); + + /* effect name */ + if (mti->isDisabled && mti->isDisabled(md, 0)) { + uiLayoutSetRedAlert(row, true); + } + uiItemR(row, &ptr, "name", 0, "", ICON_NONE); + uiLayoutSetRedAlert(row, false); + + /* mode enabling buttons */ + UI_block_align_begin(block); + uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE); + uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE); + + if (mti->flags & eShaderFxTypeFlag_SupportsEditmode) { + sub = uiLayoutRow(row, true); + uiLayoutSetActive(sub, false); + uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE); + } + + UI_block_align_end(block); + + /* Up/Down + Delete ........................... */ + UI_block_align_begin(block); + uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_shaderfx_move_up"); + uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_shaderfx_move_down"); + UI_block_align_end(block); + + UI_block_emboss_set(block, UI_EMBOSS_NONE); + uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove"); + UI_block_emboss_set(block, UI_EMBOSS); + + /* effect settings (under the header) --------------------------------------------------- */ + if (md->mode & eShaderFxMode_Expanded) { + /* apply/convert/copy */ + box = uiLayoutBox(column); + row = uiLayoutRow(box, false); + + /* only here obdata, the rest of effect is ob level */ + UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); + + /* result is the layout block inside the box, that we return so that effect settings can be drawn */ + result = uiLayoutColumn(box, false); + block = uiLayoutAbsoluteBlock(box); + } + + /* error messages */ + if (md->error) { + box = uiLayoutBox(column); + row = uiLayoutRow(box, false); + uiItemL(row, md->error, ICON_ERROR); + } + + return result; +} + +uiLayout *uiTemplateShaderFx(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + Object *ob; + ShaderFxData *fx, *vfx; + int i; + + /* verify we have valid data */ + if (!RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) { + RNA_warning("Expected shader fx on object"); + return NULL; + } + + ob = ptr->id.data; + fx = ptr->data; + + if (!ob || !(GS(ob->id.name) == ID_OB)) { + RNA_warning("Expected shader fx on object"); + return NULL; + } + + UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE); + + /* find modifier and draw it */ + vfx = ob->shader_fx.first; + for (i = 0; vfx; i++, vfx = vfx->next) { + if (fx == vfx) + return gpencil_draw_shaderfx(layout, ob, fx); + } + + return NULL; +} /************************ Redo Buttons Template *************************/ @@ -4638,7 +4906,7 @@ void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const c uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr); - uiTemplateID(layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!file) { return; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 3cb8a277e9a..e6422c423b9 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1536,15 +1536,6 @@ void init_userdef_do_versions(Main *bmain) #undef USER_VERSION_ATLEAST #define USER_VERSION_ATLEAST(ver, subver) MAIN_VERSION_ATLEAST((&(U)), ver, subver) - - if (!USER_VERSION_ATLEAST(269, 9)) { - /* grease pencil - new layer color */ - if (U.gpencil_new_layer_col[3] < 0.1f) { - /* defaults to black, but must at least be visible! */ - U.gpencil_new_layer_col[3] = 0.9f; - } - } - if (!USER_VERSION_ATLEAST(271, 5)) { U.pie_menu_radius = 100; U.pie_menu_threshold = 12; @@ -1582,6 +1573,17 @@ void init_userdef_do_versions(Main *bmain) for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) { memcpy(btheme, &U_theme_default, sizeof(*btheme)); } + + /* Annotations - new layer color + * Replace anything that used to be set if it looks like was left + * on the old default (i.e. black), which most users used + */ + if ((U.gpencil_new_layer_col[3] < 0.1f) || (U.gpencil_new_layer_col[0] < 0.1f)) { + /* - New color matches the annotation pencil icon + * - Non-full alpha looks better! + */ + ARRAY_SET_ITEMS(U.gpencil_new_layer_col, 0.38f, 0.61f, 0.78f, 0.9f); + } } /** diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 305e3287029..739975a6278 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -31,6 +31,8 @@ set(INC ../../makesdna ../../makesrna ../../modifiers + ../../gpencil_modifiers + ../../shader_fx ../../python ../../render/extern/include ../../windowmanager @@ -53,6 +55,8 @@ set(SRC object_hook.c object_modes.c object_modifier.c + object_gpencil_modifier.c + object_shader_fx.c object_ops.c object_random.c object_relations.c diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 68e84ec3f3b..87eddc2674c 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -71,6 +71,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" +#include "BKE_gpencil.h" #include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_layer.h" @@ -103,6 +104,7 @@ #include "ED_armature.h" #include "ED_curve.h" +#include "ED_gpencil.h" #include "ED_mball.h" #include "ED_mesh.h" #include "ED_node.h" @@ -985,6 +987,106 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot) ED_object_add_generic_props(ot, false); } +/********************* Add Gpencil Operator ********************/ + +static int object_gpencil_add_exec(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + bGPdata *gpd = (ob && (ob->type == OB_GPENCIL)) ? ob->data : NULL; + + const int type = RNA_enum_get(op->ptr, "type"); + + float loc[3], rot[3]; + unsigned int layer; + bool newob = false; + + /* Hack: Force view-align to be on by default + * since it's not nice for adding shapes in 2D + * for them to end up aligned oddly, but only for Monkey + */ + if ((RNA_struct_property_is_set(op->ptr, "view_align") == false) && + (type == GP_MONKEY)) { + RNA_boolean_set(op->ptr, "view_align", true); + } + + /* Note: We use 'Y' here (not 'Z'), as */ + WM_operator_view3d_unit_defaults(C, op); + if (!ED_object_add_generic_get_opts(C, op, 'Y', loc, rot, NULL, &layer, NULL)) + return OPERATOR_CANCELLED; + + /* add new object if not currently editing a GP object, + * or if "empty" was chosen (i.e. user wants a blank GP canvas) + */ + if ((gpd == NULL) || (GPENCIL_ANY_MODE(gpd) == false) || (type == GP_EMPTY)) { + const char *ob_name = (type == GP_MONKEY) ? "Suzanne" : NULL; + float radius = RNA_float_get(op->ptr, "radius"); + + ob = ED_object_add_type(C, OB_GPENCIL, ob_name, loc, rot, true, layer); + gpd = ob->data; + newob = true; + + BKE_object_obdata_size_init(ob, GP_OBGPENCIL_DEFAULT_SIZE * radius); + } + else { + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_ADDED, NULL); + } + + /* create relevant geometry */ + switch (type) { + case GP_MONKEY: + { + float radius = RNA_float_get(op->ptr, "radius"); + float mat[4][4]; + + ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + mul_v3_fl(mat[0], radius); + mul_v3_fl(mat[1], radius); + mul_v3_fl(mat[2], radius); + + ED_gpencil_create_monkey(C, mat); + break; + } + + case GP_EMPTY: + /* do nothing */ + break; + + default: + BKE_report(op->reports, RPT_WARNING, "Not implemented"); + break; + } + + /* if this is a new object, initialise default stuff (colors, etc.) */ + if (newob) { + ED_gpencil_add_defaults(C); + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_gpencil_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add GPencil"; + ot->description = "Add a grease pencil object to the scene"; + ot->idname = "OBJECT_OT_gpencil_add"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = object_gpencil_add_exec; + ot->poll = ED_operator_scene_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ED_object_add_unit_props(ot); + ED_object_add_generic_props(ot, false); + + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", ""); +} + /********************* Add Light Operator ********************/ static const char *get_light_defname(int type) @@ -1781,6 +1883,10 @@ static int convert_exec(bContext *C, wmOperator *op) if (ob->type == OB_MESH) { BKE_object_free_modifiers(ob, 0); /* after derivedmesh calls! */ } + if (ob->type == OB_GPENCIL) { + BKE_object_free_modifiers(ob, 0); /* after derivedmesh calls! */ + BKE_object_free_shaderfx(ob, 0); + } } } else if (ob->type == OB_MESH && target == OB_CURVE) { @@ -2122,6 +2228,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer ID_NEW_REMAP_US(obn->mat[a]) else { obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a])); + /* duplicate grease pencil settings */ + if (ob->mat[a]->gp_style) { + obn->mat[a]->gp_style = MEM_dupallocN(ob->mat[a]->gp_style); + } } id_us_min(id); @@ -2258,6 +2368,16 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer id_us_min(id); } break; + case OB_GPENCIL: + if (dupflag != 0) { + ID_NEW_REMAP_US2(obn->data) + else { + obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data)); + didit = 1; + } + id_us_min(id); + } + break; } /* check if obdata is copied */ @@ -2482,7 +2602,7 @@ static bool join_poll(bContext *C) if (!ob || ID_IS_LINKED(ob)) return 0; - if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE)) + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_ARMATURE, OB_GPENCIL)) return ED_operator_screenactive(C); else return 0; @@ -2500,6 +2620,13 @@ static int join_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Cannot edit external libdata"); return OPERATOR_CANCELLED; } + else if (ob->type == OB_GPENCIL) { + bGPdata *gpd = (bGPdata *)ob->data; + if ((!gpd) || GPENCIL_ANY_MODE(gpd)) { + BKE_report(op->reports, RPT_ERROR, "This data does not support joining in this mode"); + return OPERATOR_CANCELLED; + } + } if (ob->type == OB_MESH) return join_mesh_exec(C, op); @@ -2507,6 +2634,8 @@ static int join_exec(bContext *C, wmOperator *op) return join_curve_exec(C, op); else if (ob->type == OB_ARMATURE) return join_armature_exec(C, op); + else if (ob->type == OB_GPENCIL) + return ED_gpencil_join_objects_exec(C, op); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index a6c3c86922d..48048319cb7 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -100,6 +100,7 @@ #include "ED_screen.h" #include "ED_undo.h" #include "ED_image.h" +#include "ED_gpencil.h" #include "RNA_access.h" #include "RNA_define.h" @@ -1539,7 +1540,6 @@ static const EnumPropertyItem *object_mode_set_itemsf( const EnumPropertyItem *input = rna_enum_object_mode_items; EnumPropertyItem *item = NULL; Object *ob; - bGPdata *gpd; int totitem = 0; if (!C) /* needed for docs */ @@ -1555,7 +1555,9 @@ static const EnumPropertyItem *object_mode_set_itemsf( (input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) || (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) || (ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, - OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || + OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || + (ELEM(input->value, OB_MODE_GPENCIL_EDIT, OB_MODE_GPENCIL_PAINT, + OB_MODE_GPENCIL_SCULPT, OB_MODE_GPENCIL_WEIGHT) && (ob->type == OB_GPENCIL)) || (input->value == OB_MODE_OBJECT)) { RNA_enum_item_add(&item, &totitem, input); @@ -1568,14 +1570,6 @@ static const EnumPropertyItem *object_mode_set_itemsf( RNA_enum_items_add_value(&item, &totitem, input, OB_MODE_OBJECT); } - /* On top of all the rest, GPencil Stroke Edit Mode - * is available if there's a valid gp datablock... - */ - gpd = CTX_data_gpencil_data(C); - if (gpd) { - RNA_enum_items_add_value(&item, &totitem, rna_enum_object_mode_items, OB_MODE_GPENCIL); - } - RNA_enum_item_end(&item, &totitem); *r_free = true; @@ -1600,7 +1594,6 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) { bool use_submode = STREQ(op->idname, "OBJECT_OT_mode_set_or_submode"); Object *ob = CTX_data_active_object(C); - bGPdata *gpd = CTX_data_gpencil_data(C); eObjectMode mode = RNA_enum_get(op->ptr, "mode"); eObjectMode restore_mode = (ob) ? ob->mode : OB_MODE_OBJECT; const bool toggle = RNA_boolean_get(op->ptr, "toggle"); @@ -1620,22 +1613,9 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) } } - if (gpd) { - /* GP Mode is not bound to a specific object. Therefore, - * we don't want it to be actually saved on any objects, - * as weirdness can happen if you select other objects, - * or load old files. - * - * Instead, we use the following 2 rules to ensure that - * the mode selector works as expected: - * 1) If there's no object, we want to enter editmode. - * (i.e. with no object, we're in object mode) - * 2) Otherwise, exit stroke editmode, so that we can - * enter another mode... - */ - if (!ob || (gpd->flag & GP_DATA_STROKE_EDITMODE)) { - WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_EXEC_REGION_WIN, NULL); - } + /* by default the operator assume is a mesh, but if gp object change mode */ + if ((ob != NULL) && (ob->type == OB_GPENCIL) && (mode == OB_MODE_EDIT)) { + mode = OB_MODE_GPENCIL_EDIT; } if (!ob || !ED_object_mode_compat_test(ob, mode)) @@ -1666,6 +1646,14 @@ static int object_mode_set_exec(bContext *C, wmOperator *op) } } + /* if type is OB_GPENCIL, set cursor mode */ + if ((ob) && (ob->type == OB_GPENCIL)) { + if (ob->data) { + bGPdata *gpd = (bGPdata *)ob->data; + ED_gpencil_setup_modes(C, gpd, ob->mode); + } + } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c new file mode 100644 index 00000000000..175fb1706fb --- /dev/null +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -0,0 +1,637 @@ +/* + * ***** 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) 2018 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2018 + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/object_gpencil_modifier.c + * \ingroup edobj + */ + + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_report.h" +#include "BKE_object.h" +#include "BKE_gpencil.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "ED_object.h" +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "object_intern.h" + +/******************************** API ****************************/ + +GpencilModifierData *ED_object_gpencil_modifier_add( + ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type) +{ + GpencilModifierData *new_md = NULL; + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(type); + + if (ob->type != OB_GPENCIL) { + BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to object '%s'", ob->id.name + 2); + return NULL; + } + + if (mti->flags & eGpencilModifierTypeFlag_Single) { + if (BKE_gpencil_modifiers_findByType(ob, type)) { + BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed"); + return NULL; + } + } + + /* get new modifier data to add */ + new_md = BKE_gpencil_modifier_new(type); + + BLI_addtail(&ob->greasepencil_modifiers, new_md); + + if (name) { + BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name)); + } + + /* make sure modifier data has unique name */ + BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, new_md); + + + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + + return new_md; +} + +/* Return true if the object has a modifier of type 'type' other than + * the modifier pointed to be 'exclude', otherwise returns false. */ +static bool UNUSED_FUNCTION(gpencil_object_has_modifier)( + const Object *ob, const GpencilModifierData *exclude, + GpencilModifierType type) +{ + GpencilModifierData *md; + + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + if ((md != exclude) && (md->type == type)) + return true; + } + + return false; +} + +static bool gpencil_object_modifier_remove( + Main *bmain, Object *ob, GpencilModifierData *md, + bool *UNUSED(r_sort_depsgraph)) +{ + /* It seems on rapid delete it is possible to + * get called twice on same modifier, so make + * sure it is in list. */ + if (BLI_findindex(&ob->greasepencil_modifiers, md) == -1) { + return 0; + } + + DEG_relations_tag_update(bmain); + + BLI_remlink(&ob->greasepencil_modifiers, md); + BKE_gpencil_modifier_free(md); + BKE_object_free_derived_caches(ob); + + return 1; +} + +bool ED_object_gpencil_modifier_remove(ReportList *reports, Main *bmain, Object *ob, GpencilModifierData *md) +{ + bool sort_depsgraph = false; + bool ok; + + ok = gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph); + + if (!ok) { + BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name); + return 0; + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + + return 1; +} + +void ED_object_gpencil_modifier_clear(Main *bmain, Object *ob) +{ + GpencilModifierData *md = ob->greasepencil_modifiers.first; + bool sort_depsgraph = false; + + if (!md) + return; + + while (md) { + GpencilModifierData *next_md; + + next_md = md->next; + + gpencil_object_modifier_remove(bmain, ob, md, &sort_depsgraph); + + md = next_md; + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); +} + +int ED_object_gpencil_modifier_move_up(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) +{ + if (md->prev) { + BLI_remlink(&ob->greasepencil_modifiers, md); + BLI_insertlinkbefore(&ob->greasepencil_modifiers, md->prev, md); + } + + return 1; +} + +int ED_object_gpencil_modifier_move_down(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) +{ + if (md->next) { + BLI_remlink(&ob->greasepencil_modifiers, md); + BLI_insertlinkafter(&ob->greasepencil_modifiers, md->next, md); + } + + return 1; +} + +static int gpencil_modifier_apply_obdata( + ReportList *reports, Main *bmain, Depsgraph *depsgraph, Object *ob, GpencilModifierData *md) +{ + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (mti->isDisabled && mti->isDisabled(md, 0)) { + BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); + return 0; + } + + if (ob->type == OB_GPENCIL) { + if (ELEM(NULL, ob, ob->data)) { + return 0; + } + else if (mti->bakeModifier == NULL) { + BKE_report(reports, RPT_ERROR, "Not implemented"); + return 0; + } + mti->bakeModifier(bmain, depsgraph, md, ob); + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + else { + BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); + return 0; + } + + return 1; +} + +int ED_object_gpencil_modifier_apply( + Main *bmain, ReportList *reports, Depsgraph *depsgraph, + Object *ob, GpencilModifierData *md, int UNUSED(mode)) +{ + + if (ob->type == OB_GPENCIL) { + if (ob->mode != OB_MODE_OBJECT) { + BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in paint, sculpt or edit mode"); + return 0; + } + + if (((ID *)ob->data)->us > 1) { + BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); + return 0; + } + } + else if (((ID *)ob->data)->us > 1) { + BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data"); + return 0; + } + + if (md != ob->greasepencil_modifiers.first) + BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected"); + + if (!gpencil_modifier_apply_obdata(reports, bmain, depsgraph, ob, md)) { + return 0; + } + + BLI_remlink(&ob->greasepencil_modifiers, md); + BKE_gpencil_modifier_free(md); + + return 1; +} + +int ED_object_gpencil_modifier_copy(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) +{ + GpencilModifierData *nmd; + + nmd = BKE_gpencil_modifier_new(md->type); + BKE_gpencil_modifier_copyData(md, nmd); + BLI_insertlinkafter(&ob->greasepencil_modifiers, md, nmd); + BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, nmd); + + return 1; +} + +/************************ add modifier operator *********************/ + +static int gpencil_modifier_add_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + int type = RNA_enum_get(op->ptr, "type"); + + if (!ED_object_gpencil_modifier_add(op->reports, bmain, scene, ob, NULL, type)) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static const EnumPropertyItem *gpencil_modifier_add_itemf( + bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + Object *ob = ED_object_active_context(C); + EnumPropertyItem *item = NULL; + const EnumPropertyItem *md_item, *group_item = NULL; + const GpencilModifierTypeInfo *mti; + int totitem = 0, a; + + if (!ob) + return rna_enum_object_greasepencil_modifier_type_items; + + for (a = 0; rna_enum_object_greasepencil_modifier_type_items[a].identifier; a++) { + md_item = &rna_enum_object_greasepencil_modifier_type_items[a]; + if (md_item->identifier[0]) { + mti = BKE_gpencil_modifierType_getInfo(md_item->value); + + if (mti->flags & eGpencilModifierTypeFlag_NoUserAdd) + continue; + } + else { + group_item = md_item; + md_item = NULL; + + continue; + } + + if (group_item) { + RNA_enum_item_add(&item, &totitem, group_item); + group_item = NULL; + } + + RNA_enum_item_add(&item, &totitem, md_item); + } + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; +} + +void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Grease Pencil Modifier"; + ot->description = "Add a procedural operation/effect to the active grease pencil object"; + ot->idname = "OBJECT_OT_gpencil_modifier_add"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = gpencil_modifier_add_exec; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_enum(ot->srna, "type", rna_enum_object_modifier_type_items, eGpencilModifierType_Thick, "Type", ""); + RNA_def_enum_funcs(prop, gpencil_modifier_add_itemf); + ot->prop = prop; +} + +/************************ generic functions for operators using mod names and data context *********************/ + +static int gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type); + Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C); + + if (!ptr.data) { + CTX_wm_operator_poll_msg_set(C, "Context missing 'modifier'"); + return 0; + } + + if (!ob || ID_IS_LINKED(ob)) return 0; + if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0; + if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) return 0; + + if (ID_IS_STATIC_OVERRIDE(ob)) { + CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers comming from static override"); + return (((GpencilModifierData *)ptr.data)->flag & eGpencilModifierFlag_StaticOverride_Local) != 0; + } + + return 1; +} + +static bool gpencil_edit_modifier_poll(bContext *C) +{ + return gpencil_edit_modifier_poll_generic(C, &RNA_GpencilModifier, 0); +} + +static void gpencil_edit_modifier_properties(wmOperatorType *ot) +{ + RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit"); +} + +static int gpencil_edit_modifier_invoke_properties(bContext *C, wmOperator *op) +{ + GpencilModifierData *md; + + if (RNA_struct_property_is_set(op->ptr, "modifier")) { + return true; + } + else { + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_GpencilModifier); + if (ptr.data) { + md = ptr.data; + RNA_string_set(op->ptr, "modifier", md->name); + return true; + } + } + + return false; +} + +static GpencilModifierData *gpencil_edit_modifier_property_get(wmOperator *op, Object *ob, int type) +{ + char modifier_name[MAX_NAME]; + GpencilModifierData *md; + RNA_string_get(op->ptr, "modifier", modifier_name); + + md = BKE_gpencil_modifiers_findByName(ob, modifier_name); + + if (md && type != 0 && md->type != type) + md = NULL; + + return md; +} + +/************************ remove modifier operator *********************/ + +static int gpencil_modifier_remove_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Object *ob = ED_object_active_context(C); + GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); + + if (!md || !ED_object_gpencil_modifier_remove(op->reports, bmain, ob, md)) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int gpencil_modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op)) + return gpencil_modifier_remove_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_gpencil_modifier_remove(wmOperatorType *ot) +{ + ot->name = "Remove Grease Pencil Modifier"; + ot->description = "Remove a modifier from the active grease pencil object"; + ot->idname = "OBJECT_OT_gpencil_modifier_remove"; + + ot->invoke = gpencil_modifier_remove_invoke; + ot->exec = gpencil_modifier_remove_exec; + ot->poll = gpencil_edit_modifier_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + gpencil_edit_modifier_properties(ot); +} + +/************************ move up modifier operator *********************/ + +static int gpencil_modifier_move_up_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); + + if (!md || !ED_object_gpencil_modifier_move_up(op->reports, ob, md)) + return OPERATOR_CANCELLED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int gpencil_modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op)) + return gpencil_modifier_move_up_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_gpencil_modifier_move_up(wmOperatorType *ot) +{ + ot->name = "Move Up Modifier"; + ot->description = "Move modifier up in the stack"; + ot->idname = "OBJECT_OT_gpencil_modifier_move_up"; + + ot->invoke = gpencil_modifier_move_up_invoke; + ot->exec = gpencil_modifier_move_up_exec; + ot->poll = gpencil_edit_modifier_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + gpencil_edit_modifier_properties(ot); +} + +/************************ move down modifier operator *********************/ + +static int gpencil_modifier_move_down_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); + + if (!md || !ED_object_gpencil_modifier_move_down(op->reports, ob, md)) + return OPERATOR_CANCELLED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int gpencil_modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op)) + return gpencil_modifier_move_down_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_gpencil_modifier_move_down(wmOperatorType *ot) +{ + ot->name = "Move Down Modifier"; + ot->description = "Move modifier down in the stack"; + ot->idname = "OBJECT_OT_gpencil_modifier_move_down"; + + ot->invoke = gpencil_modifier_move_down_invoke; + ot->exec = gpencil_modifier_move_down_exec; + ot->poll = gpencil_edit_modifier_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + gpencil_edit_modifier_properties(ot); +} + +/************************ apply modifier operator *********************/ + +static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Object *ob = ED_object_active_context(C); + GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); + int apply_as = RNA_enum_get(op->ptr, "apply_as"); + + if (!md || !ED_object_gpencil_modifier_apply(bmain, op->reports, depsgraph, ob, md, apply_as)) { + return OPERATOR_CANCELLED; + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int gpencil_modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op)) + return gpencil_modifier_apply_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +static const EnumPropertyItem gpencil_modifier_apply_as_items[] = { + {MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"}, + {MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"}, + {0, NULL, 0, NULL, NULL} +}; + +void OBJECT_OT_gpencil_modifier_apply(wmOperatorType *ot) +{ + ot->name = "Apply Modifier"; + ot->description = "Apply modifier and remove from the stack"; + ot->idname = "OBJECT_OT_gpencil_modifier_apply"; + + ot->invoke = gpencil_modifier_apply_invoke; + ot->exec = gpencil_modifier_apply_exec; + ot->poll = gpencil_edit_modifier_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + RNA_def_enum(ot->srna, "apply_as", gpencil_modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry"); + gpencil_edit_modifier_properties(ot); +} + +/************************ copy modifier operator *********************/ + +static int gpencil_modifier_copy_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + GpencilModifierData *md = gpencil_edit_modifier_property_get(op, ob, 0); + + if (!md || !ED_object_gpencil_modifier_copy(op->reports, ob, md)) + return OPERATOR_CANCELLED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int gpencil_modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (gpencil_edit_modifier_invoke_properties(C, op)) + return gpencil_modifier_copy_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_gpencil_modifier_copy(wmOperatorType *ot) +{ + ot->name = "Copy Modifier"; + ot->description = "Duplicate modifier at the same position in the stack"; + ot->idname = "OBJECT_OT_gpencil_modifier_copy"; + + ot->invoke = gpencil_modifier_copy_invoke; + ot->exec = gpencil_modifier_copy_exec; + ot->poll = gpencil_edit_modifier_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + gpencil_edit_modifier_properties(ot); +} diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 1b5c6df2632..ef8653541f0 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -115,6 +115,7 @@ void OBJECT_OT_armature_add(struct wmOperatorType *ot); void OBJECT_OT_empty_add(struct wmOperatorType *ot); void OBJECT_OT_lightprobe_add(struct wmOperatorType *ot); void OBJECT_OT_drop_named_image(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_add(struct wmOperatorType *ot); void OBJECT_OT_light_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_camera_add(struct wmOperatorType *ot); @@ -175,6 +176,20 @@ void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot); void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot); void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot); +/* grease pencil modifiers */ +void OBJECT_OT_gpencil_modifier_add(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_modifier_remove(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_modifier_move_up(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_modifier_move_down(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_modifier_apply(struct wmOperatorType *ot); +void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot); + +/* shader fx */ +void OBJECT_OT_shaderfx_add(struct wmOperatorType *ot); +void OBJECT_OT_shaderfx_remove(struct wmOperatorType *ot); +void OBJECT_OT_shaderfx_move_up(struct wmOperatorType *ot); +void OBJECT_OT_shaderfx_move_down(struct wmOperatorType *ot); + /* object_constraint.c */ void OBJECT_OT_constraint_add(struct wmOperatorType *ot); void OBJECT_OT_constraint_add_with_targets(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index e9bd6fbce8f..261f7f42bc0 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -27,6 +27,7 @@ * actual mode switching logic is per-object type. */ +#include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_workspace_types.h" @@ -71,8 +72,14 @@ static const char *object_mode_op_string(eObjectMode mode) return "PARTICLE_OT_particle_edit_toggle"; if (mode == OB_MODE_POSE) return "OBJECT_OT_posemode_toggle"; - if (mode == OB_MODE_GPENCIL) + if (mode == OB_MODE_GPENCIL_EDIT) return "GPENCIL_OT_editmode_toggle"; + if (mode == OB_MODE_GPENCIL_PAINT) + return "GPENCIL_OT_paintmode_toggle"; + if (mode == OB_MODE_GPENCIL_SCULPT) + return "GPENCIL_OT_sculptmode_toggle"; + if (mode == OB_MODE_GPENCIL_WEIGHT) + return "GPENCIL_OT_weightmode_toggle"; return NULL; } @@ -85,8 +92,6 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) if (ob) { if (mode == OB_MODE_OBJECT) return true; - else if (mode == OB_MODE_GPENCIL) - return true; /* XXX: assume this is the case for now... */ switch (ob->type) { case OB_MESH: @@ -111,6 +116,13 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) return true; break; + case OB_GPENCIL: + if (mode & (OB_MODE_EDIT | OB_MODE_GPENCIL_EDIT | OB_MODE_GPENCIL_PAINT | + OB_MODE_GPENCIL_SCULPT | OB_MODE_GPENCIL_WEIGHT)) + { + return true; + } + break; } } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 11d0fd9f9d5..f83c6af08ee 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1,31 +1,31 @@ /* - * ***** 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, 2009 - * - * ***** END GPL LICENSE BLOCK ***** - */ +* ***** 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, 2009 +* +* ***** END GPL LICENSE BLOCK ***** +*/ /** \file blender/editors/object/object_modifier.c - * \ingroup edobj - */ +* \ingroup edobj +*/ #include @@ -117,8 +117,8 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc if (type == eModifierType_ParticleSystem) { /* don't need to worry about the new modifier's name, since that is set to the number - * of particle systems which shouldn't have too many duplicates - */ + * of particle systems which shouldn't have too many duplicates + */ new_md = object_add_particle_system(bmain, scene, ob, name); } else { @@ -182,9 +182,9 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc } /* Return true if the object has a modifier of type 'type' other than - * the modifier pointed to be 'exclude', otherwise returns false. */ +* the modifier pointed to be 'exclude', otherwise returns false. */ static bool object_has_modifier(const Object *ob, const ModifierData *exclude, - ModifierType type) + ModifierType type) { ModifierData *md; @@ -197,16 +197,16 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude, } /* If the object data of 'orig_ob' has other users, run 'callback' on - * each of them. - * - * If include_orig is true, the callback will run on 'orig_ob' too. - * - * If the callback ever returns true, iteration will stop and the - * function value will be true. Otherwise the function returns false. - */ +* each of them. +* +* If include_orig is true, the callback will run on 'orig_ob' too. +* +* If the callback ever returns true, iteration will stop and the +* function value will be true. Otherwise the function returns false. +*/ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, - bool (*callback)(Object *ob, void *callback_data), - void *callback_data) + bool (*callback)(Object *ob, void *callback_data), + void *callback_data) { ID *ob_data_id = orig_ob->data; int users = ob_data_id->us; @@ -220,10 +220,10 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, int totfound = include_orig ? 0 : 1; for (ob = bmain->object.first; ob && totfound < users; - ob = ob->id.next) + ob = ob->id.next) { if (((ob != orig_ob) || include_orig) && - (ob->data == orig_ob->data)) + (ob->data == orig_ob->data)) { if (callback(ob, callback_data)) return true; @@ -247,8 +247,8 @@ static bool object_has_modifier_cb(Object *ob, void *data) } /* Use with ED_object_iter_other(). Sets the total number of levels - * for any multires modifiers on the object to the int pointed to by - * callback_data. */ +* for any multires modifiers on the object to the int pointed to by +* callback_data. */ bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) { ModifierData *md; @@ -265,20 +265,20 @@ bool ED_object_multires_update_totlevels_cb(Object *ob, void *totlevel_v) /* Return true if no modifier of type 'type' other than 'exclude' */ static bool object_modifier_safe_to_delete(Main *bmain, Object *ob, - ModifierData *exclude, - ModifierType type) + ModifierData *exclude, + ModifierType type) { return (!object_has_modifier(ob, exclude, type) && - !ED_object_iter_other(bmain, ob, false, - object_has_modifier_cb, &type)); + !ED_object_iter_other(bmain, ob, false, + object_has_modifier_cb, &type)); } static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, - bool *r_sort_depsgraph) + bool *r_sort_depsgraph) { /* It seems on rapid delete it is possible to - * get called twice on same modifier, so make - * sure it is in list. */ + * get called twice on same modifier, so make + * sure it is in list. */ if (BLI_findindex(&ob->modifiers, md) == -1) { return 0; } @@ -318,7 +318,7 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, } if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) && - BLI_listbase_is_empty(&ob->particlesystem)) + BLI_listbase_is_empty(&ob->particlesystem)) { ob->mode &= ~OB_MODE_PARTICLE_EDIT; } @@ -522,7 +522,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * } static int modifier_apply_shape( - Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md) + Main *bmain, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -532,15 +532,15 @@ static int modifier_apply_shape( } /* - * It should be ridiculously easy to extract the original verts that we want - * and form the shape data. We can probably use the CD KEYINDEX layer (or - * whatever I ended up calling it, too tired to check now), though this would - * by necessity have to make some potentially ugly assumptions about the order - * of the mesh data :-/ you can probably assume in 99% of cases that the first - * element of a given index is the original, and any subsequent duplicates are - * copies/interpolates, but that's an assumption that would need to be tested - * and then predominantly stated in comments in a half dozen headers. - */ + * It should be ridiculously easy to extract the original verts that we want + * and form the shape data. We can probably use the CD KEYINDEX layer (or + * whatever I ended up calling it, too tired to check now), though this would + * by necessity have to make some potentially ugly assumptions about the order + * of the mesh data :-/ you can probably assume in 99% of cases that the first + * element of a given index is the original, and any subsequent duplicates are + * copies/interpolates, but that's an assumption that would need to be tested + * and then predominantly stated in comments in a half dozen headers. + */ if (ob->type == OB_MESH) { Mesh *mesh_applied; @@ -563,7 +563,7 @@ static int modifier_apply_shape( key = me->key = BKE_key_add(bmain, (ID *)me); key->type = KEY_RELATIVE; /* if that was the first key block added, then it was the basis. - * Initialize it with the mesh, and add another for the modifier */ + * Initialize it with the mesh, and add another for the modifier */ kb = BKE_keyblock_add(key, NULL); BKE_keyblock_convert_from_mesh(me, key, kb); } @@ -667,8 +667,8 @@ static int modifier_apply_obdata(ReportList *reports, Depsgraph *depsgraph, Scen } int ED_object_modifier_apply( - Main *bmain, ReportList *reports, Depsgraph *depsgraph, - Scene *scene, Object *ob, ModifierData *md, int mode) + Main *bmain, ReportList *reports, Depsgraph *depsgraph, + Scene *scene, Object *ob, ModifierData *md, int mode) { int prev_mode; @@ -681,8 +681,8 @@ int ED_object_modifier_apply( return 0; } else if ((ob->mode & OB_MODE_SCULPT) && - (find_multires_modifier_before(scene, md)) && - (modifier_isSameTopology(md) == false)) + (find_multires_modifier_before(scene, md)) && + (modifier_isSameTopology(md) == false)) { BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode"); return 0; @@ -692,7 +692,7 @@ int ED_object_modifier_apply( BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected"); /* Get evaluated modifier, so object links pointer to evaluated data, - * but still use original object it is applied to the original mesh. */ + * but still use original object it is applied to the original mesh. */ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); ModifierData *md_eval = (ob_eval) ? modifiers_findByName(ob_eval, md->name) : md; @@ -752,7 +752,7 @@ static int modifier_add_exec(bContext *C, wmOperator *op) } static const EnumPropertyItem *modifier_add_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) + bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { Object *ob = ED_object_active_context(C); EnumPropertyItem *item = NULL; @@ -1165,8 +1165,8 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op) multiresModifier_del_levels(mmd, scene, ob, 1); ED_object_iter_other(CTX_data_main(C), ob, true, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1210,8 +1210,8 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op) multiresModifier_subdivide(mmd, scene, ob, 0, mmd->simple); ED_object_iter_other(CTX_data_main(C), ob, true, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); @@ -1387,8 +1387,8 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE, - WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); + ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); edit_modifier_properties(ot); } @@ -1480,13 +1480,13 @@ static void modifier_skin_customdata_delete(Object *ob) static bool skin_poll(bContext *C) { return (!CTX_data_edit_object(C) && - edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH))); + edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH))); } static bool skin_edit_poll(bContext *C) { return (CTX_data_edit_object(C) && - edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH))); + edit_modifier_poll_generic(C, &RNA_SkinModifier, (1 << OB_MESH))); } static void skin_root_clear(BMVert *bm_vert, GSet *visited, const int cd_vert_skin_offset) @@ -1525,7 +1525,7 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op)) BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT) && - BLI_gset_add(visited, bm_vert)) + BLI_gset_add(visited, bm_vert)) { MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(bm_vert, cd_vert_skin_offset); @@ -1579,8 +1579,8 @@ static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op) BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) { MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, - bm_vert->head.data, - CD_MVERT_SKIN); + bm_vert->head.data, + CD_MVERT_SKIN); switch (action) { @@ -1636,8 +1636,8 @@ static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op)) BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT)) { MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, - bm_vert->head.data, - CD_MVERT_SKIN); + bm_vert->head.data, + CD_MVERT_SKIN); float avg = (vs->radius[0] + vs->radius[1]) * 0.5f; vs->radius[0] = vs->radius[1] = avg; @@ -1664,12 +1664,12 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) } static void skin_armature_bone_create(Object *skin_ob, - MVert *mvert, MEdge *medge, - bArmature *arm, - BLI_bitmap *edges_visited, - const MeshElemMap *emap, - EditBone *parent_bone, - int parent_v) + MVert *mvert, MEdge *medge, + bArmature *arm, + BLI_bitmap *edges_visited, + const MeshElemMap *emap, + EditBone *parent_bone, + int parent_v) { int i; @@ -1704,12 +1704,12 @@ static void skin_armature_bone_create(Object *skin_ob, } skin_armature_bone_create(skin_ob, - mvert, medge, - arm, - edges_visited, - emap, - bone, - v); + mvert, medge, + arm, + edges_visited, + emap, + bone, + v); } } @@ -1731,10 +1731,10 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, /* add vertex weights to original mesh */ CustomData_add_layer(&me->vdata, - CD_MDEFORMVERT, - CD_CALLOC, - NULL, - me->totvert); + CD_MDEFORMVERT, + CD_CALLOC, + NULL, + me->totvert); ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); arm_ob = BKE_object_add(bmain, scene, view_layer, OB_ARMATURE, NULL); @@ -1747,19 +1747,19 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, mvert_skin = CustomData_get_layer(&me->vdata, CD_MVERT_SKIN); BKE_mesh_vert_edge_map_create(&emap, &emap_mem, - me->medge, me->totvert, me->totedge); + me->medge, me->totvert, me->totedge); edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited"); /* note: we use EditBones here, easier to set them up and use - * edit-armature functions to convert back to regular bones */ + * edit-armature functions to convert back to regular bones */ for (v = 0; v < me->totvert; v++) { if (mvert_skin[v].flag & MVERT_SKIN_ROOT) { EditBone *bone = NULL; /* Unless the skin root has just one adjacent edge, create - * a fake root bone (have it going off in the Y direction - * (arbitrary) */ + * a fake root bone (have it going off in the Y direction + * (arbitrary) */ if (emap[v].count > 1) { bone = ED_armature_ebone_add(arm, "Bone"); @@ -1772,12 +1772,12 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, if (emap[v].count >= 1) { skin_armature_bone_create(skin_ob, - mvert, me->medge, - arm, - edges_visited, - emap, - bone, - v); + mvert, me->medge, + arm, + edges_visited, + emap, + bone, + v); } } } @@ -2092,7 +2092,7 @@ static int oceanbake_breakjob(void *UNUSED(customdata)) //return *(ob->stop); /* this is not nice yet, need to make the jobs list template better - * for identifying/acting upon various different jobs */ + * for identifying/acting upon various different jobs */ /* but for now we'll reuse the render break... */ return (G.is_break); } @@ -2166,8 +2166,8 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) } och = BKE_ocean_init_cache(omd->cachepath, modifier_path_relbase(bmain, ob), - omd->bakestart, omd->bakeend, omd->wave_scale, - omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); + omd->bakestart, omd->bakeend, omd->wave_scale, + omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution); och->time = MEM_mallocN(och->duration * sizeof(float), "foam bake time"); @@ -2176,22 +2176,22 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) /* precalculate time variable before baking */ for (f = omd->bakestart; f <= omd->bakeend; f++) { /* from physics_fluid.c: - * - * XXX: This can't be used due to an anim sys optimization that ignores recalc object animation, - * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) - * --> BKE_animsys_evaluate_all_animation(bmain, eval_time); - * This doesn't work with drivers: - * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL); - */ + * + * XXX: This can't be used due to an anim sys optimization that ignores recalc object animation, + * leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ ) + * --> BKE_animsys_evaluate_all_animation(bmain, eval_time); + * This doesn't work with drivers: + * --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL); + */ /* Modifying the global scene isn't nice, but we can do it in - * this part of the process before a threaded job is created */ + * this part of the process before a threaded job is created */ //scene->r.cfra = f; //ED_update_for_newframe(bmain, scene); /* ok, this doesn't work with drivers, but is way faster. - * let's use this for now and hope nobody wants to drive the time value... */ + * let's use this for now and hope nobody wants to drive the time value... */ BKE_animsys_evaluate_animdata(CTX_data_depsgraph(C), scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM); och->time[i] = omd->time; @@ -2220,7 +2220,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) /* setup job */ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", - WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN); + WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_SIM_OCEAN); oj = MEM_callocN(sizeof(OceanBakeJob), "ocean bake job"); oj->owner = ob; oj->ocean = ocean; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 7b6c1156874..ac2eb60456f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -115,6 +115,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_empty_add); WM_operatortype_append(OBJECT_OT_lightprobe_add); WM_operatortype_append(OBJECT_OT_drop_named_image); + WM_operatortype_append(OBJECT_OT_gpencil_add); WM_operatortype_append(OBJECT_OT_light_add); WM_operatortype_append(OBJECT_OT_camera_add); WM_operatortype_append(OBJECT_OT_speaker_add); @@ -147,6 +148,20 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_skin_radii_equalize); WM_operatortype_append(OBJECT_OT_skin_armature_create); + /* grease pencil modifiers */ + WM_operatortype_append(OBJECT_OT_gpencil_modifier_add); + WM_operatortype_append(OBJECT_OT_gpencil_modifier_remove); + WM_operatortype_append(OBJECT_OT_gpencil_modifier_move_up); + WM_operatortype_append(OBJECT_OT_gpencil_modifier_move_down); + WM_operatortype_append(OBJECT_OT_gpencil_modifier_apply); + WM_operatortype_append(OBJECT_OT_gpencil_modifier_copy); + + /* shader fx */ + WM_operatortype_append(OBJECT_OT_shaderfx_add); + WM_operatortype_append(OBJECT_OT_shaderfx_remove); + WM_operatortype_append(OBJECT_OT_shaderfx_move_up); + WM_operatortype_append(OBJECT_OT_shaderfx_move_down); + WM_operatortype_append(OBJECT_OT_correctivesmooth_bind); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_explode_refresh); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 331b4af077d..a6751ee12a4 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -70,6 +70,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_gpencil.h" #include "BKE_fcurve.h" #include "BKE_idprop.h" #include "BKE_lamp.h" @@ -1609,21 +1610,11 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) /**************************** Make Single User ********************************/ -static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob) +static Object *single_object_users_object(Main *bmain, Object *ob) { /* base gets copy of object */ Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); - /* remap gpencil parenting */ - - if (scene->gpd) { - bGPdata *gpd = scene->gpd; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpl->parent == ob) { - gpl->parent = obn; - } - } - } id_us_plus(&obn->id); id_us_min(&ob->id); @@ -1648,7 +1639,7 @@ static void single_object_users_collection(Main *bmain, Scene *scene, Collection /* an object may be in more than one collection */ if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) { if (!ID_IS_LINKED(ob) && ob->id.us > 1) { - cob->ob = single_object_users_object(bmain, scene, cob->ob); + cob->ob = single_object_users_object(bmain, cob->ob); } } } @@ -1702,6 +1693,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in /* collection pointers in scene */ BKE_scene_groups_relink(scene); + /* active camera */ ID_NEW_REMAP(scene->camera); if (v3d) ID_NEW_REMAP(v3d->camera); @@ -1805,6 +1797,9 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer case OB_LIGHTPROBE: ob->data = ID_NEW_SET(ob->data, BKE_lightprobe_copy(bmain, ob->data)); break; + case OB_GPENCIL: + ob->data = ID_NEW_SET(ob->data, BKE_gpencil_copy(bmain, ob->data)); + break; default: printf("ERROR %s: can't copy %s\n", __func__, id->name); BLI_assert(!"This should never happen."); @@ -1940,10 +1935,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo } } - if (scene->gpd) { - IDP_RelinkProperty(scene->gpd->id.properties); - } - if (scene->world) { IDP_RelinkProperty(scene->world->id.properties); } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index d5f7a93cc6e..c23a1d64ee8 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -41,6 +41,7 @@ #include "DNA_armature_types.h" #include "DNA_lamp_types.h" #include "DNA_workspace_types.h" +#include "DNA_gpencil_types.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -88,8 +89,8 @@ * this takes into account the 'restrict selection in 3d view' flag. * deselect works always, the restriction just prevents selection */ -/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or - * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */ + /* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or + * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */ void ED_object_base_select(Base *base, eObjectSelect_Mode mode) { diff --git a/source/blender/editors/object/object_shader_fx.c b/source/blender/editors/object/object_shader_fx.c new file mode 100644 index 00000000000..681851850a5 --- /dev/null +++ b/source/blender/editors/object/object_shader_fx.c @@ -0,0 +1,469 @@ +/* + * ***** 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) 2018 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2018 + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/object_shader_fx.c + * \ingroup edobj + */ + + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_gpencil_types.h" +#include "DNA_shader_fx_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_shader_fx.h" +#include "BKE_report.h" +#include "BKE_object.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "ED_object.h" +#include "ED_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "object_intern.h" + +/******************************** API ****************************/ + +ShaderFxData *ED_object_shaderfx_add(ReportList *reports, Main *bmain, Scene *UNUSED(scene), Object *ob, const char *name, int type) +{ + ShaderFxData *new_fx = NULL; + const ShaderFxTypeInfo *fxi = BKE_shaderfxType_getInfo(type); + + if (ob->type != OB_GPENCIL) { + BKE_reportf(reports, RPT_WARNING, "Effect cannot be added to object '%s'", ob->id.name + 2); + return NULL; + } + + if (fxi->flags & eShaderFxTypeFlag_Single) { + if (BKE_shaderfx_findByType(ob, type)) { + BKE_report(reports, RPT_WARNING, "Only one Effect of this type is allowed"); + return NULL; + } + } + + /* get new effect data to add */ + new_fx = BKE_shaderfx_new(type); + + BLI_addtail(&ob->shader_fx, new_fx); + + if (name) { + BLI_strncpy_utf8(new_fx->name, name, sizeof(new_fx->name)); + } + + /* make sure effect data has unique name */ + BKE_shaderfx_unique_name(&ob->shader_fx, new_fx); + + bGPdata *gpd = ob->data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + + return new_fx; +} + +/* Return true if the object has a effect of type 'type' other than + * the shaderfx pointed to be 'exclude', otherwise returns false. */ +static bool UNUSED_FUNCTION(object_has_shaderfx)( + const Object *ob, const ShaderFxData *exclude, + ShaderFxType type) +{ + ShaderFxData *fx; + + for (fx = ob->shader_fx.first; fx; fx = fx->next) { + if ((fx != exclude) && (fx->type == type)) + return true; + } + + return false; +} + +static bool object_shaderfx_remove( + Main *bmain, Object *ob, ShaderFxData *fx, + bool *UNUSED(r_sort_depsgraph)) +{ + /* It seems on rapid delete it is possible to + * get called twice on same effect, so make + * sure it is in list. */ + if (BLI_findindex(&ob->shader_fx, fx) == -1) { + return 0; + } + + DEG_relations_tag_update(bmain); + + BLI_remlink(&ob->shader_fx, fx); + BKE_shaderfx_free(fx); + BKE_object_free_derived_caches(ob); + + return 1; +} + +bool ED_object_shaderfx_remove(ReportList *reports, Main *bmain, Object *ob, ShaderFxData *fx) +{ + bool sort_depsgraph = false; + bool ok; + + ok = object_shaderfx_remove(bmain, ob, fx, &sort_depsgraph); + + if (!ok) { + BKE_reportf(reports, RPT_ERROR, "Effect '%s' not in object '%s'", fx->name, ob->id.name); + return 0; + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); + + return 1; +} + +void ED_object_shaderfx_clear(Main *bmain, Object *ob) +{ + ShaderFxData *fx = ob->shader_fx.first; + bool sort_depsgraph = false; + + if (!fx) + return; + + while (fx) { + ShaderFxData *next_fx; + + next_fx = fx->next; + + object_shaderfx_remove(bmain, ob, fx, &sort_depsgraph); + + fx = next_fx; + } + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + DEG_relations_tag_update(bmain); +} + +int ED_object_shaderfx_move_up(ReportList *UNUSED(reports), Object *ob, ShaderFxData *fx) +{ + if (fx->prev) { + BLI_remlink(&ob->shader_fx, fx); + BLI_insertlinkbefore(&ob->shader_fx, fx->prev, fx); + } + + return 1; +} + +int ED_object_shaderfx_move_down(ReportList *UNUSED(reports), Object *ob, ShaderFxData *fx) +{ + if (fx->next) { + BLI_remlink(&ob->shader_fx, fx); + BLI_insertlinkafter(&ob->shader_fx, fx->next, fx); + } + + return 1; +} + +/************************ add effect operator *********************/ + +static int shaderfx_add_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Object *ob = ED_object_active_context(C); + int type = RNA_enum_get(op->ptr, "type"); + + if (!ED_object_shaderfx_add(op->reports, bmain, scene, ob, NULL, type)) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static const EnumPropertyItem *shaderfx_add_itemf( + bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + Object *ob = ED_object_active_context(C); + EnumPropertyItem *item = NULL; + const EnumPropertyItem *fx_item, *group_item = NULL; + const ShaderFxTypeInfo *mti; + int totitem = 0, a; + + if (!ob) + return rna_enum_object_shaderfx_type_items; + + for (a = 0; rna_enum_object_shaderfx_type_items[a].identifier; a++) { + fx_item = &rna_enum_object_shaderfx_type_items[a]; + if (fx_item->identifier[0]) { + mti = BKE_shaderfxType_getInfo(fx_item->value); + + if (mti->flags & eShaderFxTypeFlag_NoUserAdd) + continue; + } + else { + group_item = fx_item; + fx_item = NULL; + + continue; + } + + if (group_item) { + RNA_enum_item_add(&item, &totitem, group_item); + group_item = NULL; + } + + RNA_enum_item_add(&item, &totitem, fx_item); + } + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; +} + +void OBJECT_OT_shaderfx_add(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Effect"; + ot->description = "Add a visual effect to the active object"; + ot->idname = "OBJECT_OT_shaderfx_add"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = shaderfx_add_exec; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_enum(ot->srna, "type", rna_enum_object_shaderfx_type_items, eShaderFxType_Blur, "Type", ""); + RNA_def_enum_funcs(prop, shaderfx_add_itemf); + ot->prop = prop; +} + +/************************ generic functions for operators using names and data context *********************/ + +static bool edit_shaderfx_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag) +{ + PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", rna_type); + Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C); + + if (!ptr.data) { + CTX_wm_operator_poll_msg_set(C, "Context missing 'shaderfx'"); + return 0; + } + + if (!ob || ID_IS_LINKED(ob)) return 0; + if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) return 0; + if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) return 0; + + if (ID_IS_STATIC_OVERRIDE(ob)) { + CTX_wm_operator_poll_msg_set(C, "Cannot edit shaderfxs comming from static override"); + return (((ShaderFxData *)ptr.data)->flag & eShaderFxFlag_StaticOverride_Local) != 0; + } + + return 1; +} + +static bool edit_shaderfx_poll(bContext *C) +{ + return edit_shaderfx_poll_generic(C, &RNA_ShaderFx, 0); +} + +static void edit_shaderfx_properties(wmOperatorType *ot) +{ + RNA_def_string(ot->srna, "shaderfx", NULL, MAX_NAME, "Shader", "Name of the shaderfx to edit"); +} + +static int edit_shaderfx_invoke_properties(bContext *C, wmOperator *op) +{ + ShaderFxData *fx; + + if (RNA_struct_property_is_set(op->ptr, "shaderfx")) { + return true; + } + else { + PointerRNA ptr = CTX_data_pointer_get_type(C, "shaderfx", &RNA_ShaderFx); + if (ptr.data) { + fx = ptr.data; + RNA_string_set(op->ptr, "shaderfx", fx->name); + return true; + } + } + + return false; +} + +static ShaderFxData *edit_shaderfx_property_get(wmOperator *op, Object *ob, int type) +{ + char shaderfx_name[MAX_NAME]; + ShaderFxData *fx; + RNA_string_get(op->ptr, "shaderfx", shaderfx_name); + + fx = BKE_shaderfx_findByName(ob, shaderfx_name); + + if (fx && type != 0 && fx->type != type) + fx = NULL; + + return fx; +} + +/************************ remove shaderfx operator *********************/ + +static int shaderfx_remove_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Object *ob = ED_object_active_context(C); + ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0); + + if (!fx || !ED_object_shaderfx_remove(op->reports, bmain, ob, fx)) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int shaderfx_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_shaderfx_invoke_properties(C, op)) + return shaderfx_remove_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_shaderfx_remove(wmOperatorType *ot) +{ + ot->name = "Remove Grease Pencil Modifier"; + ot->description = "Remove a shaderfx from the active grease pencil object"; + ot->idname = "OBJECT_OT_shaderfx_remove"; + + ot->invoke = shaderfx_remove_invoke; + ot->exec = shaderfx_remove_exec; + ot->poll = edit_shaderfx_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_shaderfx_properties(ot); +} + +/************************ move up shaderfx operator *********************/ + +static int shaderfx_move_up_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0); + + if (!fx || !ED_object_shaderfx_move_up(op->reports, ob, fx)) + return OPERATOR_CANCELLED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int shaderfx_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_shaderfx_invoke_properties(C, op)) + return shaderfx_move_up_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_shaderfx_move_up(wmOperatorType *ot) +{ + ot->name = "Move Up Modifier"; + ot->description = "Move shaderfx up in the stack"; + ot->idname = "OBJECT_OT_shaderfx_move_up"; + + ot->invoke = shaderfx_move_up_invoke; + ot->exec = shaderfx_move_up_exec; + ot->poll = edit_shaderfx_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_shaderfx_properties(ot); +} + +/************************ move down shaderfx operator *********************/ + +static int shaderfx_move_down_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_active_context(C); + ShaderFxData *fx = edit_shaderfx_property_get(op, ob, 0); + + if (!fx || !ED_object_shaderfx_move_down(op->reports, ob, fx)) + return OPERATOR_CANCELLED; + + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +static int shaderfx_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + if (edit_shaderfx_invoke_properties(C, op)) + return shaderfx_move_down_exec(C, op); + else + return OPERATOR_CANCELLED; +} + +void OBJECT_OT_shaderfx_move_down(wmOperatorType *ot) +{ + ot->name = "Move Down Modifier"; + ot->description = "Move shaderfx down in the stack"; + ot->idname = "OBJECT_OT_shaderfx_move_down"; + + ot->invoke = shaderfx_move_down_invoke; + ot->exec = shaderfx_move_down_exec; + ot->poll = edit_shaderfx_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + edit_shaderfx_properties(ot); +} diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index d2a0879464b..96b540251b4 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -38,6 +38,7 @@ #include "DNA_lamp_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_gpencil_types.h" #include "DNA_group_types.h" #include "DNA_lattice_types.h" @@ -59,6 +60,7 @@ #include "BKE_armature.h" #include "BKE_lattice.h" #include "BKE_tracking.h" +#include "BKE_gpencil.h" #include "DEG_depsgraph.h" @@ -73,6 +75,7 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_view3d.h" +#include "ED_gpencil.h" #include "MEM_guardedalloc.h" @@ -434,7 +437,7 @@ static int apply_objects_internal( /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { - if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF, OB_FONT)) { + if (ELEM(ob->type, OB_MESH, OB_ARMATURE, OB_LATTICE, OB_MBALL, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) { ID *obdata = ob->data; if (ID_REAL_USERS(obdata) > 1) { BKE_reportf(reports, RPT_ERROR, @@ -480,6 +483,37 @@ static int apply_objects_internal( } } + if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + if (gpd) { + if (gpd->layers.first) { + /* Unsupported configuration */ + bool has_unparented_layers = false; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* Parented layers aren't supported as we can't easily re-evaluate the scene to sample parent movement */ + if (gpl->parent == NULL) { + has_unparented_layers = true; + break; + } + } + + if (has_unparented_layers == false) { + BKE_reportf(reports, RPT_ERROR, + "Can't apply to a GP datablock where all layers are parented: Object \"%s\", %s \"%s\", aborting", + ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2); + changed = false; + } + } + else { + /* No layers/data */ + BKE_reportf(reports, RPT_ERROR, + "Can't apply to GP datablock with no layers: Object \"%s\", %s \"%s\", aborting", + ob->id.name + 2, BKE_idcode_to_name(ID_GD), gpd->id.name + 2); + } + } + } + if (ob->type == OB_LAMP) { Lamp *la = ob->data; if (la->type == LA_AREA) { @@ -587,6 +621,10 @@ static int apply_objects_internal( cu->fsize *= scale; } } + else if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + BKE_gpencil_transform(gpd, mat); + } else if (ob->type == OB_CAMERA) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); @@ -1056,6 +1094,69 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) lt->id.tag |= LIB_TAG_DOIT; do_inverse_offset = true; } + else if (ob->type == OB_GPENCIL) { + bGPdata *gpd = ob->data; + float gpcenter[3]; + if (gpd) { + if (centermode == ORIGIN_TO_GEOMETRY) { + zero_v3(gpcenter); + BKE_gpencil_centroid_3D(gpd, gpcenter); + add_v3_v3(gpcenter, ob->obmat[3]); + } + if (centermode == ORIGIN_TO_CURSOR) { + copy_v3_v3(gpcenter, cursor); + } + if ((centermode == ORIGIN_TO_GEOMETRY) || (centermode == ORIGIN_TO_CURSOR)) { + bGPDspoint *pt; + float imat[3][3], bmat[3][3]; + float offset_global[3]; + float offset_local[3]; + int i; + + sub_v3_v3v3(offset_global, gpcenter, ob->obmat[3]); + copy_m3_m4(bmat, obact->obmat); + invert_m3_m3(imat, bmat); + mul_m3_v3(imat, offset_global); + mul_v3_m3v3(offset_local, imat, offset_global); + + float diff_mat[4][4]; + float inverse_diff_mat[4][4]; + + /* recalculate all strokes (all layers are considered without evaluating lock attributtes) */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); + /* undo matrix */ + invert_m4_m4(inverse_diff_mat, diff_mat); + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) + continue; + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + float mpt[3]; + mul_v3_m4v3(mpt, inverse_diff_mat, &pt->x); + sub_v3_v3(mpt, offset_local); + mul_v3_m4v3(&pt->x, diff_mat, mpt); + } + } + } + } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + + tot_change++; + if (centermode == ORIGIN_TO_GEOMETRY) { + copy_v3_v3(ob->loc, gpcenter); + } + ob->id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; + } + else { + BKE_report(op->reports, RPT_WARNING, "Grease Pencil Object does not support this set origin option"); + } + } + } /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 22000bd2a03..ed7950f3993 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -329,7 +329,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R GPU_matrix_translate_2f(sizex / 2, sizey / 2); G.f |= G_RENDER_OGL; - ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); + ED_gpencil_draw_ex(rv3d, scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ); G.f &= ~G_RENDER_OGL; gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect"); @@ -417,7 +417,7 @@ static void screen_opengl_render_write(OGLRender *oglrender) else printf("OpenGL Render failed to write '%s'\n", name); } -static void addAlphaOverFloat(float dest[4], const float source[4]) +static void UNUSED_FUNCTION(addAlphaOverFloat)(float dest[4], const float source[4]) { /* d = s + (1-alpha_s)d*/ float mul; @@ -431,91 +431,6 @@ static void addAlphaOverFloat(float dest[4], const float source[4]) } -/* add renderlayer and renderpass for each grease pencil layer for using in composition */ -static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv) -{ - bGPdata *gpd = oglrender->scene->gpd; - Scene *scene = oglrender->scene; - - /* sanity checks */ - if (gpd == NULL) { - return; - } - if (scene == NULL) { - return; - } - if (BLI_listbase_is_empty(&gpd->layers)) { - return; - } - if (oglrender->v3d != NULL && (oglrender->v3d->flag2 & V3D_SHOW_GPENCIL) == 0) { - return; - } - - /* save old alpha mode */ - short oldalphamode = scene->r.alphamode; - /* set alpha transparent for gp */ - scene->r.alphamode = R_ALPHAPREMUL; - - /* saves layer status */ - short *oldsts = MEM_mallocN(BLI_listbase_count(&gpd->layers) * sizeof(short), "temp_gplayers_flag"); - int i = 0; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - oldsts[i] = gpl->flag; - ++i; - } - /* loop all layers to create separate render */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* dont draw layer if hidden */ - if (gpl->flag & GP_LAYER_HIDE) - continue; - /* hide all layer except current */ - for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { - if (gpl != gph) { - gph->flag |= GP_LAYER_HIDE; - } - } - - /* render this gp layer */ - screen_opengl_render_doit(C, oglrender, rr); - - /* add RendePass composite */ - RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name); - - /* copy image data from rectf */ - // XXX: Needs conversion. - unsigned char *src = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; - if (src != NULL) { - float *dest = rp->rect; - - int x, y, rectx, recty; - rectx = rr->rectx; - recty = rr->recty; - for (y = 0; y < recty; y++) { - for (x = 0; x < rectx; x++) { - unsigned char *pixSrc = src + 4 * (rectx * y + x); - if (pixSrc[3] > 0) { - float *pixDest = dest + 4 * (rectx * y + x); - float float_src[4]; - srgb_to_linearrgb_uchar4(float_src, pixSrc); - addAlphaOverFloat(pixDest, float_src); - } - } - } - } - /* back layer status */ - i = 0; - for (bGPDlayer *gph = gpd->layers.first; gph; gph = gph->next) { - gph->flag = oldsts[i]; - ++i; - } - } - /* free memory */ - MEM_freeN(oldsts); - - /* back default alpha mode */ - scene->r.alphamode = oldalphamode; -} - static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) { RenderResult *rr; @@ -550,11 +465,6 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) BLI_assert(view_id < oglrender->views_len); RE_SetActiveRenderView(oglrender->re, rv->name); oglrender->view_id = view_id; - /* add grease pencil passes. For sequencer, the render does not include renderpasses - * TODO: The sequencer render of grease pencil should be rethought */ - if (!oglrender->is_sequencer) { - add_gpencil_renderpass(C, oglrender, rr, rv); - } /* render composite */ screen_opengl_render_doit(C, oglrender, rr); } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 3423eedf7ca..069611be35d 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -198,6 +198,7 @@ typedef struct IconPreview { static Main *G_pr_main = NULL; static Main *G_pr_main_cycles = NULL; +static Main *G_pr_main_grease_pencil = NULL; #ifndef WITH_HEADLESS static Main *load_main_from_memory(const void *blend, int blend_size) @@ -227,6 +228,7 @@ void ED_preview_ensure_dbase(void) if (!base_initialized) { G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size); G_pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size); + G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend, datatoc_preview_grease_pencil_blend_size); base_initialized = true; } #endif @@ -245,6 +247,9 @@ void ED_preview_free_dbase(void) if (G_pr_main_cycles) BKE_main_free(G_pr_main_cycles); + + if (G_pr_main_grease_pencil) + BKE_main_free(G_pr_main_grease_pencil); } static Scene *preview_get_scene(Main *pr_main) @@ -1102,6 +1107,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short sp->id_copy = ip->id_copy; sp->bmain = ip->bmain; sp->own_id_copy = false; + Material *ma = NULL; if (is_render) { BLI_assert(ip->id); @@ -1109,10 +1115,22 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short * 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 + if (GS(ip->id->name) != ID_TE) { + /* grease pencil use its own preview file */ + if (GS(ip->id->name) == ID_MA) { + ma = (Material *)ip->id; + } + + if ((ma == NULL) || (ma->gp_style == NULL)) { + sp->pr_main = G_pr_main_cycles; + } + else { + sp->pr_main = G_pr_main_grease_pencil; + } + } + else { sp->pr_main = G_pr_main; + } } common_preview_startjob(sp, stop, do_update, progress); @@ -1274,11 +1292,23 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->parent = parent; sp->slot = slot; sp->bmain = CTX_data_main(C); + Material *ma = NULL; /* 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) { - sp->pr_main = G_pr_main_cycles; + /* grease pencil use its own preview file */ + if (GS(id->name) == ID_MA) { + ma = (Material *)id; + } + + if ((ma == NULL) || (ma->gp_style == NULL)) { + sp->pr_main = G_pr_main_cycles; + } + else { + sp->pr_main = G_pr_main_grease_pencil; + } + } else { sp->pr_main = G_pr_main; diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 8077079a9b5..2dd4f328d06 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -469,6 +469,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); PointerRNA ptr, idptr; PropertyRNA *prop; @@ -477,7 +478,12 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) ma = BKE_material_copy(bmain, ma); } else { - ma = BKE_material_add(bmain, DATA_("Material")); + if ((!ob) || (ob->type != OB_GPENCIL)) { + ma = BKE_material_add(bmain, DATA_("Material")); + } + else { + ma = BKE_material_add_gpencil(bmain, DATA_("Material")); + } ED_node_shader_default(C, &ma->id); ma->use_nodes = true; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 1a63bc1cd53..18bacee98b9 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1428,18 +1428,32 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand } if (flag & ED_KEYMAP_GPENCIL) { /* grease pencil */ - /* NOTE: This is now 2 keymaps - One for basic functionality, - * and one that only applies when "Edit Mode" is enabled - * for strokes. + /* NOTE: This is now 4 keymaps - One for basic functionality, + * and others for special stroke modes (edit, paint and sculpt). * - * For now, it's easier to just include both, - * since you hardly want one without the other. + * For now, it's easier to just include all, + * since you hardly want one without the others. */ wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0); - wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_general); + + wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0); WM_event_add_keymap_handler(handlers, keymap_edit); + + wmKeyMap *keymap_paint = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint Mode", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint); + + wmKeyMap *keymap_paint_draw = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_draw); + + wmKeyMap *keymap_paint_erase = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Erase)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_erase); + + wmKeyMap *keymap_paint_fill = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Paint (Fill)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_fill); + + wmKeyMap *keymap_sculpt = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Sculpt Mode", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_sculpt); } if (flag & ED_KEYMAP_HEADER) { /* standard keymap for headers regions */ diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 17b1af29010..ecfc9f2cca0 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -34,6 +34,7 @@ #include "DNA_object_types.h" #include "DNA_armature_types.h" +#include "DNA_brush_types.h" #include "DNA_gpencil_types.h" #include "DNA_sequence_types.h" #include "DNA_scene_types.h" @@ -44,10 +45,13 @@ #include "BLI_utildefines.h" +#include "BKE_brush.h" #include "BKE_context.h" #include "BKE_object.h" #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_paint.h" +#include "BKE_main.h" #include "BKE_gpencil.h" #include "BKE_layer.h" #include "BKE_screen.h" @@ -80,8 +84,7 @@ const char *screen_context_dir[] = { "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ "gpencil_data", "gpencil_data_owner", /* grease pencil data */ "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes", - "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette", - "active_gpencil_palettecolor", "active_gpencil_brush", + "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_brush", "active_operator", "selected_editable_fcurves", NULL}; @@ -467,7 +470,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when * called from context. For that reason, we end up using an alternative where we pass everything in! */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); if (gpd) { CTX_data_id_pointer_set(result, &gpd->id); @@ -482,7 +485,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult PointerRNA ptr; /* get pointer to Grease Pencil Data */ - gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr); + gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, sa, scene, obact, &ptr); if (gpd_ptr) { CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data); @@ -491,7 +494,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if (CTX_data_equals(member, "active_gpencil_layer")) { /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); if (gpd) { bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); @@ -502,47 +505,17 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } } - else if (CTX_data_equals(member, "active_gpencil_palette")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); - - if (gpd) { - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - - if (palette) { - CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPalette, palette); - return 1; - } - } - } - else if (CTX_data_equals(member, "active_gpencil_palettecolor")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); - - if (gpd) { - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - - if (palette) { - bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette); - if (palcolor) { - CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPaletteColor, palcolor); - return 1; - } - } - } - } else if (CTX_data_equals(member, "active_gpencil_brush")) { - /* XXX: see comment for gpencil_data case... */ - bGPDbrush *brush = BKE_gpencil_brush_getactive(scene->toolsettings); + Brush *brush = BKE_brush_getactive_gpencil(scene->toolsettings); if (brush) { - CTX_data_pointer_set(result, &scene->id, &RNA_GPencilBrush, brush); + CTX_data_pointer_set(result, &scene->id, &RNA_Brush, brush); return 1; } } else if (CTX_data_equals(member, "active_gpencil_frame")) { /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); if (gpd) { bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); @@ -555,7 +528,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if (CTX_data_equals(member, "visible_gpencil_layers")) { /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); if (gpd) { bGPDlayer *gpl; @@ -571,7 +544,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if (CTX_data_equals(member, "editable_gpencil_layers")) { /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); if (gpd) { bGPDlayer *gpl; @@ -587,24 +560,37 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if (CTX_data_equals(member, "editable_gpencil_strokes")) { /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact); + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); if (gpd) { bGPDlayer *gpl; for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) { - bGPDframe *gpf = gpl->actframe; + bGPDframe *gpf; bGPDstroke *gps; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } - for (gps = gpf->strokes.first; gps; gps = gps->next) { - if (ED_gpencil_stroke_can_use_direct(sa, gps)) { - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { - continue; + for (gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + for (gps = gpf->strokes.first; gps; gps = gps->next) { + if (ED_gpencil_stroke_can_use_direct(sa, gps)) { + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { + continue; + } + + CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); + } } - - CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); + } + /* if not multiedit out of loop */ + if (!is_multiedit) { + break; } } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a837b32b0bb..df909794353 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2608,11 +2608,14 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) /* populate tree with keyframe nodes */ scene_to_keylist(&ads, scene, &keys, NULL); - gpencil_to_keylist(&ads, scene->gpd, &keys); if (ob) { ob_to_keylist(&ads, ob, &keys, NULL); - gpencil_to_keylist(&ads, ob->gpd, &keys); + + if (ob->type == OB_GPENCIL) { + const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY); + gpencil_to_keylist(&ads, ob->data, &keys, active); + } } { diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 0f796020d9e..86d36ade477 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -29,20 +29,27 @@ #include "BLI_string.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" +#include "BLI_math_color.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "DNA_gpencil_types.h" #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_paint.h" +#include "BKE_gpencil.h" #include "BKE_main.h" +#include "BKE_report.h" + +#include "DEG_depsgraph.h" #include "ED_paint.h" #include "ED_screen.h" #include "ED_image.h" +#include "ED_gpencil.h" #include "UI_resources.h" #include "WM_api.h" @@ -96,6 +103,43 @@ static void BRUSH_OT_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int brush_add_gpencil_exec(bContext *C, wmOperator *UNUSED(op)) +{ + /*int type = RNA_enum_get(op->ptr, "type");*/ + ToolSettings *ts = CTX_data_tool_settings(C); + Paint *paint = &ts->gp_paint->paint; + Brush *br = BKE_paint_brush(paint); + Main *bmain = CTX_data_main(C); + // ePaintMode mode = ePaintGpencil; + + if (br) { + br = BKE_brush_copy(bmain, br); + } + else { + br = BKE_brush_add(bmain, "Brush", OB_MODE_GPENCIL_PAINT); + id_us_min(&br->id); /* fake user only */ + } + + BKE_paint_brush_set(paint, br); + + /* TODO init grease pencil specific data */ + + return OPERATOR_FINISHED; +} + +static void BRUSH_OT_add_gpencil(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Drawing Brush"; + ot->description = "Add brush for grease pencil"; + ot->idname = "BRUSH_OT_add_gpencil"; + + /* api callbacks */ + ot->exec = brush_add_gpencil_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} static int brush_scale_size_exec(bContext *C, wmOperator *op) { @@ -232,7 +276,6 @@ static void PALETTE_OT_color_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } - static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Paint *paint = BKE_paint_get_active_from_context(C); @@ -1031,6 +1074,7 @@ void ED_operatortypes_paint(void) /* brush */ WM_operatortype_append(BRUSH_OT_add); + WM_operatortype_append(BRUSH_OT_add_gpencil); WM_operatortype_append(BRUSH_OT_scale_size); WM_operatortype_append(BRUSH_OT_curve_preset); WM_operatortype_append(BRUSH_OT_reset); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index c46d0fdb035..831c461538a 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -51,6 +51,7 @@ #include "BKE_fcurve.h" #include "BKE_nla.h" #include "BKE_context.h" +#include "BKE_gpencil.h" #include "UI_view2d.h" @@ -134,15 +135,20 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) /* Now set the flags */ for (ale = anim_data.first; ale; ale = ale->next) { - if (ale->type == ANIMTYPE_GPLAYER) + if (ale->type == ANIMTYPE_GPLAYER) { ED_gplayer_frame_select_set(ale->data, sel); - else if (ale->type == ANIMTYPE_MASKLAYER) + ale->update |= ANIM_UPDATE_DEPS; + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_masklayer_frame_select_set(ale->data, sel); - else + } + else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL); + } } /* Cleanup */ + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -283,12 +289,16 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { ED_gplayer_frames_select_border(gpl, rectf.xmin, rectf.xmax, selectmode); } + ale->update |= ANIM_UPDATE_DEPS; break; } #endif case ANIMTYPE_GPLAYER: + { ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode); + ale->update |= ANIM_UPDATE_DEPS; break; + } case ANIMTYPE_MASKDATABLOCK: { Mask *mask = ale->data; @@ -312,6 +322,7 @@ static void borderselect_action(bAnimContext *ac, const rcti rect, short mode, s } /* cleanup */ + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -493,6 +504,7 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view, case ANIMTYPE_GPLAYER: { ED_gplayer_frames_select_region(&ked, ale->data, mode, selectmode); + ale->update |= ANIM_UPDATE_DEPS; break; } case ANIMTYPE_MASKDATABLOCK: @@ -520,6 +532,7 @@ static void region_select_action_keys(bAnimContext *ac, const rctf *rectf_view, } /* cleanup */ + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -707,6 +720,7 @@ static void markers_selectkeys_between(bAnimContext *ac) } else if (ale->type == ANIMTYPE_GPLAYER) { ED_gplayer_frames_select_border(ale->data, min, max, SELECT_ADD); + ale->update |= ANIM_UPDATE_DEPS; } else if (ale->type == ANIMTYPE_MASKLAYER) { ED_masklayer_frames_select_border(ale->data, min, max, SELECT_ADD); @@ -717,6 +731,7 @@ static void markers_selectkeys_between(bAnimContext *ac) } /* Cleanup */ + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -796,17 +811,23 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) ked.f1 = ce->cfra; /* select elements with frame number matching cfraelem */ - if (ale->type == ANIMTYPE_GPLAYER) + if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD); - else if (ale->type == ANIMTYPE_MASKLAYER) + ale->update |= ANIM_UPDATE_DEPS; + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD); - else + } + else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); + } } } /* free elements */ BLI_freelistN(&ked.list); + + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -1081,12 +1102,16 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } - else if (ale->type == ANIMTYPE_GPLAYER) + else if (ale->type == ANIMTYPE_GPLAYER) { ED_gplayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); - else if (ale->type == ANIMTYPE_MASKLAYER) + ale->update |= ANIM_UPDATE_DEPS; + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_masklayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); - else + } + else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); + } } /* Sync marker support */ @@ -1111,6 +1136,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se } /* Cleanup */ + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -1227,6 +1253,7 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s /* select the nominated keyframe on the given frame */ if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->data, selx, select_mode); + ale->update |= ANIM_UPDATE_DEPS; } else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->data, selx, select_mode); @@ -1244,12 +1271,14 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->data, selx, select_mode); + ale->update |= ANIM_UPDATE_DEPS; } else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->data, selx, select_mode); } } + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } else { @@ -1294,16 +1323,22 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se ked.f1 = selx; /* select elements with frame number matching cfra */ - if (ale->type == ANIMTYPE_GPLAYER) + if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frame(ale->key_data, selx, select_mode); - else if (ale->type == ANIMTYPE_MASKLAYER) + ale->update |= ANIM_UPDATE_DEPS; + } + else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frame(ale->key_data, selx, select_mode); - else + } + else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); + } } /* free elements */ BLI_freelistN(&ked.list); + + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } @@ -1318,6 +1353,7 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s /* select all keyframes in this channel */ if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frames(ale->data, select_mode); + ale->update = ANIM_UPDATE_DEPS; } else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frames(ale->data, select_mode); @@ -1335,12 +1371,14 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { ED_gpencil_select_frames(ale->data, select_mode); + ale->update |= ANIM_UPDATE_DEPS; } else if (ale->type == ANIMTYPE_MASKLAYER) { ED_mask_select_frames(ale->data, select_mode); } } + ANIM_animdata_update(ac, &anim_data); ANIM_animdata_freelist(&anim_data); } else { @@ -1473,6 +1511,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ /* remove active channel from list of channels for separate treatment (since it's needed later on) */ BLI_remlink(&anim_data, ale); + ale->next = ale->prev = NULL; /* cleanup temporary lists */ BLI_dlrbTree_free(&anim_keys); @@ -1557,6 +1596,12 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ } } + /* flush tagged updates + * NOTE: We temporarily add this channel back to the list so that this can happen + */ + anim_data.first = anim_data.last = ale; + ANIM_animdata_update(ac, &anim_data); + /* free this channel */ MEM_freeN(ale); } diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index faee9c2b7ac..67632f6a53a 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -237,6 +237,7 @@ static int buttons_context_path_data(ButsContextPath *path, int type) else if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1; else if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) return 1; + else if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) return 1; /* try to get an object in the path, no pinning supported here */ else if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; @@ -260,7 +261,21 @@ static int buttons_context_path_modifier(ButsContextPath *path) if (buttons_context_path_object(path)) { ob = path->ptr[path->len - 1].data; - if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE)) + if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE, OB_GPENCIL)) + return 1; + } + + return 0; +} + +static int buttons_context_path_shaderfx(ButsContextPath *path) +{ + Object *ob; + + if (buttons_context_path_object(path)) { + ob = path->ptr[path->len - 1].data; + + if (ob && ELEM(ob->type, OB_GPENCIL)) return 1; } @@ -485,6 +500,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma WorkSpace *workspace = CTX_wm_workspace(C); ID *id; int found; + Object *ob = CTX_data_active_object(C); memset(path, 0, sizeof(*path)); path->flag = flag; @@ -546,6 +562,9 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma case BCONTEXT_MODIFIER: found = buttons_context_path_modifier(path); break; + case BCONTEXT_SHADERFX: + found = buttons_context_path_shaderfx(path); + break; case BCONTEXT_DATA: found = buttons_context_path_data(path, -1); break; @@ -553,7 +572,14 @@ 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); + /* NOTE: Grease Pencil materials use different panels... */ + if (ob && ob->type == OB_GPENCIL) { + /* XXX: Why path_data? */ + found = buttons_context_path_data(path, -1); + } + else { + found = buttons_context_path_material(path); + } break; case BCONTEXT_TEXTURE: found = buttons_context_path_texture(C, path, sbuts->texuser); @@ -626,10 +652,18 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) if (a == BCONTEXT_DATA) { ptr = &path->ptr[path->len - 1]; - if (ptr->type) + if (ptr->type) { sbuts->dataicon = RNA_struct_ui_icon(ptr->type); - else - sbuts->dataicon = ICON_EMPTY_DATA; + } + else { + Object *ob = CTX_data_active_object(C); + if (ob->type == OB_GPENCIL) { + sbuts->dataicon = ICON_GREASEPENCIL; + } + else { + sbuts->dataicon = ICON_EMPTY_DATA; + } + } } } } diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 66684de18ac..de422565abd 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -55,6 +55,7 @@ #include "BKE_layer.h" #include "BKE_linestyle.h" #include "BKE_modifier.h" +#include "BKE_gpencil_modifier.h" #include "BKE_node.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -152,6 +153,19 @@ static void buttons_texture_modifier_foreach(void *userData, Object *ob, Modifie N_("Modifiers"), RNA_struct_ui_icon(ptr.type), md->name); } +static void buttons_texture_modifier_gpencil_foreach(void *userData, Object *ob, GpencilModifierData *md, const char *propname) +{ + PointerRNA ptr; + PropertyRNA *prop; + ListBase *users = userData; + + RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr); + prop = RNA_struct_find_property(&ptr, propname); + + buttons_texture_user_property_add(users, &ob->id, ptr, prop, + N_("Grease Pencil Modifiers"), RNA_struct_ui_icon(ptr.type), md->name); +} + static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts) { Scene *scene = NULL; @@ -203,6 +217,9 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * /* modifiers */ modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users); + /* grease pencil modifiers */ + BKE_gpencil_modifiers_foreachTexLink(ob, buttons_texture_modifier_gpencil_foreach, users); + /* particle systems */ if (psys && !limited_mode) { for (a = 0; a < MAX_MTEX; a++) { diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 6f7a4ca971a..62115aea11d 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -180,6 +180,9 @@ static void buttons_main_region_layout_properties(const bContext *C, SpaceButs * case BCONTEXT_MODIFIER: contexts[0] = "modifier"; break; + case BCONTEXT_SHADERFX: + contexts[0] = "shaderfx"; + break; case BCONTEXT_CONSTRAINT: contexts[0] = "constraint"; break; @@ -200,8 +203,9 @@ static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar) const char *contexts[3] = {NULL}; const WorkSpace *workspace = CTX_wm_workspace(C); + const int mode = CTX_data_mode_enum(C); + if (workspace->tools_space_type == SPACE_VIEW3D) { - const int mode = CTX_data_mode_enum(C); switch (mode) { case CTX_MODE_EDIT_MESH: ARRAY_SET_ITEMS(contexts, ".mesh_edit"); @@ -245,12 +249,39 @@ static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar) case CTX_MODE_OBJECT: ARRAY_SET_ITEMS(contexts, ".objectmode"); break; + case CTX_MODE_GPENCIL_PAINT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_paint"); + break; + case CTX_MODE_GPENCIL_SCULPT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt"); + break; + case CTX_MODE_GPENCIL_WEIGHT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_weight"); + break; } } else if (workspace->tools_space_type == SPACE_IMAGE) { /* TODO */ } + /* for grease pencil we don't use tool system yet, so we need check outside + * workspace->tools_space_type because this value is not available + */ + switch (mode) { + case CTX_MODE_GPENCIL_PAINT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_paint"); + break; + case CTX_MODE_GPENCIL_SCULPT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_sculpt"); + break; + case CTX_MODE_GPENCIL_WEIGHT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_weight"); + break; + case CTX_MODE_GPENCIL_EDIT: + ARRAY_SET_ITEMS(contexts, ".greasepencil_edit"); + break; + } + const bool vertical = true; ED_region_panels_layout_ex(C, ar, contexts, -1, vertical); } @@ -495,6 +526,14 @@ static void buttons_area_listener( break; } break; + case NC_GPENCIL: + switch(wmn->data) { + case ND_DATA: + if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) + ED_area_tag_redraw(sa); + break; + } + break; case NC_NODE: if (wmn->action == NA_SELECTED) { ED_area_tag_redraw(sa); diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index db5f6c2451c..6953b7cfb71 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -107,7 +107,7 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr); if (!compact) - uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (clip) { uiLayout *col; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 2b98ff43c5f..725c2b7fa6d 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -236,7 +236,7 @@ static SpaceLink *clip_new(const ScrArea *sa, const Scene *scene) sc = MEM_callocN(sizeof(SpaceClip), "initclip"); sc->spacetype = SPACE_CLIP; sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | - SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL; + SC_SHOW_GRAPH_TRACKS_MOTION | SC_SHOW_GRAPH_FRAMES | SC_SHOW_ANNOTATION; sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; @@ -1196,7 +1196,7 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar) clip_draw_cache_and_notes(C, sc, ar); - if (sc->flag & SC_SHOW_GPENCIL) { + if (sc->flag & SC_SHOW_ANNOTATION) { /* Grease Pencil */ clip_draw_grease_pencil((bContext *)C, true); } @@ -1204,7 +1204,7 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar) /* reset view matrix */ UI_view2d_view_restore(C); - if (sc->flag & SC_SHOW_GPENCIL) { + if (sc->flag & SC_SHOW_ANNOTATION) { /* draw Grease Pencil - screen space only */ clip_draw_grease_pencil((bContext *)C, false); } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 1d8c6721b64..afcae7a27ab 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -876,7 +876,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char if (!compact) { uiTemplateID( layout, C, ptr, propname, - ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); } if (ima) { diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 8aa37bb5e16..fdf9d6df374 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -32,6 +32,7 @@ #include "DNA_armature_types.h" #include "DNA_curve_types.h" +#include "DNA_gpencil_types.h" #include "DNA_group_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -55,6 +56,7 @@ #include "BKE_particle.h" #include "BKE_editmesh.h" #include "BKE_object.h" +#include "BKE_gpencil.h" #include "ED_info.h" #include "ED_armature.h" @@ -72,6 +74,7 @@ typedef struct SceneStats { int totobj, totobjsel; int totlamp, totlampsel; int tottri; + int totgplayer, totgpframe, totgpstroke, totgppoint; char infostr[MAX_INFO_LEN]; } SceneStats; @@ -85,6 +88,8 @@ typedef struct SceneStatsFmt { char totobj[MAX_INFO_NUM_LEN], totobjsel[MAX_INFO_NUM_LEN]; char totlamp[MAX_INFO_NUM_LEN], totlampsel[MAX_INFO_NUM_LEN]; char tottri[MAX_INFO_NUM_LEN]; + char totgplayer[MAX_INFO_NUM_LEN], totgpframe[MAX_INFO_NUM_LEN]; + char totgpstroke[MAX_INFO_NUM_LEN], totgppoint[MAX_INFO_NUM_LEN]; } SceneStatsFmt; static void stats_object(Object *ob, int sel, int totob, SceneStats *stats) @@ -144,6 +149,20 @@ static void stats_object(Object *ob, int sel, int totob, SceneStats *stats) } break; } + case OB_GPENCIL: + { + bGPdata *gpd = (bGPdata *)ob->data; + /* GPXX Review if we can move to other place when object change + * maybe to depsgraph evaluation + */ + BKE_gpencil_stats_update(gpd); + + stats->totgplayer = gpd->totlayer; + stats->totgpframe = gpd->totframe; + stats->totgpstroke = gpd->totstroke; + stats->totgppoint = gpd->totpoint; + break; + } } } @@ -442,6 +461,11 @@ static void stats_string(ViewLayer *view_layer) SCENE_STATS_FMT_INT(tottri); + SCENE_STATS_FMT_INT(totgplayer); + SCENE_STATS_FMT_INT(totgpframe); + SCENE_STATS_FMT_INT(totgpstroke); + SCENE_STATS_FMT_INT(totgppoint); + #undef SCENE_STATS_FMT_INT @@ -501,6 +525,14 @@ static void stats_string(ViewLayer *view_layer) ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%s/%s %s%s"), stats_fmt.totbonesel, stats_fmt.totbone, memstr, gpumemstr); } + else if ((ob) && (ob->type == OB_GPENCIL)) { + ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, + IFACE_("Layers:%s | Frames:%s | Strokes:%s | Points:%s"), + stats_fmt.totgplayer, stats_fmt.totgpframe, stats_fmt.totgpstroke, stats_fmt.totgppoint); + + ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs); + ofs += BLI_strncpy_rlen(s + ofs, gpumemstr, MAX_INFO_LEN - ofs); + } else if (stats_is_object_dynamic_topology_sculpt(ob, object_mode)) { ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%s | Tris:%s%s"), stats_fmt.totvert, stats_fmt.tottri, gpumemstr); diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 57464cbf092..40caf919848 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -145,6 +145,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: + case ANIMTYPE_PALETTE: { /* for these channels, we only do AnimData */ if (ale->adt && adt_ptr) { @@ -287,7 +288,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa) row = uiLayoutRow(layout, true); uiTemplateID( row, (bContext *)C, &adt_ptr, "action", - "ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL); + "ACTION_OT_new", NULL, "NLA_OT_action_unlink", UI_TEMPLATE_ID_FILTER_ALL, false); /* extrapolation */ row = uiLayoutRow(layout, true); diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index 3368ad4fe8d..51177a77f0d 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -182,6 +182,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe case ANIMTYPE_DSLINESTYLE: case ANIMTYPE_DSSPK: case ANIMTYPE_DSGPENCIL: + case ANIMTYPE_PALETTE: { /* sanity checking... */ if (ale->adt) { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index d1ad8cb396c..f284fa015b8 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -744,7 +744,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); uiLayoutSetContextPointer(layout, "image_user", &iuserptr); - uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); @@ -775,7 +775,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateID( layout, C, ptr, "image", - "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false); @@ -793,7 +793,7 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateID( layout, C, ptr, "image", - "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!ima) return; @@ -1274,7 +1274,7 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateID( layout, C, ptr, "image", - "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!node->id) return; imaptr = RNA_pointer_get(ptr, "image"); @@ -1304,7 +1304,7 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer const char *layer_name; char scene_name[MAX_ID_NAME - 2]; - uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!node->id) return; @@ -1418,7 +1418,7 @@ static void node_composit_buts_defocus(uiLayout *layout, bContext *C, PointerRNA col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "use_preview", 0, NULL, ICON_NONE); - uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false); col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "use_zbuffer", 0, NULL, ICON_NONE); @@ -1985,7 +1985,7 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr) { - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); } static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -1993,7 +1993,7 @@ static void node_composit_buts_movieclip_ex(uiLayout *layout, bContext *C, Point bNode *node = ptr->data; PointerRNA clipptr; - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!node->id) return; @@ -2007,7 +2007,7 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!node->id) return; @@ -2031,7 +2031,7 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (!node->id) return; @@ -2339,7 +2339,7 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false); uiItemR(layout, ptr, "use_antialiasing", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "use_feather", 0, NULL, ICON_NONE); @@ -2361,7 +2361,7 @@ static void node_composit_buts_keyingscreen(uiLayout *layout, bContext *C, Point { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (node->id) { MovieClip *clip = (MovieClip *) node->id; @@ -2397,7 +2397,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN { bNode *node = ptr->data; - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (node->id) { MovieClip *clip = (MovieClip *) node->id; @@ -2437,7 +2437,7 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P bNode *node = ptr->data; NodePlaneTrackDeformData *data = node->storage; - uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); if (node->id) { MovieClip *clip = (MovieClip *) node->id; @@ -2838,7 +2838,7 @@ static void node_texture_buts_proc(uiLayout *layout, bContext *UNUSED(C), Pointe static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { - uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL); + uiTemplateID(layout, C, ptr, "image", "IMAGE_OT_new", "IMAGE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false); } static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 435e0018ac0..feab82a59c8 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -32,6 +32,7 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" #include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_lightprobe_types.h" @@ -50,6 +51,7 @@ #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_fcurve.h" +#include "BKE_gpencil.h" #include "BKE_global.h" #include "BKE_idcode.h" #include "BKE_layer.h" @@ -438,12 +440,16 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) } case TSE_GP_LAYER: { - bGPdata *gpd = (bGPdata *)tselem->id; // id = GP Datablock + bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */ bGPDlayer *gpl = te->directdata; + /* always make layer active */ + BKE_gpencil_layer_setactive(gpd, gpl); + // XXX: name needs translation stuff BLI_uniquename(&gpd->layers, gpl, "GP Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd); break; } @@ -872,39 +878,6 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) } -static void UNUSED_FUNCTION(tselem_draw_gp_icon_uibut)(struct DrawIconArg *arg, ID *id, bGPDlayer *gpl) -{ - /* restrict column clip - skip it for now... */ - if (arg->x >= arg->xmax) { - /* pass */ - } - else { - PointerRNA ptr; - const float eps = 0.001f; - const bool is_stroke_visible = (gpl->color[3] > eps); - const bool is_fill_visible = (gpl->fill[3] > eps); - float w = 0.5f * UI_UNIT_X; - float h = 0.85f * UI_UNIT_Y; - - RNA_pointer_create(id, &RNA_GPencilLayer, gpl, &ptr); - - UI_block_align_begin(arg->block); - - UI_block_emboss_set(arg->block, is_stroke_visible ? UI_EMBOSS : UI_EMBOSS_NONE); - uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb, arg->yb, w, h, - &ptr, "color", -1, - 0, 0, 0, 0, NULL); - - UI_block_emboss_set(arg->block, is_fill_visible ? UI_EMBOSS : UI_EMBOSS_NONE); - uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb + w, arg->yb, w, h, - &ptr, "fill_color", -1, - 0, 0, 0, 0, NULL); - - UI_block_emboss_set(arg->block, UI_EMBOSS_NONE); - UI_block_align_end(arg->block); - } -} - static void tselem_draw_icon( uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha, const bool is_clickable) @@ -969,156 +942,212 @@ static void tselem_draw_icon( case TSE_MODIFIER: { Object *ob = (Object *)tselem->id; - ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr); - switch ((ModifierType)md->type) { - case eModifierType_Subsurf: - ICON_DRAW(ICON_MOD_SUBSURF); - break; - case eModifierType_Armature: - ICON_DRAW(ICON_MOD_ARMATURE); - break; - case eModifierType_Lattice: - ICON_DRAW(ICON_MOD_LATTICE); - break; - case eModifierType_Curve: - ICON_DRAW(ICON_MOD_CURVE); - break; - case eModifierType_Build: - ICON_DRAW(ICON_MOD_BUILD); - break; - case eModifierType_Mirror: - ICON_DRAW(ICON_MOD_MIRROR); - break; - case eModifierType_Decimate: - ICON_DRAW(ICON_MOD_DECIM); - break; - case eModifierType_Wave: - ICON_DRAW(ICON_MOD_WAVE); - break; - case eModifierType_Hook: - ICON_DRAW(ICON_HOOK); - break; - case eModifierType_Softbody: - ICON_DRAW(ICON_MOD_SOFT); - break; - case eModifierType_Boolean: - ICON_DRAW(ICON_MOD_BOOLEAN); - break; - case eModifierType_ParticleSystem: - ICON_DRAW(ICON_MOD_PARTICLES); - break; - case eModifierType_ParticleInstance: - ICON_DRAW(ICON_MOD_PARTICLES); - break; - case eModifierType_EdgeSplit: - ICON_DRAW(ICON_MOD_EDGESPLIT); - break; - case eModifierType_Array: - ICON_DRAW(ICON_MOD_ARRAY); - break; - case eModifierType_UVProject: - case eModifierType_UVWarp: /* TODO, get own icon */ - ICON_DRAW(ICON_MOD_UVPROJECT); - break; - case eModifierType_Displace: - ICON_DRAW(ICON_MOD_DISPLACE); - break; - case eModifierType_Shrinkwrap: - ICON_DRAW(ICON_MOD_SHRINKWRAP); - break; - case eModifierType_Cast: - ICON_DRAW(ICON_MOD_CAST); - break; - case eModifierType_MeshDeform: - case eModifierType_SurfaceDeform: - ICON_DRAW(ICON_MOD_MESHDEFORM); - break; - case eModifierType_Bevel: - ICON_DRAW(ICON_MOD_BEVEL); - break; - case eModifierType_Smooth: - case eModifierType_LaplacianSmooth: - case eModifierType_CorrectiveSmooth: - ICON_DRAW(ICON_MOD_SMOOTH); - break; - case eModifierType_SimpleDeform: - ICON_DRAW(ICON_MOD_SIMPLEDEFORM); - break; - case eModifierType_Mask: - ICON_DRAW(ICON_MOD_MASK); - break; - case eModifierType_Cloth: - ICON_DRAW(ICON_MOD_CLOTH); - break; - case eModifierType_Explode: - ICON_DRAW(ICON_MOD_EXPLODE); - break; - case eModifierType_Collision: - case eModifierType_Surface: - ICON_DRAW(ICON_MOD_PHYSICS); - break; - case eModifierType_Fluidsim: - ICON_DRAW(ICON_MOD_FLUIDSIM); - break; - case eModifierType_Multires: - ICON_DRAW(ICON_MOD_MULTIRES); - break; - case eModifierType_Smoke: - ICON_DRAW(ICON_MOD_SMOKE); - break; - case eModifierType_Solidify: - ICON_DRAW(ICON_MOD_SOLIDIFY); - break; - case eModifierType_Screw: - ICON_DRAW(ICON_MOD_SCREW); - break; - case eModifierType_Remesh: - ICON_DRAW(ICON_MOD_REMESH); - break; - case eModifierType_WeightVGEdit: - case eModifierType_WeightVGMix: - case eModifierType_WeightVGProximity: - ICON_DRAW(ICON_MOD_VERTEX_WEIGHT); - break; - case eModifierType_DynamicPaint: - ICON_DRAW(ICON_MOD_DYNAMICPAINT); - break; - case eModifierType_Ocean: - ICON_DRAW(ICON_MOD_OCEAN); - break; - case eModifierType_Warp: - ICON_DRAW(ICON_MOD_WARP); - break; - case eModifierType_Skin: - ICON_DRAW(ICON_MOD_SKIN); - break; - case eModifierType_Triangulate: - ICON_DRAW(ICON_MOD_TRIANGULATE); - break; - case eModifierType_MeshCache: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ - break; - case eModifierType_MeshSequenceCache: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ - break; - case eModifierType_Wireframe: - ICON_DRAW(ICON_MOD_WIREFRAME); - break; - case eModifierType_LaplacianDeform: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ - break; - case eModifierType_DataTransfer: - ICON_DRAW(ICON_MOD_DATA_TRANSFER); - break; - case eModifierType_NormalEdit: - ICON_DRAW(ICON_MOD_NORMALEDIT); - break; - /* Default */ - case eModifierType_None: - case eModifierType_ShapeKey: - case NUM_MODIFIER_TYPES: - ICON_DRAW(ICON_DOT); - break; + if (ob->type != OB_GPENCIL) { + ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr); + switch ((ModifierType)md->type) { + case eModifierType_Subsurf: + ICON_DRAW(ICON_MOD_SUBSURF); + break; + case eModifierType_Armature: + ICON_DRAW(ICON_MOD_ARMATURE); + break; + case eModifierType_Lattice: + ICON_DRAW(ICON_MOD_LATTICE); + break; + case eModifierType_Curve: + ICON_DRAW(ICON_MOD_CURVE); + break; + case eModifierType_Build: + ICON_DRAW(ICON_MOD_BUILD); + break; + case eModifierType_Mirror: + ICON_DRAW(ICON_MOD_MIRROR); + break; + case eModifierType_Decimate: + ICON_DRAW(ICON_MOD_DECIM); + break; + case eModifierType_Wave: + ICON_DRAW(ICON_MOD_WAVE); + break; + case eModifierType_Hook: + ICON_DRAW(ICON_HOOK); + break; + case eModifierType_Softbody: + ICON_DRAW(ICON_MOD_SOFT); + break; + case eModifierType_Boolean: + ICON_DRAW(ICON_MOD_BOOLEAN); + break; + case eModifierType_ParticleSystem: + ICON_DRAW(ICON_MOD_PARTICLES); + break; + case eModifierType_ParticleInstance: + ICON_DRAW(ICON_MOD_PARTICLES); + break; + case eModifierType_EdgeSplit: + ICON_DRAW(ICON_MOD_EDGESPLIT); + break; + case eModifierType_Array: + ICON_DRAW(ICON_MOD_ARRAY); + break; + case eModifierType_UVProject: + case eModifierType_UVWarp: /* TODO, get own icon */ + ICON_DRAW(ICON_MOD_UVPROJECT); + break; + case eModifierType_Displace: + ICON_DRAW(ICON_MOD_DISPLACE); + break; + case eModifierType_Shrinkwrap: + ICON_DRAW(ICON_MOD_SHRINKWRAP); + break; + case eModifierType_Cast: + ICON_DRAW(ICON_MOD_CAST); + break; + case eModifierType_MeshDeform: + case eModifierType_SurfaceDeform: + ICON_DRAW(ICON_MOD_MESHDEFORM); + break; + case eModifierType_Bevel: + ICON_DRAW(ICON_MOD_BEVEL); + break; + case eModifierType_Smooth: + case eModifierType_LaplacianSmooth: + case eModifierType_CorrectiveSmooth: + ICON_DRAW(ICON_MOD_SMOOTH); + break; + case eModifierType_SimpleDeform: + ICON_DRAW(ICON_MOD_SIMPLEDEFORM); + break; + case eModifierType_Mask: + ICON_DRAW(ICON_MOD_MASK); + break; + case eModifierType_Cloth: + ICON_DRAW(ICON_MOD_CLOTH); + break; + case eModifierType_Explode: + ICON_DRAW(ICON_MOD_EXPLODE); + break; + case eModifierType_Collision: + case eModifierType_Surface: + ICON_DRAW(ICON_MOD_PHYSICS); + break; + case eModifierType_Fluidsim: + ICON_DRAW(ICON_MOD_FLUIDSIM); + break; + case eModifierType_Multires: + ICON_DRAW(ICON_MOD_MULTIRES); + break; + case eModifierType_Smoke: + ICON_DRAW(ICON_MOD_SMOKE); + break; + case eModifierType_Solidify: + ICON_DRAW(ICON_MOD_SOLIDIFY); + break; + case eModifierType_Screw: + ICON_DRAW(ICON_MOD_SCREW); + break; + case eModifierType_Remesh: + ICON_DRAW(ICON_MOD_REMESH); + break; + case eModifierType_WeightVGEdit: + case eModifierType_WeightVGMix: + case eModifierType_WeightVGProximity: + ICON_DRAW(ICON_MOD_VERTEX_WEIGHT); + break; + case eModifierType_DynamicPaint: + ICON_DRAW(ICON_MOD_DYNAMICPAINT); + break; + case eModifierType_Ocean: + ICON_DRAW(ICON_MOD_OCEAN); + break; + case eModifierType_Warp: + ICON_DRAW(ICON_MOD_WARP); + break; + case eModifierType_Skin: + ICON_DRAW(ICON_MOD_SKIN); + break; + case eModifierType_Triangulate: + ICON_DRAW(ICON_MOD_TRIANGULATE); + break; + case eModifierType_MeshCache: + ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + break; + case eModifierType_MeshSequenceCache: + ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + break; + case eModifierType_Wireframe: + ICON_DRAW(ICON_MOD_WIREFRAME); + break; + case eModifierType_LaplacianDeform: + ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + break; + case eModifierType_DataTransfer: + ICON_DRAW(ICON_MOD_DATA_TRANSFER); + break; + case eModifierType_NormalEdit: + ICON_DRAW(ICON_MOD_NORMALEDIT); + break; + /* Default */ + case eModifierType_None: + case eModifierType_ShapeKey: + + case NUM_MODIFIER_TYPES: + ICON_DRAW(ICON_DOT); + break; + } + } + else { + /* grease pencil modifiers */ + GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr); + switch ((GpencilModifierType)md->type) { + case eGpencilModifierType_Noise: + ICON_DRAW(ICON_RNDCURVE); + break; + case eGpencilModifierType_Subdiv: + ICON_DRAW(ICON_MOD_SUBSURF); + break; + case eGpencilModifierType_Thick: + ICON_DRAW(ICON_MAN_ROT); + break; + case eGpencilModifierType_Tint: + ICON_DRAW(ICON_COLOR); + break; + case eGpencilModifierType_Instance: + ICON_DRAW(ICON_MOD_ARRAY); + break; + case eGpencilModifierType_Build: + ICON_DRAW(ICON_MOD_BUILD); + break; + case eGpencilModifierType_Opacity: + ICON_DRAW(ICON_MOD_MASK); + break; + case eGpencilModifierType_Color: + ICON_DRAW(ICON_GROUP_VCOL); + break; + case eGpencilModifierType_Lattice: + ICON_DRAW(ICON_MOD_LATTICE); + break; + case eGpencilModifierType_Mirror: + ICON_DRAW(ICON_MOD_MIRROR); + break; + case eGpencilModifierType_Simplify: + ICON_DRAW(ICON_MOD_DECIM); + break; + case eGpencilModifierType_Smooth: + ICON_DRAW(ICON_MOD_SMOOTH); + break; + case eGpencilModifierType_Hook: + ICON_DRAW(ICON_HOOK); + break; + case eGpencilModifierType_Offset: + ICON_DRAW(ICON_MOD_DISPLACE); + break; + + /* Default */ + default: + ICON_DRAW(ICON_DOT); + break; + } } break; } @@ -1185,11 +1214,18 @@ static void tselem_draw_icon( ICON_DRAW(ICON_GROUP); break; /* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */ -#if 0 case TSE_GP_LAYER: - tselem_draw_gp_icon_uibut(&arg, tselem->id, te->directdata); + { + /* indicate whether layer is active */ + bGPDlayer *gpl = te->directdata; + if (gpl->flag & GP_LAYER_ACTIVE) { + ICON_DRAW(ICON_GREASEPENCIL); + } + else { + ICON_DRAW(ICON_DOT); + } break; -#endif + } default: ICON_DRAW(ICON_DOT); break; @@ -1229,6 +1265,9 @@ static void tselem_draw_icon( ICON_CLICK_DRAW(ICON_OUTLINER_OB_EMPTY); } break; + case OB_GPENCIL: + ICON_CLICK_DRAW(ICON_OUTLINER_OB_GREASEPENCIL); break; + break; } } else { @@ -1304,7 +1343,7 @@ static void tselem_draw_icon( case ID_LS: tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break; case ID_GD: - tselem_draw_icon_uibut(&arg, ICON_GREASEPENCIL); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_GREASEPENCIL); break; case ID_LP: { LightProbe * lp = (LightProbe *)tselem->id; diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 7ab13f36953..ec5e11520a6 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -39,6 +39,7 @@ #include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_world_types.h" +#include "DNA_gpencil_types.h" #include "BLI_utildefines.h" #include "BLI_listbase.h" @@ -46,9 +47,11 @@ #include "BKE_armature.h" #include "BKE_collection.h" #include "BKE_context.h" +#include "BKE_gpencil.h" #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_paint.h" #include "BKE_scene.h" #include "BKE_sequencer.h" #include "BKE_workspace.h" @@ -60,6 +63,7 @@ #include "ED_screen.h" #include "ED_sequencer.h" #include "ED_undo.h" +#include "ED_gpencil.h" #include "WM_api.h" #include "WM_types.h" @@ -470,6 +474,28 @@ static eOLDrawState tree_element_active_defgroup( return OL_DRAWSEL_NONE; } +static eOLDrawState UNUSED_FUNCTION(tree_element_active_gplayer)( + bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tselem, const eOLSetState set) +{ + bGPdata *gpd = (bGPdata *)tselem->id; + bGPDlayer *gpl = te->directdata; + + /* We can only have a single "active" layer at a time + * and there must always be an active layer... + */ + if (set != OL_SETSEL_NONE) { + if (gpl) { + BKE_gpencil_layer_setactive(gpd, gpl); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, gpd); + } + } + else { + return OL_DRAWSEL_NORMAL; + } + + return OL_DRAWSEL_NONE; +} + static eOLDrawState tree_element_active_posegroup( bContext *C, Scene *UNUSED(scene), ViewLayer *view_layer, TreeElement *te, TreeStoreElem *tselem, const eOLSetState set) { @@ -1006,6 +1032,10 @@ static void do_outliner_item_activate_tree_element( } } } + else if (ELEM(te->idcode, ID_GD)) { + /* set grease pencil to object mode */ + WM_operator_name_call(C, "GPENCIL_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); + } else { // rest of types tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false); } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 28890e42139..539df3aa085 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -319,8 +319,6 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s if (outliner_animdata_test(sce->adt)) outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); - /* Grease Pencil */ - outliner_add_element(soops, lb, sce->gpd, te, 0, 0); } TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c index e45159124e8..6113922c02e 100644 --- a/source/blender/editors/space_topbar/space_topbar.c +++ b/source/blender/editors/space_topbar/space_topbar.c @@ -168,6 +168,10 @@ static void topbar_main_region_listener(wmWindow *UNUSED(win), ScrArea *UNUSED(s if (wmn->data == ND_SPACE_VIEW3D) ED_region_tag_redraw(ar); break; + case NC_GPENCIL: + if (wmn->data == ND_DATA) + ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c0abbe636c3..3649c6f6dbb 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -80,6 +80,7 @@ #include "BKE_subsurf.h" #include "BKE_unit.h" #include "BKE_tracking.h" +#include "BKE_gpencil.h" #include "BKE_editmesh.h" diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 2577077002e..c1776ef18e7 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -36,6 +36,7 @@ #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_gpencil_types.h" #include "MEM_guardedalloc.h" @@ -335,12 +336,18 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR; v3d->flag = V3D_SELECT_OUTLINE; - v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL; + v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_ANNOTATION; v3d->lens = 50.0f; v3d->near = 0.01f; v3d->far = 1000.0f; + v3d->overlay.gpencil_grid_scale = 1.0; // Scales + v3d->overlay.gpencil_grid_lines = GP_DEFAULT_GRID_LINES; // NUmber of Lines + v3d->overlay.gpencil_paper_opacity = 0.5f; + v3d->overlay.gpencil_grid_axis = V3D_GP_GRID_AXIS_Y; + v3d->overlay.gpencil_grid_opacity = 0.9f; + v3d->bundle_size = 0.2f; v3d->bundle_drawtype = OB_PLAINAXES; @@ -350,6 +357,10 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene) v3d->stereo3d_convergence_alpha = 0.15f; v3d->stereo3d_volume_alpha = 0.05f; + /* grease pencil settings */ + v3d->vertex_opacity = 1.0f; + v3d->flag3 |= V3D_GP_SHOW_EDIT_LINES; + /* header */ ar = MEM_callocN(sizeof(ARegion), "header for view3d"); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 941f9262694..0157bc567ca 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1593,7 +1593,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( v3d.flag2 = V3D_RENDER_OVERRIDE; if (draw_flags & V3D_OFSDRAW_USE_GPENCIL) { - v3d.flag2 |= V3D_SHOW_GPENCIL; + v3d.flag2 |= V3D_SHOW_ANNOTATION; } if (draw_flags & V3D_OFSDRAW_USE_SOLID_TEX) { v3d.flag2 |= V3D_SOLID_TEX; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 94cd4dfc73d..45e4c4b4676 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -881,7 +881,7 @@ void ED_view3d_draw_depth_gpencil( GPU_depth_test(true); - if (v3d->flag2 & V3D_SHOW_GPENCIL) { + if (v3d->flag2 & V3D_SHOW_ANNOTATION) { ED_gpencil_draw_view3d(NULL, scene, view_layer, depsgraph, v3d, ar, true); } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e94d3a13225..468b33ea9a6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -52,6 +52,7 @@ #include "BKE_camera.h" #include "BKE_context.h" #include "BKE_font.h" +#include "BKE_gpencil.h" #include "BKE_layer.h" #include "BKE_library.h" #include "BKE_main.h" @@ -77,7 +78,6 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_mesh.h" -#include "ED_gpencil.h" #include "ED_view3d.h" #include "ED_transform_snap_object_context.h" @@ -2811,7 +2811,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph); bGPdata *gpd = CTX_data_gpencil_data(C); - const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)); + const bool is_gp_edit = GPENCIL_ANY_MODE(gpd); const bool is_face_map = ((is_gp_edit == false) && ar->gizmo_map && WM_gizmomap_is_any_selected(ar->gizmo_map)); Object *ob_eval = OBACT(view_layer_eval); @@ -2850,9 +2850,7 @@ static int viewselected_exec(bContext *C, wmOperator *op) { /* we're only interested in selected points here... */ if ((gps->flag & GP_STROKE_SELECT) && (gps->flag & GP_STROKE_3DSPACE)) { - if (ED_gpencil_stroke_minmax(gps, true, min, max)) { - ok = true; - } + ok |= BKE_gpencil_stroke_minmax(gps, true, min, max); } } CTX_DATA_END; diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index c716692eb9b..d5ef7cdf441 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -36,13 +36,17 @@ #include "BKE_object.h" #include "BKE_unit.h" +#include "BKE_material.h" +#include "BKE_main.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_gpencil_types.h" #include "DNA_view3d_types.h" #include "BIF_gl.h" +#include "ED_gpencil.h" #include "ED_screen.h" #include "ED_transform_snap_object_context.h" #include "ED_view3d.h" @@ -385,37 +389,28 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) // RulerInfo *ruler_info = gzgroup->customdata; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + + bGPdata *gpd; bGPDlayer *gpl; bGPDframe *gpf; bGPDstroke *gps; - bGPDpalette *palette; - bGPDpalettecolor *palcolor; RulerItem *ruler_item; const char *ruler_name = RULER_ID; bool changed = false; if (scene->gpd == NULL) { - scene->gpd = BKE_gpencil_data_addnew(bmain, "GPencil"); + scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations"); } + gpd = scene->gpd; - gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info)); + gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info)); if (gpl == NULL) { - gpl = BKE_gpencil_layer_addnew(scene->gpd, ruler_name, false); + gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false); + copy_v4_v4(gpl->color, U.gpencil_new_layer_col); gpl->thickness = 1; gpl->flag |= GP_LAYER_HIDE; } - /* try to get active palette or create a new one */ - palette = BKE_gpencil_palette_getactive(scene->gpd); - if (palette == NULL) { - palette = BKE_gpencil_palette_addnew(scene->gpd, DATA_("GP_Palette"), true); - } - /* try to get color with the ruler name or create a new one */ - palcolor = BKE_gpencil_palettecolor_getbyname(palette, (char *)ruler_name); - if (palcolor == NULL) { - palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true); - } - gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); BKE_gpencil_free_strokes(gpf); @@ -428,6 +423,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) if (ruler_item->flag & RULERITEM_USE_ANGLE) { gps->totpoints = 3; pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); for (j = 0; j < 3; j++) { copy_v3_v3(&pt->x, ruler_item->co[j]); pt->pressure = 1.0f; @@ -438,6 +434,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) else { gps->totpoints = 2; pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); for (j = 0; j < 3; j += 2) { copy_v3_v3(&pt->x, ruler_item->co[j]); pt->pressure = 1.0f; @@ -447,9 +444,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, wmGizmoGroup *gzgroup) } gps->flag = GP_STROKE_3DSPACE; gps->thickness = 3; - /* assign color to stroke */ - BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname)); - gps->palcolor = palcolor; + BLI_addtail(&gpf->strokes, gps); changed = true; } diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 690fc5e3bdb..0475159712b 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -26,9 +26,11 @@ /* defines VIEW3D_OT_ruler modal operator */ +#include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_gpencil_types.h" +#include "DNA_brush_types.h" #include "MEM_guardedalloc.h" @@ -40,6 +42,7 @@ #include "BKE_context.h" #include "BKE_gpencil.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_unit.h" #include "BIF_gl.h" @@ -51,6 +54,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_gpencil.h" #include "ED_screen.h" #include "ED_view3d.h" #include "ED_transform_snap_object_context.h" @@ -300,37 +304,28 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + bGPDlayer *gpl; bGPDframe *gpf; bGPDstroke *gps; - bGPDpalette *palette; - bGPDpalettecolor *palcolor; RulerItem *ruler_item; const char *ruler_name = RULER_ID; bool changed = false; + /* FIXME: This needs to be reviewed. Should it keep being done like this? */ if (scene->gpd == NULL) { - scene->gpd = BKE_gpencil_data_addnew(bmain, "GPencil"); + scene->gpd = BKE_gpencil_data_addnew(bmain, "Annotations"); } + bGPdata *gpd = scene->gpd; - gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info)); + gpl = BLI_findstring(&gpd->layers, ruler_name, offsetof(bGPDlayer, info)); if (gpl == NULL) { - gpl = BKE_gpencil_layer_addnew(scene->gpd, ruler_name, false); + gpl = BKE_gpencil_layer_addnew(gpd, ruler_name, false); + copy_v4_v4(gpl->color, U.gpencil_new_layer_col); gpl->thickness = 1; gpl->flag |= GP_LAYER_HIDE; } - /* try to get active palette or create a new one */ - palette = BKE_gpencil_palette_getactive(scene->gpd); - if (palette == NULL) { - palette = BKE_gpencil_palette_addnew(scene->gpd, DATA_("GP_Palette"), true); - } - /* try to get color with the ruler name or create a new one */ - palcolor = BKE_gpencil_palettecolor_getbyname(palette, (char *)ruler_name); - if (palcolor == NULL) { - palcolor = BKE_gpencil_palettecolor_addnew(palette, (char *)ruler_name, true); - } - gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true); BKE_gpencil_free_strokes(gpf); @@ -343,6 +338,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) if (ruler_item->flag & RULERITEM_USE_ANGLE) { gps->totpoints = 3; pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); for (j = 0; j < 3; j++) { copy_v3_v3(&pt->x, ruler_item->co[j]); pt->pressure = 1.0f; @@ -353,6 +349,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) else { gps->totpoints = 2; pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); for (j = 0; j < 3; j += 2) { copy_v3_v3(&pt->x, ruler_item->co[j]); pt->pressure = 1.0f; @@ -362,9 +359,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) } gps->flag = GP_STROKE_3DSPACE; gps->thickness = 3; - /* assign color to stroke */ - BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname)); - gps->palcolor = palcolor; + BLI_addtail(&gpf->strokes, gps); changed = true; } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 7da69c5b2d5..afff5eb7f66 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -44,6 +44,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_tracking_types.h" +#include "DNA_gpencil_types.h" #include "MEM_guardedalloc.h" @@ -76,6 +77,7 @@ #include "BKE_editmesh.h" #include "BKE_scene.h" #include "BKE_tracking.h" +#include "BKE_workspace.h" #include "DEG_depsgraph.h" @@ -95,6 +97,7 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_mball.h" +#include "ED_gpencil.h" #include "UI_interface.h" @@ -1675,6 +1678,27 @@ static bool ed_object_select_pick( if ((oldbasact != basact) && (is_obedit == false)) { ED_object_base_activate(C, basact); /* adds notifier */ } + + /* Set special modes for grease pencil + The grease pencil modes are not real modes, but a hack to make the interface + consistent, so need some tricks to keep UI synchronized */ + // XXX: This stuff neeeds reviewing (Aligorith) +#if 0 + if (((oldbasact) && oldbasact->object->type == OB_GPENCIL) || (basact->object->type == OB_GPENCIL)) { + /* set cursor */ + if (ELEM(basact->object->mode == OB_MODE_GPENCIL_PAINT, + OB_MODE_GPENCIL_SCULPT, + OB_MODE_GPENCIL_WEIGHT)) { + ED_gpencil_toggle_brush_cursor(C, true, NULL); + } + else { + /* TODO: maybe is better use restore */ + ED_gpencil_toggle_brush_cursor(C, false, NULL); + } + /* set workspace mode */ + BKE_workspace_object_mode_set(CTX_wm_workspace(C), scene, basact->object->mode); + } +#endif } DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 07ef6b9a819..9ad80f2ab12 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -44,6 +44,7 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ #include "DNA_workspace_types.h" +#include "DNA_gpencil_types.h" #include "BLI_alloca.h" #include "BLI_utildefines.h" @@ -85,6 +86,7 @@ #include "ED_mesh.h" #include "ED_clip.h" #include "ED_node.h" +#include "ED_gpencil.h" #include "WM_types.h" #include "WM_api.h" @@ -101,6 +103,8 @@ #include "transform.h" +#include "DEG_depsgraph.h" + /* Disabling, since when you type you know what you are doing, and being able to set it to zero is handy. */ // #define USE_NUM_NO_ZERO @@ -571,6 +575,10 @@ void removeAspectRatio(TransInfo *t, float vec[2]) static void viewRedrawForce(const bContext *C, TransInfo *t) { if (t->options & CTX_GPENCIL_STROKES) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + if (gpd) { + DEG_id_tag_update(&gpd->id, OB_RECALC_DATA); + } WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); } else if (t->spacetype == SPACE_VIEW3D) { @@ -1800,7 +1808,23 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) (float)t->mval[1], }; + +#if 0 /* XXX: Fix from 1c9690e7607bc990cc4a3e6ba839949bb83a78af cannot be used anymore */ + if ((t->flag & T_POINTS) && (t->options & CTX_GPENCIL_STROKES)) { + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + Object *ob = tc->obedit; + float vecrot[3]; + copy_v3_v3(vecrot, t->center); + mul_m4_v3(ob->obmat, vecrot); + projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO); + } + } + else { + projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); + } +#else projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); +#endif /* Offset the values for the area region. */ const float offset[2] = { @@ -3551,7 +3575,25 @@ static void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, f else sub_v3_v3(vec, td->center); - mul_v3_fl(vec, td->factor); + /* grease pencil falloff */ + if (t->options & CTX_GPENCIL_STROKES) { + bGPDstroke *gps = (bGPDstroke *)td->extra; + mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff); + + /* scale stroke thickness */ + if (td->val) { + snapGridIncrement(t, t->values); + applyNumInput(&t->num, t->values); + + float ratio = t->values[0]; + *td->val = td->ival * ratio * gps->runtime.multi_frame_falloff; + CLAMP_MIN(*td->val, 0.001f); + } + + } + else { + mul_v3_fl(vec, td->factor); + } if (t->flag & (T_OBJECT | T_POSE)) { mul_m3_v3(td->smtx, vec); @@ -3905,6 +3947,20 @@ static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData * mul_m3_m3m3(totmat, mat, td->mtx); mul_m3_m3m3(smat, td->smtx, totmat); + /* apply gpencil falloff */ + if (t->options & CTX_GPENCIL_STROKES) { + bGPDstroke *gps = (bGPDstroke *)td->extra; + float sx = smat[0][0]; + float sy = smat[1][1]; + float sz = smat[2][2]; + + mul_m3_fl(smat, gps->runtime.multi_frame_falloff); + /* fix scale */ + smat[0][0] = sx; + smat[1][1] = sy; + smat[2][2] = sz; + } + sub_v3_v3v3(vec, td->iloc, center); mul_m3_v3(smat, vec); @@ -4578,7 +4634,16 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) } mul_m3_v3(td->smtx, tvec); - mul_v3_fl(tvec, td->factor); + + if (t->options & CTX_GPENCIL_STROKES) { + /* grease pencil multiframe falloff */ + bGPDstroke *gps = (bGPDstroke *)td->extra; + mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff); + } + else { + /* proportional editing falloff */ + mul_v3_fl(tvec, td->factor); + } protectedTransBits(td->protectflag, tvec); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 675441189b0..d3b7417c4dd 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -90,6 +90,7 @@ #include "BKE_editmesh.h" #include "BKE_tracking.h" #include "BKE_mask.h" +#include "BKE_colortools.h" #include "BIK_api.h" @@ -3609,6 +3610,8 @@ static void posttrans_gpd_clean(bGPdata *gpd) } #endif } + /* set cache flag to dirty */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); } static void posttrans_mask_clean(Mask *mask) @@ -8086,7 +8089,14 @@ void flushTransPaintCurve(TransInfo *t) static void createTransGPencil(bContext *C, TransInfo *t) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); \ bGPdata *gpd = ED_gpencil_data_get_active(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + bool use_multiframe_falloff = (ts->gp_sculpt.flag & GP_BRUSHEDIT_FLAG_FRAME_FALLOFF) != 0; + + Object *obact = CTX_data_active_object(C); bGPDlayer *gpl; TransData *td = NULL; float mtx[3][3], smtx[3][3]; @@ -8110,50 +8120,67 @@ static void createTransGPencil(bContext *C, TransInfo *t) if (gpd == NULL) return; + /* initialize falloff curve */ + if (is_multiedit) { + curvemapping_initialize(ts->gp_sculpt.cur_falloff); + } + /* First Pass: Count the number of datapoints required for the strokes, * (and additional info about the configuration - e.g. 2D/3D?) */ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* only editable and visible layers are considered */ if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { - bGPDframe *gpf = gpl->actframe; + bGPDframe *gpf; bGPDstroke *gps; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { - continue; - } + for (gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + for (gps = gpf->strokes.first; gps; gps = gps->next) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { + continue; + } - if (is_prop_edit) { - /* Proportional Editing... */ - if (is_prop_edit_connected) { - /* connected only - so only if selected */ - if (gps->flag & GP_STROKE_SELECT) - tc->data_len += gps->totpoints; - } - else { - /* everything goes - connection status doesn't matter */ - tc->data_len += gps->totpoints; - } - } - else { - /* only selected stroke points are considered */ - if (gps->flag & GP_STROKE_SELECT) { - bGPDspoint *pt; - int i; - - // TODO: 2D vs 3D? - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) - tc->data_len++; + if (is_prop_edit) { + /* Proportional Editing... */ + if (is_prop_edit_connected) { + /* connected only - so only if selected */ + if (gps->flag & GP_STROKE_SELECT) + tc->data_len += gps->totpoints; + } + else { + /* everything goes - connection status doesn't matter */ + tc->data_len += gps->totpoints; + } + } + else { + /* only selected stroke points are considered */ + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + int i; + + // TODO: 2D vs 3D? + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) + tc->data_len++; + } + } } } } + /* if not multiedit out of loop */ + if (!is_multiedit) { + break; + } } } } @@ -8180,153 +8207,166 @@ static void createTransGPencil(bContext *C, TransInfo *t) float diff_mat[4][4]; float inverse_diff_mat[4][4]; - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - /* undo matrix */ - invert_m4_m4(inverse_diff_mat, diff_mat); + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; } + /* init multiframe falloff options */ + int f_init = 0; + int f_end = 0; + + if (use_multiframe_falloff) { + BKE_gpencil_get_range_selected(gpl, &f_init, &f_end); + } + + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, obact, gpd, gpl, diff_mat); + /* undo matrix */ + invert_m4_m4(inverse_diff_mat, diff_mat); /* Make a new frame to work on if the layer's frame and the current scene frame don't match up * - This is useful when animating as it saves that "uh-oh" moment when you realize you've * spent too much time editing the wrong frame... */ - if (gpf->framenum != cfra) { + // XXX: should this be allowed when framelock is enabled? + if ((gpf->framenum != cfra) && (!is_multiedit)) { gpf = BKE_gpencil_frame_addcopy(gpl, cfra); /* in some weird situations (framelock enabled) return NULL */ if (gpf == NULL) { continue; } + if (!is_multiedit) { + init_gpf = gpf; + } } /* Loop over strokes, adding TransData for points as needed... */ - for (gps = gpf->strokes.first; gps; gps = gps->next) { - TransData *head = td; - TransData *tail = td; - bool stroke_ok; - - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps) == false) { - continue; - } - /* What we need to include depends on proportional editing settings... */ - if (is_prop_edit) { - if (is_prop_edit_connected) { - /* A) "Connected" - Only those in selected strokes */ - stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; - } - else { - /* B) All points, always */ - stroke_ok = true; - } - } - else { - /* C) Only selected points in selected strokes */ - stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; - } - - /* Do stroke... */ - if (stroke_ok && gps->totpoints) { - bGPDspoint *pt; - int i; - -#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or is_prop_edit breaks */ - const float ninv = 1.0f / gps->totpoints; - float center[3] = {0.0f}; - - /* compute midpoint of stroke */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - madd_v3_v3v3fl(center, center, &pt->x, ninv); + for (gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + + /* if multiframe and falloff, recalculate and save value */ + float falloff = 1.0f; /* by default no falloff */ + if ((is_multiedit) && (use_multiframe_falloff)) { + /* Faloff depends on distance to active frame (relative to the overall frame range) */ + falloff = BKE_gpencil_multiframe_falloff_calc(gpf, gpl->actframe->framenum, + f_init, f_end, ts->gp_sculpt.cur_falloff); } -#endif - /* add all necessary points... */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - bool point_ok; + for (gps = gpf->strokes.first; gps; gps = gps->next) { + TransData *head = td; + TransData *tail = td; + bool stroke_ok; - /* include point? */ + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; + } + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { + continue; + } + /* What we need to include depends on proportional editing settings... */ if (is_prop_edit) { - /* Always all points in strokes that get included */ - point_ok = true; + if (is_prop_edit_connected) { + /* A) "Connected" - Only those in selected strokes */ + stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; + } + else { + /* B) All points, always */ + stroke_ok = true; + } } else { - /* Only selected points in selected strokes */ - point_ok = (pt->flag & GP_SPOINT_SELECT) != 0; + /* C) Only selected points in selected strokes */ + stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0; } - /* do point... */ - if (point_ok) { - copy_v3_v3(td->iloc, &pt->x); - copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local? - - td->loc = &pt->x; - - td->flag = 0; + /* Do stroke... */ + if (stroke_ok && gps->totpoints) { + bGPDspoint *pt; + int i; - if (pt->flag & GP_SPOINT_SELECT) - td->flag |= TD_SELECTED; - - /* for other transform modes (e.g. shrink-fatten), need to additional data */ - if (t->mode == TFM_GPENCIL_SHRINKFATTEN) { - td->val = &pt->pressure; - td->ival = pt->pressure; - } + /* save falloff factor */ + gps->runtime.multi_frame_falloff = falloff; - /* screenspace needs special matrices... */ - if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) == 0) { - /* screenspace */ - td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ; + /* add all necessary points... */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + bool point_ok; - /* apply parent transformations */ - if (gpl->parent == NULL) { - copy_m3_m4(td->smtx, t->persmat); - copy_m3_m4(td->mtx, t->persinv); - unit_m3(td->axismtx); + /* include point? */ + if (is_prop_edit) { + /* Always all points in strokes that get included */ + point_ok = true; } else { - /* apply matrix transformation relative to parent */ - copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */ - copy_m3_m4(td->mtx, diff_mat); /* display position */ - copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */ - } - } - else { - /* configure 2D dataspace points so that they don't play up... */ - if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) { - td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ; - // XXX: matrices may need to be different? + /* Only selected points in selected strokes */ + point_ok = (pt->flag & GP_SPOINT_SELECT) != 0; } - /* apply parent transformations */ - if (gpl->parent == NULL) { - copy_m3_m3(td->smtx, smtx); - copy_m3_m3(td->mtx, mtx); - unit_m3(td->axismtx); // XXX? - } - else { - /* apply matrix transformation relative to parent */ - copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */ - copy_m3_m4(td->mtx, diff_mat); /* display position */ - copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */ + /* do point... */ + if (point_ok) { + copy_v3_v3(td->iloc, &pt->x); + copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local? + + td->loc = &pt->x; + + td->flag = 0; + + if (pt->flag & GP_SPOINT_SELECT) + td->flag |= TD_SELECTED; + + /* for other transform modes (e.g. shrink-fatten), need to additional data + * but never for scale or mirror + */ + if ((t->mode != TFM_RESIZE) && (t->mode != TFM_MIRROR)) { + td->val = &pt->pressure; + td->ival = pt->pressure; + } + + /* screenspace needs special matrices... */ + if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) == 0) { + /* screenspace */ + td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ; + + /* apply matrix transformation relative to parent */ + copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */ + copy_m3_m4(td->mtx, diff_mat); /* display position */ + copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */ + } + else { + /* configure 2D dataspace points so that they don't play up... */ + if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) { + td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ; + // XXX: matrices may need to be different? + } + + /* apply parent transformations */ + copy_m3_m4(td->smtx, inverse_diff_mat); /* final position */ + copy_m3_m4(td->mtx, diff_mat); /* display position */ + copy_m3_m4(td->axismtx, diff_mat); /* axis orientation */ + } + /* Triangulation must be calculated again, so save the stroke for recalc function */ + td->extra = gps; + + /* save pointer to object */ + td->ob = obact; + + td++; + tail++; } } - /* Triangulation must be calculated again, so save the stroke for recalc function */ - td->extra = gps; - td++; - tail++; + /* March over these points, and calculate the proportional editing distances */ + if (is_prop_edit && (head != tail)) { + /* XXX: for now, we are similar enough that this works... */ + calc_distanceCurveVerts(head, tail - 1); + } } } - - /* March over these points, and calculate the proportional editing distances */ - if (is_prop_edit && (head != tail)) { - /* XXX: for now, we are similar enough that this works... */ - calc_distanceCurveVerts(head, tail - 1); - } + } + /* if not multiedit out of loop */ + if (!is_multiedit) { + break; } } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 3618d57b3ed..a2377166dff 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -74,6 +74,7 @@ #include "BKE_armature.h" #include "BKE_curve.h" #include "BKE_fcurve.h" +#include "BKE_gpencil.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_main.h" @@ -105,6 +106,7 @@ #include "ED_curve.h" /* for curve_editnurbs */ #include "ED_clip.h" #include "ED_screen.h" +#include "ED_gpencil.h" #include "WM_types.h" #include "WM_api.h" @@ -379,7 +381,8 @@ static void recalcData_actedit(TransInfo *t) /* flush transform values back to actual coordinates */ flushTransIntFrameActionData(t); } - else { + + if (ac.datatype != ANIMCONT_MASK) { /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ANIMDATA); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); @@ -1311,7 +1314,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } /* GPencil editing context */ - if ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)) { + if (GPENCIL_ANY_MODE(gpd)) { t->options |= CTX_GPENCIL_STROKES; } @@ -1823,6 +1826,21 @@ void calculateCenterCursor(TransInfo *t, float r_center[3]) } r_center[2] = 0.0f; } + else if (t->options & CTX_GPENCIL_STROKES) { + /* move cursor in local space */ + TransData *td = NULL; + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + float mat[3][3], imat[3][3]; + + td = tc->data; + Object *ob = td->ob; + + sub_v3_v3v3(r_center, r_center, ob->obmat[3]); + copy_m3_m4(mat, ob->obmat); + invert_m3_m3(imat, mat); + mul_m3_v3(imat, r_center); + } + } } void calculateCenterCursor2D(TransInfo *t, float r_center[2]) diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index cbc2b312512..3b5d7d5871a 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -604,6 +604,7 @@ int ED_transform_calc_gizmo_stats( ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); View3D *v3d = sa->spacedata.first; @@ -611,7 +612,7 @@ int ED_transform_calc_gizmo_stats( Base *base; Object *ob = OBACT(view_layer); bGPdata *gpd = CTX_data_gpencil_data(C); - const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE)); + const bool is_gp_edit = GPENCIL_ANY_MODE(gpd); int a, totsel = 0; const int pivot_point = scene->toolsettings->transform_pivot_point; @@ -728,10 +729,8 @@ int ED_transform_calc_gizmo_stats( /* only editable and visible layers are considered */ if (gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) { - /* calculate difference matrix if parent object */ - if (gpl->parent != NULL) { - ED_gpencil_parent_location(gpl, diff_mat); - } + /* calculate difference matrix */ + ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, diff_mat); for (bGPDstroke *gps = gpl->actframe->strokes.first; gps; gps = gps->next) { /* skip strokes that are invalid for current view */ diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index a6e857c4a60..bc35e6e6b89 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2280,7 +2280,12 @@ static short snapObject( dist_px, r_loc, r_no, r_index); break; - + case OB_GPENCIL: + retval = snapEmpty( + snapdata, ob, obmat, + dist_px, + r_loc, r_no, r_index); + break; case OB_CAMERA: retval = snapCamera( sctx, snapdata, ob, obmat, diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 14592149579..7c1dc148dde 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -51,9 +51,12 @@ #include "BKE_screen.h" #include "BKE_layer.h" #include "BKE_undo_system.h" +#include "BKE_workspace.h" +#include "BKE_paint.h" #include "ED_gpencil.h" #include "ED_render.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_undo.h" @@ -110,6 +113,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); + ScrArea *sa = CTX_wm_area(C); /* undo during jobs are running can easily lead to freeing data using by jobs, * or they can just lead to freezing job in some other cases */ @@ -122,6 +126,12 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) if (ED_gpencil_session_active()) { return ED_undo_gpencil_step(C, step, undoname); } + if (sa && (sa->spacetype == SPACE_VIEW3D)) { + Object *obact = CTX_data_active_object(C); + if (obact && (obact->type == OB_GPENCIL)) { + ED_gpencil_toggle_brush_cursor(C, false, NULL); + } + } UndoStep *step_data_from_name = NULL; int step_for_callback = step; @@ -156,6 +166,23 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) else { BKE_undosys_step_undo_compat_only(wm->undo_stack, C, step); } + + /* Set special modes for grease pencil */ + if (sa && (sa->spacetype == SPACE_VIEW3D)) { + Object *obact = CTX_data_active_object(C); + if (obact && (obact->type == OB_GPENCIL)) { + /* set cursor */ + if (ELEM(obact->mode, OB_MODE_GPENCIL_PAINT, OB_MODE_GPENCIL_SCULPT, OB_MODE_GPENCIL_WEIGHT)) { + ED_gpencil_toggle_brush_cursor(C, true, NULL); + } + else { + ED_gpencil_toggle_brush_cursor(C, false, NULL); + } + /* set workspace mode */ + Base *basact = CTX_data_active_base(C); + ED_object_base_activate(C, basact); + } + } } /* App-Handlers (post). */ diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt new file mode 100644 index 00000000000..5ad91d4e01b --- /dev/null +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -0,0 +1,70 @@ +# ***** 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) 2018, Blender Foundation +# All rights reserved. +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + intern + ../blenkernel + ../blenlib + ../blenfont + ../depsgraph + ../makesdna + ../makesrna + ../bmesh + ../render/extern/include + ../../../intern/elbeem/extern + ../../../intern/guardedalloc + ../../../intern/eigen +) + +set(INC_SYS + ${ZLIB_INCLUDE_DIRS} +) + +set(SRC + intern/MOD_gpencil_util.h + + intern/MOD_gpencil_util.c + intern/MOD_gpencilnoise.c + intern/MOD_gpencilsubdiv.c + intern/MOD_gpencilsimplify.c + intern/MOD_gpencilthick.c + intern/MOD_gpenciltint.c + intern/MOD_gpencilcolor.c + intern/MOD_gpencilinstance.c + intern/MOD_gpencilbuild.c + intern/MOD_gpencilopacity.c + intern/MOD_gpencillattice.c + intern/MOD_gpencilmirror.c + intern/MOD_gpencilsmooth.c + intern/MOD_gpencilhook.c + intern/MOD_gpenciloffset.c + + MOD_gpencil_modifiertypes.h +) + +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + +add_definitions(${GL_DEFINITIONS}) + +blender_add_lib(bf_gpencil_modifiers "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h new file mode 100644 index 00000000000..ca941017ff9 --- /dev/null +++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h @@ -0,0 +1,53 @@ +/* + * ***** 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. + * + * Contributor(s): Ben Batt + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file MOD_modifiertypes.h + * \ingroup modifiers + */ + +#ifndef __MOD_GP_MODIFIERTYPES_H__ +#define __MOD_GP_MODIFIERTYPES_H__ + +#include "BKE_gpencil_modifier.h" + +/* ****************** Type structures for all modifiers ****************** */ + +extern GpencilModifierTypeInfo modifierType_Gpencil_None; +extern GpencilModifierTypeInfo modifierType_Gpencil_Noise; +extern GpencilModifierTypeInfo modifierType_Gpencil_Subdiv; +extern GpencilModifierTypeInfo modifierType_Gpencil_Simplify; +extern GpencilModifierTypeInfo modifierType_Gpencil_Thick; +extern GpencilModifierTypeInfo modifierType_Gpencil_Tint; +extern GpencilModifierTypeInfo modifierType_Gpencil_Color; +extern GpencilModifierTypeInfo modifierType_Gpencil_Instance; +extern GpencilModifierTypeInfo modifierType_Gpencil_Build; +extern GpencilModifierTypeInfo modifierType_Gpencil_Opacity; +extern GpencilModifierTypeInfo modifierType_Gpencil_Lattice; +extern GpencilModifierTypeInfo modifierType_Gpencil_Mirror; +extern GpencilModifierTypeInfo modifierType_Gpencil_Smooth; +extern GpencilModifierTypeInfo modifierType_Gpencil_Hook; +extern GpencilModifierTypeInfo modifierType_Gpencil_Offset; + +/* MOD_gpencil_util.c */ +void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]); + +#endif /* __MOD_GP_MODIFIERTYPES_H__ */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c new file mode 100644 index 00000000000..97d28863095 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -0,0 +1,142 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/modifiers/intern/MOD_gpencil_util.c + * \ingroup bke + */ + + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" +#include "BLI_math_color.h" +#include "BLI_rand.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_global.h" +#include "BKE_object.h" +#include "BKE_lattice.h" +#include "BKE_material.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_colortools.h" + +#include "MOD_gpencil_modifiertypes.h" +#include "MOD_gpencil_util.h" + +void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]) +{ +#define INIT_GP_TYPE(typeName) (types[eGpencilModifierType_##typeName] = &modifierType_Gpencil_##typeName) + INIT_GP_TYPE(Noise); + INIT_GP_TYPE(Subdiv); + INIT_GP_TYPE(Simplify); + INIT_GP_TYPE(Thick); + INIT_GP_TYPE(Tint); + INIT_GP_TYPE(Color); + INIT_GP_TYPE(Instance); + INIT_GP_TYPE(Build); + INIT_GP_TYPE(Opacity); + INIT_GP_TYPE(Lattice); + INIT_GP_TYPE(Mirror); + INIT_GP_TYPE(Smooth); + INIT_GP_TYPE(Hook); + INIT_GP_TYPE(Offset); +#undef INIT_GP_TYPE +} + +/* verify if valid layer and pass index */ +bool is_stroke_affected_by_modifier( + Object *ob, char *mlayername, int mpassindex, int minpoints, + bGPDlayer *gpl, bGPDstroke *gps, bool inv1, bool inv2) +{ + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + + /* omit if filter by layer */ + if (mlayername[0] != '\0') { + if (inv1 == false) { + if (!STREQ(mlayername, gpl->info)) { + return false; + } + } + else { + if (STREQ(mlayername, gpl->info)) { + return false; + } + } + } + /* verify pass */ + if (mpassindex > 0) { + if (inv2 == false) { + if (gp_style->index != mpassindex) { + return false; + } + } + else { + if (gp_style->index == mpassindex) { + return false; + } + } + } + /* need to have a minimum number of points */ + if ((minpoints > 0) && (gps->totpoints < minpoints)) { + return false; + } + + return true; +} + +/* verify if valid vertex group *and return weight */ +float get_modifier_point_weight(MDeformVert *dvert, int inverse, int vindex) +{ + float weight = 1.0f; + + if (vindex >= 0) { + weight = BKE_gpencil_vgroup_use_index(dvert, vindex); + if ((weight >= 0.0f) && (inverse == 1)) { + return -1.0f; + } + + if ((weight < 0.0f) && (inverse == 0)) { + return -1.0f; + } + + /* if inverse, weight is always 1 */ + if ((weight < 0.0f) && (inverse == 1)) { + return 1.0f; + } + + } + + return weight; +} diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h new file mode 100644 index 00000000000..50ac557042d --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h @@ -0,0 +1,47 @@ +/* + * ***** 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) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/modifiers/intern/MOD_gpencil_util.h + * \ingroup modifiers + */ + + +#ifndef __MOD_GPENCIL_UTIL_H__ +#define __MOD_GPENCIL_UTIL_H__ + +struct Object; +struct bGPDlayer; +struct bGPDstroke; +struct MDeformVert; + +bool is_stroke_affected_by_modifier( + struct Object *ob, char *mlayername, int mpassindex, int minpoints, + bGPDlayer *gpl, bGPDstroke *gps, bool inv1, bool inv2); + +float get_modifier_point_weight(struct MDeformVert *dvert, int inverse, int vindex); + +#endif /* __MOD_GPENCIL_UTIL_H__ */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c new file mode 100644 index 00000000000..6b959659a60 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -0,0 +1,558 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilbuild.c + * \ingroup modifiers + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + BuildGpencilModifierData *gpmd = (BuildGpencilModifierData *)md; + + /* We deliberately set this range to the half the default + * frame-range to have an immediate effect ot suggest use-cases + */ + gpmd->start_frame = 1; + gpmd->end_frame = 125; + + /* Init default length of each build effect - Nothing special */ + gpmd->start_delay = 0.0f; + gpmd->length = 100.0f; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static bool dependsOnTime(GpencilModifierData *UNUSED(md)) +{ + return true; +} + +/* ******************************************** */ +/* Build Modifier - Stroke generation logic + * + * There are two modes for how the strokes are sequenced (at a macro-level): + * - Sequential Mode - Strokes appear/disappear one after the other. Only a single one changes at a time. + * - Concurrent Mode - Multiple strokes appear/disappear at once. + * + * Assumptions: + * - Stroke points are generally equally spaced. This implies that we can just add/remove points, + * without worrying about distances between them / adding extra interpolated points between + * an visible point and one about to be added/removed (or any similar tapering effects). + + * - All strokes present are fully visible (i.e. we don't have to ignore any) + */ + +/* Remove a particular stroke */ +static void clear_stroke(bGPDframe *gpf, bGPDstroke *gps) +{ + BLI_remlink(&gpf->strokes, gps); + BKE_gpencil_free_stroke(gps); +} + +/* Clear all strokes in frame */ +static void gpf_clear_all_strokes(bGPDframe *gpf) +{ + bGPDstroke *gps, *gps_next; + for (gps = gpf->strokes.first; gps; gps = gps_next) { + gps_next = gps->next; + clear_stroke(gpf, gps); + } + BLI_listbase_clear(&gpf->strokes); +} + +/* Reduce the number of points in the stroke + * + * Note: This won't be called if all points are present/removed + * TODO: Allow blending of growing/shrinking tip (e.g. for more gradual transitions) + */ +static void reduce_stroke_points(bGPDstroke *gps, const int num_points, const eBuildGpencil_Transition transition) +{ + bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * num_points, __func__); + MDeformVert *new_dvert = MEM_callocN(sizeof(MDeformVert) * num_points, __func__); + + /* Which end should points be removed from */ + // TODO: free stroke weights + switch (transition) { + case GP_BUILD_TRANSITION_GROW: /* Show in forward order = Remove ungrown-points from end of stroke */ + case GP_BUILD_TRANSITION_SHRINK: /* Hide in reverse order = Remove dead-points from end of stroke */ + { + /* copy over point data */ + memcpy(new_points, gps->points, sizeof(bGPDspoint) * num_points); + memcpy(new_dvert, gps->dvert, sizeof(MDeformVert) * num_points); + + /* free unused point weights */ + for (int i = num_points; i < gps->totpoints; i++) { + MDeformVert *dvert = &gps->dvert[i]; + BKE_gpencil_free_point_weights(dvert); + } + + break; + } + + /* Hide in forward order = Remove points from start of stroke */ + case GP_BUILD_TRANSITION_FADE: + { + /* num_points is the number of points left after reducing. + * We need to know how many to remove + */ + const int offset = gps->totpoints - num_points; + + /* copy over point data */ + memcpy(new_points, gps->points + offset, sizeof(bGPDspoint) * num_points); + memcpy(new_dvert, gps->dvert + offset, sizeof(MDeformVert) * num_points); + + /* free unused weights */ + for (int i = 0; i < offset; i++) { + MDeformVert *dvert = &gps->dvert[i]; + BKE_gpencil_free_point_weights(dvert); + } + + break; + } + + default: + printf("ERROR: Unknown transition %d in %s()\n", (int)transition, __func__); + break; + } + + /* replace stroke geometry */ + MEM_SAFE_FREE(gps->points); + MEM_SAFE_FREE(gps->dvert); + gps->points = new_points; + gps->dvert = new_dvert; + gps->totpoints = num_points; + + /* mark stroke as needing to have its geometry caches rebuilt */ + gps->flag |= GP_STROKE_RECALC_CACHES; + gps->tot_triangles = 0; + MEM_SAFE_FREE(gps->triangles); +} + +/* --------------------------------------------- */ + +/* Stroke Data Table Entry - This represents one stroke being generated */ +typedef struct tStrokeBuildDetails { + bGPDstroke *gps; + + /* Indices - first/last indices for the stroke's points (overall) */ + size_t start_idx, end_idx; + + /* Number of points - Cache for more convenient access */ + int totpoints; +} tStrokeBuildDetails; + + +/* Sequential - Show strokes one after the other */ +static void build_sequential(BuildGpencilModifierData *mmd, bGPDframe *gpf, float fac) +{ + const size_t tot_strokes = BLI_listbase_count(&gpf->strokes); + bGPDstroke *gps; + size_t i; + + /* 1) Compute proportion of time each stroke should occupy */ + /* NOTE: This assumes that the total number of points won't overflow! */ + tStrokeBuildDetails *table = MEM_callocN(sizeof(tStrokeBuildDetails) * tot_strokes, __func__); + size_t totpoints = 0; + + /* 1.1) First pass - Tally up points */ + for (gps = gpf->strokes.first, i = 0; gps; gps = gps->next, i++) { + tStrokeBuildDetails *cell = &table[i]; + + cell->gps = gps; + cell->totpoints = gps->totpoints; + + totpoints += cell->totpoints; + } + + /* 1.2) Second pass - Compute the overall indices for points */ + for (i = 0; i < tot_strokes; i++) { + tStrokeBuildDetails *cell = &table[i]; + + if (i == 0) { + cell->start_idx = 0; + } + else { + cell->start_idx = (cell - 1)->end_idx; + } + cell->end_idx = cell->start_idx + cell->totpoints - 1; + } + + + /* 2) Determine the global indices for points that should be visible */ + size_t first_visible = 0; + size_t last_visible = 0; + + switch (mmd->transition) { + /* Show in forward order + * - As fac increases, the number of visible points increases + */ + case GP_BUILD_TRANSITION_GROW: + first_visible = 0; /* always visible */ + last_visible = (size_t)roundf(totpoints * fac); + break; + + /* Hide in reverse order + * - As fac increases, the number of points visible at the end decreases + */ + case GP_BUILD_TRANSITION_SHRINK: + first_visible = 0; /* always visible (until last point removed) */ + last_visible = (size_t)(totpoints * (1.0f - fac)); + break; + + /* Hide in forward order + * - As fac increases, the early points start getting hidden + */ + case GP_BUILD_TRANSITION_FADE: + first_visible = (size_t)(totpoints * fac); + last_visible = totpoints; /* i.e. visible until the end, unless first overlaps this */ + break; + } + + + /* 3) Go through all strokes, deciding which to keep, and/or how much of each to keep */ + for (i = 0; i < tot_strokes; i++) { + tStrokeBuildDetails *cell = &table[i]; + + /* Determine what portion of the stroke is visible */ + if ((cell->end_idx < first_visible) || (cell->start_idx > last_visible)) { + /* Not visible at all - Either ended before */ + clear_stroke(gpf, cell->gps); + } + else { + /* Some proportion of stroke is visible */ + /* XXX: Will the transition settings still be valid now? */ + if ((first_visible <= cell->start_idx) && (last_visible >= cell->end_idx)) { + /* Do nothing - whole stroke is visible */ + } + else if (first_visible > cell->start_idx) { + /* Starts partway through this stroke */ + int num_points = cell->end_idx - first_visible; + reduce_stroke_points(cell->gps, num_points, mmd->transition); + } + else { + /* Ends partway through this stroke */ + int num_points = last_visible - cell->start_idx; + reduce_stroke_points(cell->gps, num_points, mmd->transition); + } + } + } + + /* Free table */ + MEM_freeN(table); +} + +/* --------------------------------------------- */ + +/* Concurrent - Show multiple strokes at once */ +// TODO: Allow random offsets to start times +// TODO: Allow varying speeds? Scaling of progress? +static void build_concurrent(BuildGpencilModifierData *mmd, bGPDframe *gpf, float fac) +{ + bGPDstroke *gps, *gps_next; + int max_points = 0; + + const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW); + + /* 1) Determine the longest stroke, to figure out when short strokes should start */ + /* FIXME: A *really* long stroke here could dwarf everything else, causing bad timings */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + if (gps->totpoints > max_points) { + max_points = gps->totpoints; + } + } + if (max_points == 0) { + printf("ERROR: Strokes are all empty (GP Build Modifier: %s)\n", __func__); + return; + } + + /* 2) For each stroke, determine how it should be handled */ + for (gps = gpf->strokes.first; gps; gps = gps_next) { + gps_next = gps->next; + + /* Relative Length of Stroke - Relative to the longest stroke, + * what proportion of the available time should this stroke use + */ + const float relative_len = (float)gps->totpoints / (float)max_points; + + /* Determine how many points should be left in the stroke */ + int num_points = 0; + + switch (mmd->time_alignment) { + case GP_BUILD_TIMEALIGN_START: /* all start on frame 1 */ + { + /* Build effect occurs over when fac = 0, to fac = relative_len */ + if (fac <= relative_len) { + /* Scale fac to fit relative_len */ + /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */ + const float scaled_fac = fac / relative_len; + + if (reverse) { + num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints); + } + else { + num_points = (int)roundf(scaled_fac * gps->totpoints); + } + } + else { + /* Build effect has ended */ + if (reverse) { + num_points = 0; + } + else { + num_points = gps->totpoints; + } + } + + break; + } + case GP_BUILD_TIMEALIGN_END: /* all end on same frame */ + { + /* Build effect occurs over 1.0 - relative_len, to 1.0 (i.e. over the end of the range) */ + const float start_fac = 1.0f - relative_len; + + if (fac >= start_fac) { + /* FIXME: prevent potential div by zero (e.g. very short stroke vs one very long one) */ + const float scaled_fac = (fac - start_fac) / relative_len; + + if (reverse) { + num_points = (int)roundf((1.0f - scaled_fac) * gps->totpoints); + } + else { + num_points = (int)roundf(scaled_fac * gps->totpoints); + } + } + else { + /* Build effect hasn't started */ + if (reverse) { + num_points = gps->totpoints; + } + else { + num_points = 0; + } + } + + break; + } + + /* TODO... */ + } + + /* Modify the stroke geometry */ + if (num_points <= 0) { + /* Nothing Left - Delete the stroke */ + clear_stroke(gpf, gps); + } + else if (num_points < gps->totpoints) { + /* Remove some points */ + reduce_stroke_points(gps, num_points, mmd->transition); + } + } +} + +/* --------------------------------------------- */ + +/* Entry-point for Build Modifier */ +static void generateStrokes( + GpencilModifierData *md, Depsgraph *depsgraph, + Object *UNUSED(ob), bGPDlayer *gpl, bGPDframe *gpf) +{ + BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md; + const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW); + + const float ctime = DEG_get_ctime(depsgraph); + //printf("GP Build Modifier - %f\n", ctime); + + /* Early exit if it's an empty frame */ + if (gpf->strokes.first == NULL) { + return; + } + + /* Omit layer if filter by layer */ + if (mmd->layername[0] != '\0') { + if ((mmd->flag & GP_BUILD_INVERT_LAYER) == 0) { + if (!STREQ(mmd->layername, gpl->info)) { + return; + } + } + else { + if (STREQ(mmd->layername, gpl->info)) { + return; + } + } + } + + /* Early exit if outside of the frame range for this modifier + * (e.g. to have one forward, and one backwards modifier) + */ + if (mmd->flag & GP_BUILD_RESTRICT_TIME) { + if ((ctime < mmd->start_frame) || (ctime > mmd->end_frame)) { + return; + } + } + + /* Compute start and end frames for the animation effect + * By default, the upper bound is given by the "maximum length" setting + */ + float start_frame = gpf->framenum + mmd->start_delay; + float end_frame = gpf->framenum + mmd->length; + + if (gpf->next) { + /* Use the next frame or upper bound as end frame, whichever is lower/closer */ + end_frame = MIN2(end_frame, gpf->next->framenum); + } + + + /* Early exit if current frame is outside start/end bounds */ + /* NOTE: If we're beyond the next/prev frames (if existent), then we wouldn't have this problem anyway... */ + if (ctime < start_frame) { + /* Before Start - Animation hasn't started. Display initial state. */ + if (reverse) { + /* 1) Reverse = Start with all, end with nothing. + * ==> Do nothing (everything already present) + */ + } + else { + /* 2) Forward Order = Start with nothing, end with the full frame. + * ==> Free all strokes, and return an empty frame + */ + gpf_clear_all_strokes(gpf); + } + + /* Early exit */ + return; + } + else if (ctime >= end_frame) { + /* Past End - Animation finished. Display final result. */ + if (reverse) { + /* 1) Reverse = Start with all, end with nothing. + * ==> Free all strokes, and return an empty frame + */ + gpf_clear_all_strokes(gpf); + } + else { + /* 2) Forward Order = Start with nothing, end with the full frame. + * ==> Do Nothing (everything already present) + */ + } + + /* Early exit */ + return; + } + + + /* Determine how far along we are between the keyframes */ + float fac = (ctime - start_frame) / (end_frame - start_frame); + //printf(" Progress on %d = %f (%f - %f)\n", gpf->framenum, fac, start_frame, end_frame); + + /* Time management mode */ + switch (mmd->mode) { + case GP_BUILD_MODE_SEQUENTIAL: + build_sequential(mmd, gpf, fac); + break; + + case GP_BUILD_MODE_CONCURRENT: + build_concurrent(mmd, gpf, fac); + break; + + default: + printf("Unsupported build mode (%d) for GP Build Modifier: '%s'\n", mmd->mode, mmd->modifier.name); + break; + } +} + +/* ******************************************** */ + +/* FIXME: Baking the Build Modifier is currently unsupported. + * Adding support for this is more complicated than for other + * modifiers, as to implement this, we'd have to add more frames, + * which would in turn break how the modifier functions. + */ +#if 0 +static void bakeModifier( + Main *bmain, const Depsgraph *UNUSED(depsgraph), + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + + } + } +} +#endif + +/* ******************************************** */ + +GpencilModifierTypeInfo modifierType_Gpencil_Build = { + /* name */ "Build", + /* structName */ "BuildGpencilModifierData", + /* structSize */ sizeof(BuildGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ 0, + + /* copyData */ copyData, + + /* deformStroke */ NULL, + /* generateStrokes */ generateStrokes, + /* bakeModifier */ NULL, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ dependsOnTime, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c new file mode 100644 index 00000000000..af00b24715f --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -0,0 +1,178 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilcolor.c + * \ingroup modifiers + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math_color.h" +#include "BLI_math_vector.h" +#include "BLI_utildefines.h" + +#include "BKE_global.h" +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md; + gpmd->pass_index = 0; + ARRAY_SET_ITEMS(gpmd->hsv, 1.0f, 1.0f, 1.0f); + gpmd->layername[0] = '\0'; + gpmd->flag |= GP_COLOR_CREATE_COLORS; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* color correction strokes */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + + ColorGpencilModifierData *mmd = (ColorGpencilModifierData *)md; + float hsv[3], factor[3]; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_COLOR_INVERT_LAYER, mmd->flag & GP_COLOR_INVERT_PASS)) + { + return; + } + + copy_v3_v3(factor, mmd->hsv); + add_v3_fl(factor, -1.0f); + + rgb_to_hsv_v(gps->runtime.tmp_stroke_rgba, hsv); + add_v3_v3(hsv, factor); + CLAMP3(hsv, 0.0f, 1.0f); + hsv_to_rgb_v(hsv, gps->runtime.tmp_stroke_rgba); + + rgb_to_hsv_v(gps->runtime.tmp_fill_rgba, hsv); + add_v3_v3(hsv, factor); + CLAMP3(hsv, 0.0f, 1.0f); + hsv_to_rgb_v(hsv, gps->runtime.tmp_fill_rgba); +} + +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + ColorGpencilModifierData *mmd = (ColorGpencilModifierData *)md; + bGPdata *gpd = ob->data; + + GHash *gh_color = BLI_ghash_str_new("GP_Color modifier"); + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + + Material *mat = give_current_material(ob, gps->mat_nr + 1); + if (mat == NULL) + continue; + MaterialGPencilStyle *gp_style = mat->gp_style; + /* skip stroke if it doesn't have color info */ + if (ELEM(NULL, gp_style)) + continue; + + copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); + copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + + /* look for color */ + if (mmd->flag & GP_TINT_CREATE_COLORS) { + Material *newmat = BLI_ghash_lookup(gh_color, mat->id.name); + if (newmat == NULL) { + BKE_object_material_slot_add(bmain, ob); + newmat = BKE_material_copy(bmain, mat); + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + + copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + + BLI_ghash_insert(gh_color, mat->id.name, newmat); + } + /* reasign color index */ + int idx = BKE_object_material_slot_find_index(ob, newmat); + gps->mat_nr = idx - 1; + } + else { + /* reuse existing color */ + copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + } + + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } + /* free hash buffers */ + if (gh_color) { + BLI_ghash_free(gh_color, NULL, NULL); + gh_color = NULL; + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Color = { + /* name */ "Hue/Saturation", + /* structName */ "ColorGpencilModifierData", + /* structSize */ sizeof(ColorGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c new file mode 100644 index 00000000000..e036b6b78be --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -0,0 +1,355 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilhook.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_modifier_types.h" +#include "BLI_math.h" + +#include "BLI_utildefines.h" + +#include "BKE_action.h" +#include "BKE_context.h" +#include "BKE_colortools.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_modifier.h" +#include "BKE_library_query.h" +#include "BKE_scene.h" +#include "BKE_main.h" +#include "BKE_layer.h" + +#include "MEM_guardedalloc.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +/* temp struct to hold data */ +struct GPHookData_cb { + struct CurveMapping *curfalloff; + + char falloff_type; + float falloff; + float falloff_sq; + float fac_orig; + + unsigned int use_falloff : 1; + unsigned int use_uniform : 1; + + float cent[3]; + + float mat_uniform[3][3]; + float mat[4][4]; +}; + +static void initData(GpencilModifierData *md) +{ + HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + gpmd->object = NULL; + gpmd->force = 0.5f; + gpmd->falloff_type = eGPHook_Falloff_Smooth; + gpmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + if (gpmd->curfalloff) { + curvemapping_initialize(gpmd->curfalloff); + } +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + HookGpencilModifierData *gmd = (HookGpencilModifierData *)md; + HookGpencilModifierData *tgmd = (HookGpencilModifierData *)target; + + if (tgmd->curfalloff != NULL) { + curvemapping_free(tgmd->curfalloff); + tgmd->curfalloff = NULL; + } + + BKE_gpencil_modifier_copyData_generic(md, target); + + tgmd->curfalloff = curvemapping_copy(gmd->curfalloff); +} + +/* calculate factor of fallof */ +static float gp_hook_falloff(const struct GPHookData_cb *tData, const float len_sq) +{ + BLI_assert(tData->falloff_sq); + if (len_sq > tData->falloff_sq) { + return 0.0f; + } + else if (len_sq > 0.0f) { + float fac; + + if (tData->falloff_type == eGPHook_Falloff_Const) { + fac = 1.0f; + goto finally; + } + else if (tData->falloff_type == eGPHook_Falloff_InvSquare) { + /* avoid sqrt below */ + fac = 1.0f - (len_sq / tData->falloff_sq); + goto finally; + } + + fac = 1.0f - (sqrtf(len_sq) / tData->falloff); + + switch (tData->falloff_type) { + case eGPHook_Falloff_Curve: + fac = curvemapping_evaluateF(tData->curfalloff, 0, fac); + break; + case eGPHook_Falloff_Sharp: + fac = fac * fac; + break; + case eGPHook_Falloff_Smooth: + fac = 3.0f * fac * fac - 2.0f * fac * fac * fac; + break; + case eGPHook_Falloff_Root: + fac = sqrtf(fac); + break; + case eGPHook_Falloff_Linear: + /* pass */ + break; + case eGPHook_Falloff_Sphere: + fac = sqrtf(2 * fac - fac * fac); + break; + default: + fac = fac; + break; + } + + finally: + return fac * tData->fac_orig; + } + else { + return tData->fac_orig; + } +} + +/* apply point deformation */ +static void gp_hook_co_apply(struct GPHookData_cb *tData, float weight, bGPDspoint *pt) +{ + float fac; + + if (tData->use_falloff) { + float len_sq; + + if (tData->use_uniform) { + float co_uniform[3]; + mul_v3_m3v3(co_uniform, tData->mat_uniform, &pt->x); + len_sq = len_squared_v3v3(tData->cent, co_uniform); + } + else { + len_sq = len_squared_v3v3(tData->cent, &pt->x); + } + + fac = gp_hook_falloff(tData, len_sq); + } + else { + fac = tData->fac_orig; + } + + if (fac) { + float co_tmp[3]; + mul_v3_m4v3(co_tmp, tData->mat, &pt->x); + interp_v3_v3v3(&pt->x, &pt->x, co_tmp, fac * weight); + } +} + +/* deform stroke */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; + if (!mmd->object) { + return; + } + + int vindex = defgroup_name_index(ob, mmd->vgname); + float weight = 1.0f; + + bPoseChannel *pchan = BKE_pose_channel_find_name(mmd->object->pose, mmd->subtarget); + float dmat[4][4]; + struct GPHookData_cb tData; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_HOOK_INVERT_LAYER, mmd->flag & GP_HOOK_INVERT_PASS)) + { + return; + } + + /* init struct */ + tData.curfalloff = mmd->curfalloff; + tData.falloff_type = mmd->falloff_type; + tData.falloff = (mmd->falloff_type == eHook_Falloff_None) ? 0.0f : mmd->falloff; + tData.falloff_sq = SQUARE(tData.falloff); + tData.fac_orig = mmd->force; + tData.use_falloff = (tData.falloff_sq != 0.0f); + tData.use_uniform = (mmd->flag & GP_HOOK_UNIFORM_SPACE) != 0; + + if (tData.use_uniform) { + copy_m3_m4(tData.mat_uniform, mmd->parentinv); + mul_v3_m3v3(tData.cent, tData.mat_uniform, mmd->cent); + } + else { + unit_m3(tData.mat_uniform); + copy_v3_v3(tData.cent, mmd->cent); + } + + /* get world-space matrix of target, corrected for the space the verts are in */ + if (mmd->subtarget[0] && pchan) { + /* bone target if there's a matching pose-channel */ + mul_m4_m4m4(dmat, mmd->object->obmat, pchan->pose_mat); + } + else { + /* just object target */ + copy_m4_m4(dmat, mmd->object->obmat); + } + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_series(tData.mat, ob->imat, dmat, mmd->parentinv); + + /* loop points and apply deform */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_HOOK_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + gp_hook_co_apply(&tData, weight, pt); + } +} + +/* FIXME: Ideally we be doing this on a copy of the main depsgraph + * (i.e. one where we don't have to worry about restoring state) + */ +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + bGPdata *gpd = ob->data; + int oldframe = (int)DEG_get_ctime(depsgraph); + + if (mmd->object == NULL) + return; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* apply hook effects on this frame + * NOTE: this assumes that we don't want hook animation on non-keyframed frames + */ + CFRA = gpf->framenum; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); + + /* compute hook effects on this frame */ + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } + + /* return frame state and DB to original state */ + CFRA = oldframe; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); +} + +static void freeData(GpencilModifierData *md) +{ + HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; + + if (mmd->curfalloff) { + curvemapping_free(mmd->curfalloff); + } +} + +static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) +{ + HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; + + return !mmd->object; +} + +static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + HookGpencilModifierData *lmd = (HookGpencilModifierData *)md; + if (lmd->object != NULL) { + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Hook Modifier"); + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); + } + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); +} + +static void foreachObjectLink( + GpencilModifierData *md, Object *ob, + ObjectWalkFunc walk, void *userData) +{ + HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; + + walk(userData, ob, &mmd->object, IDWALK_CB_NOP); +} + +GpencilModifierTypeInfo modifierType_Gpencil_Hook = { + /* name */ "Hook", + /* structName */ "HookGpencilModifierData", + /* structSize */ sizeof(HookGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ 0, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ freeData, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c new file mode 100644 index 00000000000..64f3fbc4a95 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c @@ -0,0 +1,360 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez, Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilinstance.c + * \ingroup modifiers + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_rand.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_object.h" +#include "BKE_main.h" +#include "BKE_scene.h" +#include "BKE_layer.h" +#include "BKE_collection.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + InstanceGpencilModifierData *gpmd = (InstanceGpencilModifierData *)md; + gpmd->count[0] = 1; + gpmd->count[1] = 1; + gpmd->count[2] = 1; + gpmd->offset[0] = 1.0f; + gpmd->offset[1] = 1.0f; + gpmd->offset[2] = 1.0f; + gpmd->shift[0] = 0.0f; + gpmd->shift[1] = 0.0f; + gpmd->shift[2] = 0.0f; + gpmd->scale[0] = 1.0f; + gpmd->scale[1] = 1.0f; + gpmd->scale[2] = 1.0f; + gpmd->rnd_rot = 0.5f; + gpmd->rnd_size = 0.5f; + gpmd->lock_axis |= GP_LOCKAXIS_X; + gpmd->flag |= GP_INSTANCE_MAKE_OBJECTS; + + /* fill random values */ + BLI_array_frand(gpmd->rnd, 20, 1); + gpmd->rnd[0] = 1; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* -------------------------------- */ + +/* array modifier - generate geometry callback (for viewport/rendering) */ +/* TODO: How to skip this for the simplify options? --> !GP_SIMPLIFY_MODIF(ts, playing) */ +static void generate_geometry( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDframe *gpf) +{ + InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; + ListBase stroke_cache = {NULL, NULL}; + bGPDstroke *gps; + int idx; + + /* Check which strokes we can use once, and store those results in an array + * for quicker checking of what's valid (since string comparisons are expensive) + */ + const int num_strokes = BLI_listbase_count(&gpf->strokes); + int num_valid = 0; + + bool *valid_strokes = MEM_callocN(sizeof(bool) * num_strokes, __func__); + + for (gps = gpf->strokes.first, idx = 0; gps; gps = gps->next, idx++) { + /* Record whether this stroke can be used + * ATTENTION: The logic here is the inverse of what's used everywhere else! + */ + if (is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_INSTANCE_INVERT_LAYER, mmd->flag & GP_INSTANCE_INVERT_PASS)) + { + valid_strokes[idx] = true; + num_valid++; + } + } + + /* Early exit if no strokes can be copied */ + if (num_valid == 0) { + if (G.debug & G_DEBUG) { + printf("GP Array Mod - No strokes to be included\n"); + } + + MEM_SAFE_FREE(valid_strokes); + return; + } + + + /* Generate new instances of all existing strokes, + * keeping each instance together so they maintain + * the correct ordering relative to each other + */ + for (int x = 0; x < mmd->count[0]; x++) { + for (int y = 0; y < mmd->count[1]; y++) { + for (int z = 0; z < mmd->count[2]; z++) { + /* original strokes are at index = 0,0,0 */ + if ((x == 0) && (y == 0) && (z == 0)) { + continue; + } + + /* Compute transforms for this instance */ + const int elem_idx[3] = {x, y, z}; + float mat[4][4]; + + BKE_gpencil_instance_modifier_instance_tfm(mmd, elem_idx, mat); + + /* apply shift */ + int sh = x; + if (mmd->lock_axis == GP_LOCKAXIS_Y) { + sh = y; + } + if (mmd->lock_axis == GP_LOCKAXIS_Z) { + sh = z; + } + madd_v3_v3fl(mat[3], mmd->shift, sh); + + /* Duplicate original strokes to create this instance */ + for (gps = gpf->strokes.first, idx = 0; gps; gps = gps->next, idx++) { + /* check if stroke can be duplicated */ + if (valid_strokes[idx]) { + /* Duplicate stroke */ + bGPDstroke *gps_dst = MEM_dupallocN(gps); + gps_dst->points = MEM_dupallocN(gps->points); + gps_dst->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, gps_dst); + + gps_dst->triangles = MEM_dupallocN(gps->triangles); + + /* Move points */ + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps_dst->points[i]; + mul_m4_v3(mat, &pt->x); + } + + /* Add new stroke to cache, to be added to the frame once + * all duplicates have been made + */ + BLI_addtail(&stroke_cache, gps_dst); + } + } + } + } + } + + /* merge newly created stroke instances back into the main stroke list */ + BLI_movelisttolist(&gpf->strokes, &stroke_cache); + + /* free temp data */ + MEM_SAFE_FREE(valid_strokes); +} + +/* bakeModifier - "Bake to Data" Mode */ +static void bakeModifierGP_strokes( + Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + generate_geometry(md, depsgraph, ob, gpl, gpf); + } + } +} + +/* -------------------------------- */ + +/* helper to create a new object */ +static Object *array_instance_add_ob_copy(Main *bmain, Scene *scene, Object *from_ob) +{ + Object *ob; + + ob = BKE_object_copy(bmain, from_ob); + BKE_collection_object_add_from(bmain, scene, from_ob, ob); + + zero_v3(ob->loc); + zero_v3(ob->rot); + + DEG_id_type_tag(bmain, ID_OB); + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&scene->id, 0); + + return ob; +} + +/* bakeModifier - "Make Objects" Mode */ +static void bakeModifierGP_objects(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) +{ + InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + /* reset random */ + mmd->rnd[0] = 1; + + /* generate instances as objects */ + for (int x = 0; x < mmd->count[0]; x++) { + for (int y = 0; y < mmd->count[1]; y++) { + for (int z = 0; z < mmd->count[2]; z++) { + Object *newob; + GpencilModifierData *fmd; + + const int elem_idx[3] = {x, y, z}; + float mat[4][4], finalmat[4][4]; + int sh; + + /* original strokes are at index = 0,0,0 */ + if ((x == 0) && (y == 0) && (z == 0)) { + continue; + } + + /* compute transform for instance */ + BKE_gpencil_instance_modifier_instance_tfm(mmd, elem_idx, mat); + mul_m4_m4m4(finalmat, ob->obmat, mat); + + /* moves to new origin */ + sh = x; + if (mmd->lock_axis == GP_LOCKAXIS_Y) { + sh = y; + } + if (mmd->lock_axis == GP_LOCKAXIS_Z) { + sh = z; + } + madd_v3_v3fl(finalmat[3], mmd->shift, sh); + + /* Create a new object + * + * NOTE: Copies share the same original GP datablock + * Artists can later user make_single_user on these + * to make them unique (if necessary), without too + * much extra memory usage. + */ + newob = array_instance_add_ob_copy(bmain, scene, ob); + + /* remove array on destination object */ + fmd = (GpencilModifierData *)BLI_findstring(&newob->greasepencil_modifiers, md->name, offsetof(GpencilModifierData, name)); + if (fmd) { + BLI_remlink(&newob->greasepencil_modifiers, fmd); + BKE_gpencil_modifier_free(fmd); + } + + /* copy transforms to destination object */ + copy_m4_m4(newob->obmat, finalmat); + + copy_v3_v3(newob->loc, finalmat[3]); + mat4_to_eul(newob->rot, finalmat); + mat4_to_size(newob->size, finalmat); + } + } + } +} + +/* -------------------------------- */ + +/* Generic "generateStrokes" callback */ +static void generateStrokes( + GpencilModifierData *md, Depsgraph *depsgraph, + Object *ob, bGPDlayer *gpl, bGPDframe *gpf) +{ + InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; + + /* When the "make_objects" flag is set, this modifier is handled as part of the + * draw engine instead. The main benefit is that the instances won't suffer from + * z-ordering problems. + * + * FIXME: Ultimately, the draw-engine hack here shouldn't be necessary, but until + * we find a better fix to the z-ordering problems, it's better to have + * working functionality + */ + if ((mmd->flag & GP_INSTANCE_MAKE_OBJECTS) == 0) { + generate_geometry(md, depsgraph, ob, gpl, gpf); + } +} + +/* Generic "bakeModifier" callback */ +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; + + /* Create new objects or add all to current datablock. + * Sometimes it's useful to have the option to do either of these... + */ + if (mmd->flag & GP_INSTANCE_MAKE_OBJECTS) { + bakeModifierGP_objects(bmain, depsgraph, md, ob); + } + else { + bakeModifierGP_strokes(depsgraph, md, ob); + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Instance = { + /* name */ "Instance", + /* structName */ "InstanceGpencilModifierData", + /* structSize */ sizeof(InstanceGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ 0, + + /* copyData */ copyData, + + /* deformStroke */ NULL, + /* generateStrokes */ generateStrokes, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c new file mode 100644 index 00000000000..944e787020e --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -0,0 +1,213 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencillattice.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_modifier.h" +#include "BKE_lattice.h" +#include "BKE_library_query.h" +#include "BKE_scene.h" +#include "BKE_main.h" +#include "BKE_layer.h" + +#include "MEM_guardedalloc.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +static void initData(GpencilModifierData *md) +{ + LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + gpmd->object = NULL; + gpmd->cache_data = NULL; + gpmd->strength = 1.0f; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + int vindex = defgroup_name_index(ob, mmd->vgname); + float weight = 1.0f; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_LATTICE_INVERT_LAYER, mmd->flag & GP_LATTICE_INVERT_PASS)) + { + return; + } + + if (mmd->cache_data == NULL) { + return; + } + + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_LATTICE_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + + calc_latt_deform((struct LatticeDeformData *)mmd->cache_data, &pt->x, mmd->strength * weight); + } +} + +/* FIXME: Ideally we be doing this on a copy of the main depsgraph + * (i.e. one where we don't have to worry about restoring state) + */ +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + struct LatticeDeformData *ldata = NULL; + bGPdata *gpd = ob->data; + int oldframe = (int)DEG_get_ctime(depsgraph); + + if (mmd->object == NULL) + return; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* apply lattice effects on this frame + * NOTE: this assumes that we don't want lattice animation on non-keyframed frames + */ + CFRA = gpf->framenum; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); + + /* recalculate lattice data */ + BKE_gpencil_lattice_init(ob); + + /* compute lattice effects on this frame */ + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } + + /* free lingering data */ + ldata = (struct LatticeDeformData *)mmd->cache_data; + if (ldata) { + end_latt_deform(ldata); + mmd->cache_data = NULL; + } + + /* return frame state and DB to original state */ + CFRA = oldframe; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); +} + +static void freeData(GpencilModifierData *md) +{ + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + struct LatticeDeformData *ldata = (struct LatticeDeformData *)mmd->cache_data; + /* free deform data */ + if (ldata) { + end_latt_deform(ldata); + } +} + +static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) +{ + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + + return !mmd->object; +} + +static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + LatticeGpencilModifierData *lmd = (LatticeGpencilModifierData *)md; + if (lmd->object != NULL) { + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Lattice Modifier"); + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier"); + } + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier"); +} + +static void foreachObjectLink( + GpencilModifierData *md, Object *ob, + ObjectWalkFunc walk, void *userData) +{ + LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; + + walk(userData, ob, &mmd->object, IDWALK_CB_NOP); +} + +GpencilModifierTypeInfo modifierType_Gpencil_Lattice = { + /* name */ "Lattice", + /* structName */ "LatticeGpencilModifierData", + /* structSize */ sizeof(LatticeGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_Single | eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ freeData, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c new file mode 100644 index 00000000000..9b5186755d6 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -0,0 +1,239 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilmirror.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_modifier.h" +#include "BKE_library_query.h" +#include "BKE_scene.h" +#include "BKE_main.h" +#include "BKE_layer.h" + +#include "MEM_guardedalloc.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" + +static void initData(GpencilModifierData *md) +{ + MirrorGpencilModifierData *gpmd = (MirrorGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->layername[0] = '\0'; + gpmd->object = NULL; + gpmd->flag |= GP_MIRROR_AXIS_X; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static void clip_stroke(MirrorGpencilModifierData *mmd, bGPDstroke *gps) +{ + int i; + bGPDspoint *pt; + float fpt[3]; + if ((mmd->flag & GP_MIRROR_CLIPPING) == 0) { + return; + } + + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + copy_v3_v3(fpt, &pt->x); + for (int xi = 0; xi < 3; ++xi) { + if (mmd->flag & (GP_MIRROR_AXIS_X << xi)) { + if (fpt[xi] >= 0.0f) { + fpt[xi] = 0.0f; + } + } + } + copy_v3_v3(&pt->x, fpt); + } + +} + +static void update_position(Object *ob, MirrorGpencilModifierData *mmd, bGPDstroke *gps, int axis) +{ + int i; + bGPDspoint *pt; + float factor[3] = { 1.0f, 1.0f, 1.0f }; + factor[axis] = -1.0f; + + float clear[3] = { 0.0f, 0.0f, 0.0f }; + clear[axis] = 1.0f; + + float origin[3]; + float mirror_origin[3]; + + copy_v3_v3(origin, ob->loc); + /* only works with current axis */ + mul_v3_v3(origin, clear); + zero_v3(mirror_origin); + + if (mmd->object) { + copy_v3_v3(mirror_origin, mmd->object->loc); + mul_v3_v3(mirror_origin, clear); + sub_v3_v3(origin, mirror_origin); + } + /* clear other axis */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + add_v3_v3(&pt->x, origin); + mul_v3_v3(&pt->x, factor); + add_v3_v3(&pt->x, mirror_origin); + } + +} + +/* Generic "generateStrokes" callback */ +static void generateStrokes( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDframe *gpf) +{ + MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; + bGPDstroke *gps, *gps_new = NULL; + int tot_strokes; + int i; + + /* count strokes to avoid infinite loop after adding new strokes to tail of listbase */ + tot_strokes = BLI_listbase_count(&gpf->strokes); + + for (i = 0, gps = gpf->strokes.first; i < tot_strokes; i++, gps = gps->next) { + if (is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) + { + /* check each axis for mirroring */ + for (int xi = 0; xi < 3; ++xi) { + if (mmd->flag & (GP_MIRROR_AXIS_X << xi)) { + /* clip before duplicate */ + clip_stroke(mmd, gps); + + gps_new = BKE_gpencil_stroke_duplicate(gps); + update_position(ob, mmd, gps_new, xi); + BLI_addtail(&gpf->strokes, gps_new); + } + } + } + } +} + +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + bGPdata *gpd = ob->data; + int oldframe = (int)DEG_get_ctime(depsgraph); + + if (mmd->object == NULL) + return; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + /* apply mirror effects on this frame */ + CFRA = gpf->framenum; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); + + /* compute mirror effects on this frame */ + generateStrokes(md, depsgraph, ob, gpl, gpf); + } + } + + /* return frame state and DB to original state */ + CFRA = oldframe; + BKE_scene_graph_update_for_newframe(depsgraph, bmain); +} + +static bool isDisabled(GpencilModifierData *UNUSED(md), int UNUSED(userRenderParams)) +{ + //MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; + + return false; +} + +static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + MirrorGpencilModifierData *lmd = (MirrorGpencilModifierData *)md; + if (lmd->object != NULL) { + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Mirror Modifier"); + DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Mirror Modifier"); + } + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Mirror Modifier"); +} + +static void foreachObjectLink( + GpencilModifierData *md, Object *ob, + ObjectWalkFunc walk, void *userData) +{ + MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; + + walk(userData, ob, &mmd->object, IDWALK_CB_NOP); +} + +GpencilModifierTypeInfo modifierType_Gpencil_Mirror = { + /* name */ "Mirror", + /* structName */ "MirrorGpencilModifierData", + /* structSize */ sizeof(MirrorGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ NULL, + /* generateStrokes */ generateStrokes, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c new file mode 100644 index 00000000000..37c8bf0b0f0 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -0,0 +1,285 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilnoise.c + * \ingroup modifiers + */ + +#include + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" +#include "BLI_rand.h" + +#include "PIL_time.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_object.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->flag |= GP_NOISE_MOD_LOCATION; + gpmd->flag |= GP_NOISE_FULL_STROKE; + gpmd->flag |= GP_NOISE_USE_RANDOM; + gpmd->factor = 0.5f; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + gpmd->step = 1; + gpmd->scene_frame = -999999; + gpmd->gp_frame = -999999; + + gpmd->vrand1 = 1.0; + gpmd->vrand2 = 1.0; +} + +static void freeData(GpencilModifierData *md) +{ + NoiseGpencilModifierData *mmd = (NoiseGpencilModifierData *)md; + + if (mmd->rng != NULL) { + BLI_rng_free(mmd->rng); + } +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static bool dependsOnTime(GpencilModifierData *md) +{ + NoiseGpencilModifierData *mmd = (NoiseGpencilModifierData *)md; + return (mmd->flag & GP_NOISE_USE_RANDOM) != 0; +} + +/* aply noise effect based on stroke direction */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *depsgraph, + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + NoiseGpencilModifierData *mmd = (NoiseGpencilModifierData *)md; + bGPDspoint *pt0, *pt1; + MDeformVert *dvert; + float shift, vran, vdir; + float normal[3]; + float vec1[3], vec2[3]; +#if 0 + Scene *scene = DEG_get_evaluated_scene(depsgraph); +#endif + int sc_frame = 0; + int sc_diff = 0; + int vindex = defgroup_name_index(ob, mmd->vgname); + float weight = 1.0f; + + /* Random generator, only init once. */ + if (mmd->rng == NULL) { + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= GET_UINT_FROM_POINTER(mmd); + mmd->rng = BLI_rng_new(rng_seed); + } + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_NOISE_INVERT_LAYER, mmd->flag & GP_NOISE_INVERT_PASS)) + { + return; + } + + sc_frame = (int)DEG_get_ctime(depsgraph); + + zero_v3(vec2); + + /* calculate stroke normal*/ + BKE_gpencil_stroke_normal(gps, normal); + + /* move points */ + for (int i = 0; i < gps->totpoints; i++) { + if (((i == 0) || (i == gps->totpoints - 1)) && ((mmd->flag & GP_NOISE_MOVE_EXTREME) == 0)) { + continue; + } + + /* last point is special */ + if (i == gps->totpoints) { + dvert = &gps->dvert[i - 2]; + pt0 = &gps->points[i - 2]; + pt1 = &gps->points[i - 1]; + } + else { + dvert = &gps->dvert[i - 1]; + pt0 = &gps->points[i - 1]; + pt1 = &gps->points[i]; + + } + + /* verify vertex group */ + weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_NOISE_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + + /* initial vector (p0 -> p1) */ + sub_v3_v3v3(vec1, &pt1->x, &pt0->x); + vran = len_v3(vec1); + /* vector orthogonal to normal */ + cross_v3_v3v3(vec2, vec1, normal); + normalize_v3(vec2); + /* use random noise */ + if (mmd->flag & GP_NOISE_USE_RANDOM) { + sc_diff = abs(mmd->scene_frame - sc_frame); + /* only recalc if the gp frame change or the number of scene frames is bigger than step */ + if ((!gpl->actframe) || (mmd->gp_frame != gpl->actframe->framenum) || + (sc_diff >= mmd->step)) + { + vran = mmd->vrand1 = BLI_rng_get_float(mmd->rng); + vdir = mmd->vrand2 = BLI_rng_get_float(mmd->rng); + mmd->gp_frame = gpl->actframe->framenum; + mmd->scene_frame = sc_frame; + } + else { + vran = mmd->vrand1; + if (mmd->flag & GP_NOISE_FULL_STROKE) { + vdir = mmd->vrand2; + } + else { + int f = (mmd->vrand2 * 10.0f) + i; + vdir = f % 2; + } + } + } + else { + vran = 1.0f; + if (mmd->flag & GP_NOISE_FULL_STROKE) { + vdir = gps->totpoints % 2; + } + else { + vdir = i % 2; + } + mmd->gp_frame = -999999; + } + + /* apply randomness to location of the point */ + if (mmd->flag & GP_NOISE_MOD_LOCATION) { + /* factor is too sensitive, so need divide */ + shift = ((vran * mmd->factor) / 1000.0f) * weight; + if (vdir > 0.5f) { + mul_v3_fl(vec2, shift); + } + else { + mul_v3_fl(vec2, shift * -1.0f); + } + add_v3_v3(&pt1->x, vec2); + } + + /* apply randomness to thickness */ + if (mmd->flag & GP_NOISE_MOD_THICKNESS) { + if (vdir > 0.5f) { + pt1->pressure -= pt1->pressure * vran * mmd->factor; + } + else { + pt1->pressure += pt1->pressure * vran * mmd->factor; + } + CLAMP_MIN(pt1->pressure, GPENCIL_STRENGTH_MIN); + } + + /* apply randomness to color strength */ + if (mmd->flag & GP_NOISE_MOD_STRENGTH) { + if (vdir > 0.5f) { + pt1->strength -= pt1->strength * vran * mmd->factor; + } + else { + pt1->strength += pt1->strength * vran * mmd->factor; + } + CLAMP_MIN(pt1->strength, GPENCIL_STRENGTH_MIN); + } + /* apply randomness to uv rotation */ + if (mmd->flag & GP_NOISE_MOD_UV) { + if (vdir > 0.5f) { + pt1->uv_rot -= pt1->uv_rot * vran * mmd->factor; + } + else { + pt1->uv_rot += pt1->uv_rot * vran * mmd->factor; + } + CLAMP(pt1->uv_rot, -M_PI_2, M_PI_2); + } + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Noise = { + /* name */ "Noise", + /* structName */ "NoiseGpencilModifierData", + /* structSize */ sizeof(NoiseGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ freeData, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ dependsOnTime, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c new file mode 100644 index 00000000000..8a96c705f08 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -0,0 +1,143 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpenciloffset.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + OffsetGpencilModifierData *gpmd = (OffsetGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + ARRAY_SET_ITEMS(gpmd->loc, 0.0f, 0.0f, 0.0f); + ARRAY_SET_ITEMS(gpmd->rot, 0.0f, 0.0f, 0.0f); + ARRAY_SET_ITEMS(gpmd->scale, 0.0f, 0.0f, 0.0f); +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* change stroke offsetness */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + OffsetGpencilModifierData *mmd = (OffsetGpencilModifierData *)md; + int vindex = defgroup_name_index(ob, mmd->vgname); + + float mat[4][4]; + float loc[3], rot[3], scale[3]; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_OFFSET_INVERT_LAYER, mmd->flag & GP_OFFSET_INVERT_PASS)) + { + return; + } + + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + float weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_OFFSET_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + /* calculate matrix */ + mul_v3_v3fl(loc, mmd->loc, weight); + mul_v3_v3fl(rot, mmd->rot, weight); + mul_v3_v3fl(scale, mmd->scale, weight); + add_v3_fl(scale, 1.0); + loc_eul_size_to_mat4(mat, loc, rot, scale); + + mul_m4_v3(mat, &pt->x); + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Offset = { + /* name */ "Offset", + /* structName */ "OffsetGpencilModifierData", + /* structSize */ sizeof(OffsetGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c new file mode 100644 index 00000000000..bdd651a69fc --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -0,0 +1,171 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilopacity.c + * \ingroup modifiers + */ + +#include + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_material.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->factor = 1.0f; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* opacity strokes */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + OpacityGpencilModifierData *mmd = (OpacityGpencilModifierData *)md; + MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); + int vindex = defgroup_name_index(ob, mmd->vgname); + + if (!is_stroke_affected_by_modifier( + ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_OPACITY_INVERT_LAYER, mmd->flag & GP_OPACITY_INVERT_PASS)) + { + return; + } + + gp_style->fill_rgba[3]*= mmd->factor; + + /* if factor is > 1, then force opacity */ + if (mmd->factor > 1.0f) { + gp_style->stroke_rgba[3] += mmd->factor - 1.0f; + if (gp_style->fill_rgba[3] > 1e-5) { + gp_style->fill_rgba[3] += mmd->factor - 1.0f; + } + } + + CLAMP(gp_style->stroke_rgba[3], 0.0f, 1.0f); + CLAMP(gp_style->fill_rgba[3], 0.0f, 1.0f); + + /* if opacity > 1.0, affect the strength of the stroke */ + if (mmd->factor > 1.0f) { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + float weight = get_modifier_point_weight(dvert, (!(mmd->flag & GP_OPACITY_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + pt->strength += mmd->factor - 1.0f; + } + else { + pt->strength += (mmd->factor - 1.0f) * weight; + } + CLAMP(pt->strength, 0.0f, 1.0f); + } + } + else { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + if (mmd->vgname == NULL) { + pt->strength *= mmd->factor; + } + else { + float weight = get_modifier_point_weight(dvert, (!(mmd->flag & GP_OPACITY_INVERT_VGROUP) == 0), vindex); + if (weight >= 0) { + pt->strength *= mmd->factor * weight; + } + } + CLAMP(pt->strength, 0.0f, 1.0f); + } + } + +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Opacity = { + /* name */ "Opacity", + /* structName */ "OpacityGpencilModifierData", + /* structSize */ sizeof(OpacityGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c new file mode 100644 index 00000000000..f0400e39b73 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c @@ -0,0 +1,123 @@ +/* ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilsimplify.c + * \ingroup modifiers + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_vec_types.h" + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + SimplifyGpencilModifierData *gpmd = (SimplifyGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->step = 1; + gpmd->factor = 0.0f; + gpmd->layername[0] = '\0'; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + SimplifyGpencilModifierData *mmd = (SimplifyGpencilModifierData *)md; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 4, gpl, gps, + mmd->flag & GP_SIMPLIFY_INVERT_LAYER, mmd->flag & GP_SIMPLIFY_INVERT_PASS)) + { + return; + } + + if (mmd->mode == GP_SIMPLIFY_FIXED) { + for (int i = 0; i < mmd->step; i++) { + BKE_gpencil_simplify_fixed(gps); + } + } + else { + /* simplify stroke using Ramer-Douglas-Peucker algorithm */ + BKE_gpencil_simplify_stroke(gps, mmd->factor); + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Simplify = { + /* name */ "Simplify", + /* structName */ "SimplifyGpencilModifierData", + /* structSize */ sizeof(SimplifyGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c new file mode 100644 index 00000000000..b83c8ed98b1 --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -0,0 +1,152 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilsmooth.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->flag |= GP_SMOOTH_MOD_LOCATION; + gpmd->factor = 0.5f; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + gpmd->step = 1; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* aply smooth effect based on stroke direction */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + SmoothGpencilModifierData *mmd = (SmoothGpencilModifierData *)md; + int vindex = defgroup_name_index(ob, mmd->vgname); + float weight = 1.0f; + float val; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_SMOOTH_INVERT_LAYER, mmd->flag & GP_SMOOTH_INVERT_PASS)) + { + return; + } + + /* smooth stroke */ + if (mmd->factor > 0.0f) { + for (int r = 0; r < mmd->step; r++) { + for (int i = 0; i < gps->totpoints; i++) { + // bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + + /* verify vertex group */ + weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_SMOOTH_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + + val = mmd->factor * weight; + /* perform smoothing */ + if (mmd->flag & GP_SMOOTH_MOD_LOCATION) { + BKE_gpencil_smooth_stroke(gps, i, val); + } + if (mmd->flag & GP_SMOOTH_MOD_STRENGTH) { + BKE_gpencil_smooth_stroke_strength(gps, i, val); + } + if ((mmd->flag & GP_SMOOTH_MOD_THICKNESS) && (val > 0)) { + /* thickness need to repeat process several times */ + for (int r2 = 0; r2 < r * 10; r2++) { + BKE_gpencil_smooth_stroke_thickness(gps, i, val); + } + } + if (mmd->flag & GP_SMOOTH_MOD_UV) { + BKE_gpencil_smooth_stroke_uv(gps, i, val); + } + } + } + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Smooth = { + /* name */ "Smooth", + /* structName */ "SmoothGpencilModifierData", + /* structSize */ sizeof(SmoothGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c new file mode 100644 index 00000000000..6fe9c34c06b --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -0,0 +1,193 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilsubdiv.c + * \ingroup modifiers + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + SubdivGpencilModifierData *gpmd = (SubdivGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->level = 1; + gpmd->layername[0] = '\0'; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* subdivide stroke to get more control points */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + SubdivGpencilModifierData *mmd = (SubdivGpencilModifierData *)md; + bGPDspoint *temp_points; + int totnewpoints, oldtotpoints; + int i2; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_SUBDIV_INVERT_LAYER, mmd->flag & GP_SUBDIV_INVERT_PASS)) + { + return; + } + + /* loop as many times as levels */ + for (int s = 0; s < mmd->level; s++) { + totnewpoints = gps->totpoints - 1; + /* duplicate points in a temp area */ + temp_points = MEM_dupallocN(gps->points); + oldtotpoints = gps->totpoints; + + /* resize the points arrys */ + gps->totpoints += totnewpoints; + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints); + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints); + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* move points from last to first to new place */ + i2 = gps->totpoints - 1; + for (int i = oldtotpoints - 1; i > 0; i--) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *pt_final = &gps->points[i2]; + + MDeformVert *dvert = &gps->dvert[i]; + MDeformVert *dvert_final = &gps->dvert[i2]; + + copy_v3_v3(&pt_final->x, &pt->x); + pt_final->pressure = pt->pressure; + pt_final->strength = pt->strength; + pt_final->time = pt->time; + pt_final->flag = pt->flag; + + dvert_final->totweight = dvert->totweight; + dvert_final->dw = dvert->dw; + i2 -= 2; + } + /* interpolate mid points */ + i2 = 1; + for (int i = 0; i < oldtotpoints - 1; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i2]; + MDeformVert *dvert_final = &gps->dvert[i2]; + + /* add a half way point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + pt_final->pressure = interpf(pt->pressure, next->pressure, 0.5f); + pt_final->strength = interpf(pt->strength, next->strength, 0.5f); + CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt_final->time = interpf(pt->time, next->time, 0.5f); + + dvert_final->totweight = 0; + dvert_final->dw = NULL; + i2 += 2; + } + + MEM_SAFE_FREE(temp_points); + + /* move points to smooth stroke (not simple flag )*/ + if ((mmd->flag & GP_SUBDIV_SIMPLE) == 0) { + /* duplicate points in a temp area with the new subdivide data */ + temp_points = MEM_dupallocN(gps->points); + + /* extreme points are not changed */ + for (int i = 0; i < gps->totpoints - 2; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i + 1]; + + /* move point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + } + /* free temp memory */ + MEM_SAFE_FREE(temp_points); + } + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Subdiv = { + /* name */ "Subdivision", + /* structName */ "SubdivGpencilModifierData", + /* structSize */ sizeof(SubdivGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c new file mode 100644 index 00000000000..118cc33255f --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -0,0 +1,171 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpencilthick.c + * \ingroup modifiers + */ + +#include + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_utildefines.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->thickness = 0; + gpmd->layername[0] = '\0'; + gpmd->vgname[0] = '\0'; + gpmd->curve_thickness = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + if (gpmd->curve_thickness) { + curvemapping_initialize(gpmd->curve_thickness); + } +} + +static void freeData(GpencilModifierData *md) +{ + ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; + + if (gpmd->curve_thickness) { + curvemapping_free(gpmd->curve_thickness); + } +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + ThickGpencilModifierData *gmd = (ThickGpencilModifierData *)md; + ThickGpencilModifierData *tgmd = (ThickGpencilModifierData *)target; + + if (tgmd->curve_thickness != NULL) { + curvemapping_free(tgmd->curve_thickness); + tgmd->curve_thickness = NULL; + } + + BKE_gpencil_modifier_copyData_generic(md, target); + + tgmd->curve_thickness = curvemapping_copy(gmd->curve_thickness); +} + +/* change stroke thickness */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + ThickGpencilModifierData *mmd = (ThickGpencilModifierData *)md; + int vindex = defgroup_name_index(ob, mmd->vgname); + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->flag & GP_THICK_INVERT_LAYER, mmd->flag & GP_THICK_INVERT_PASS)) + { + return; + } + + /* if normalize, set stroke thickness */ + if (mmd->flag & GP_THICK_NORMALIZE) { + gps->thickness = mmd->thickness; + } + + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + MDeformVert *dvert = &gps->dvert[i]; + float curvef = 1.0f; + /* verify vertex group */ + float weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_THICK_INVERT_VGROUP) == 0), vindex); + if (weight < 0) { + continue; + } + + if (mmd->flag & GP_THICK_NORMALIZE) { + pt->pressure = 1.0f; + } + else { + if ((mmd->flag & GP_THICK_CUSTOM_CURVE) && (mmd->curve_thickness)) { + /* normalize value to evaluate curve */ + float value = (float)i / (gps->totpoints - 1); + curvef = curvemapping_evaluateF(mmd->curve_thickness, 0, value); + } + + pt->pressure += mmd->thickness * weight * curvef; + CLAMP(pt->strength, 0.0f, 1.0f); + } + } +} + +static void bakeModifier( + struct Main *UNUSED(bmain), Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + bGPdata *gpd = ob->data; + + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Thick = { + /* name */ "Thickness", + /* structName */ "ThickGpencilModifierData", + /* structSize */ sizeof(ThickGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ freeData, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c new file mode 100644 index 00000000000..9d1e9eccb8c --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -0,0 +1,186 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_gpenciltint.c + * \ingroup modifiers + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math_vector.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_material.h" +#include "BKE_main.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + TintGpencilModifierData *gpmd = (TintGpencilModifierData *)md; + gpmd->pass_index = 0; + gpmd->factor = 0.5f; + gpmd->layername[0] = '\0'; + ARRAY_SET_ITEMS(gpmd->rgb, 1.0f, 1.0f, 1.0f); + gpmd->flag |= GP_TINT_CREATE_COLORS; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +/* tint strokes */ +static void deformStroke( + GpencilModifierData *md, Depsgraph *UNUSED(depsgraph), + Object *ob, bGPDlayer *gpl, bGPDstroke *gps) +{ + TintGpencilModifierData *mmd = (TintGpencilModifierData *)md; + + if (!is_stroke_affected_by_modifier(ob, + mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_TINT_INVERT_LAYER, mmd->flag & GP_TINT_INVERT_PASS)) + { + return; + } + + interp_v3_v3v3(gps->runtime.tmp_stroke_rgba, gps->runtime.tmp_stroke_rgba, mmd->rgb, mmd->factor); + interp_v3_v3v3(gps->runtime.tmp_fill_rgba, gps->runtime.tmp_fill_rgba, mmd->rgb, mmd->factor); + + /* if factor is > 1, the alpha must be changed to get full tint */ + if (mmd->factor > 1.0f) { + gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; + if (gps->runtime.tmp_fill_rgba[3] > 1e-5) { + gps->runtime.tmp_fill_rgba[3] += mmd->factor - 1.0f; + } + } + + CLAMP4(gps->runtime.tmp_stroke_rgba, 0.0f, 1.0f); + CLAMP4(gps->runtime.tmp_fill_rgba, 0.0f, 1.0f); + + /* if factor > 1.0, affect the strength of the stroke */ + if (mmd->factor > 1.0f) { + for (int i = 0; i < gps->totpoints; i++) { + bGPDspoint *pt = &gps->points[i]; + pt->strength += mmd->factor - 1.0f; + CLAMP(pt->strength, 0.0f, 1.0f); + } + } +} + +static void bakeModifier( + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) +{ + TintGpencilModifierData *mmd = (TintGpencilModifierData *)md; + bGPdata *gpd = ob->data; + + GHash *gh_color = BLI_ghash_str_new("GP_Tint modifier"); + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + + Material *mat = give_current_material(ob, gps->mat_nr + 1); + if (mat == NULL) + continue; + MaterialGPencilStyle *gp_style = mat->gp_style; + /* skip stroke if it doesn't have color info */ + if (ELEM(NULL, gp_style)) + continue; + + copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); + copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + + /* look for color */ + if (mmd->flag & GP_TINT_CREATE_COLORS) { + Material *newmat = (Material *)BLI_ghash_lookup(gh_color, mat->id.name); + if (newmat == NULL) { + BKE_object_material_slot_add(bmain, ob); + newmat = BKE_material_copy(bmain, mat); + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + + copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + + BLI_ghash_insert(gh_color, mat->id.name, newmat); + } + /* reasign color index */ + int idx = BKE_object_material_slot_find_index(ob, newmat); + gps->mat_nr = idx - 1; + } + else { + /* reuse existing color */ + copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + } + + deformStroke(md, depsgraph, ob, gpl, gps); + } + } + } + /* free hash buffers */ + if (gh_color) { + BLI_ghash_free(gh_color, NULL, NULL); + gh_color = NULL; + } +} + +GpencilModifierTypeInfo modifierType_Gpencil_Tint = { + /* name */ "Tint", + /* structName */ "TintGpencilModifierData", + /* structSize */ sizeof(TintGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 8273f3f1992..b9cc1de447f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -260,6 +260,14 @@ data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC) data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_gpencil_stroke_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_gpencil_stroke_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_gpencil_stroke_geom.glsl SRC) + +data_to_c_simple(shaders/gpu_shader_gpencil_fill_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_gpencil_fill_frag.glsl SRC) + + if(WITH_MOD_SMOKE) add_definitions(-DWITH_SMOKE) endif() diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 7f334cec21f..704abdb13a1 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -346,7 +346,10 @@ typedef enum GPUBuiltinShader { GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */ GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, - /* specialized for UI drawing */ + /* grease pencil drawing */ + GPU_SHADER_GPENCIL_STROKE, + GPU_SHADER_GPENCIL_FILL, + /* specialized for widget drawing */ GPU_SHADER_2D_WIDGET_BASE, GPU_SHADER_2D_WIDGET_BASE_INST, GPU_SHADER_2D_WIDGET_SHADOW, diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 3543c73f71d..0d5183d82ab 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -162,6 +162,13 @@ extern char datatoc_gpu_shader_vsm_store_frag_glsl[]; extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[]; extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[]; +extern char datatoc_gpu_shader_gpencil_stroke_vert_glsl[]; +extern char datatoc_gpu_shader_gpencil_stroke_frag_glsl[]; +extern char datatoc_gpu_shader_gpencil_stroke_geom_glsl[]; + +extern char datatoc_gpu_shader_gpencil_fill_vert_glsl[]; +extern char datatoc_gpu_shader_gpencil_fill_frag_glsl[]; + /* cache of built-in shaders (each is created on first use) */ static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL }; @@ -868,6 +875,13 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) datatoc_gpu_shader_2D_nodelink_frag_glsl }, [GPU_SHADER_2D_NODELINK_INST] = { datatoc_gpu_shader_2D_nodelink_vert_glsl, datatoc_gpu_shader_2D_nodelink_frag_glsl }, + + [GPU_SHADER_GPENCIL_STROKE] = { datatoc_gpu_shader_gpencil_stroke_vert_glsl, + datatoc_gpu_shader_gpencil_stroke_frag_glsl, + datatoc_gpu_shader_gpencil_stroke_geom_glsl }, + + [GPU_SHADER_GPENCIL_FILL] = { datatoc_gpu_shader_gpencil_fill_vert_glsl, + datatoc_gpu_shader_gpencil_fill_frag_glsl }, }; if (builtin_shaders[shader] == NULL) { diff --git a/source/blender/gpu/shaders/gpu_shader_gpencil_fill_frag.glsl b/source/blender/gpu/shaders/gpu_shader_gpencil_fill_frag.glsl new file mode 100644 index 00000000000..328fbbe26a1 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_gpencil_fill_frag.glsl @@ -0,0 +1,166 @@ +uniform vec4 color; +uniform vec4 color2; +uniform int fill_type; +uniform float mix_factor; + +uniform float g_angle; +uniform float g_radius; +uniform float g_boxsize; +uniform vec2 g_scale; +uniform vec2 g_shift; + +uniform float t_angle; +uniform vec2 t_scale; +uniform vec2 t_offset; +uniform int t_mix; +uniform int t_flip; +uniform float t_opacity; + +uniform sampler2D myTexture; + +/* keep this list synchronized with list in DNA_brush_types.h */ +#define SOLID 0 +#define GRADIENT 1 +#define RADIAL 2 +#define CHESS 3 +#define TEXTURE 4 + +in vec2 texCoord_interp; +out vec4 fragColor; +#define texture2D texture + +void set_color(in vec4 color, in vec4 color2, in vec4 tcolor, in float mixv, in float factor, + in int tmix, in int flip, out vec4 ocolor) +{ + /* full color A */ + if (mixv == 1.0) { + if (tmix == 1) { + if (flip == 0) { + ocolor = color; + } + else { + ocolor = tcolor; + } + } + else { + if (flip == 0) { + ocolor = color; + } + else { + ocolor = color2; + } + } + } + /* full color B */ + else if (mixv == 0.0) { + if (tmix == 1) { + if (flip == 0) { + ocolor = tcolor; + } + else { + ocolor = color; + } + } + else { + if (flip == 0) { + ocolor = color2; + } + else { + ocolor = color; + } + } + } + /* mix of colors */ + else { + if (tmix == 1) { + if (flip == 0) { + ocolor = mix(color, tcolor, factor); + } + else { + ocolor = mix(tcolor, color, factor); + } + } + else { + if (flip == 0) { + ocolor = mix(color, color2, factor); + } + else { + ocolor = mix(color2, color, factor); + } + } + } +} + +void main() +{ + vec2 t_center = vec2(0.5, 0.5); + mat2 matrot_tex = mat2(cos(t_angle), -sin(t_angle), sin(t_angle), cos(t_angle)); + vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + t_offset; + vec4 tmp_color = texture2D(myTexture, rot_tex * t_scale); + vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * t_opacity); + vec4 chesscolor; + + /* solid fill */ + if (fill_type == SOLID) { + if (t_mix == 1) { + fragColor = mix(color, text_color, mix_factor); + } + else { + fragColor = color; + } + } + else { + vec2 center = vec2(0.5, 0.5) + g_shift; + mat2 matrot = mat2(cos(g_angle), -sin(g_angle), sin(g_angle), cos(g_angle)); + vec2 rot = (((matrot * (texCoord_interp - center)) + center) * g_scale) + g_shift; + /* gradient */ + if (fill_type == GRADIENT) { + set_color(color, color2, text_color, mix_factor, rot.x - mix_factor + 0.5, t_mix, t_flip, fragColor); + } + /* radial gradient */ + if (fill_type == RADIAL) { + float in_rad = g_radius * mix_factor; + float ex_rad = g_radius - in_rad; + float intensity = 0; + float distance = length((center - texCoord_interp) * g_scale); + if (distance > g_radius) { + discard; + } + if (distance > in_rad) { + intensity = clamp(((distance - in_rad) / ex_rad), 0.0, 1.0); + } + set_color(color, color2, text_color, mix_factor, intensity, t_mix, t_flip, fragColor); + } + /* chessboard */ + if (fill_type == CHESS) { + vec2 pos = rot / g_boxsize; + if ((fract(pos.x) < 0.5 && fract(pos.y) < 0.5) || (fract(pos.x) > 0.5 && fract(pos.y) > 0.5)) { + if (t_flip == 0) { + chesscolor = color; + } + else { + chesscolor = color2; + } + } + else { + if (t_flip == 0) { + chesscolor = color2; + } + else { + chesscolor = color; + } + } + /* mix with texture */ + if (t_mix == 1) { + fragColor = mix(chesscolor, text_color, mix_factor); + } + else { + fragColor = chesscolor; + } + } + /* texture */ + if (fill_type == TEXTURE) { + fragColor = text_color; + } + } +} diff --git a/source/blender/gpu/shaders/gpu_shader_gpencil_fill_vert.glsl b/source/blender/gpu/shaders/gpu_shader_gpencil_fill_vert.glsl new file mode 100644 index 00000000000..2bc381a3689 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_gpencil_fill_vert.glsl @@ -0,0 +1,11 @@ +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec2 texCoord; +out vec2 texCoord_interp; + +void main(void) +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + texCoord_interp = texCoord; +} diff --git a/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_frag.glsl new file mode 100644 index 00000000000..7bb7693d202 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_frag.glsl @@ -0,0 +1,20 @@ +in vec4 mColor; +in vec2 mTexCoord; + +out vec4 fragColor; + +void main() +{ + const vec2 center = vec2(0, 0.5); + vec4 tColor = vec4(mColor); + /* if alpha < 0, then encap */ + if (mColor.a < 0) { + tColor.a = tColor.a * -1.0; + float dist = length(mTexCoord - center); + if (dist > 0.25) { + discard; + } + } + /* Solid */ + fragColor = tColor; +} diff --git a/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl new file mode 100644 index 00000000000..3de1bd838b3 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl @@ -0,0 +1,196 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform vec2 Viewport; +uniform int xraymode; + +layout(lines_adjacency) in; +layout(triangle_strip, max_vertices = 13) out; + +in vec4 finalColor[4]; +in float finalThickness[4]; + +out vec4 mColor; +out vec2 mTexCoord; + +#define GP_XRAY_FRONT 0 +#define GP_XRAY_3DSPACE 1 +#define GP_XRAY_BACK 2 + +/* project 3d point to 2d on screen space */ +vec2 toScreenSpace(vec4 vertex) +{ + return vec2(vertex.xy / vertex.w) * Viewport; +} + +/* get zdepth value */ +float getZdepth(vec4 point) +{ + if (xraymode == GP_XRAY_FRONT) { + return 0.0; + } + if (xraymode == GP_XRAY_3DSPACE) { + return (point.z / point.w); + } + if (xraymode == GP_XRAY_BACK) { + return 1.0; + } + + /* in front by default */ + return 0.0; +} +void main(void) +{ + float MiterLimit = 0.75; + + /* receive 4 points */ + vec4 P0 = gl_in[0].gl_Position; + vec4 P1 = gl_in[1].gl_Position; + vec4 P2 = gl_in[2].gl_Position; + vec4 P3 = gl_in[3].gl_Position; + + /* get the four vertices passed to the shader */ + vec2 sp0 = toScreenSpace(P0); // start of previous segment + vec2 sp1 = toScreenSpace(P1); // end of previous segment, start of current segment + vec2 sp2 = toScreenSpace(P2); // end of current segment, start of next segment + vec2 sp3 = toScreenSpace(P3); // end of next segment + + /* culling outside viewport */ + vec2 area = Viewport * 4.0; + if (sp1.x < -area.x || sp1.x > area.x) return; + if (sp1.y < -area.y || sp1.y > area.y) return; + if (sp2.x < -area.x || sp2.x > area.x) return; + if (sp2.y < -area.y || sp2.y > area.y) return; + + /* determine the direction of each of the 3 segments (previous, current, next) */ + vec2 v0 = normalize(sp1 - sp0); + vec2 v1 = normalize(sp2 - sp1); + vec2 v2 = normalize(sp3 - sp2); + + /* determine the normal of each of the 3 segments (previous, current, next) */ + vec2 n0 = vec2(-v0.y, v0.x); + vec2 n1 = vec2(-v1.y, v1.x); + vec2 n2 = vec2(-v2.y, v2.x); + + /* determine miter lines by averaging the normals of the 2 segments */ + vec2 miter_a = normalize(n0 + n1); // miter at start of current segment + vec2 miter_b = normalize(n1 + n2); // miter at end of current segment + + /* determine the length of the miter by projecting it onto normal and then inverse it */ + float an1 = dot(miter_a, n1); + float bn1 = dot(miter_b, n2); + if (an1 == 0) an1 = 1; + if (bn1 == 0) bn1 = 1; + float length_a = finalThickness[1] / an1; + float length_b = finalThickness[2] / bn1; + if (length_a <= 0.0) length_a = 0.01; + if (length_b <= 0.0) length_b = 0.01; + + /* prevent excessively long miters at sharp corners */ + if (dot(v0, v1) < -MiterLimit) { + miter_a = n1; + length_a = finalThickness[1]; + + /* close the gap */ + if (dot(v0, n1) > 0) { + mTexCoord = vec2(0, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0.5); + mColor = finalColor[1]; + gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + EndPrimitive(); + } + else { + mTexCoord = vec2(0, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0.5); + mColor = finalColor[1]; + gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + EndPrimitive(); + } + } + + if (dot(v1, v2) < -MiterLimit) { + miter_b = n1; + length_b = finalThickness[2]; + } + + /* generate the start endcap (alpha < 0 used as endcap flag)*/ + if (P0 == P2) { + mTexCoord = vec2(1, 0.5); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + vec2 svn1 = normalize(sp1 - sp2) * length_a * 4.0; + gl_Position = vec4((sp1 + svn1) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + gl_Position = vec4((sp1 - (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 1); + mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ; + gl_Position = vec4((sp1 + (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + } + + /* generate the triangle strip */ + mTexCoord = vec2(0, 0); + mColor = finalColor[1]; + gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 1); + mColor = finalColor[1]; + gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = finalColor[2]; + gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 1); + mColor = finalColor[2]; + gl_Position = vec4((sp2 - length_b * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + /* generate the end endcap (alpha < 0 used as endcap flag)*/ + if (P1 == P3) { + mTexCoord = vec2(0, 1); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = vec2(0, 0); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + + mTexCoord = vec2(1, 0.5); + mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ; + vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0; + gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0); + EmitVertex(); + } + + EndPrimitive(); +} diff --git a/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_vert.glsl b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_vert.glsl new file mode 100644 index 00000000000..5f4f56dcca1 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_vert.glsl @@ -0,0 +1,33 @@ +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 ProjectionMatrix; + +uniform float pixsize; /* rv3d->pixsize */ +uniform float pixelsize; /* U.pixelsize */ +uniform int keep_size; +uniform float objscale; +uniform int pixfactor; + +in vec3 pos; +in vec4 color; +in float thickness; + +out vec4 finalColor; +out float finalThickness; + +#define TRUE 1 + +float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor); + +void main(void) +{ + gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 ); + finalColor = color; + + if (keep_size == TRUE) { + finalThickness = thickness; + } + else { + float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize); + finalThickness = max(size * objscale, 1.0); + } +} diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index ec71f28cb23..634819b33ce 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -564,6 +564,7 @@ enum { INDEX_ID_IP, INDEX_ID_AC, INDEX_ID_KE, + INDEX_ID_PAL, INDEX_ID_GD, INDEX_ID_NT, INDEX_ID_IM, @@ -581,7 +582,6 @@ enum { INDEX_ID_TXT, INDEX_ID_SO, INDEX_ID_GR, - INDEX_ID_PAL, INDEX_ID_PC, INDEX_ID_BR, INDEX_ID_PA, diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index fc3b4afe18d..dcb7fbd344b 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -44,6 +44,7 @@ struct CurveMapping; struct MTex; struct Image; +struct Material; typedef struct BrushClone { struct Image *image; /* image for clone tool */ @@ -51,6 +52,109 @@ typedef struct BrushClone { float alpha, pad; /* transparency for drawing of clone image */ } BrushClone; + +typedef struct BrushGpencilSettings { + float draw_smoothfac; /* amount of smoothing to apply to newly created strokes */ + float draw_sensitivity; /* amount of sensivity to apply to newly created strokes */ + float draw_strength; /* amount of alpha strength to apply to newly created strokes */ + float draw_jitter; /* amount of jitter to apply to newly created strokes */ + float draw_angle; /* angle when the brush has full thickness */ + float draw_angle_factor; /* factor to apply when angle change (only 90 degrees) */ + float draw_random_press; /* factor of randomness for pressure */ + float draw_random_strength; /* factor of strength for strength */ + float draw_random_sub; /* factor of randomness for subdivision */ + short draw_smoothlvl; /* number of times to apply smooth factor to new strokes */ + short draw_subdivide; /* number of times to subdivide new strokes */ + short flag; /* internal grease pencil drawing flags */ + + short thick_smoothlvl; /* number of times to apply thickness smooth factor to new strokes */ + float thick_smoothfac; /* amount of thickness smoothing to apply to newly created strokes */ + + float fill_threshold; /* factor for transparency */ + short fill_leak; /* number of pixel to consider the leak is too small (x 2) */ + char pad_1[6]; + + int fill_simplylvl; /* number of simplify steps */ + int fill_draw_mode; /* type of control lines drawing mode */ + int icon_id; /* icon identifier */ + + int input_samples; /* maximum distance before generate new point for very fast mouse movements */ + float uv_random; /* random factor for UV rotation */ + + int brush_type; /* type of brush (draw, fill, erase, etc..) */ + int eraser_mode; /* soft, hard or stroke */ + float active_smooth; /* smooth while drawing factor */ + char pad_2[4]; + + struct CurveMapping *curve_sensitivity; + struct CurveMapping *curve_strength; + struct CurveMapping *curve_jitter; + + /* optional link of material to replace default in context */ + struct Material *material; /* material */ +} BrushGpencilSettings; + +/* BrushGpencilSettings->gp_flag */ +typedef enum eGPDbrush_Flag { + /* brush use pressure */ + GP_BRUSH_USE_PRESSURE = (1 << 0), + /* brush use pressure for alpha factor */ + GP_BRUSH_USE_STENGTH_PRESSURE = (1 << 1), + /* brush use pressure for alpha factor */ + GP_BRUSH_USE_JITTER_PRESSURE = (1 << 2), + /* enable screen cursor */ + GP_BRUSH_ENABLE_CURSOR = (1 << 5), + /* fill hide transparent */ + GP_BRUSH_FILL_HIDE = (1 << 6), + /* show fill help lines */ + GP_BRUSH_FILL_SHOW_HELPLINES = (1 << 7), + /* lazy mouse */ + GP_BRUSH_STABILIZE_MOUSE = (1 << 8), + /* lazy mouse override (internal only) */ + GP_BRUSH_STABILIZE_MOUSE_TEMP = (1 << 9), + /* default eraser brush for quick switch */ + GP_BRUSH_DEFAULT_ERASER = (1 << 10), + /* settings group */ + GP_BRUSH_GROUP_SETTINGS = (1 << 11), + /* Random settings group */ + GP_BRUSH_GROUP_RANDOM = (1 << 12) +} eGPDbrush_Flag; + +/* BrushGpencilSettings->gp_fill_draw_mode */ +typedef enum eGP_FillDrawModes { + GP_FILL_DMODE_BOTH = 0, + GP_FILL_DMODE_STROKE = 1, + GP_FILL_DMODE_CONTROL = 2, +} eGP_FillDrawModes; + +/* BrushGpencilSettings->brush type */ +typedef enum eGP_BrushType { + GP_BRUSH_TYPE_DRAW = 0, + GP_BRUSH_TYPE_FILL = 1, + GP_BRUSH_TYPE_ERASE = 2, +} eGP_BrushType; + +/* BrushGpencilSettings->gp_eraser_mode */ +typedef enum eGP_BrushEraserMode { + GP_BRUSH_ERASER_SOFT = 0, + GP_BRUSH_ERASER_HARD = 1, + GP_BRUSH_ERASER_STROKE = 2, +} eGP_BrushEraserMode; + +/* BrushGpencilSettings default brush icons */ +typedef enum eGP_BrushIcons { + GP_BRUSH_ICON_PENCIL = 1, + GP_BRUSH_ICON_PEN = 2, + GP_BRUSH_ICON_INK = 3, + GP_BRUSH_ICON_INKNOISE = 4, + GP_BRUSH_ICON_BLOCK = 5, + GP_BRUSH_ICON_MARKER = 6, + GP_BRUSH_ICON_FILL = 7, + GP_BRUSH_ICON_ERASE_SOFT = 8, + GP_BRUSH_ICON_ERASE_HARD = 9, + GP_BRUSH_ICON_ERASE_STROKE = 10 +} eGP_BrushIcons; + typedef struct Brush { ID id; @@ -139,8 +243,10 @@ typedef struct Brush { float mask_stencil_pos[2]; float mask_stencil_dimension[2]; -} Brush; + struct BrushGpencilSettings *gpencil_settings; + +} Brush; typedef struct PaletteColor { struct PaletteColor *next, *prev; /* two values, one to store rgb, other to store values for sculpt/weight */ @@ -355,5 +461,6 @@ enum { }; #define MAX_BRUSH_PIXEL_RADIUS 500 +#define GP_MAX_BRUSH_PIXEL_RADIUS 1000 #endif /* __DNA_BRUSH_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 8ed38b0b05d..4f860e16b88 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -99,6 +99,7 @@ typedef enum eCurveMappingPreset { CURVE_PRESET_MID9 = 4, CURVE_PRESET_ROUND = 5, CURVE_PRESET_ROOT = 6, + CURVE_PRESET_GAUSS = 7, } eCurveMappingPreset; /* histogram->mode */ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h new file mode 100644 index 00000000000..150b4a2d9f1 --- /dev/null +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -0,0 +1,404 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_greasepencil_modifier_types.h + * \ingroup DNA + */ + +#ifndef __DNA_GREASEPENCIL_TYPES_H__ +#define __DNA_GREASEPENCIL_TYPES_H__ + +#include "DNA_defs.h" +#include "DNA_listBase.h" + +/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! + * (ONLY ADD NEW ITEMS AT THE END) + */ + +struct RNG; + +typedef enum GpencilModifierType { + eGpencilModifierType_None = 0, + eGpencilModifierType_Noise = 1, + eGpencilModifierType_Subdiv = 2, + eGpencilModifierType_Thick = 3, + eGpencilModifierType_Tint = 4, + eGpencilModifierType_Instance = 5, + eGpencilModifierType_Build = 6, + eGpencilModifierType_Opacity = 7, + eGpencilModifierType_Color = 8, + eGpencilModifierType_Lattice = 9, + eGpencilModifierType_Simplify = 10, + eGpencilModifierType_Smooth = 11, + eGpencilModifierType_Hook = 12, + eGpencilModifierType_Offset = 13, + eGpencilModifierType_Mirror = 14, + NUM_GREASEPENCIL_MODIFIER_TYPES +} GpencilModifierType; + +typedef enum GpencilModifierMode { + eGpencilModifierMode_Realtime = (1 << 0), + eGpencilModifierMode_Render = (1 << 1), + eGpencilModifierMode_Editmode = (1 << 2), + eGpencilModifierMode_Expanded = (1 << 3), +} GpencilModifierMode; + +typedef enum { + /* This modifier has been inserted in local override, and hence can be fully edited. */ + eGpencilModifierFlag_StaticOverride_Local = (1 << 0), +} GpencilModifierFlag; + +typedef struct GpencilModifierData { + struct GpencilModifierData *next, *prev; + + int type, mode; + int stackindex; + short flag; + short pad; + char name[64]; /* MAX_NAME */ + + char *error; +} GpencilModifierData; + +typedef struct NoiseGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* several flags */ + float factor; /* factor of noise */ + int step; /* how many frames before recalculate randoms */ + int gp_frame; /* last gp frame used */ + int scene_frame; /* last scene frame used */ + float vrand1, vrand2; /* random values */ + struct RNG *rng; +} NoiseGpencilModifierData; + +typedef enum eNoiseGpencil_Flag { + GP_NOISE_USE_RANDOM = (1 << 0), + GP_NOISE_MOD_LOCATION = (1 << 1), + GP_NOISE_MOD_STRENGTH = (1 << 2), + GP_NOISE_MOD_THICKNESS = (1 << 3), + GP_NOISE_FULL_STROKE = (1 << 4), + GP_NOISE_MOVE_EXTREME = (1 << 5), + GP_NOISE_INVERT_LAYER = (1 << 6), + GP_NOISE_INVERT_PASS = (1 << 7), + GP_NOISE_INVERT_VGROUP = (1 << 8), + GP_NOISE_MOD_UV = (1 << 9), +} eNoiseGpencil_Flag; + +typedef struct SubdivGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + int level; /* factor of subdivision */ + char pad[4]; +} SubdivGpencilModifierData; + +typedef enum eSubdivGpencil_Flag { + GP_SUBDIV_SIMPLE = (1 << 0), + GP_SUBDIV_INVERT_LAYER = (1 << 1), + GP_SUBDIV_INVERT_PASS = (1 << 2), +} eSubdivGpencil_Flag; + +typedef struct ThickGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + int thickness; /* Thickness change */ + char pad[4]; + struct CurveMapping *curve_thickness; +} ThickGpencilModifierData; + +typedef enum eThickGpencil_Flag { + GP_THICK_INVERT_LAYER = (1 << 0), + GP_THICK_INVERT_PASS = (1 << 1), + GP_THICK_INVERT_VGROUP = (1 << 2), + GP_THICK_CUSTOM_CURVE = (1 << 3), + GP_THICK_NORMALIZE = (1 << 4), +} eThickGpencil_Flag; + +typedef struct TintGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float rgb[3]; /* Tint color */ + float factor; /* Mix factor */ +} TintGpencilModifierData; + +typedef enum eTintGpencil_Flag { + GP_TINT_CREATE_COLORS = (1 << 0), + GP_TINT_INVERT_LAYER = (1 << 1), + GP_TINT_INVERT_PASS = (1 << 2), +} eTintGpencil_Flag; + +typedef struct ColorGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float hsv[3]; /* hsv factors */ + char pad[4]; +} ColorGpencilModifierData; + +typedef enum eColorGpencil_Flag { + GP_COLOR_CREATE_COLORS = (1 << 0), + GP_COLOR_INVERT_LAYER = (1 << 1), + GP_COLOR_INVERT_PASS = (1 << 2), +} eColorGpencil_Flag; + +typedef struct OpacityGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float factor; /* Main Opacity factor */ + char pad[4]; +} OpacityGpencilModifierData; + +typedef enum eOpacityGpencil_Flag { + GP_OPACITY_INVERT_LAYER = (1 << 0), + GP_OPACITY_INVERT_PASS = (1 << 1), + GP_OPACITY_INVERT_VGROUP = (1 << 2), +} eOpacityGpencil_Flag; + +typedef struct InstanceGpencilModifierData { + GpencilModifierData modifier; + int count[3]; /* number of elements in array */ + int flag; /* several flags */ + float offset[3]; /* Location increments */ + float shift[3]; /* shift increment */ + float rnd_size; /* random size factor */ + float rnd_rot; /* random size factor */ + float rot[3]; /* Rotation changes */ + float scale[3]; /* Scale changes */ + float rnd[20]; /* (first element is the index) random values */ + int lock_axis; /* lock shift to one axis */ + + int pass_index; /* custom index for passes */ + char layername[64]; /* layer name */ +} InstanceGpencilModifierData; + +typedef enum eInstanceGpencil_Flag { + GP_INSTANCE_RANDOM_SIZE = (1 << 0), + GP_INSTANCE_RANDOM_ROT = (1 << 1), + GP_INSTANCE_INVERT_LAYER = (1 << 2), + GP_INSTANCE_INVERT_PASS = (1 << 3), + GP_INSTANCE_MAKE_OBJECTS = (1 << 4), +} eInstanceGpencil_Flag; + +typedef struct BuildGpencilModifierData { + GpencilModifierData modifier; + + char layername[64]; /* if set, restrict modifier to operating on this layer */ + int pass_index; + + int pad; + + float start_frame; /* If GP_BUILD_RESTRICT_TIME is set, the defines the frame range where GP frames are considered */ + float end_frame; + + float start_delay; /* For each pair of gp keys, number of frames before strokes start appearing */ + float length; /* For each pair of gp keys, number of frames that build effect must be completed within */ + + short flag; /* (eGpencilBuild_Flag) Options for controlling modifier behaviour */ + + short mode; /* (eGpencilBuild_Mode) How are strokes ordered */ + short transition; /* (eGpencilBuild_Transition) In what order do stroke points appear/disappear */ + + short time_alignment; /* (eGpencilBuild_TimeAlignment) For the "Concurrent" mode, when should "shorter" strips start/end */ +} BuildGpencilModifierData; + +typedef enum eBuildGpencil_Mode { + /* Strokes are shown one by one until all have appeared */ + GP_BUILD_MODE_SEQUENTIAL = 0, + /* All strokes start at the same time */ + GP_BUILD_MODE_CONCURRENT = 1, +} eBuildGpencil_Mode; + +typedef enum eBuildGpencil_Transition { + /* Show in forward order */ + GP_BUILD_TRANSITION_GROW = 0, + /* Hide in reverse order */ + GP_BUILD_TRANSITION_SHRINK = 1, + /* Hide in forward order */ + GP_BUILD_TRANSITION_FADE = 2, +} eBuildGpencil_Transition; + +typedef enum eBuildGpencil_TimeAlignment { + /* All strokes start at same time */ + GP_BUILD_TIMEALIGN_START = 0, + /* All strokes end at same time */ + GP_BUILD_TIMEALIGN_END = 1, + + /* TODO: Random Offsets, Stretch-to-Fill */ +} eBuildGpencil_TimeAlignment; + +typedef enum eBuildGpencil_Flag { + /* Restrict modifier to particular layer/passes? */ + GP_BUILD_INVERT_LAYER = (1 << 0), + GP_BUILD_INVERT_PASS = (1 << 1), + + /* Restrict modifier to only operating between the nominated frames */ + GP_BUILD_RESTRICT_TIME = (1 << 2), +} eBuildGpencil_Flag; + +typedef struct LatticeGpencilModifierData { + GpencilModifierData modifier; + struct Object *object; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float strength; + char pad[4]; + void *cache_data; /* runtime only (LatticeDeformData) */ +} LatticeGpencilModifierData; + +typedef enum eLatticeGpencil_Flag { + GP_LATTICE_INVERT_LAYER = (1 << 0), + GP_LATTICE_INVERT_PASS = (1 << 1), + GP_LATTICE_INVERT_VGROUP = (1 << 2), +} eLatticeGpencil_Flag; + +typedef struct MirrorGpencilModifierData { + GpencilModifierData modifier; + struct Object *object; + char layername[64]; /* layer name */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ +} MirrorGpencilModifierData; + +typedef enum eMirrorGpencil_Flag { + GP_MIRROR_INVERT_LAYER = (1 << 0), + GP_MIRROR_INVERT_PASS = (1 << 1), + GP_MIRROR_CLIPPING = (1 << 2), + GP_MIRROR_AXIS_X = (1 << 3), + GP_MIRROR_AXIS_Y = (1 << 4), + GP_MIRROR_AXIS_Z = (1 << 5), +} eMirrorGpencil_Flag; + +typedef struct HookGpencilModifierData { + GpencilModifierData modifier; + + struct Object *object; + char subtarget[64]; /* optional name of bone target, MAX_ID_NAME-2 */ + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + + int flag; + char falloff_type; /* use enums from WarpGpencilModifier (exact same functionality) */ + char pad[3]; + float parentinv[4][4]; /* matrix making current transform unmodified */ + float cent[3]; /* visualization of hook */ + float falloff; /* if not zero, falloff is distance where influence zero */ + float force; + struct CurveMapping *curfalloff; +} HookGpencilModifierData; + +typedef enum eHookGpencil_Flag { + GP_HOOK_INVERT_LAYER = (1 << 0), + GP_HOOK_INVERT_PASS = (1 << 1), + GP_HOOK_INVERT_VGROUP = (1 << 2), + GP_HOOK_UNIFORM_SPACE = (1 << 3), +} eHookGpencil_Flag; + +typedef enum eHookGpencil_Falloff { + eGPHook_Falloff_None = 0, + eGPHook_Falloff_Curve = 1, + eGPHook_Falloff_Sharp = 2, + eGPHook_Falloff_Smooth = 3, + eGPHook_Falloff_Root = 4, + eGPHook_Falloff_Linear = 5, + eGPHook_Falloff_Const = 6, + eGPHook_Falloff_Sphere = 7, + eGPHook_Falloff_InvSquare = 8, +} eHookGpencil_Falloff; + +typedef struct SimplifyGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float factor; /* factor of simplify */ + short mode; /* type of simplify */ + short step; /* every n vertex to keep */ +} SimplifyGpencilModifierData; + +typedef enum eSimplifyGpencil_Flag { + GP_SIMPLIFY_INVERT_LAYER = (1 << 0), + GP_SIMPLIFY_INVERT_PASS = (1 << 1), +} eSimplifyGpencil_Flag; + +typedef enum eSimplifyGpencil_Mode { + /* Keep only one vertex every n vertices */ + GP_SIMPLIFY_FIXED = 0, + /* Use RDP algorithm */ + GP_SIMPLIFY_ADAPTATIVE = 1, +} eSimplifyGpencil_Mode; + +typedef struct OffsetGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* flags */ + float loc[3]; + float rot[3]; + float scale[3]; + char pad[4]; +} OffsetGpencilModifierData; + +typedef enum eOffsetGpencil_Flag { + GP_OFFSET_INVERT_LAYER = (1 << 0), + GP_OFFSET_INVERT_PASS = (1 << 1), + GP_OFFSET_INVERT_VGROUP = (1 << 2) +} eOffsetGpencil_Flag; + +typedef struct SmoothGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + char vgname[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + int pass_index; /* custom index for passes */ + int flag; /* several flags */ + float factor; /* factor of noise */ + int step; /* how many times apply smooth */ +} SmoothGpencilModifierData; + +typedef enum eSmoothGpencil_Flag { + GP_SMOOTH_MOD_LOCATION = (1 << 0), + GP_SMOOTH_MOD_STRENGTH = (1 << 1), + GP_SMOOTH_MOD_THICKNESS = (1 << 2), + GP_SMOOTH_INVERT_LAYER = (1 << 3), + GP_SMOOTH_INVERT_PASS = (1 << 4), + GP_SMOOTH_INVERT_VGROUP = (1 << 5), + GP_SMOOTH_MOD_UV = (1 << 6), +} eSmoothGpencil_Flag; + +#define MOD_MESHSEQ_READ_ALL \ + (MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR) + +#endif /* __DNA_GREASEPENCIL_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index e2ee561de7f..8febfbc8ffc 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -36,6 +36,17 @@ struct AnimData; struct CurveMapping; +struct GHash; +struct MDeformVert; + +/* TODO: add size as userprefs parameter */ +#define GP_OBGPENCIL_DEFAULT_SIZE 0.2f +#define GP_DEFAULT_PIX_FACTOR 1.0f +#define GP_DEFAULT_GRID_LINES 4 +#define GP_MAX_INPUT_SAMPLES 10 + +/* ***************************************** */ +/* GP Stroke Points */ /* Grease-Pencil Annotations - 'Stroke Point' * -> Coordinates may either be 2d or 3d depending on settings at the time @@ -47,7 +58,10 @@ typedef struct bGPDspoint { float pressure; /* pressure of input device (from 0 to 1) at this point */ float strength; /* color strength (used for alpha factor) */ float time; /* seconds since start of stroke */ - int flag; /* additional options (NOTE: can shrink this field down later if needed) */ + int flag; /* additional options */ + + float uv_fac; /* factor of uv along the stroke */ + float uv_rot; /* uv rotation for dot mode */ } bGPDspoint; /* bGPDspoint->flag */ @@ -59,54 +73,24 @@ typedef enum eGPDspoint_Flag { GP_SPOINT_TAG = (1 << 1), } eGPSPoint_Flag; +/* ***************************************** */ +/* GP Fill - Triangle Tesselation Data */ + /* Grease-Pencil Annotations - 'Triangle' - * A triangle contains the index of three vertices for filling the stroke - * This is only used if high quality fill is enabled. - * (not saved to blend file). + * -> A triangle contains the index of three vertices for filling the stroke + * This is only used if high quality fill is enabled */ typedef struct bGPDtriangle { /* indices for tesselated triangle used for GP Fill */ unsigned int verts[3]; + /* texture coordinates for verts */ + float uv[3][2]; } bGPDtriangle; -/* GP brush (used for new strokes) */ -typedef struct bGPDbrush { - struct bGPDbrush *next, *prev; +/* ***************************************** */ - char info[64]; /* Brush name. Must be unique. */ - short thickness; /* thickness to apply to strokes */ - short flag; - float draw_smoothfac; /* amount of smoothing to apply to newly created strokes */ - short draw_smoothlvl; /* number of times to apply smooth factor to new strokes */ - short sublevel; /* number of times to subdivide new strokes */ - - float draw_sensitivity; /* amount of sensivity to apply to newly created strokes */ - float draw_strength; /* amount of alpha strength to apply to newly created strokes */ - float draw_jitter; /* amount of jitter to apply to newly created strokes */ - float draw_angle; /* angle when the brush has full thickness */ - float draw_angle_factor; /* factor to apply when angle change (only 90 degrees) */ - float draw_random_press; /* factor of randomness for sensitivity and strength */ - float draw_random_sub; /* factor of randomness for subdivision */ - struct CurveMapping *cur_sensitivity; - struct CurveMapping *cur_strength; - struct CurveMapping *cur_jitter; -} bGPDbrush; - -/* bGPDbrush->flag */ -typedef enum eGPDbrush_Flag { - /* brush is active */ - GP_BRUSH_ACTIVE = (1 << 0), - /* brush use pressure */ - GP_BRUSH_USE_PRESSURE = (1 << 1), - /* brush use pressure for alpha factor */ - GP_BRUSH_USE_STENGTH_PRESSURE = (1 << 2), - /* brush use pressure for alpha factor */ - GP_BRUSH_USE_JITTER_PRESSURE = (1 << 3), - /* brush use random for pressure */ - GP_BRUSH_USE_RANDOM_PRESSURE = (1 << 4), - /* brush use random for strength */ - GP_BRUSH_USE_RANDOM_STRENGTH = (1 << 5) -} eGPDbrush_Flag; +/* ***************************************** */ +/* GP Palettes (Deprecated - 2.78 - 2.79 only) */ /* color of palettes */ typedef struct bGPDpalettecolor { @@ -129,9 +113,7 @@ typedef enum eGPDpalettecolor_Flag { /* do onion skinning */ PC_COLOR_ONIONSKIN = (1 << 3), /* "volumetric" strokes */ - PC_COLOR_VOLUMETRIC = (1 << 4), - /* Use High quality fill */ - PC_COLOR_HQ_FILL = (1 << 5) + PC_COLOR_VOLUMETRIC = (1 << 4) } eGPDpalettecolor_Flag; /* palette of colors */ @@ -152,6 +134,21 @@ typedef enum eGPDpalette_Flag { PL_PALETTE_ACTIVE = (1 << 0) } eGPDpalette_Flag; +/* ***************************************** */ +/* GP Strokes */ + +/* Runtime temp data for bGPDstroke */ +typedef struct bGPDstroke_runtime { + /* runtime final colors (result of original colors and modifiers) */ + float tmp_stroke_rgba[4]; + float tmp_fill_rgba[4]; + + /* temporary layer name only used during copy/paste to put the stroke in the original layer */ + char tmp_layerinfo[128]; + + float multi_frame_falloff; /* runtime falloff factor (only for transform) */ +} bGPDstroke_runtime; + /* Grease-Pencil Annotations - 'Stroke' * -> A stroke represents a (simplified version) of the curve * drawn by the user in one 'mousedown'->'mouseup' operation @@ -168,14 +165,16 @@ typedef struct bGPDstroke { short flag, pad[2]; /* various settings about this stroke */ double inittime; /* Init time of stroke */ - /* The pointer to color is only used during drawing, but not saved - * colorname is the join with the palette, but when draw, the pointer is update if the value is NULL - * to speed up the drawing - */ - char colorname[128]; /* color name */ - bGPDpalettecolor *palcolor; /* current palette color */ - /* temporary layer name only used during copy/paste to put the stroke in the original layer */ - char tmp_layerinfo[128]; + + char colorname[128] DNA_DEPRECATED; /* color name */ + + int mat_nr; /* material index */ + char pad_[4]; + + struct MDeformVert *dvert; /* vertex weight data */ + + bGPDstroke_runtime runtime; + char pad_1[4]; } bGPDstroke; /* bGPDstroke->flag */ @@ -190,14 +189,22 @@ typedef enum eGPDstroke_Flag { GP_STROKE_SELECT = (1 << 3), /* Recalculate triangulation for high quality fill (when true, force a new recalc) */ GP_STROKE_RECALC_CACHES = (1 << 4), - /* Recalculate the color pointer using the name as index (true force a new recalc) */ - GP_STROKE_RECALC_COLOR = (1 << 5), /* Flag used to indicate that stroke is closed and draw edge between last and first point */ GP_STROKE_CYCLIC = (1 << 7), + /* Flag used to indicate that stroke is used for fill close and must use fill color for stroke and no fill area */ + GP_STROKE_NOFILL = (1 << 8), /* only for use with stroke-buffer (while drawing eraser) */ GP_STROKE_ERASER = (1 << 15) } eGPDstroke_Flag; +/* ***************************************** */ +/* GP Frame */ + +/* Runtime temp data for bGPDframe */ +typedef struct bGPDframe_runtime { + float viewmatrix[4][4]; /* parent matrix for drawing */ +} bGPDframe_runtime; + /* Grease-Pencil Annotations - 'Frame' * -> Acts as storage for the 'image' formed by strokes */ @@ -210,6 +217,8 @@ typedef struct bGPDframe { short flag; /* temp settings */ short key_type; /* keyframe type (eBezTriple_KeyframeType) */ + + bGPDframe_runtime runtime; } bGPDframe; /* bGPDframe->flag */ @@ -220,6 +229,16 @@ typedef enum eGPDframe_Flag { GP_FRAME_SELECT = (1 << 1) } eGPDframe_Flag; +/* ***************************************** */ +/* GP Layer */ + +/* Runtime temp data for bGPDlayer */ +typedef struct bGPDlayer_runtime { + struct GHash *derived_data; /* runtime data created by modifiers */ + int icon_id; /* id for dynamic icon used to show annotation color preview for layer */ + char pad[4]; +} bGPDlayer_runtime; + /* Grease-Pencil Annotations - 'Layer' */ typedef struct bGPDlayer { struct bGPDlayer *next, *prev; @@ -228,27 +247,27 @@ typedef struct bGPDlayer { bGPDframe *actframe; /* active frame (should be the frame that is currently being displayed) */ short flag; /* settings for layer */ - short thickness; /* current thickness to apply to strokes */ - - short gstep; /* Ghosts Before: max number of ghost frames to show between active frame and the one before it (0 = only the ghost itself) */ - short gstep_next; /* Ghosts After: max number of ghost frames to show after active frame and the following it (0 = only the ghost itself) */ + short onion_flag; /* Per-layer onion-skinning flags (eGPDlayer_OnionFlag) */ - float gcolor_prev[3]; /* optional color for ghosts before the active frame */ - float gcolor_next[3]; /* optional color for ghosts after the active frame */ + float color[4]; /* Color for strokes in layers. Used for annotations, and for ruler (which uses GPencil internally) */ + float fill[4]; /* Fill color for strokes in layers. Not used anymore (was only for) */ - float color[4]; /* Color for strokes in layers (replaced by palettecolor). Only used for ruler (which uses GPencil internally) */ - float fill[4]; /* Fill color for strokes in layers. Not used and replaced by palettecolor fill */ + char info[128]; /* name/reference info for this layer (i.e. "director's comments, 12/3") + * needs to be kept unique, as it's used as the layer identifier */ - char info[128]; /* optional reference info about this layer (i.e. "director's comments, 12/3") - * this is used for the name of the layer too and kept unique. */ + short thickness; /* thickness to apply to strokes (Annotations) */ + char pad_1[2]; struct Object *parent; /* parent object */ float inverse[4][4]; /* inverse matrix (only used if parented) */ char parsubstr[64]; /* String describing subobject info, MAX_ID_NAME-2 */ - short partype, pad; + short partype; + short line_change; /* Thickness adjustment */ float tintcolor[4]; /* Color used to tint layer, alpha value is used as factor */ float opacity; /* Opacity of the layer */ + + bGPDlayer_runtime runtime; } bGPDlayer; /* bGPDlayer->flag */ @@ -261,51 +280,89 @@ typedef enum eGPDlayer_Flag { GP_LAYER_ACTIVE = (1 << 2), /* draw points of stroke for debugging purposes */ GP_LAYER_DRAWDEBUG = (1 << 3), - /* do onion skinning */ - GP_LAYER_ONIONSKIN = (1 << 4), /* for editing in Action Editor */ GP_LAYER_SELECT = (1 << 5), /* current frame for layer can't be changed */ GP_LAYER_FRAMELOCK = (1 << 6), /* don't render xray (which is default) */ GP_LAYER_NO_XRAY = (1 << 7), - /* use custom color for ghosts before current frame */ - GP_LAYER_GHOST_PREVCOL = (1 << 8), - /* use custom color for ghosts after current frame */ - GP_LAYER_GHOST_NEXTCOL = (1 << 9), /* "volumetric" strokes */ GP_LAYER_VOLUMETRIC = (1 << 10), - /* Use high quality fill (instead of buggy legacy OpenGL Fill) */ - GP_LAYER_HQ_FILL = (1 << 11), /* Unlock color */ GP_LAYER_UNLOCK_COLOR = (1 << 12), - /* always show onion skins (i.e. even during renders/animation playback) */ - GP_LAYER_GHOST_ALWAYS = (1 << 13), } eGPDlayer_Flag; +/* bGPDlayer->onion_flag */ +typedef enum eGPDlayer_OnionFlag { + /* do onion skinning */ + GP_LAYER_ONIONSKIN = (1 << 0), +} eGPDlayer_OnionFlag; + +/* ***************************************** */ +/* GP Datablock */ + +/* Runtime temp data for bGPdata */ +typedef struct bGPdata_runtime { + /* Drawing Manager cache */ + struct GHash *batch_cache_data; + void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */ + + /* GP Object drawing */ + float scolor[4]; /* buffer stroke color */ + float sfill[4]; /* buffer fill color */ + short mode; /* settings for color */ + short bstroke_style; /* buffer style for drawing strokes (used to select shader type) */ + short bfill_style; /* buffer style for filling areas (used to select shader type) */ + + /* Stroke Buffer data (only used during paint-session) + * - buffer must be initialized before use, but freed after + * whole paint operation is over + */ + short sbuffer_size; /* number of elements currently in cache */ + short sbuffer_sflag; /* flags for stroke that cache represents */ + char pad_[6]; +} bGPdata_runtime; + /* Grease-Pencil Annotations - 'DataBlock' */ typedef struct bGPdata { ID id; /* Grease Pencil data is a datablock */ struct AnimData *adt; /* animation data - for animating draw settings */ - /* saved Grease-Pencil data */ + /* Grease-Pencil data */ ListBase layers; /* bGPDlayers */ int flag; /* settings for this datablock */ - /* not-saved stroke buffer data (only used during paint-session) - * - buffer must be initialized before use, but freed after - * whole paint operation is over - */ - short sbuffer_size; /* number of elements currently in cache */ - short sbuffer_sflag; /* flags for stroke that cache represents */ - void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */ - float scolor[4]; /* buffer color using palettes */ - float sfill[4]; /* buffer fill color */ - char pad[6]; /* padding for compiler alignment error */ - short sflag; /* settings for palette color */ - - /* saved palettes */ - ListBase palettes; + short xray_mode; /* xray mode for strokes (eGP_DepthOrdering) */ + char pad_1[2]; + + /* Palettes */ + ListBase palettes DNA_DEPRECATED; /* list of bGPDpalette's - Deprecated (2.78 - 2.79 only) */ + + /* 3D Viewport/Appearance Settings */ + float pixfactor; /* factor to define pixel size conversion */ + float line_color[4]; /* color for edit line */ + + /* Onion skinning */ + float onion_factor; /* onion alpha factor change */ + int onion_mode; /* onion skinning range (eGP_OnionModes) */ + int onion_flag; /* onion skinning flags (eGPD_OnionFlag) */ + short gstep; /* Ghosts Before: max number of ghost frames to show between active frame and the one before it (0 = only the ghost itself) */ + short gstep_next; /* Ghosts After: max number of ghost frames to show after active frame and the following it (0 = only the ghost itself) */ + + float gcolor_prev[3]; /* optional color for ghosts before the active frame */ + float gcolor_next[3]; /* optional color for ghosts after the active frame */ + + char pad[4]; + struct Material **mat; /* materials array */ + short totcol; /* total materials */ + + /* stats */ + short totlayer; + short totframe; + short totstroke; + short totpoint; + char pad_2[6]; + bGPdata_runtime runtime; } bGPdata; /* bGPdata->flag */ @@ -314,8 +371,12 @@ typedef struct bGPdata { * changes made during the porting process. */ typedef enum eGPdata_Flag { - /* don't allow painting to occur at all */ - /* GP_DATA_LMBPLOCK = (1 << 0), */ + /* datablock is used for "annotations" + * NOTE: This flag used to be used in 2.4x, but should hardly ever have been set. + * We can use this freely now, as all GP datablocks from pre-2.8 will get + * set on file load (as many old use cases are for "annotations" only) + */ + GP_DATA_ANNOTATIONS = (1 << 0), /* show debugging info in viewport (i.e. status print) */ GP_DATA_DISPINFO = (1 << 1), @@ -339,10 +400,80 @@ typedef enum eGPdata_Flag { /* Stroke Editing Mode - Toggle to enable alternative keymap for easier editing of stroke points */ GP_DATA_STROKE_EDITMODE = (1 << 8), - /* Convenience/cache flag to make it easier to quickly toggle onion skinning on/off */ + /* Main flag to switch onion skinning on/off */ GP_DATA_SHOW_ONIONSKINS = (1 << 9), /* Draw a green and red point to indicate start and end of the stroke */ - GP_DATA_SHOW_DIRECTION = (1 << 10) + GP_DATA_SHOW_DIRECTION = (1 << 10), + + /* Batch drawing cache need to be recalculated */ + GP_DATA_CACHE_IS_DIRTY = (1 << 11), + + /* Stroke Paint Mode - Toggle paint mode */ + GP_DATA_STROKE_PAINTMODE = (1 << 12), + /* Stroke Editing Mode - Toggle sculpt mode */ + GP_DATA_STROKE_SCULPTMODE = (1 << 13), + /* Stroke Editing Mode - Toggle weight paint mode */ + GP_DATA_STROKE_WEIGHTMODE = (1 << 14), + + /* keep stroke thickness unchanged when zoom change */ + GP_DATA_STROKE_KEEPTHICKNESS = (1 << 15), + + /* Allow edit several frames at the same time */ + GP_DATA_STROKE_MULTIEDIT = (1 << 16), } eGPdata_Flag; +/* gpd->onion_flag */ +typedef enum eGPD_OnionFlag { + /* use custom color for ghosts before current frame */ + GP_ONION_GHOST_PREVCOL = (1 << 0), + /* use custom color for ghosts after current frame */ + GP_ONION_GHOST_NEXTCOL = (1 << 1), + /* always show onion skins (i.e. even during renders/animation playback) */ + GP_ONION_GHOST_ALWAYS = (1 << 2), + /* use fade color in onion skin */ + GP_ONION_FADE = (1 << 3), + /* Loop showing first frame after last frame */ + GP_ONION_LOOP = (1 << 4), +} eGPD_OnionFlag; + +/* gpd->onion_mode */ +typedef enum eGP_OnionModes { + GP_ONION_MODE_ABSOLUTE = 0, + GP_ONION_MODE_RELATIVE = 1, + GP_ONION_MODE_SELECTED = 2, +} eGP_OnionModes; + +/* xray modes (Depth Ordering) */ +typedef enum eGP_DepthOrdering { + GP_XRAY_FRONT = 0, + GP_XRAY_3DSPACE = 1, + GP_XRAY_BACK = 2 +} eGP_DepthOrdering; + +/* ***************************************** */ +/* Mode Checking Macros */ + +/* Check if 'multiedit sessions' is enabled */ +#define GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) \ + ((gpd) && (gpd->flag & \ + (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE)) && \ + (gpd->flag & GP_DATA_STROKE_MULTIEDIT)) + +/* Macros to check grease pencil modes */ +#define GPENCIL_ANY_MODE(gpd) \ + ((gpd) && (gpd->flag & \ + (GP_DATA_STROKE_PAINTMODE | GP_DATA_STROKE_EDITMODE | \ + GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE))) +#define GPENCIL_ANY_EDIT_MODE(gpd) \ + ((gpd) && (gpd->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE))) +#define GPENCIL_PAINT_MODE(gpd) \ + ((gpd) && (gpd->flag & (GP_DATA_STROKE_PAINTMODE))) +#define GPENCIL_SCULPT_OR_WEIGHT_MODE(gpd) \ + ((gpd) && (gpd->flag & (GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE))) +#define GPENCIL_NONE_EDIT_MODE(gpd) \ + ((gpd) && ((gpd->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE | GP_DATA_STROKE_WEIGHTMODE)) == 0)) +#define GPENCIL_LAZY_MODE(brush, shift) \ + (((brush) && ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) && (shift == 0))) || \ + (((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && (shift == 1))) + #endif /* __DNA_GPENCIL_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index eb469895fd7..50d9b890724 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -54,6 +54,59 @@ typedef struct TexPaintSlot { int pad; } TexPaintSlot; +typedef struct MaterialGPencilStyle { + struct Image *sima; /* Texture image for strokes */ + struct Image *ima; /* Texture image for filling */ + float stroke_rgba[4]; /* color for paint and strokes (alpha included) */ + float fill_rgba[4]; /* color that should be used for drawing "fills" for strokes (alpha included) */ + float mix_rgba[4]; /* secondary color used for gradients and other stuff */ + short flag; /* settings */ + short index; /* custom index for passes */ + short stroke_style; /* style for drawing strokes (used to select shader type) */ + short fill_style; /* style for filling areas (used to select shader type) */ + float mix_factor; /* factor used to define shader behavior (several uses) */ + float gradient_angle; /* angle used for gradients orientation */ + float gradient_radius; /* radius for radial gradients */ + float pattern_gridsize; /* cheesboard size */ + float gradient_scale[2]; /* uv coordinates scale */ + float gradient_shift[2]; /* factor to shift filling in 2d space */ + float texture_angle; /* angle used for texture orientation */ + float texture_scale[2]; /* texture scale (separated of uv scale) */ + float texture_offset[2]; /* factor to shift texture in 2d space */ + float texture_opacity; /* texture opacity */ + float texture_pixsize; /* pixel size for uv along the stroke */ + int mode; /* drawing mode (line or dots) */ + + int gradient_type; /* type of gradient */ + char pad[4]; +} MaterialGPencilStyle; + +/* MaterialGPencilStyle->flag */ +typedef enum eMaterialGPencilStyle_Flag { + /* Fill Texture is a pattern */ + GP_STYLE_FILL_PATTERN = (1 << 0), + /* don't display color */ + GP_STYLE_COLOR_HIDE = (1 << 1), + /* protected from further editing */ + GP_STYLE_COLOR_LOCKED = (1 << 2), + /* do onion skinning */ + GP_STYLE_COLOR_ONIONSKIN = (1 << 3), + /* clamp texture */ + GP_STYLE_COLOR_TEX_CLAMP = (1 << 4), + /* mix texture */ + GP_STYLE_COLOR_TEX_MIX = (1 << 5), + /* Flip fill colors */ + GP_STYLE_COLOR_FLIP_FILL = (1 << 6), + /* Stroke Texture is a pattern */ + GP_STYLE_STROKE_PATTERN = (1 << 7) +} eMaterialGPencilStyle_Flag; + +typedef enum eMaterialGPencilStyle_Mode { + GP_STYLE_MODE_LINE = 0, /* line */ + GP_STYLE_MODE_DOTS = 1, /* dots */ + GP_STYLE_MODE_BOX = 2, /* rectangles */ +} eMaterialGPencilStyle_Mode; + typedef struct Material { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ @@ -107,6 +160,9 @@ typedef struct Material { /* Runtime cache for GLSL materials. */ ListBase gpumaterial; + + /* grease pencil color */ + struct MaterialGPencilStyle *gp_style; } Material; /* **************** MATERIAL ********************* */ @@ -229,4 +285,24 @@ enum { MA_BS_HASHED, }; +/* Grease Pencil Stroke styles */ +enum { + GP_STYLE_STROKE_STYLE_SOLID = 0, + GP_STYLE_STROKE_STYLE_TEXTURE +}; + +/* Grease Pencil Fill styles */ +enum { + GP_STYLE_FILL_STYLE_SOLID = 0, + GP_STYLE_FILL_STYLE_GRADIENT, + GP_STYLE_FILL_STYLE_CHESSBOARD, + GP_STYLE_FILL_STYLE_TEXTURE +}; + +/* Grease Pencil Gradient Types */ +enum { + GP_STYLE_GRADIENT_LINEAR = 0, + GP_STYLE_GRADIENT_RADIAL +}; + #endif diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h index 802ca6c7d0d..01228376174 100644 --- a/source/blender/makesdna/DNA_object_enums.h +++ b/source/blender/makesdna/DNA_object_enums.h @@ -37,7 +37,10 @@ typedef enum eObjectMode { OB_MODE_TEXTURE_PAINT = 1 << 4, OB_MODE_PARTICLE_EDIT = 1 << 5, OB_MODE_POSE = 1 << 6, - OB_MODE_GPENCIL = 1 << 7, /* NOTE: Just a dummy to make the UI nicer */ + OB_MODE_GPENCIL_EDIT = 1 << 7, + OB_MODE_GPENCIL_PAINT = 1 << 8, + OB_MODE_GPENCIL_SCULPT = 1 << 9, + OB_MODE_GPENCIL_WEIGHT = 1 << 10, } eObjectMode; /* Any mode where the brush system is used. */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index a8d50543e80..47fb2feb7f4 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -180,7 +180,9 @@ typedef struct Object { ListBase effect DNA_DEPRECATED; // XXX deprecated... keep for readfile ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */ ListBase modifiers; /* list of ModifierData structures */ + ListBase greasepencil_modifiers; /* list of GpencilModifierData structures */ ListBase fmaps; /* list of facemaps */ + ListBase shader_fx; /* list of viewport effects. Actually only used by grease pencil */ int mode; /* Local object mode */ int restore_mode; @@ -351,6 +353,9 @@ enum { /* 23 and 24 are for life and sector (old file compat.) */ OB_ARMATURE = 25, +/* Grease Pencil object used in 3D view but not used for annotation in 2D */ + OB_GPENCIL = 26, + OB_TYPE_MAX, }; @@ -361,9 +366,9 @@ enum { /* check if the object type supports materials */ #define OB_TYPE_SUPPORT_MATERIAL(_type) \ - ((_type) >= OB_MESH && (_type) <= OB_MBALL) + (((_type) >= OB_MESH && (_type) <= OB_MBALL) || ((_type) == OB_GPENCIL)) #define OB_TYPE_SUPPORT_VGROUP(_type) \ - (ELEM(_type, OB_MESH, OB_LATTICE)) + (ELEM(_type, OB_MESH, OB_LATTICE, OB_GPENCIL)) #define OB_TYPE_SUPPORT_EDITMODE(_type) \ (ELEM(_type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)) #define OB_TYPE_SUPPORT_PARVERT(_type) \ @@ -375,10 +380,10 @@ enum { /* is this ID type used as object data */ #define OB_DATA_SUPPORT_ID(_id_type) \ - (ELEM(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_LP, ID_CA, ID_LT, ID_AR)) + (ELEM(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_LP, ID_CA, ID_LT, ID_GD, ID_AR)) #define OB_DATA_SUPPORT_ID_CASE \ - ID_ME: case ID_CU: case ID_MB: case ID_LA: case ID_SPK: case ID_LP: case ID_CA: case ID_LT: case ID_AR + ID_ME: case ID_CU: case ID_MB: case ID_LA: case ID_SPK: case ID_LP: case ID_CA: case ID_LT: case ID_GD: case ID_AR /* partype: first 4 bits: type */ enum { @@ -466,6 +471,12 @@ enum { OB_EMPTY_IMAGE = 8, }; +/* gpencil add types */ +enum { + GP_EMPTY = 0, + GP_MONKEY = 1 +}; + /* boundtype */ enum { OB_BOUND_BOX = 0, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a4235a07ed5..6629eeae3fa 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -66,7 +66,6 @@ struct AnimData; struct Editing; struct SceneStats; struct bGPdata; -struct bGPDbrush; struct MovieClip; struct ColorSpace; struct SceneCollection; @@ -686,7 +685,8 @@ typedef struct RenderData { /* render simplify */ short simplify_subsurf; short simplify_subsurf_render; - short pad9, pad10; + short simplify_gpencil; + short pad10; float simplify_particles; float simplify_particles_render; @@ -905,6 +905,11 @@ typedef struct UvSculpt { Paint paint; } UvSculpt; +/* grease pencil drawing brushes */ +typedef struct GpPaint { + Paint paint; +} GpPaint; + /* ------------------------------------------- */ /* Vertex Paint */ @@ -929,15 +934,18 @@ enum { typedef enum eGP_EditBrush_Types { GP_EDITBRUSH_TYPE_SMOOTH = 0, GP_EDITBRUSH_TYPE_THICKNESS = 1, - GP_EDITBRUSH_TYPE_GRAB = 2, - GP_EDITBRUSH_TYPE_PUSH = 3, - GP_EDITBRUSH_TYPE_TWIST = 4, - GP_EDITBRUSH_TYPE_PINCH = 5, - GP_EDITBRUSH_TYPE_RANDOMIZE = 6, - GP_EDITBRUSH_TYPE_SUBDIVIDE = 7, - GP_EDITBRUSH_TYPE_SIMPLIFY = 8, - GP_EDITBRUSH_TYPE_CLONE = 9, - GP_EDITBRUSH_TYPE_STRENGTH = 10, + GP_EDITBRUSH_TYPE_STRENGTH = 2, + GP_EDITBRUSH_TYPE_GRAB = 3, + GP_EDITBRUSH_TYPE_PUSH = 4, + GP_EDITBRUSH_TYPE_TWIST = 5, + GP_EDITBRUSH_TYPE_PINCH = 6, + GP_EDITBRUSH_TYPE_RANDOMIZE = 7, + GP_EDITBRUSH_TYPE_CLONE = 8, + GP_EDITBRUSH_TYPE_SUBDIVIDE = 9, + GP_EDITBRUSH_TYPE_SIMPLIFY = 10, + /* add any sculpt brush above this value */ + GP_EDITBRUSH_TYPE_WEIGHT = 11, + /* add any weight paint brush below this value. Do no mix brushes */ /* !!! Update GP_EditBrush_Data brush[###]; below !!! */ TOT_GP_EDITBRUSH_TYPES @@ -956,6 +964,8 @@ typedef struct GP_EditBrush_Data { short size; /* radius of brush */ short flag; /* eGP_EditBrush_Flag */ float strength; /* strength of effect */ + float curcolor_add[3]; /* cursor color for add */ + float curcolor_sub[3]; /* cursor color for sub */ } GP_EditBrush_Data; /* GP_EditBrush_Data.flag */ @@ -969,20 +979,31 @@ typedef enum eGP_EditBrush_Flag { GP_EDITBRUSH_FLAG_USE_FALLOFF = (1 << 2), /* smooth brush affects pressure values as well */ - GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE = (1 << 3) + GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE = (1 << 3), + /* enable screen cursor */ + GP_EDITBRUSH_FLAG_ENABLE_CURSOR = (1 << 4), + /* temporary invert action */ + GP_EDITBRUSH_FLAG_TMP_INVERT = (1 << 5), } eGP_EditBrush_Flag; /* GPencil Stroke Sculpting Settings */ typedef struct GP_BrushEdit_Settings { - GP_EditBrush_Data brush[11]; /* TOT_GP_EDITBRUSH_TYPES */ + GP_EditBrush_Data brush[12]; /* TOT_GP_EDITBRUSH_TYPES */ void *paintcursor; /* runtime */ - int brushtype; /* eGP_EditBrush_Types */ + int brushtype; /* eGP_EditBrush_Types (sculpt) */ int flag; /* eGP_BrushEdit_SettingsFlag */ int lock_axis; /* eGP_Lockaxis_Types lock drawing to one axis */ - float alpha; /* alpha factor for selection color */ + char pad1[4]; + + /* weight paint is a submode of sculpt but use its own index. All weight paint + * brushes must be defined at the end of the brush array. + */ + int weighttype; /* eGP_EditBrush_Types (weight paint) */ + char pad[4]; + struct CurveMapping *cur_falloff; /* multiframe edit falloff effect by frame */ } GP_BrushEdit_Settings; /* GP_BrushEdit_Settings.flag */ @@ -995,6 +1016,12 @@ typedef enum eGP_BrushEdit_SettingsFlag { GP_BRUSHEDIT_FLAG_APPLY_STRENGTH = (1 << 2), /* apply brush to thickness */ GP_BRUSHEDIT_FLAG_APPLY_THICKNESS = (1 << 3), + /* apply brush to thickness */ + GP_BRUSHEDIT_FLAG_WEIGHT_MODE = (1 << 4), + /* enable falloff for multiframe editing */ + GP_BRUSHEDIT_FLAG_FRAME_FALLOFF = (1 << 5), + /* apply brush to uv data */ + GP_BRUSHEDIT_FLAG_APPLY_UV = (1 << 6), } eGP_BrushEdit_SettingsFlag; @@ -1213,6 +1240,7 @@ typedef struct ToolSettings { VPaint *wpaint; /* weight paint */ Sculpt *sculpt; UvSculpt *uvsculpt; /* uv smooth */ + GpPaint *gp_paint; /* gpencil paint */ /* Vertex group weight - used only for editmode, not weight * paint */ @@ -1236,19 +1264,19 @@ typedef struct ToolSettings { /* Auto-IK */ short autoik_chainlen; /* runtime only */ - /* SCE_MPR_LOC/SCAL */ - char gizmo_flag; - /* Grease Pencil */ char gpencil_flags; /* flags/options for how the tool works */ - char gpencil_src; /* for main 3D view Grease Pencil, where data comes from */ char gpencil_v3d_align; /* stroke placement settings: 3D View */ char gpencil_v2d_align; /* : General 2D Editor */ char gpencil_seq_align; /* : Sequencer Preview */ char gpencil_ima_align; /* : Image Editor */ - char _pad3[3]; + /* Annotations */ + char annotate_v3d_align; /* stroke placement settings - 3D View */ + + short annotate_thickness; /* default stroke thickness for annotation strokes */ + char _pad3[2]; /* Grease Pencil Sculpt */ struct GP_BrushEdit_Settings gp_sculpt; @@ -1256,10 +1284,7 @@ typedef struct ToolSettings { /* Grease Pencil Interpolation Tool(s) */ struct GP_Interpolate_Settings gp_interpolate; - /* Grease Pencil Drawing Brushes (bGPDbrush) */ - ListBase gp_brushes; - - /* Image Paint (8 byttse aligned please!) */ + /* Image Paint (8 bytes aligned please!) */ struct ImagePaintSettings imapaint; /* Particle Editing */ @@ -1281,7 +1306,9 @@ typedef struct ToolSettings { /* Alt+RMB option */ char edge_mode; char edge_mode_live_unwrap; - char _pad1; + + /* SCE_MPR_LOC/SCAL */ + char gizmo_flag; /* Transform */ char transform_pivot_point; @@ -1503,7 +1530,7 @@ typedef struct Scene { /* Units */ struct UnitSettings unit; - /* Grease Pencil */ + /* Grease Pencil - Annotations */ struct bGPdata *gpd; /* Movie Tracking */ @@ -1515,6 +1542,7 @@ typedef struct Scene { uint64_t customdata_mask; /* XXX. runtime flag for drawing, actually belongs in the window, only used by BKE_object_handle_update() */ uint64_t customdata_mask_modal; /* XXX. same as above but for temp operator use (gl renders) */ + /* Color Management */ ColorManagedViewSettings view_settings; ColorManagedDisplaySettings display_settings; @@ -2020,19 +2048,27 @@ typedef enum eImagePaintMode { /* ToolSettings.gpencil_flags */ typedef enum eGPencil_Flags { - /* "Continuous Drawing" - The drawing operator enters a mode where multiple strokes can be drawn */ - GP_TOOL_FLAG_PAINTSESSIONS_ON = (1 << 0), /* When creating new frames, the last frame gets used as the basis for the new one */ GP_TOOL_FLAG_RETAIN_LAST = (1 << 1), /* Add the strokes below all strokes in the layer */ - GP_TOOL_FLAG_PAINT_ONBACK = (1 << 2) + GP_TOOL_FLAG_PAINT_ONBACK = (1 << 2), + /* Show compact list of colors */ + GP_TOOL_FLAG_THUMBNAIL_LIST = (1 << 3), } eGPencil_Flags; -/* ToolSettings.gpencil_src */ -typedef enum eGPencil_Source_3D { - GP_TOOL_SOURCE_SCENE = 0, - GP_TOOL_SOURCE_OBJECT = 1 -} eGPencil_Source_3d; +/* scene->r.simplify_gpencil */ +typedef enum eGPencil_SimplifyFlags { + /* Simplify */ + SIMPLIFY_GPENCIL_ENABLE = (1 << 0), + /* Simplify on play */ + SIMPLIFY_GPENCIL_ON_PLAY = (1 << 1), + /* Simplify fill on viewport */ + SIMPLIFY_GPENCIL_FILL = (1 << 2), + /* Simplify modifier on viewport */ + SIMPLIFY_GPENCIL_MODIFIER = (1 << 3), + /* Remove fill external line */ + SIMPLIFY_GPENCIL_REMOVE_FILL_LINE = (1 << 4) +} eGPencil_SimplifyFlags; /* ToolSettings.gpencil_*_align - Stroke Placement mode flags */ typedef enum eGPencil_Placement_Flags { @@ -2048,6 +2084,7 @@ typedef enum eGPencil_Placement_Flags { /* "Use Endpoints" */ GP_PROJECT_DEPTH_STROKE_ENDPOINTS = (1 << 4), + GP_PROJECT_CURSOR = (1 << 5), } eGPencil_Placement_Flags; /* ToolSettings.particle flag */ diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h new file mode 100644 index 00000000000..15147cf2b6c --- /dev/null +++ b/source/blender/makesdna/DNA_shader_fx_types.h @@ -0,0 +1,196 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file DNA_shader_fx_types.h + * \ingroup DNA + */ + +#ifndef __DNA_SHADERFX_TYPES_H__ +#define __DNA_SHADERFX_TYPES_H__ + +#include "DNA_defs.h" +#include "DNA_listBase.h" + +struct DRWShadingGroup; + +/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! + * (ONLY ADD NEW ITEMS AT THE END) + */ + +typedef enum ShaderFxType { + eShaderFxType_None = 0, + eShaderFxType_Blur = 1, + eShaderFxType_Flip = 2, + eShaderFxType_Light = 3, + eShaderFxType_Pixel = 4, + eShaderFxType_Swirl = 5, + eShaderFxType_Wave = 6, + eShaderFxType_Rim = 7, + eShaderFxType_Colorize = 8, + NUM_SHADER_FX_TYPES +} ShaderFxType; + +typedef enum ShaderFxMode { + eShaderFxMode_Realtime = (1 << 0), + eShaderFxMode_Render = (1 << 1), + eShaderFxMode_Editmode = (1 << 2), + eShaderFxMode_Expanded = (1 << 3), +} ShaderFxMode; + +typedef enum { + /* This fx has been inserted in local override, and hence can be fully edited. */ + eShaderFxFlag_StaticOverride_Local = (1 << 0), +} ShaderFxFlag; + +typedef struct ShaderFxData { + struct ShaderFxData *next, *prev; + + int type, mode; + int stackindex; + short flag; + short pad; + char name[64]; /* MAX_NAME */ + + char *error; +} ShaderFxData; + +/* Runtime temp data */ +typedef struct ShaderFxData_runtime { + struct DRWShadingGroup *fx_sh; + struct DRWShadingGroup *fx_sh_b; + struct DRWShadingGroup *fx_sh_c; +} ShaderFxData_runtime; + +typedef struct BlurShaderFxData { + ShaderFxData shaderfx; + int radius[2]; + int flag; /* flags */ + int samples; /* number of samples */ + float coc; /* circle of confusion */ + int blur[2]; /* not visible in rna */ + char pad[4]; + ShaderFxData_runtime runtime; +} BlurShaderFxData; + +typedef enum eBlurShaderFx_Flag { + FX_BLUR_DOF_MODE = (1 << 0) +} eBlurShaderFx_Flag; + +typedef struct ColorizeShaderFxData { + ShaderFxData shaderfx; + int mode; + float low_color[4]; + float high_color[4]; + float factor; + int flag; /* flags */ + char pad[4]; + ShaderFxData_runtime runtime; +} ColorizeShaderFxData; + +typedef enum ColorizeShaderFxModes { + eShaderFxColorizeMode_GrayScale = 0, + eShaderFxColorizeMode_Sepia = 1, + eShaderFxColorizeMode_BiTone = 2, + eShaderFxColorizeMode_Custom = 3, + eShaderFxColorizeMode_Transparent = 4, +} ColorizeShaderFxModes; + +typedef struct FlipShaderFxData { + ShaderFxData shaderfx; + int flag; /* flags */ + int flipmode; /* internal, not visible in rna */ + ShaderFxData_runtime runtime; +} FlipShaderFxData; + +typedef enum eFlipShaderFx_Flag { + FX_FLIP_HORIZONTAL = (1 << 0), + FX_FLIP_VERTICAL = (1 << 1), +} eFlipShaderFx_Flag; + +typedef struct LightShaderFxData { + ShaderFxData shaderfx; + struct Object *object; + int flag; /* flags */ + float energy; + float ambient; + float loc[4]; /* internal, not visible in rna */ + char pad[4]; + ShaderFxData_runtime runtime; +} LightShaderFxData; + +typedef struct PixelShaderFxData { + ShaderFxData shaderfx; + int size[3]; /* last element used for shader only */ + int flag; /* flags */ + float rgba[4]; + ShaderFxData_runtime runtime; +} PixelShaderFxData; + +typedef enum ePixelShaderFx_Flag { + FX_PIXEL_USE_LINES = (1 << 0), +} ePixelShaderFx_Flag; + +typedef struct RimShaderFxData { + ShaderFxData shaderfx; + int offset[2]; + int flag; /* flags */ + float rim_rgb[3]; + float mask_rgb[3]; + int mode; + int blur[2]; + int samples; + char pad[4]; + ShaderFxData_runtime runtime; +} RimShaderFxData; + +typedef enum RimShaderFxModes { + eShaderFxRimMode_Normal = 0, + eShaderFxRimMode_Overlay = 1, + eShaderFxRimMode_Add = 2, + eShaderFxRimMode_Subtract = 3, + eShaderFxRimMode_Multiply = 4, + eShaderFxRimMode_Divide = 5, +} RimShaderFxModes; + +typedef struct SwirlShaderFxData { + ShaderFxData shaderfx; + struct Object *object; + int flag; /* flags */ + int radius; + float angle; + int transparent; /* not visible in rna */ + ShaderFxData_runtime runtime; +} SwirlShaderFxData; + +typedef enum eSwirlShaderFx_Flag { + FX_SWIRL_MAKE_TRANSPARENT = (1 << 0), +} eSwirlShaderFx_Flag; + +typedef struct WaveShaderFxData { + ShaderFxData shaderfx; + float amplitude; + float period; + float phase; + int orientation; + int flag; /* flags */ + char pad[4]; + ShaderFxData_runtime runtime; +} WaveShaderFxData; +#endif /* __DNA_SHADERFX_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d6d043b03ae..5404f4160fd 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -198,6 +198,7 @@ typedef enum eSpaceButtons_Context { BCONTEXT_VIEW_LAYER = 13, BCONTEXT_TOOL = 14, BCONTEXT_WORKSPACE = 15, + BCONTEXT_SHADERFX = 16, /* always as last... */ BCONTEXT_TOT @@ -1346,7 +1347,7 @@ typedef enum eSpaceClip_Flag { SC_SHOW_GRID = (1 << 9), SC_SHOW_STABLE = (1 << 10), SC_MANUAL_CALIBRATION = (1 << 11), - SC_SHOW_GPENCIL = (1 << 12), + SC_SHOW_ANNOTATION = (1 << 12), SC_SHOW_FILTERS = (1 << 13), SC_SHOW_GRAPH_FRAMES = (1 << 14), SC_SHOW_GRAPH_TRACKS_MOTION = (1 << 15), diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index e7a540f9afc..cb2c69e2fa1 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -651,7 +651,9 @@ typedef struct UserDef { struct WalkNavigation walk_navigation; short opensubdiv_compute_type; - char pad5[6]; + short gpencil_multisamples; /* eMultiSample_Type, amount of samples for Grease Pencil */ + + char pad5[4]; } UserDef; extern UserDef U; /* from blenkernel blender.c */ @@ -958,7 +960,7 @@ typedef enum eNdof_Flag { #define NDOF_PIXELS_PER_SECOND 600.0f -/* UserDef.ogl_multisamples */ +/* UserDef.ogl_multisamples and gpencil_multisamples */ typedef enum eMultiSample_Type { USER_MULTISAMPLE_NONE = 0, USER_MULTISAMPLE_2 = 2, diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index bbbaf8bb957..27b07a317ed 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -190,6 +190,14 @@ typedef struct View3DOverlay { float wireframe_threshold; char _pad0[4]; + /* grease pencil setttings */ + float gpencil_grid_scale; + float gpencil_paper_opacity; + int gpencil_grid_lines; + int gpencil_grid_axis; + float gpencil_grid_opacity; + char _pad1[4]; + } View3DOverlay; /* 3D ViewPort Struct */ @@ -256,7 +264,8 @@ typedef struct View3D { char multiview_eye; /* multiview current eye - for internal use */ - char pad3[4]; + /* actually only used to define the opacity of the grease pencil vertex in edit mode */ + float vertex_opacity; /* note, 'fx_settings.dof' is currently _not_ allocated, * instead set (temporarily) from camera */ @@ -340,7 +349,7 @@ typedef struct View3D { /* View3d->flag2 (short) */ #define V3D_RENDER_OVERRIDE (1 << 2) #define V3D_SOLID_TEX (1 << 3) -#define V3D_SHOW_GPENCIL (1 << 4) +#define V3D_SHOW_ANNOTATION (1 << 4) #define V3D_LOCK_CAMERA (1 << 5) #define V3D_RENDER_SHADOW (1 << 6) /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ #define V3D_SHOW_RECONSTRUCTION (1 << 7) @@ -353,9 +362,13 @@ typedef struct View3D { #define V3D_OCCLUDE_WIRE (1 << 14) #define V3D_SHOW_MODE_SHADE_OVERRIDE (1 << 15) /* XXX: DNA deprecated */ - /* View3d->flag3 (short) */ -#define V3D_SHOW_WORLD (1 << 0) /* LEGACY replaced by V3D_SHADING_BACKGROUND_WORLD */ +#define V3D_SHOW_WORLD (1 << 0) /* LEGACY replaced by V3D_SHADING_BACKGROUND_WORLD */ +#define V3D_GP_SHOW_PAPER (1 << 2) /* Activate paper to cover all viewport */ +#define V3D_GP_SHOW_GRID (1 << 3) /* Activate paper grid */ +#define V3D_GP_SHOW_EDIT_LINES (1 << 4) +#define V3D_GP_SHOW_MULTIEDIT_LINES (1 << 5) +#define V3D_GP_SHOW_ONION_SKIN (1 << 6) /* main switch at view level */ /* View3DShading->light */ enum { @@ -482,4 +495,12 @@ enum { #define RV3D_CAMZOOM_MIN_FACTOR 0.1657359312880714853f #define RV3D_CAMZOOM_MAX_FACTOR 44.9852813742385702928f +/* View3d.gpencil_grid_axis */ +enum { + V3D_GP_GRID_AXIS_LOCK = (1 << 0), + V3D_GP_GRID_AXIS_X = (1 << 1), + V3D_GP_GRID_AXIS_Y = (1 << 2), + V3D_GP_GRID_AXIS_Z = (1 << 3), +}; + #endif diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index a1bfac66115..7b27ec05865 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -113,6 +113,8 @@ static const char *includefiles[] = { "DNA_particle_types.h", "DNA_cloth_types.h", "DNA_gpencil_types.h", + "DNA_gpencil_modifier_types.h", + "DNA_shader_fx_types.h", "DNA_windowmanager_types.h", "DNA_anim_types.h", "DNA_boid_types.h", @@ -1337,6 +1339,8 @@ int main(int argc, char **argv) #include "DNA_particle_types.h" #include "DNA_cloth_types.h" #include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_windowmanager_types.h" #include "DNA_anim_types.h" #include "DNA_boid_types.h" diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index cb5e2e61f9a..16194c9b419 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -269,9 +269,6 @@ extern StructRNA RNA_FreestyleSettings; extern StructRNA RNA_Function; extern StructRNA RNA_GPencilFrame; extern StructRNA RNA_GPencilLayer; -extern StructRNA RNA_GPencilPalette; -extern StructRNA RNA_GPencilPaletteColor; -extern StructRNA RNA_GPencilBrush; extern StructRNA RNA_GPencilInterpolateSettings; extern StructRNA RNA_GPencilStroke; extern StructRNA RNA_GPencilStrokePoint; @@ -600,6 +597,31 @@ extern StructRNA RNA_SunLight; extern StructRNA RNA_SurfaceCurve; extern StructRNA RNA_SurfaceDeformModifier; extern StructRNA RNA_SurfaceModifier; +extern StructRNA RNA_GpencilModifier; +extern StructRNA RNA_BuildGpencilModifier; +extern StructRNA RNA_NoiseGpencilModifier; +extern StructRNA RNA_SubdivGpencilModifier; +extern StructRNA RNA_SimplifyGpencilModifier; +extern StructRNA RNA_ThickGpencilModifier; +extern StructRNA RNA_TintGpencilModifier; +extern StructRNA RNA_ColorGpencilModifier; +extern StructRNA RNA_InstanceGpencilModifier; +extern StructRNA RNA_DupliGpencilModifier; +extern StructRNA RNA_OpacityGpencilModifier; +extern StructRNA RNA_LatticeGpencilModifier; +extern StructRNA RNA_MirrorGpencilModifier; +extern StructRNA RNA_SmoothGpencilModifier; +extern StructRNA RNA_HookGpencilModifier; +extern StructRNA RNA_OffsetGpencilModifier; +extern StructRNA RNA_ShaderFx; +extern StructRNA RNA_ShaderFxBlur; +extern StructRNA RNA_ShaderFxColorize; +extern StructRNA RNA_ShaderFxFlip; +extern StructRNA RNA_ShaderFxLight; +extern StructRNA RNA_ShaderFxPixel; +extern StructRNA RNA_ShaderFxRim; +extern StructRNA RNA_ShaderFxSwirl; +extern StructRNA RNA_ShaderFxWave; extern StructRNA RNA_TexMapping; extern StructRNA RNA_Text; extern StructRNA RNA_TextBox; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 043375a066a..4c0861757f4 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -44,6 +44,7 @@ extern const EnumPropertyItem rna_enum_id_type_items[]; extern const EnumPropertyItem rna_enum_object_mode_items[]; extern const EnumPropertyItem rna_enum_object_empty_drawtype_items[]; +extern const EnumPropertyItem rna_enum_object_gpencil_type_items[]; extern const EnumPropertyItem rna_enum_metaelem_type_items[]; extern const EnumPropertyItem rna_enum_proportional_falloff_items[]; @@ -65,6 +66,8 @@ extern const EnumPropertyItem rna_enum_object_modifier_type_items[]; extern const EnumPropertyItem rna_enum_constraint_type_items[]; extern const EnumPropertyItem rna_enum_boidrule_type_items[]; extern const EnumPropertyItem rna_enum_sequence_modifier_type_items[]; +extern const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[]; +extern const EnumPropertyItem rna_enum_object_shaderfx_type_items[]; extern const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[]; extern const EnumPropertyItem rna_enum_modifier_triangulate_ngon_method_items[]; @@ -228,6 +231,7 @@ const EnumPropertyItem *rna_node_socket_type_itemf( struct bContext; struct PointerRNA; struct PropertyRNA; + const EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free); const EnumPropertyItem *rna_Sensor_type_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free); const EnumPropertyItem *rna_Actuator_type_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free); diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index eb32a5fc6cb..ec240c222a1 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -49,6 +49,8 @@ set(DEFSRC rna_fcurve.c rna_fluidsim.c rna_gpencil.c + rna_gpencil_modifier.c + rna_shader_fx.c rna_group.c rna_image.c rna_key.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 393ebc15d3e..b0713987e16 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -3416,6 +3416,8 @@ static RNAProcessItem PROCESS_ITEMS[] = { {"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh}, {"rna_meta.c", "rna_meta_api.c", RNA_def_meta}, {"rna_modifier.c", NULL, RNA_def_modifier}, + {"rna_gpencil_modifier.c", NULL, RNA_def_greasepencil_modifier}, + {"rna_shader_fx.c", NULL, RNA_def_shader_fx }, {"rna_nla.c", NULL, RNA_def_nla}, {"rna_nodetree.c", NULL, RNA_def_nodetree}, {"rna_object.c", "rna_object_api.c", RNA_def_object}, diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 4f1e29b482d..0f3e74c567f 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -31,6 +31,8 @@ #include "DNA_texture_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_workspace_types.h" +#include "DNA_gpencil_types.h" #include "BLI_math.h" @@ -122,6 +124,44 @@ const EnumPropertyItem rna_enum_brush_image_tool_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_brush_types_items[] = { + { GP_BRUSH_TYPE_DRAW, "DRAW", ICON_GREASEPENCIL_STROKE_PAINT, "Draw", "The brush is of type used for drawing strokes" }, + { GP_BRUSH_TYPE_FILL, "FILL", ICON_COLOR, "Fill", "The brush is of type used for filling areas" }, + { GP_BRUSH_TYPE_ERASE, "ERASE", ICON_PANEL_CLOSE, "Erase", "The brush is used for erasing strokes" }, + { 0, NULL, 0, NULL, NULL } +}; + +static EnumPropertyItem rna_enum_gpencil_brush_eraser_modes_items[] = { + { GP_BRUSH_ERASER_SOFT, "SOFT", 0, "Soft", "Use soft eraser" }, + { GP_BRUSH_ERASER_HARD, "HARD", 0, "Hard", "Use hard eraser" }, + { GP_BRUSH_ERASER_STROKE, "STROKE", 0, "Stroke", "Use stroke eraser" }, + { 0, NULL, 0, NULL, NULL } +}; + +static EnumPropertyItem rna_enum_gpencil_fill_draw_modes_items[] = { + { GP_FILL_DMODE_STROKE, "STROKE", 0, "Strokes", "Use visible strokes as fill boundary limits" }, + { GP_FILL_DMODE_CONTROL, "CONTROL", 0, "Control", "Use internal control lines as fill boundary limits" }, + { GP_FILL_DMODE_BOTH, "BOTH", 0, "Both", "Use visible strokes and control lines as fill boundary limits" }, + { 0, NULL, 0, NULL, NULL } +}; + +static EnumPropertyItem rna_enum_gpencil_brush_icons_items[] = { + { GP_BRUSH_ICON_PENCIL, "PENCIL", ICON_GPBRUSH_PENCIL, "Pencil", "" }, + { GP_BRUSH_ICON_PEN, "PEN", ICON_GPBRUSH_PEN, "Pen", "" }, + { GP_BRUSH_ICON_INK, "INK", ICON_GPBRUSH_INK, "Ink", "" }, + { GP_BRUSH_ICON_INKNOISE, "INKNOISE", ICON_GPBRUSH_INKNOISE, "Ink Noise", "" }, + { GP_BRUSH_ICON_BLOCK, "BLOCK", ICON_GPBRUSH_BLOCK, "Block", "" }, + { GP_BRUSH_ICON_MARKER, "MARKER", ICON_GPBRUSH_MARKER, "Marker", "" }, + { GP_BRUSH_ICON_FILL, "FILL", ICON_GPBRUSH_FILL, "Fill", "" }, + { GP_BRUSH_ICON_ERASE_SOFT, "SOFT", ICON_GPBRUSH_ERASE_SOFT, "Eraser Soft", "" }, + { GP_BRUSH_ICON_ERASE_HARD, "HARD", ICON_GPBRUSH_ERASE_HARD, "Eraser Hard", "" }, + { GP_BRUSH_ICON_ERASE_STROKE, "STROKE", ICON_GPBRUSH_ERASE_STROKE, "Eraser Stroke", "" }, + { 0, NULL, 0, NULL, NULL } +}; +#endif + + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -442,6 +482,33 @@ static void rna_Brush_icon_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poi WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); } +static const EnumPropertyItem *rna_DynamicGpencil_type_itemf( + bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + Main *bmain = CTX_data_main(C); + EnumPropertyItem *item = NULL, item_tmp = { 0 }; + int totitem = 0; + int i = 0; + + Brush *brush; + for (brush = bmain->brush.first; brush; brush = brush->id.next, i++) { + if (brush->gpencil_settings == NULL) + continue; + + item_tmp.identifier = brush->id.name + 2; + item_tmp.name = brush->id.name + 2; + item_tmp.value = i; + item_tmp.icon = brush->gpencil_settings->icon_id; + + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; +} + static void rna_TextureSlot_brush_angle_update(bContext *C, PointerRNA *ptr) { Scene *scene = CTX_data_scene(C); @@ -615,6 +682,58 @@ static const EnumPropertyItem *rna_Brush_stroke_itemf(bContext *C, PointerRNA *U return brush_stroke_method_items; } } + +/* Grease Pencil Drawing Brushes Settings */ +static void rna_BrushGpencilSettings_default_eraser_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +{ + ToolSettings *ts = scene->toolsettings; + Paint *paint = &ts->gp_paint->paint; + Brush *brush_cur = paint->brush; + + /* disable default eraser in all brushes */ + for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) { + if ((brush != brush_cur) && + (brush->ob_mode == OB_MODE_GPENCIL_PAINT) && + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + { + brush->gpencil_settings->flag &= ~GP_BRUSH_DEFAULT_ERASER; + } + } +} + +static void rna_BrushGpencilSettings_eraser_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) +{ + ToolSettings *ts = scene->toolsettings; + Paint *paint = &ts->gp_paint->paint; + Brush *brush = paint->brush; + + /* set eraser icon */ + if ((brush) && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { + switch (brush->gpencil_settings->eraser_mode) { + case GP_BRUSH_ERASER_SOFT: + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT; + break; + case GP_BRUSH_ERASER_HARD: + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_HARD; + break; + case GP_BRUSH_ERASER_STROKE: + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_STROKE; + break; + default: + brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT; + break; + } + } +} + +static bool rna_BrushGpencilSettings_material_poll(PointerRNA *UNUSED(ptr), PointerRNA value) +{ + Material *ma = (Material *)value.data; + + /* GP materials only */ + return (ma->gp_style != NULL); +} + #else static void rna_def_brush_texture_slot(BlenderRNA *brna) @@ -809,6 +928,316 @@ static void rna_def_image_paint_capabilities(BlenderRNA *brna) #undef IMAPAINT_TOOL_CAPABILITY } +static void rna_def_gpencil_options(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* Grease Pencil Drawing - generated dynamically */ + static const EnumPropertyItem prop_dynamic_gpencil_type[] = { + { 1, "DRAW", 0, "Draw", "" }, + { 0, NULL, 0, NULL, NULL } + }; + + srna = RNA_def_struct(brna, "BrushGpencilSettings", NULL); + RNA_def_struct_sdna(srna, "BrushGpencilSettings"); + RNA_def_struct_ui_text(srna, "Grease Pencil Brush Settings", "Settings for grease pencil brush"); + + /* grease pencil drawing brushes */ + prop = RNA_def_property(srna, "grease_pencil_tool", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "brush_type"); + RNA_def_property_enum_items(prop, prop_dynamic_gpencil_type); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DynamicGpencil_type_itemf"); + RNA_def_property_ui_text(prop, "Grease Pencil Tool", ""); + /* TODO: GPXX review update */ + RNA_def_property_update(prop, 0, NULL); + //RNA_def_property_update(prop, 0, "rna_Brush_gpencil_tool_update"); + + /* Sensitivity factor for new strokes */ + prop = RNA_def_property(srna, "pen_sensitivity_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_sensitivity"); + RNA_def_property_range(prop, 0.1f, 3.0f); + RNA_def_property_ui_text(prop, "Sensitivity", "Pressure sensitivity factor for new strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Strength factor for new strokes */ + prop = RNA_def_property(srna, "pen_strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_strength"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Strength", "Color strength for new strokes (affect alpha factor of color)"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Jitter factor for new strokes */ + prop = RNA_def_property(srna, "pen_jitter", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_jitter"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Jitter", "Jitter factor for new strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Randomnes factor for pressure */ + prop = RNA_def_property(srna, "random_pressure", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_random_press"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Pressure Randomness", "Randomness factor for pressure in new strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Randomnes factor for strength */ + prop = RNA_def_property(srna, "random_strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_random_strength"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Strength Randomness", "Randomness factor strength in new strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Randomnes factor for subdivision */ + prop = RNA_def_property(srna, "random_subdiv", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_random_sub"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Random Subdivision", "Randomness factor for new strokes after subdivision"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Angle when brush is full size */ + prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "draw_angle"); + RNA_def_property_range(prop, -M_PI_2, M_PI_2); + RNA_def_property_ui_text(prop, "Angle", + "Direction of the stroke at which brush gives maximal thickness " + "(0° for horizontal)"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Factor to change brush size depending of angle */ + prop = RNA_def_property(srna, "angle_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_angle_factor"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Angle Factor", + "Reduce brush thickness by this factor when stroke is perpendicular to 'Angle' direction"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Smoothing factor for new strokes */ + prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac"); + RNA_def_property_range(prop, 0.0, 2.0f); + RNA_def_property_ui_text(prop, "Smooth", + "Amount of smoothing to apply after finish newly created strokes, to reduce jitter/noise"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Iterations of the Smoothing factor */ + prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl"); + RNA_def_property_range(prop, 1, 3); + RNA_def_property_ui_text(prop, "Iterations", + "Number of times to smooth newly created strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Thickness smoothing factor for new strokes */ + prop = RNA_def_property(srna, "pen_thick_smooth_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "thick_smoothfac"); + RNA_def_property_range(prop, 0.0, 2.0f); + RNA_def_property_ui_text(prop, "Smooth Thickness", + "Amount of thickness smoothing to apply after finish newly created strokes, to reduce jitter/noise"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Thickness iterations of the Smoothing factor */ + prop = RNA_def_property(srna, "pen_thick_smooth_steps", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "thick_smoothlvl"); + RNA_def_property_range(prop, 1, 3); + RNA_def_property_ui_text(prop, "Iterations Thickness", + "Number of times to smooth thickness for newly created strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Subdivision level for new strokes */ + prop = RNA_def_property(srna, "pen_subdivision_steps", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "draw_subdivide"); + RNA_def_property_range(prop, 0, 3); + RNA_def_property_ui_text(prop, "Subdivision Steps", + "Number of times to subdivide newly created strokes, for less jagged strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Curves for pressure */ + prop = RNA_def_property(srna, "curve_sensitivity", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "curve_sensitivity"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "curve_strength", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "curve_strength"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Curve Strength", "Curve used for the strength"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "curve_jitter", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "curve_jitter"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Curve Jitter", "Curve used for the jitter effect"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* fill threshold for transparence */ + prop = RNA_def_property(srna, "gpencil_fill_threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "fill_threshold"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Threshold", + "Threshold to consider color transparent for filling"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* fill leak size */ + prop = RNA_def_property(srna, "gpencil_fill_leak", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "fill_leak"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Leak Size", + "Size in pixels to consider the leak closed"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* fill simplify steps */ + prop = RNA_def_property(srna, "gpencil_fill_simplyfy_level", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "fill_simplylvl"); + RNA_def_property_range(prop, 0, 10); + RNA_def_property_ui_text(prop, "Simplify", + "Number of simplify steps (large values reduce fill accuracy)"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "uv_random", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "uv_random"); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_text(prop, "UV Random", "Random factor for autogenerated UV rotation"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "input_samples", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "input_samples"); + RNA_def_property_range(prop, 0, GP_MAX_INPUT_SAMPLES); + RNA_def_property_ui_text(prop, "Input Samples", "Generate intermediate points for very fast mouse movements. Set to 0 to disable"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* active smooth factor while drawing */ + prop = RNA_def_property(srna, "active_smooth_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "active_smooth"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Active Smooth", + "Amount of smoothing while drawing "); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* brush standard icon */ + prop = RNA_def_property(srna, "gp_icon", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "icon_id"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_icons_items); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_ui_text(prop, "Grease Pencil Icon", ""); + + /* Flags */ + prop = RNA_def_property(srna, "use_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure", "Use tablet pressure"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_STENGTH_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure Strength", "Use tablet pressure for color strength"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_JITTER_PRESSURE); + RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); + RNA_def_property_ui_text(prop, "Use Pressure Jitter", "Use tablet pressure for jitter"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "use_stabilizer", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_STABILIZE_MOUSE); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Stabilizer", + "Draw lines with a delay to allow smooth strokes. Press Shift key to override while drawing"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "use_cursor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_ENABLE_CURSOR); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Enable Cursor", "Enable cursor on screen"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "gpencil_brush_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "brush_type"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_types_items); + RNA_def_property_ui_text(prop, "Type", "Category of the brush"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "eraser_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "eraser_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_eraser_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Eraser Mode"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_eraser_mode_update"); + + prop = RNA_def_property(srna, "gpencil_fill_draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "fill_draw_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_draw_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Mode to draw boundary limits"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + /* Material */ + prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Material"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_BrushGpencilSettings_material_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_ui_text(prop, "Material", "Material used for strokes drawn using this brush"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + prop = RNA_def_property(srna, "gpencil_fill_show_boundary", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_SHOW_HELPLINES); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Show Lines", "Show help lines for filling to see boundaries"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "gpencil_fill_hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_HIDE); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Hide", "Hide transparent lines to use as boundary for filling"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "default_eraser", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_DEFAULT_ERASER); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1); + RNA_def_property_ui_text(prop, "Default Eraser", "Use this brush when enable eraser with fast switch key"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_default_eraser_update"); + + prop = RNA_def_property(srna, "enable_settings", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_GROUP_SETTINGS); + RNA_def_property_ui_text(prop, "Settings", "Enable additional post processing options for new strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "enable_random", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_GROUP_RANDOM); + RNA_def_property_ui_text(prop, "Random Settings", "Enable random settings for brush"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); +} + static void rna_def_brush(BlenderRNA *brna) { StructRNA *srna; @@ -1373,6 +1802,10 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_TEXTURE_PAINT); RNA_def_property_ui_text(prop, "Use Texture", "Use this brush in texture paint mode"); + prop = RNA_def_property(srna, "use_paint_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_GPENCIL_PAINT); + RNA_def_property_ui_text(prop, "Use Sculpt", "Use this brush in grease pencil drawing mode"); + /* texture */ prop = RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "BrushTextureSlot"); @@ -1475,6 +1908,13 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_struct_type(prop, "ImapaintToolCapabilities"); RNA_def_property_pointer_funcs(prop, "rna_Imapaint_tool_capabilities_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Image Painting Capabilities", "Brush's capabilities in image paint mode"); + + prop = RNA_def_property(srna, "gpencil_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "BrushGpencilSettings"); + RNA_def_property_pointer_sdna(prop, NULL, "gpencil_settings"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Gpencil Settings", ""); + } @@ -1543,6 +1983,7 @@ void RNA_def_brush(BlenderRNA *brna) rna_def_brush_capabilities(brna); rna_def_sculpt_capabilities(brna); rna_def_image_paint_capabilities(brna); + rna_def_gpencil_options(brna); rna_def_brush_texture_slot(brna); rna_def_operator_stroke_element(brna); } diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index 7b07faf8ee7..781be07f1dc 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -52,6 +52,10 @@ const EnumPropertyItem rna_enum_context_mode_items[] = { {CTX_MODE_PAINT_TEXTURE, "PAINT_TEXTURE", 0, "Texture Paint", ""}, {CTX_MODE_PARTICLE, "PARTICLE", 0, "Particle", ""}, {CTX_MODE_OBJECT, "OBJECT", 0, "Object", ""}, + {CTX_MODE_GPENCIL_PAINT, "GPENCIL_PAINT", 0, "Grease Pencil Paint", "" }, + {CTX_MODE_GPENCIL_EDIT, "GPENCIL_EDIT", 0, "Grease Pencil Edit", "" }, + {CTX_MODE_GPENCIL_SCULPT, "GPENCIL_SCULPT", 0, "Grease Pencil Sculpt", "" }, + {CTX_MODE_GPENCIL_WEIGHT, "GPENCIL_WEIGHT", 0, "Grease Pencil Weight Paint", "" }, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index d9dba4679e0..f84f31b02f1 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -26,8 +26,12 @@ #include +#include "BLI_math.h" + +#include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" +#include "DNA_brush_types.h" #include "MEM_guardedalloc.h" @@ -38,10 +42,12 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" #include "WM_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "ED_gpencil.h" @@ -53,31 +59,54 @@ static const EnumPropertyItem parent_type_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_xraymodes_items[] = { + { GP_XRAY_FRONT, "FRONT", 0, "Front", "Draw all strokes in front" }, + { GP_XRAY_3DSPACE, "3DSPACE", 0, "3DSpace", "Draw strokes relative to other objects in 3D space" }, + { GP_XRAY_BACK, "BACK", 0, "Back", "Draw all strokes on back" }, + { 0, NULL, 0, NULL, NULL } +}; + +static EnumPropertyItem rna_enum_gpencil_onion_modes_items[] = { + { GP_ONION_MODE_ABSOLUTE, "ABSOLUTE", 0, "Frames", "Frames in absolute range of scene frame number" }, + { GP_ONION_MODE_RELATIVE, "RELATIVE", 0, "Keyframes", "Frames in relative range of grease pencil keyframes" }, + { GP_ONION_MODE_SELECTED, "SELECTED", 0, "Selected", "Only Selected Frames" }, + { 0, NULL, 0, NULL, NULL } +}; +#endif #ifdef RNA_RUNTIME #include "BLI_math.h" +#include "BLI_ghash.h" #include "WM_api.h" +#include "BKE_action.h" #include "BKE_animsys.h" #include "BKE_gpencil.h" -#include "BKE_action.h" +#include "BKE_icons.h" +#include "DEG_depsgraph.h" -static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) + +static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { + DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA); WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } -static void rna_GPencil_editmode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_GPencil_editmode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { + bGPdata *gpd = (bGPdata *)ptr->id.data; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + /* Notify all places where GPencil data lives that the editing state is different */ WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); WM_main_add_notifier(NC_SCENE | ND_MODE | NC_MOVIECLIP, NULL); } -static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void UNUSED_FUNCTION(rna_GPencil_onion_skinning_update)(Main *bmain, Scene *scene, PointerRNA *ptr) { bGPdata *gpd = (bGPdata *)ptr->id.data; bGPDlayer *gpl; @@ -87,7 +116,7 @@ static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, Pointer * stays in sync with the status of the actual layers */ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpl->flag & GP_LAYER_ONIONSKIN) { + if (gpl->onion_flag & GP_LAYER_ONIONSKIN) { enabled = true; } } @@ -102,16 +131,22 @@ static void rna_GPencil_onion_skinning_update(Main *bmain, Scene *scene, Pointer rna_GPencil_update(bmain, scene, ptr); } -static void rna_GPencil_stroke_colorname_update(Main *bmain, Scene *scene, PointerRNA *ptr) + +/* Poll Callback to filter GP Datablocks to only show those for Annotations */ +bool rna_GPencil_datablocks_annotations_poll(PointerRNA *UNUSED(ptr), const PointerRNA value) { - bGPDstroke *gps = (bGPDstroke *)ptr->data; - gps->flag |= GP_STROKE_RECALC_COLOR; - gps->palcolor = NULL; + bGPdata *gpd = value.data; + return (gpd->flag & GP_DATA_ANNOTATIONS) != 0; +} - /* Now do standard updates... */ - rna_GPencil_update(bmain, scene, ptr); +/* Poll Callback to filter GP Datablocks to only show those for GP Objects */ +bool rna_GPencil_datablocks_obdata_poll(PointerRNA *UNUSED(ptr), const PointerRNA value) +{ + bGPdata *gpd = value.data; + return (gpd->flag & GP_DATA_ANNOTATIONS) == 0; } + static char *rna_GPencilLayer_path(PointerRNA *ptr) { bGPDlayer *gpl = (bGPDlayer *)ptr->data; @@ -133,36 +168,6 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr, const char ** return PROP_EDITABLE; } -static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *max, - int *softmin, int *softmax) -{ - bGPDlayer *gpl = ptr->data; - - /* The restrictions on max width here are due to OpenGL on Windows not supporting - * any widths greater than 10 (for driver-drawn) strokes/points. - * - * Although most of our 2D strokes also don't suffer from this restriction, - * it's relatively hard to test for that. So, for now, only volumetric strokes - * get to be larger... - */ - - /* From GP v2 this value is used to increase or decrease the thickness of the stroke */ - if (gpl->flag & GP_LAYER_VOLUMETRIC) { - *min = -300; - *max = 300; - - *softmin = -100; - *softmax = 100; - } - else { - *min = -10; - *max = 10; - - *softmin = -10; - *softmax = 10; - } -} - /* set parent */ static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *substr) { @@ -202,21 +207,6 @@ static void rna_GPencilLayer_parent_set(PointerRNA *ptr, PointerRNA value) set_parent(gpl, par, gpl->partype, gpl->parsubstr); } else { - /* keep strokes in the same place, so apply current transformation */ - if (gpl->parent != NULL) { - bGPDspoint *pt; - int i; - float diff_mat[4][4]; - /* calculate difference matrix */ - ED_gpencil_parent_location(gpl, diff_mat); - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - mul_m4_v3(diff_mat, &pt->x); - } - } - } - } /* clear parent */ gpl->parent = NULL; } @@ -306,6 +296,15 @@ static void rna_GPencil_active_layer_set(PointerRNA *ptr, PointerRNA value) { bGPdata *gpd = ptr->id.data; + /* Don't allow setting active layer to NULL if layers exist + * as this breaks various tools. Tools should be used instead + * if it's necessary to remove layers + */ + if (value.data == NULL) { + printf("%s: Setting active layer to None is not allowed\n", __func__); + return; + } + if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */ bGPDlayer *gl; @@ -349,6 +348,36 @@ static void rna_GPencil_active_layer_index_range(PointerRNA *ptr, int *min, int *softmax = *max; } +static const EnumPropertyItem *rna_GPencil_active_layer_itemf( + bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) +{ + bGPdata *gpd = (bGPdata *)ptr->id.data; + bGPDlayer *gpl; + EnumPropertyItem *item = NULL, item_tmp = {0}; + int totitem = 0; + int i = 0; + + if (ELEM(NULL, C, gpd)) { + return DummyRNA_NULL_items; + } + + /* Existing layers */ + for (gpl = gpd->layers.first, i = 0; gpl; gpl = gpl->next, i++) { + item_tmp.identifier = gpl->info; + item_tmp.name = gpl->info; + item_tmp.value = i; + + item_tmp.icon = BKE_icon_gplayer_color_ensure(gpl); + + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + RNA_enum_item_end(&item, &totitem); + *r_free = true; + + return item; +} + static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) { bGPdata *gpd = ptr->id.data; @@ -366,31 +395,6 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) BKE_animdata_fix_paths_rename_all(&gpd->id, "layers", oldname, gpl->info); } -static void rna_GPencil_use_onion_skinning_set(PointerRNA *ptr, const bool value) -{ - bGPdata *gpd = ptr->id.data; - bGPDlayer *gpl; - - /* set new value */ - if (value) { - /* enable on active layer (it's the one that's most likely to be of interest right now) */ - gpl = BKE_gpencil_layer_getactive(gpd); - if (gpl) { - gpl->flag |= GP_LAYER_ONIONSKIN; - } - - gpd->flag |= GP_DATA_SHOW_ONIONSKINS; - } - else { - /* disable on all layers - allowa quickly turning them all off, without having to check */ - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - gpl->flag &= ~GP_LAYER_ONIONSKIN; - } - - gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS; - } -} - static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd, const bGPDspoint *pt, bGPDlayer **r_gpl, bGPDframe **r_gpf) { bGPDlayer *gpl; @@ -454,14 +458,21 @@ static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count, float pr stroke->points = MEM_recallocN_id(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count), "gp_stroke_points"); + stroke->dvert = MEM_recallocN_id(stroke->dvert, + sizeof(MDeformVert) * (stroke->totpoints + count), + "gp_stroke_weight"); /* init the pressure and strength values so that old scripts won't need to * be modified to give these initial values... */ for (int i = 0; i < count; i++) { bGPDspoint *pt = stroke->points + (stroke->totpoints + i); + MDeformVert *dvert = stroke->dvert + (stroke->totpoints + i); pt->pressure = pressure; pt->strength = strength; + + dvert->totweight = 0; + dvert->dw = NULL; } stroke->totpoints += count; @@ -471,6 +482,7 @@ static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count, float pr static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports, int index) { bGPDspoint *pt_tmp = stroke->points; + MDeformVert *pt_dvert = stroke->dvert; /* python style negative indexing */ if (index < 0) { @@ -485,27 +497,35 @@ static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports stroke->totpoints--; stroke->points = MEM_callocN(sizeof(bGPDspoint) * stroke->totpoints, "gp_stroke_points"); + stroke->dvert = MEM_callocN(sizeof(MDeformVert) * stroke->totpoints, "gp_stroke_weights"); - if (index > 0) + if (index > 0) { memcpy(stroke->points, pt_tmp, sizeof(bGPDspoint) * index); + /* verify weight data is available */ + if (pt_dvert != NULL) { + memcpy(stroke->dvert, pt_dvert, sizeof(MDeformVert) * index); + } + } - if (index < stroke->totpoints) + if (index < stroke->totpoints) { memcpy(&stroke->points[index], &pt_tmp[index + 1], sizeof(bGPDspoint) * (stroke->totpoints - index)); + if (pt_dvert != NULL) { + memcpy(&stroke->dvert[index], &pt_dvert[index + 1], sizeof(MDeformVert) * (stroke->totpoints - index)); + } + } /* free temp buffer */ MEM_freeN(pt_tmp); + if (pt_dvert != NULL) { + MEM_freeN(pt_dvert); + } WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } -static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame, const char *colorname) +static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame) { bGPDstroke *stroke = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); - if (colorname) { - BLI_strncpy(stroke->colorname, colorname, sizeof(stroke->colorname)); - } - stroke->palcolor = NULL; - stroke->flag |= GP_STROKE_RECALC_COLOR; BLI_addtail(&frame->strokes, stroke); return stroke; @@ -635,260 +655,18 @@ static void rna_GPencil_clear(bGPdata *gpd) WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } -/* Palettes */ -static bGPDpalette *rna_GPencil_palette_new(bGPdata *gpd, const char *name, bool setactive) -{ - bGPDpalette *palette = BKE_gpencil_palette_addnew(gpd, name, setactive != 0); - - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return palette; -} - -static void rna_GPencil_palette_remove(bGPdata *gpd, ReportList *reports, PointerRNA *palette_ptr) -{ - bGPDpalette *palette = palette_ptr->data; - if (BLI_findindex(&gpd->palettes, palette) == -1) { - BKE_report(reports, RPT_ERROR, "Palette not found in grease pencil data"); - return; - } - - BKE_gpencil_palette_delete(gpd, palette); - RNA_POINTER_INVALIDATE(palette_ptr); - - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -static PointerRNA rna_GPencil_active_palette_get(PointerRNA *ptr) -{ - bGPdata *gpd = ptr->id.data; - - if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */ - bGPDpalette *palette; - - for (palette = gpd->palettes.first; palette; palette = palette->next) { - if (palette->flag & PL_PALETTE_ACTIVE) { - break; - } - } - - if (palette) { - return rna_pointer_inherit_refine(ptr, &RNA_GPencilPalette, palette); - } - } - - return rna_pointer_inherit_refine(ptr, NULL, NULL); -} - -static void rna_GPencil_active_palette_set(PointerRNA *ptr, PointerRNA value) -{ - bGPdata *gpd = ptr->id.data; - - if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */ - bGPDpalette *palette; - - for (palette = gpd->palettes.first; palette; palette = palette->next) { - if (palette == value.data) { - palette->flag |= PL_PALETTE_ACTIVE; - } - else { - palette->flag &= ~PL_PALETTE_ACTIVE; - } - } - /* force color recalc */ - BKE_gpencil_palette_change_strokes(gpd); - - WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); - } -} - -static int rna_GPencilPalette_index_get(PointerRNA *ptr) -{ - bGPdata *gpd = (bGPdata *)ptr->id.data; - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - - return BLI_findindex(&gpd->palettes, palette); -} - -static void rna_GPencilPalette_index_set(PointerRNA *ptr, int value) -{ - bGPdata *gpd = (bGPdata *)ptr->id.data; - bGPDpalette *palette = BLI_findlink(&gpd->palettes, value); - - BKE_gpencil_palette_setactive(gpd, palette); - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -static void rna_GPencilPalette_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) -{ - bGPdata *gpd = (bGPdata *)ptr->id.data; - - *min = 0; - *max = max_ii(0, BLI_listbase_count(&gpd->palettes) - 1); - - *softmin = *min; - *softmax = *max; -} - -/* Palette colors */ -static bGPDpalettecolor *rna_GPencilPalette_color_new(bGPDpalette *palette) -{ - bGPDpalettecolor *color = BKE_gpencil_palettecolor_addnew(palette, DATA_("Color"), true); - - return color; -} - -static void rna_GPencilPalette_color_remove(bGPDpalette *palette, ReportList *reports, PointerRNA *color_ptr) -{ - bGPDpalettecolor *color = color_ptr->data; - - if (BLI_findindex(&palette->colors, color) == -1) { - BKE_reportf(reports, RPT_ERROR, "Palette '%s' does not contain color given", palette->info + 2); - return; - } - - BKE_gpencil_palettecolor_delete(palette, color); - RNA_POINTER_INVALIDATE(color_ptr); - - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -static PointerRNA rna_GPencilPalette_active_color_get(PointerRNA *ptr) -{ - bGPDpalette *palette = (bGPDpalette *)ptr->data; - bGPDpalettecolor *color; - - for (color = palette->colors.first; color; color = color->next) { - if (color->flag & PC_COLOR_ACTIVE) { - break; - } - } - - if (color) { - return rna_pointer_inherit_refine(ptr, &RNA_GPencilPaletteColor, color); - } - - return rna_pointer_inherit_refine(ptr, NULL, NULL); -} - -static void rna_GPencilPalette_active_color_set(PointerRNA *ptr, PointerRNA value) -{ - bGPDpalette *palette = (bGPDpalette *)ptr->data; - bGPDpalettecolor *color = value.data; - - BKE_gpencil_palettecolor_setactive(palette, color); -} - -static void rna_GPencilPalette_info_set(PointerRNA *ptr, const char *value) -{ - bGPdata *gpd = ptr->id.data; - bGPDpalette *palette = ptr->data; - - char oldname[64] = ""; - BLI_strncpy(oldname, palette->info, sizeof(oldname)); - - /* copy the new name into the name slot */ - BLI_strncpy_utf8(palette->info, value, sizeof(palette->info)); - - BLI_uniquename(&gpd->palettes, palette, DATA_("GP_Palette"), '.', offsetof(bGPDpalette, info), - sizeof(palette->info)); - /* now fix animation paths */ - BKE_animdata_fix_paths_rename_all(&gpd->id, "palettes", oldname, palette->info); -} - -static char *rna_GPencilPalette_path(PointerRNA *ptr) -{ - bGPDpalette *palette = ptr->data; - char name_esc[sizeof(palette->info) * 2]; - - BLI_strescape(name_esc, palette->info, sizeof(name_esc)); - - return BLI_sprintfN("palettes[\"%s\"]", name_esc); -} - -static char *rna_GPencilPalette_color_path(PointerRNA *ptr) -{ - bGPdata *gpd = ptr->id.data; - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = ptr->data; - - char name_palette[sizeof(palette->info) * 2]; - char name_color[sizeof(palcolor->info) * 2]; - - BLI_strescape(name_palette, palette->info, sizeof(name_palette)); - BLI_strescape(name_color, palcolor->info, sizeof(name_color)); - - return BLI_sprintfN("palettes[\"%s\"].colors[\"%s\"]", name_palette, name_color); -} - -static void rna_GPencilPaletteColor_info_set(PointerRNA *ptr, const char *value) -{ - bGPdata *gpd = ptr->id.data; - bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd); - bGPDpalettecolor *palcolor = ptr->data; - - char oldname[64] = ""; - BLI_strncpy(oldname, palcolor->info, sizeof(oldname)); - - /* copy the new name into the name slot */ - BLI_strncpy_utf8(palcolor->info, value, sizeof(palcolor->info)); - BLI_uniquename(&palette->colors, palcolor, DATA_("Color"), '.', offsetof(bGPDpalettecolor, info), - sizeof(palcolor->info)); - - /* rename all strokes */ - BKE_gpencil_palettecolor_changename(gpd, oldname, palcolor->info); - - /* now fix animation paths */ - BKE_animdata_fix_paths_rename_all(&gpd->id, "colors", oldname, palcolor->info); -} - -static void rna_GPencilStrokeColor_info_set(PointerRNA *ptr, const char *value) +static void rna_GpencilVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { bGPDstroke *gps = ptr->data; - /* copy the new name into the name slot */ - BLI_strncpy_utf8(gps->colorname, value, sizeof(gps->colorname)); -} + if (gps->dvert) { + MDeformVert *dvert = gps->dvert; - -static bool rna_GPencilPaletteColor_is_stroke_visible_get(PointerRNA *ptr) -{ - bGPDpalettecolor *pcolor = (bGPDpalettecolor *)ptr->data; - return (pcolor->color[3] > GPENCIL_ALPHA_OPACITY_THRESH); -} - -static bool rna_GPencilPaletteColor_is_fill_visible_get(PointerRNA *ptr) -{ - bGPDpalettecolor *pcolor = (bGPDpalettecolor *)ptr->data; - return (pcolor->fill[3] > GPENCIL_ALPHA_OPACITY_THRESH); -} - -static int rna_GPencilPaletteColor_index_get(PointerRNA *ptr) -{ - bGPDpalette *palette = (bGPDpalette *)ptr->data; - bGPDpalettecolor *pcolor = BKE_gpencil_palettecolor_getactive(palette); - - return BLI_findindex(&palette->colors, pcolor); -} - -static void rna_GPencilPaletteColor_index_set(PointerRNA *ptr, int value) -{ - bGPDpalette *palette = (bGPDpalette *)ptr->data; - bGPDpalettecolor *pcolor = BLI_findlink(&palette->colors, value); - BKE_gpencil_palettecolor_setactive(palette, pcolor); -} - -static void rna_GPencilPaletteColor_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) -{ - bGPDpalette *palette = (bGPDpalette *)ptr->data; - - *min = 0; - *max = max_ii(0, BLI_listbase_count(&palette->colors) - 1); - - *softmin = *min; - *softmax = *max; + rna_iterator_array_begin(iter, (void *)dvert->dw, sizeof(MDeformWeight), dvert->totweight, 0, NULL); + } + else + rna_iterator_array_begin(iter, NULL, 0, 0, 0, NULL); } - #else static void rna_def_gpencil_stroke_point(BlenderRNA *brna) @@ -918,11 +696,24 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Strength", "Color intensity (alpha factor)"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + prop = RNA_def_property(srna, "uv_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "uv_fac"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "UV Factor", "Internal UV factor"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "uv_rotation", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "uv_rot"); + RNA_def_property_range(prop, 0.0f, M_PI * 2); + RNA_def_property_ui_text(prop, "UV Rotation", "Internal UV factor for dot mode"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SPOINT_SELECT); RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_point_select_set"); RNA_def_property_ui_text(prop, "Select", "Point is selected for viewport editing"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + } static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -955,7 +746,7 @@ static void rna_def_gpencil_triangle(BlenderRNA *brna) srna = RNA_def_struct(brna, "GPencilTriangle", NULL); RNA_def_struct_sdna(srna, "bGPDtriangle"); - RNA_def_struct_ui_text(srna, "Triangle", "Triangulation data for HQ fill"); + RNA_def_struct_ui_text(srna, "Triangle", "Triangulation data for Grease Pencil fills"); /* point v1 */ prop = RNA_def_property(srna, "v1", PROP_INT, PROP_NONE); @@ -974,6 +765,51 @@ static void rna_def_gpencil_triangle(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "verts[2]"); RNA_def_property_ui_text(prop, "v3", "Third triangle vertex index"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + /* texture coord for point v1 */ + prop = RNA_def_property(srna, "uv1", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "uv[0]"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "uv1", "First triangle vertex texture coordinates"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + /* texture coord for point v2 */ + prop = RNA_def_property(srna, "uv2", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "uv[1]"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "uv2", "Second triangle vertex texture coordinates"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + /* texture coord for point v3 */ + prop = RNA_def_property(srna, "uv3", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "uv[2]"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "uv3", "Third triangle vertex texture coordinates"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); +} + +static void rna_def_gpencil_mvert_group(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "GpencilVertexGroupElement", NULL); + RNA_def_struct_sdna(srna, "MDeformWeight"); + RNA_def_struct_ui_text(srna, "Vertex Group Element", "Weight value of a vertex in a vertex group"); + RNA_def_struct_ui_icon(srna, ICON_GROUP_VERTEX); + + /* we can't point to actual group, it is in the object and so + * there is no unique group to point to, hence the index */ + prop = RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "def_nr"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Group Index", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Weight", "Vertex Weight"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); } static void rna_def_gpencil_stroke(BlenderRNA *brna) @@ -1000,24 +836,30 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); rna_def_gpencil_stroke_points_api(brna, prop); + /* vertex groups */ + prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_GpencilVertex_groups_begin", "rna_iterator_array_next", + "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL); + RNA_def_property_struct_type(prop, "GpencilVertexGroupElement"); + RNA_def_property_ui_text(prop, "Groups", "Weights for the vertex groups this vertex is member of"); + /* Triangles */ prop = RNA_def_property(srna, "triangles", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "triangles", "tot_triangles"); RNA_def_property_struct_type(prop, "GPencilTriangle"); RNA_def_property_ui_text(prop, "Triangles", "Triangulation data for HQ fill"); - /* Color */ - prop = RNA_def_property(srna, "color", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "GPencilPaletteColor"); - RNA_def_property_pointer_sdna(prop, NULL, "palcolor"); - RNA_def_property_ui_text(prop, "Palette Color", "Color from palette used in Stroke"); - RNA_def_property_update(prop, 0, "rna_GPencil_update"); + /* Material Index */ + prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "mat_nr"); + RNA_def_property_ui_text(prop, "Material Index", "Index of material used in this stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Settings */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, stroke_draw_mode_items); - RNA_def_property_ui_text(prop, "Draw Mode", ""); + RNA_def_property_ui_text(prop, "Draw Mode", "Coordinate space that stroke is in"); RNA_def_property_update(prop, 0, "rna_GPencil_update"); prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); @@ -1026,22 +868,23 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Select", "Stroke is selected for viewport editing"); RNA_def_property_update(prop, 0, "rna_GPencil_update"); - /* Color Name */ - prop = RNA_def_property(srna, "colorname", PROP_STRING, PROP_NONE); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilStrokeColor_info_set"); - RNA_def_property_ui_text(prop, "Color Name", "Palette color name"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_stroke_colorname_update"); - /* Cyclic: Draw a line from end to start point */ prop = RNA_def_property(srna, "draw_cyclic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_CYCLIC); RNA_def_property_ui_text(prop, "Cyclic", "Enable cyclic drawing, closing the stroke"); RNA_def_property_update(prop, 0, "rna_GPencil_update"); + /* No fill: The stroke never must fill area and must use fill color as stroke color (this is a special flag for fill brush) */ + prop = RNA_def_property(srna, "is_nofill_stroke", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_NOFILL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "No Fill", "Special stroke to use as boundary for filling areas"); + RNA_def_property_update(prop, 0, "rna_GPencil_update"); + /* Line Thickness */ prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "thickness"); - RNA_def_property_range(prop, 1, 300); + RNA_def_property_range(prop, 1, 1000); RNA_def_property_ui_range(prop, 1, 10, 1, 0); RNA_def_property_ui_text(prop, "Thickness", "Thickness of stroke (in pixels)"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); @@ -1062,7 +905,6 @@ static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new"); RNA_def_function_ui_description(func, "Add a new grease pencil stroke"); - parm = RNA_def_string(func, "colorname", 0, MAX_NAME, "Color", "Name of the color"); parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke"); RNA_def_function_return(func, parm); @@ -1183,20 +1025,30 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* Draw Style */ - // TODO: replace these with a "draw type" combo (i.e. strokes only, filled strokes, strokes + fills, volumetric)? - prop = RNA_def_property(srna, "use_volumetric_strokes", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_VOLUMETRIC); - RNA_def_property_ui_text(prop, "Volumetric Strokes", - "Draw strokes as a series of circular blobs, resulting in a volumetric effect"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* Layer Opacity */ prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "opacity"); RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + /* Stroke Drawing Color (Annotations) */ + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Color", "Color for all strokes in this layer"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + /* Line Thickness (Annotations) */ + prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "thickness"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_text(prop, "Thickness", "Thickness of annotation strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + /* Tint Color */ prop = RNA_def_property(srna, "tint_color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "tintcolor"); @@ -1212,62 +1064,21 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Tint Factor", "Factor of tinting color"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - /* Line Thickness change */ + /* Line Thickness Change */ prop = RNA_def_property(srna, "line_change", PROP_INT, PROP_PIXEL); - RNA_def_property_int_sdna(prop, NULL, "thickness"); - //RNA_def_property_range(prop, 1, 10); /* 10 px limit comes from Windows OpenGL limits for natively-drawn strokes */ - RNA_def_property_int_funcs(prop, NULL, NULL, "rna_GPencilLayer_line_width_range"); - RNA_def_property_ui_text(prop, "Thickness", "Thickness change to apply to current strokes (in pixels)"); + RNA_def_property_int_sdna(prop, NULL, "line_change"); + RNA_def_property_range(prop, -300, 300); + RNA_def_property_ui_range(prop, -100, 100, 1.0, 1); + RNA_def_property_ui_text(prop, "Thickness Change", "Thickness change to apply to current strokes (in pixels)"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* Onion-Skinning */ prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ONIONSKIN); + RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_LAYER_ONIONSKIN); RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_onion_skinning_update"); - - prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "gstep"); - RNA_def_property_range(prop, -1, 120); - RNA_def_property_ui_text(prop, "Frames Before", - "Maximum number of frames to show before current frame " - "(0 = show only the previous sketch, -1 = don't show any frames before current)"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "gstep_next"); - RNA_def_property_range(prop, -1, 120); - RNA_def_property_ui_text(prop, "Frames After", - "Maximum number of frames to show after current frame " - "(0 = show only the next sketch, -1 = don't show any frames after current)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_PREVCOL | GP_LAYER_GHOST_NEXTCOL); - RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "gcolor_prev"); - RNA_def_property_array(prop, 3); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "gcolor_next"); - RNA_def_property_array(prop, 3); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "use_ghosts_always", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_ALWAYS); - RNA_def_property_ui_text(prop, "Always Show Ghosts", - "Ghosts are shown in renders and animation playback. Useful for special effects (e.g. motion blur)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Flags */ prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE); @@ -1296,7 +1107,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* expose as layers.active */ + /* exposed as layers.active */ #if 0 prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_ACTIVE); @@ -1310,7 +1121,6 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, "rna_GPencil_update"); - /* XXX keep this option? */ prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG); RNA_def_property_ui_text(prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)"); @@ -1399,215 +1209,24 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL); prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, - "rna_GPencil_active_layer_index_get", - "rna_GPencil_active_layer_index_set", - "rna_GPencil_active_layer_index_range"); + RNA_def_property_int_funcs( + prop, + "rna_GPencil_active_layer_index_get", + "rna_GPencil_active_layer_index_set", + "rna_GPencil_active_layer_index_range"); RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL); -} - -static void rna_def_gpencil_palettecolor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - srna = RNA_def_struct(brna, "GPencilPaletteColor", NULL); - RNA_def_struct_sdna(srna, "bGPDpalettecolor"); - RNA_def_struct_ui_text(srna, "Grease Pencil Palette color", "Collection of related colors"); - RNA_def_struct_path_func(srna, "rna_GPencilPalette_color_path"); - - /* Stroke Drawing Color */ - prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "color"); - RNA_def_property_array(prop, 3); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Color", "Color for strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "color[3]"); - RNA_def_property_range(prop, 0.0, 1.0f); - RNA_def_property_ui_text(prop, "Opacity", "Color Opacity"); + /* Active Layer - As an enum (for selecting active layer for annotations) */ + prop = RNA_def_property(srna, "active_note", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_funcs( + prop, + "rna_GPencil_active_layer_index_get", + "rna_GPencil_active_layer_index_set", + "rna_GPencil_active_layer_itemf"); + RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items); /* purely dynamic, as it maps to user-data */ + RNA_def_property_ui_text(prop, "Active Note", "Note/Layer to add annotation strokes to"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Name */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "info"); - RNA_def_property_ui_text(prop, "Name", "Color name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilPaletteColor_info_set"); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Fill Drawing Color */ - prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "fill"); - RNA_def_property_array(prop, 3); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Fill alpha */ - prop = RNA_def_property(srna, "fill_alpha", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "fill[3]"); - RNA_def_property_range(prop, 0.0, 1.0f); - RNA_def_property_ui_text(prop, "Fill Opacity", "Opacity for filling region bounded by each stroke"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Flags */ - prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_HIDE); - RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, 1); - RNA_def_property_ui_text(prop, "Hide", "Set color Visibility"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_LOCKED); - RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); - RNA_def_property_ui_text(prop, "Locked", "Protect color from further editing and/or frame changes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - prop = RNA_def_property(srna, "ghost", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_ONIONSKIN); - RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); - RNA_def_property_ui_text(prop, "Show in Ghosts", "Display strokes using this color when showing onion skins"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Draw Style */ - prop = RNA_def_property(srna, "use_volumetric_strokes", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_VOLUMETRIC); - RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in " - "a volumetric effect"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Use High quality fill */ - prop = RNA_def_property(srna, "use_hq_fill", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_HQ_FILL); - RNA_def_property_ui_text(prop, "High Quality Fill", "Fill strokes using high quality to avoid glitches " - "(slower fps during animation play)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Read-only state props (for simpler UI code) */ - prop = RNA_def_property(srna, "is_stroke_visible", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_GPencilPaletteColor_is_stroke_visible_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Is Stroke Visible", "True when opacity of stroke is set high enough to be visible"); - - prop = RNA_def_property(srna, "is_fill_visible", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_GPencilPaletteColor_is_fill_visible_get", NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible"); -} - -/* palette colors api */ -static void rna_def_gpencil_palettecolors_api(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "GPencilPaletteColors"); - srna = RNA_def_struct(brna, "GPencilPaletteColors", NULL); - RNA_def_struct_sdna(srna, "bGPDpalette"); - RNA_def_struct_ui_text(srna, "Palette colors", "Collection of palette colors"); - - func = RNA_def_function(srna, "new", "rna_GPencilPalette_color_new"); - RNA_def_function_ui_description(func, "Add a new color to the palette"); - parm = RNA_def_pointer(func, "color", "GPencilPaletteColor", "", "The newly created color"); - RNA_def_function_return(func, parm); - - func = RNA_def_function(srna, "remove", "rna_GPencilPalette_color_remove"); - RNA_def_function_ui_description(func, "Remove a color from the palette"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_pointer(func, "color", "GPencilPaletteColor", "", "The color to remove"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); - RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); - - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "GPencilPaletteColor"); - RNA_def_property_pointer_funcs(prop, "rna_GPencilPalette_active_color_get", "rna_GPencilPalette_active_color_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active Palette Color", "Current active color"); - - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, - "rna_GPencilPaletteColor_index_get", - "rna_GPencilPaletteColor_index_set", - "rna_GPencilPaletteColor_index_range"); - RNA_def_property_ui_text(prop, "Active color Index", "Index of active palette color"); -} - -static void rna_def_gpencil_palette(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "GPencilPalette", NULL); - RNA_def_struct_sdna(srna, "bGPDpalette"); - RNA_def_struct_ui_text(srna, "Grease Pencil Palette", "Collection of related palettes"); - RNA_def_struct_path_func(srna, "rna_GPencilPalette_path"); - RNA_def_struct_ui_icon(srna, ICON_COLOR); - - /* Name */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "info"); - RNA_def_property_ui_text(prop, "Name", "Palette name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilPalette_info_set"); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); - - /* Colors */ - prop = RNA_def_property(srna, "colors", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "colors", NULL); - RNA_def_property_struct_type(prop, "GPencilPaletteColor"); - RNA_def_property_ui_text(prop, "Colors", "Colors of the palette"); - rna_def_gpencil_palettecolors_api(brna, prop); - -} - -static void rna_def_gpencil_palettes_api(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "GreasePencilPalettes"); - srna = RNA_def_struct(brna, "GreasePencilPalettes", NULL); - RNA_def_struct_sdna(srna, "bGPdata"); - RNA_def_struct_ui_text(srna, "Grease Pencil Palettes", "Collection of grease pencil palettes"); - - func = RNA_def_function(srna, "new", "rna_GPencil_palette_new"); - RNA_def_function_ui_description(func, "Add a new grease pencil palette"); - parm = RNA_def_string(func, "name", "GPencilPalette", MAX_NAME, "Name", "Name of the palette"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - RNA_def_boolean(func, "set_active", true, "Set Active", "Activate the newly created palette"); - parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The newly created palette"); - RNA_def_function_return(func, parm); - - func = RNA_def_function(srna, "remove", "rna_GPencil_palette_remove"); - RNA_def_function_ui_description(func, "Remove a grease pencil palette"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The palette to remove"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); - RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); - - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "GPencilPalette"); - RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_palette_get", "rna_GPencil_active_palette_set", - NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active Palette", "Current active palette"); - - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, - "rna_GPencilPalette_index_get", - "rna_GPencilPalette_index_set", - "rna_GPencilPalette_index_range"); - RNA_def_property_ui_text(prop, "Active Palette Index", "Index of active palette"); } static void rna_def_gpencil_data(BlenderRNA *brna) @@ -1616,6 +1235,10 @@ static void rna_def_gpencil_data(BlenderRNA *brna) PropertyRNA *prop; FunctionRNA *func; + static float default_1[4] = { 0.6f, 0.6f, 0.6f, 0.5f }; + static float onion_dft1[3] = { 0.145098f, 0.419608f, 0.137255f }; /* green */ + static float onion_dft2[3] = { 0.125490f, 0.082353f, 0.529412f }; /* blue */ + srna = RNA_def_struct(brna, "GreasePencil", "ID"); RNA_def_struct_sdna(srna, "bGPdata"); RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook"); @@ -1628,28 +1251,52 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Layers", ""); rna_def_gpencil_layers_api(brna, prop); - /* Palettes */ - prop = RNA_def_property(srna, "palettes", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "palettes", NULL); - RNA_def_property_struct_type(prop, "GPencilPalette"); - RNA_def_property_ui_text(prop, "Palettes", ""); - rna_def_gpencil_palettes_api(brna, prop); - /* Animation Data */ rna_def_animdata_common(srna); + /* materials */ + prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol"); + RNA_def_property_struct_type(prop, "Material"); + RNA_def_property_ui_text(prop, "Materials", ""); + RNA_def_property_srna(prop, "IDMaterials"); /* see rna_ID.c */ + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "rna_IDMaterials_assign_int"); + + /* xray modes */ + prop = RNA_def_property(srna, "xray_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "xray_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_xraymodes_items); + RNA_def_property_ui_text(prop, "Xray", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* Flags */ prop = RNA_def_property(srna, "use_stroke_edit_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_EDITMODE); RNA_def_property_ui_text(prop, "Stroke Edit Mode", "Edit Grease Pencil strokes instead of viewport data"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update"); + prop = RNA_def_property(srna, "is_stroke_paint_mode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_PAINTMODE); + RNA_def_property_ui_text(prop, "Stroke Paint Mode", "Draw Grease Pencil strokes on click/drag"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update"); + + prop = RNA_def_property(srna, "is_stroke_sculpt_mode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_SCULPTMODE); + RNA_def_property_ui_text(prop, "Stroke Sculpt Mode", "Sculpt Grease Pencil strokes instead of viewport data"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update"); + + prop = RNA_def_property(srna, "is_stroke_weight_mode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_WEIGHTMODE); + RNA_def_property_ui_text(prop, "Stroke Weight Paint Mode", "Grease Pencil weight paint"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update"); + prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_ONIONSKINS); - RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_use_onion_skinning_set"); - RNA_def_property_ui_text(prop, "Onion Skins", - "Show ghosts of the frames before and after the current frame, toggle to enable on active layer or disable all"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_ui_text(prop, "Onion Skins", "Show ghosts of the frames before and after the current frame"); + RNA_def_property_update(prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update"); prop = RNA_def_property(srna, "show_stroke_direction", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_DIRECTION); @@ -1657,6 +1304,102 @@ static void rna_def_gpencil_data(BlenderRNA *brna) "and smaller red dot (end) points"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + prop = RNA_def_property(srna, "show_constant_thickness", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_KEEPTHICKNESS); + RNA_def_property_ui_text(prop, "Keep thickness", "Show stroke with same thickness when viewport zoom change"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "pixfactor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "pixfactor"); + RNA_def_property_range(prop, 0.1f, 30.0f); + RNA_def_property_ui_range(prop, 0.1f, 30.0f, 1, 2); + RNA_def_property_ui_text(prop, "Scale", "Scale conversion factor for pixel size (use larger values for thicker lines)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_multiedit", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_MULTIEDIT); + RNA_def_property_ui_text(prop, "MultiFrame", "Edit strokes from multiple grease pencil keyframes at the same time (keyframes must be selected to be included)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "edit_line_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "line_color"); + RNA_def_property_array(prop, 4); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_array_default(prop, default_1); + RNA_def_property_ui_text(prop, "Edit Line Color", "Color for editing line"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + /* onion skinning */ + prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "gstep"); + RNA_def_property_range(prop, 0, 120); + RNA_def_property_int_default(prop, 1); + RNA_def_property_ui_text(prop, "Frames Before", + "Maximum number of frames to show before current frame " + "(0 = don't show any frames before current)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "gstep_next"); + RNA_def_property_range(prop, 0, 120); + RNA_def_property_int_default(prop, 1); + RNA_def_property_ui_text(prop, "Frames After", + "Maximum number of frames to show after current frame " + "(0 = don't show any frames after current)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL); + RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "gcolor_prev"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_array_default(prop, onion_dft1); + RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame"); + RNA_def_property_update(prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "gcolor_next"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_array_default(prop, onion_dft2); + RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame"); + RNA_def_property_update(prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_ghosts_always", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_GHOST_ALWAYS); + RNA_def_property_ui_text(prop, "Always Show Ghosts", + "Ghosts are shown in renders and animation playback. Useful for special effects (e.g. motion blur)"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "onion_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "onion_mode"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_onion_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Mode to display frames"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_onion_fade", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_FADE); + RNA_def_property_ui_text(prop, "Fade", + "Display onion keyframes with a fade in color transparency"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_onion_loop", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_LOOP); + RNA_def_property_ui_text(prop, "Loop", + "Display first onion keyframes using next frame color to show indication of loop start frame"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "onion_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "onion_factor"); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_range(prop, 0.0, 1.0f); + RNA_def_property_ui_text(prop, "Onion Opacity", "Change fade opacity of displayed onion frames"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* API Functions */ func = RNA_def_function(srna, "clear", "rna_GPencil_clear"); RNA_def_function_ui_description(func, "Remove all the grease pencil data"); @@ -1670,12 +1413,12 @@ void RNA_def_gpencil(BlenderRNA *brna) rna_def_gpencil_layer(brna); rna_def_gpencil_frame(brna); - rna_def_gpencil_triangle(brna); + rna_def_gpencil_stroke(brna); rna_def_gpencil_stroke_point(brna); + rna_def_gpencil_triangle(brna); - rna_def_gpencil_palette(brna); - rna_def_gpencil_palettecolor(brna); + rna_def_gpencil_mvert_group(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c new file mode 100644 index 00000000000..df64121b2b4 --- /dev/null +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -0,0 +1,1314 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_gpencil_modifier.c + * \ingroup RNA + */ + + +#include +#include +#include + +#include "DNA_armature_types.h" +#include "DNA_cachefile_types.h" +#include "DNA_mesh_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force_types.h" +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "BLT_translation.h" + +#include "BKE_animsys.h" +#include "BKE_data_transfer.h" +#include "BKE_DerivedMesh.h" +#include "BKE_dynamicpaint.h" +#include "BKE_effect.h" +#include "BKE_mesh_mapping.h" +#include "BKE_mesh_remap.h" +#include "BKE_multires.h" +#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */ +#include "BKE_gpencil_modifier.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "rna_internal.h" + +#include "WM_api.h" +#include "WM_types.h" + +const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = { + {0, "", 0, N_("Generate"), "" }, + {eGpencilModifierType_Instance, "GP_INSTANCE", ICON_MOD_ARRAY, "Instance", "Create grid of duplicate instances"}, + {eGpencilModifierType_Build, "GP_BUILD", ICON_MOD_BUILD, "Build", "Create duplication of strokes"}, + {eGpencilModifierType_Simplify, "GP_SIMPLIFY", ICON_MOD_DECIM, "Simplify", "Simplify stroke reducing number of points"}, + {eGpencilModifierType_Subdiv, "GP_SUBDIV", ICON_MOD_SUBSURF, "Subdivide", "Subdivide stroke adding more control points"}, + {0, "", 0, N_("Deform"), "" }, + {eGpencilModifierType_Hook, "GP_HOOK", ICON_HOOK, "Hook", "Deform stroke points using objects"}, + {eGpencilModifierType_Lattice, "GP_LATTICE", ICON_MOD_LATTICE, "Lattice", "Deform strokes using lattice"}, + {eGpencilModifierType_Mirror, "GP_MIRROR", ICON_MOD_MIRROR, "Mirror", "Duplicate strokes like a mirror"}, + {eGpencilModifierType_Noise, "GP_NOISE", ICON_RNDCURVE, "Noise", "Add noise to strokes"}, + {eGpencilModifierType_Offset, "GP_OFFSET", ICON_MOD_DISPLACE, "Offset", "Change stroke location, rotation or scale"}, + {eGpencilModifierType_Smooth, "GP_SMOOTH", ICON_MOD_SMOOTH, "Smooth", "Smooth stroke"}, + {eGpencilModifierType_Thick, "GP_THICK", ICON_MAN_ROT, "Thickness", "Change stroke thickness"}, + {0, "", 0, N_("Color"), "" }, + {eGpencilModifierType_Color, "GP_COLOR", ICON_GROUP_VCOL, "Hue/Saturation", "Apply changes to stroke colors"}, + {eGpencilModifierType_Opacity, "GP_OPACITY", ICON_MOD_MASK, "Opacity", "Opacity of the strokes"}, + {eGpencilModifierType_Tint, "GP_TINT", ICON_COLOR, "Tint", "Tint strokes with new color"}, + {0, NULL, 0, NULL, NULL} +}; + +#ifndef RNA_RUNTIME +static const EnumPropertyItem modifier_gphook_falloff_items[] = { + { eGPHook_Falloff_None, "NONE", 0, "No Falloff", "" }, + { eGPHook_Falloff_Curve, "CURVE", 0, "Curve", "" }, + { eGPHook_Falloff_Smooth, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", "" }, + { eGPHook_Falloff_Sphere, "SPHERE", ICON_SPHERECURVE, "Sphere", "" }, + { eGPHook_Falloff_Root, "ROOT", ICON_ROOTCURVE, "Root", "" }, + { eGPHook_Falloff_InvSquare, "INVERSE_SQUARE", ICON_ROOTCURVE, "Inverse Square", "" }, + { eGPHook_Falloff_Sharp, "SHARP", ICON_SHARPCURVE, "Sharp", "" }, + { eGPHook_Falloff_Linear, "LINEAR", ICON_LINCURVE, "Linear", "" }, + { eGPHook_Falloff_Const, "CONSTANT", ICON_NOCURVE, "Constant", "" }, + { 0, NULL, 0, NULL, NULL } +}; + +static const EnumPropertyItem rna_enum_gpencil_lockshift_items[] = { + { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", 0, "X", "Use X axis" }, + { GP_LOCKAXIS_Y, "GP_LOCKAXIS_Y", 0, "Y", "Use Y axis" }, + { GP_LOCKAXIS_Z, "GP_LOCKAXIS_Z", 0, "Z", "Use Z axis" }, + { 0, NULL, 0, NULL, NULL } +}; + +#endif + +#ifdef RNA_RUNTIME + +#include "DNA_particle_types.h" +#include "DNA_curve_types.h" +#include "DNA_smoke_types.h" + +#include "BKE_cachefile.h" +#include "BKE_context.h" +#include "BKE_library.h" +#include "BKE_gpencil_modifier.h" +#include "BKE_object.h" +#include "BKE_gpencil.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + +static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr) +{ + GpencilModifierData *md = (GpencilModifierData *)ptr->data; + + switch ((GpencilModifierType)md->type) { + case eGpencilModifierType_Noise: + return &RNA_NoiseGpencilModifier; + case eGpencilModifierType_Subdiv: + return &RNA_SubdivGpencilModifier; + case eGpencilModifierType_Simplify: + return &RNA_SimplifyGpencilModifier; + case eGpencilModifierType_Thick: + return &RNA_ThickGpencilModifier; + case eGpencilModifierType_Tint: + return &RNA_TintGpencilModifier; + case eGpencilModifierType_Color: + return &RNA_ColorGpencilModifier; + case eGpencilModifierType_Instance: + return &RNA_InstanceGpencilModifier; + case eGpencilModifierType_Build: + return &RNA_BuildGpencilModifier; + case eGpencilModifierType_Opacity: + return &RNA_OpacityGpencilModifier; + case eGpencilModifierType_Lattice: + return &RNA_LatticeGpencilModifier; + case eGpencilModifierType_Mirror: + return &RNA_MirrorGpencilModifier; + case eGpencilModifierType_Smooth: + return &RNA_SmoothGpencilModifier; + case eGpencilModifierType_Hook: + return &RNA_HookGpencilModifier; + case eGpencilModifierType_Offset: + return &RNA_OffsetGpencilModifier; + /* Default */ + case eGpencilModifierType_None: + case NUM_GREASEPENCIL_MODIFIER_TYPES: + return &RNA_GpencilModifier; + } + + return &RNA_GpencilModifier; +} + +static void rna_GpencilModifier_name_set(PointerRNA *ptr, const char *value) +{ + GpencilModifierData *gmd = ptr->data; + char oldname[sizeof(gmd->name)]; + + /* make a copy of the old name first */ + BLI_strncpy(oldname, gmd->name, sizeof(gmd->name)); + + /* copy the new name into the name slot */ + BLI_strncpy_utf8(gmd->name, value, sizeof(gmd->name)); + + /* make sure the name is truly unique */ + if (ptr->id.data) { + Object *ob = ptr->id.data; + BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, gmd); + } + + /* fix all the animation data which may link to this */ + BKE_animdata_fix_paths_rename_all(NULL, "grease_pencil_modifiers", oldname, gmd->name); +} + +static char *rna_GpencilModifier_path(PointerRNA *ptr) +{ + GpencilModifierData *gmd = ptr->data; + char name_esc[sizeof(gmd->name) * 2]; + + BLI_strescape(name_esc, gmd->name, sizeof(name_esc)); + return BLI_sprintfN("grease_pencil_modifiers[\"%s\"]", name_esc); +} + +static void rna_GpencilModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ptr->id.data); +} + +static void rna_GpencilModifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + rna_GpencilModifier_update(bmain, scene, ptr); + DEG_relations_tag_update(bmain); +} + +/* Vertex Groups */ + +#define RNA_GP_MOD_VGROUP_NAME_SET(_type, _prop) \ +static void rna_##_type##GpencilModifier_##_prop##_set(PointerRNA *ptr, const char *value) \ +{ \ + _type##GpencilModifierData *tmd = (_type##GpencilModifierData *)ptr->data; \ + rna_object_vgroup_name_set(ptr, value, tmd->_prop, sizeof(tmd->_prop)); \ +} + +RNA_GP_MOD_VGROUP_NAME_SET(Noise, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Thick, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Opacity, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Lattice, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Smooth, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Hook, vgname); +RNA_GP_MOD_VGROUP_NAME_SET(Offset, vgname); + +#undef RNA_GP_MOD_VGROUP_NAME_SET + +/* Objects */ + +static void greasepencil_modifier_object_set(Object *self, Object **ob_p, int type, PointerRNA value) +{ + Object *ob = value.data; + + if (!self || ob != self) { + if (!ob || type == OB_EMPTY || ob->type == type) { + id_lib_extern((ID *)ob); + *ob_p = ob; + } + } +} + +#define RNA_GP_MOD_OBJECT_SET(_type, _prop, _obtype) \ +static void rna_##_type##GpencilModifier_##_prop##_set(PointerRNA *ptr, PointerRNA value) \ +{ \ + _type##GpencilModifierData *tmd = (_type##GpencilModifierData *)ptr->data; \ + greasepencil_modifier_object_set(ptr->id.data, &tmd->_prop, _obtype, value); \ +} + +RNA_GP_MOD_OBJECT_SET(Lattice, object, OB_LATTICE); +RNA_GP_MOD_OBJECT_SET(Mirror, object, OB_EMPTY); + +#undef RNA_GP_MOD_OBJECT_SET + +static void rna_HookGpencilModifier_object_set(PointerRNA *ptr, PointerRNA value) +{ + HookGpencilModifierData *hmd = ptr->data; + Object *ob = (Object *)value.data; + + hmd->object = ob; + id_lib_extern((ID *)ob); + BKE_object_modifier_gpencil_hook_reset(ob, hmd); +} + +#else + +static void rna_def_modifier_gpencilnoise(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "NoiseGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Noise Modifier", "Noise effect modifier"); + RNA_def_struct_sdna(srna, "NoiseGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_RNDCURVE); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NoiseGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_range(prop, 0, 30.0); + RNA_def_property_ui_text(prop, "Factor", "Amount of noise to apply"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "random", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_USE_RANDOM); + RNA_def_property_ui_text(prop, "Random", "Use random values"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_position", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_MOD_LOCATION); + RNA_def_property_ui_text(prop, "Affect Position", "The modifier affects the position of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_strength", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_MOD_STRENGTH); + RNA_def_property_ui_text(prop, "Affect Strength", "The modifier affects the color strength of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_thickness", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_MOD_THICKNESS); + RNA_def_property_ui_text(prop, "Affect Thickness", "The modifier affects the thickness of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_uv", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_MOD_UV); + RNA_def_property_ui_text(prop, "Affect UV", "The modifier affects the UV rotation factor of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "full_stroke", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_FULL_STROKE); + RNA_def_property_ui_text(prop, "Full Stroke", "The noise moves the stroke as a whole, not point by point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "move_extreme", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_MOVE_EXTREME); + RNA_def_property_ui_text(prop, "Move Extremes", "The noise moves the stroke extreme points"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "step"); + RNA_def_property_range(prop, 1, 100); + RNA_def_property_ui_text(prop, "Step", "Number of frames before recalculate random values again"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_NOISE_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilsmooth(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "SmoothGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Smooth Modifier", "Smooth effect modifier"); + RNA_def_struct_sdna(srna, "SmoothGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_SMOOTH); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmoothGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_range(prop, 0, 2); + RNA_def_property_ui_text(prop, "Factor", "Amount of smooth to apply"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_position", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_MOD_LOCATION); + RNA_def_property_ui_text(prop, "Affect Position", "The modifier affects the position of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_strength", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_MOD_STRENGTH); + RNA_def_property_ui_text(prop, "Affect Strength", "The modifier affects the color strength of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_thickness", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_MOD_THICKNESS); + RNA_def_property_ui_text(prop, "Affect Thickness", "The modifier affects the thickness of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "affect_uv", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_MOD_UV); + RNA_def_property_ui_text(prop, "Affect UV", "The modifier affects the UV rotation factor of the point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "step"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_text(prop, "Step", "Number of times to apply smooth (high numbers can reduce fps)"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilsubdiv(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "SubdivGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Subdivision Modifier", "Subdivide Stroke modifier"); + RNA_def_struct_sdna(srna, "SubdivGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_SUBSURF); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "level", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "level"); + RNA_def_property_range(prop, 0, 5); + RNA_def_property_ui_text(prop, "Level", "Number of subdivisions"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "simple", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SUBDIV_SIMPLE); + RNA_def_property_ui_text(prop, "Simple", "The modifier only add control points"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SUBDIV_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SUBDIV_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilsimplify(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_gpencil_simplify_mode_items[] = { + { GP_SIMPLIFY_FIXED, "FIXED", ICON_IPO_CONSTANT, "Fixed", + "Delete alternative vertices in the stroke, except extrems" }, + { GP_SIMPLIFY_ADAPTATIVE, "ADAPTATIVE", ICON_IPO_EASE_IN_OUT, "Adaptative", + "Use a RDP algorithm to simplify" }, + { 0, NULL, 0, NULL, NULL } + }; + + srna = RNA_def_struct(brna, "SimplifyGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Simplify Modifier", "Simplify Stroke modifier"); + RNA_def_struct_sdna(srna, "SimplifyGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_DECIM); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_range(prop, 0, 100.0); + RNA_def_property_ui_range(prop, 0, 100.0, 1.0f, 3); + RNA_def_property_ui_text(prop, "Factor", "Factor of Simplify"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SIMPLIFY_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SIMPLIFY_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Mode */ + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_gpencil_simplify_mode_items); + RNA_def_property_ui_text(prop, "Mode", "How simplify the stroke"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "step"); + RNA_def_property_range(prop, 1, 50); + RNA_def_property_ui_text(prop, "Iterations", "Number of times to apply simplify"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilthick(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ThickGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Thick Modifier", "Subdivide and Smooth Stroke modifier"); + RNA_def_struct_sdna(srna, "ThickGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MAN_ROT); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ThickGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "thickness"); + RNA_def_property_range(prop, -100, 500); + RNA_def_property_ui_text(prop, "Thickness", "Factor of thickness change"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "use_custom_curve", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_CUSTOM_CURVE); + RNA_def_property_ui_text(prop, "Custom Curve", "Use a custom curve to define thickness changes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "normalize_thickness", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_THICK_NORMALIZE); + RNA_def_property_ui_text(prop, "Normalize", "Normalize the full stroke to modifier thickness"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "curve_thickness"); + RNA_def_property_ui_text(prop, "Curve", "Custom Thickness Curve"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpenciloffset(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "OffsetGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Offset Modifier", "Offset Stroke modifier"); + RNA_def_struct_sdna(srna, "OffsetGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_DISPLACE); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_OffsetGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OFFSET_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OFFSET_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OFFSET_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "loc"); + RNA_def_property_ui_text(prop, "Location", "Values for change location"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); + RNA_def_property_float_sdna(prop, NULL, "rot"); + RNA_def_property_ui_text(prop, "Rotation", "Values for chages in rotation"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_ui_text(prop, "Scale", "Values for changes in scale"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpenciltint(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "TintGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Tint Modifier", "Tint Stroke Color modifier"); + RNA_def_struct_sdna(srna, "TintGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_COLOR); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "rgb"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Color", "Color used for tinting"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_ui_range(prop, 0, 2.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Factor", "Factor for mixing color"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "create_colors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TINT_CREATE_COLORS); + RNA_def_property_ui_text(prop, "Create Colors", "When apply modifier, create new color in the palette"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TINT_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TINT_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilcolor(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ColorGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Hue/Saturation Modifier", "Change Hue/Saturation modifier"); + RNA_def_struct_sdna(srna, "ColorGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "hue", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.1, 3); + RNA_def_property_float_sdna(prop, NULL, "hsv[0]"); + RNA_def_property_ui_text(prop, "Hue", "Color Hue"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.1, 3); + RNA_def_property_float_sdna(prop, NULL, "hsv[1]"); + RNA_def_property_ui_text(prop, "Saturation", "Color Saturation"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.1, 3); + RNA_def_property_float_sdna(prop, NULL, "hsv[2]"); + RNA_def_property_ui_text(prop, "Value", "Color Value"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "create_colors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_COLOR_CREATE_COLORS); + RNA_def_property_ui_text(prop, "Create Colors", "When apply modifier, create new color in the palette"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_COLOR_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_COLOR_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilopacity(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "OpacityGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Opacity Modifier", "Opacity of Strokes modifier"); + RNA_def_struct_sdna(srna, "OpacityGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_OpacityGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_ui_range(prop, 0, 2.0, 0.1, 3); + RNA_def_property_ui_text(prop, "Factor", "Factor of Opacity"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OPACITY_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OPACITY_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OPACITY_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilinstance(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "InstanceGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Instance Modifier", "Create grid of duplicate instances"); + RNA_def_struct_sdna(srna, "InstanceGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_ARRAY); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "count", PROP_INT, PROP_XYZ); + RNA_def_property_range(prop, 1, INT_MAX); + RNA_def_property_ui_range(prop, 1, 1000, 1, -1); + RNA_def_property_ui_text(prop, "Count", "Number of items"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Offset parameters */ + prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "offset"); + RNA_def_property_ui_text(prop, "Offset", "Value for the distance between items"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "shift", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_float_sdna(prop, NULL, "shift"); + RNA_def_property_ui_text(prop, "Shift", "Shiftness value"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "lock_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "lock_axis"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_lockshift_items); + //RNA_def_property_flag(prop, PROP_ENUM_FLAG); + RNA_def_property_ui_text(prop, "Axis", ""); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); + RNA_def_property_float_sdna(prop, NULL, "rot"); + RNA_def_property_ui_text(prop, "Rotation", "Value for chages in rotation"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_ui_text(prop, "Scale", "Value for changes in scale"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "random_rot", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_RANDOM_ROT); + RNA_def_property_ui_text(prop, "Random Rotation", "Use random factors for rotation"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "rot_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "rnd_rot"); + RNA_def_property_ui_text(prop, "Rotation Factor", "Random factor for rotation"); + RNA_def_property_range(prop, -10.0, 10.0); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "random_scale", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_RANDOM_SIZE); + RNA_def_property_ui_text(prop, "Random Scale", "Use random factors for scale"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "scale_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "rnd_size"); + RNA_def_property_ui_text(prop, "Scale Factor", "Random factor for scale"); + RNA_def_property_range(prop, -10.0, 10.0); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "use_make_objects", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_MAKE_OBJECTS); + RNA_def_property_ui_text(prop, "Make Objects", + "When applying this modifier, instances get created as separate objects"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilbuild(BlenderRNA *brna) +{ + static EnumPropertyItem prop_gpencil_build_mode_items[] = { + {GP_BUILD_MODE_SEQUENTIAL, "SEQUENTIAL", ICON_PARTICLE_POINT, "Sequential", + "Strokes appear/disappear one after the other, but only a single one changes at a time"}, + {GP_BUILD_MODE_CONCURRENT, "CONCURRENT", ICON_PARTICLE_TIP, "Concurrent", + "Multiple strokes appear/disappear at once"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem prop_gpencil_build_transition_items[] = { + {GP_BUILD_TRANSITION_GROW, "GROW", 0, "Grow", + "Show points in the order they occur in each stroke " + "(e.g. for animating lines being drawn)"}, + {GP_BUILD_TRANSITION_SHRINK, "SHRINK", 0, "Shrink", + "Hide points from the end of each stroke to the start " + "(e.g. for animating lines being erased)"}, + {GP_BUILD_TRANSITION_FADE, "FADE", 0, "Fade", + "Hide points in the order they occur in each stroke " + "(e.g. for animating ink fading or vanishing after getting drawn)"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem prop_gpencil_build_time_align_items[] = { + {GP_BUILD_TIMEALIGN_START, "START", 0, "Align Start", + "All strokes start at same time (i.e. short strokes finish earlier)"}, + {GP_BUILD_TIMEALIGN_END, "END", 0, "Align End", + "All strokes end at same time (i.e. short strokes start later)"}, + {0, NULL, 0, NULL, NULL} + }; + + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "BuildGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Build Modifier", "Animate strokes appearing and disappearing"); + RNA_def_struct_sdna(srna, "BuildGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_BUILD); + + /* Mode */ + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_gpencil_build_mode_items); + RNA_def_property_ui_text(prop, "Mode", "How many strokes are being animated at a time"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Direction */ + prop = RNA_def_property(srna, "transition", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_gpencil_build_transition_items); + RNA_def_property_ui_text(prop, "Transition", "How are strokes animated (i.e. are they appearing or disappearing)"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + + /* Transition Onset Delay + Length */ + prop = RNA_def_property(srna, "start_delay", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "start_delay"); + RNA_def_property_ui_text(prop, "Start Delay", "Number of frames after each GP keyframe before the modifier has any effect"); + RNA_def_property_range(prop, 0, MAXFRAMEF); + RNA_def_property_ui_range(prop, 0, 200, 1, -1); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "length", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "length"); + RNA_def_property_ui_text(prop, "Length", + "Maximum number of frames that the build effect can run for " + "(unless another GP keyframe occurs before this time has elapsed)"); + RNA_def_property_range(prop, 1, MAXFRAMEF); + RNA_def_property_ui_range(prop, 1, 1000, 1, -1); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + + /* Concurrent Mode Settings */ + prop = RNA_def_property(srna, "concurrent_time_alignment", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "time_alignment"); + RNA_def_property_enum_items(prop, prop_gpencil_build_time_align_items); + RNA_def_property_ui_text(prop, "Time Alignment", "When should strokes start to appear/disappear"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + + + /* Time Limits */ + prop = RNA_def_property(srna, "use_restrict_frame_range", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BUILD_RESTRICT_TIME); + RNA_def_property_ui_text(prop, "Restrict Frame Range", "Only modify strokes during the specified frame range"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "start_frame"); + RNA_def_property_ui_text(prop, "Start Frame", "Start Frame (when Restrict Frame Range is enabled)"); + RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "end_frame"); + RNA_def_property_ui_text(prop, "End Frame", "End Frame (when Restrict Frame Range is enabled)"); + RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + + /* Filters - Layer */ + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BUILD_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Filters - Pass Index */ +#if 0 + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BUILD_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +#endif +} + +static void rna_def_modifier_gpencillattice(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "LatticeGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Lattice Modifier", "Change stroke using lattice to deform modifier"); + RNA_def_struct_sdna(srna, "LatticeGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_LATTICE); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LatticeGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LATTICE_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LATTICE_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LATTICE_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Object", "Lattice object to deform with"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_LatticeGpencilModifier_object_set", NULL, "rna_Lattice_object_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); + + prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 1, 10, 2); + RNA_def_property_ui_text(prop, "Strength", "Strength of modifier effect"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilmirror(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "MirrorGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Mirror Modifier", "Change stroke using lattice to deform modifier"); + RNA_def_struct_sdna(srna, "MirrorGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_MIRROR); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Object", "Object used as center"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_MirrorGpencilModifier_object_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); + + prop = RNA_def_property(srna, "clip", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_CLIPPING); + RNA_def_property_ui_text(prop, "Clip", "Clip points"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "x_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_AXIS_X); + RNA_def_property_ui_text(prop, "X", "Mirror this axis"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "y_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_AXIS_Y); + RNA_def_property_ui_text(prop, "Y", "Mirror this axis"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "z_axis", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MIRROR_AXIS_Z); + RNA_def_property_ui_text(prop, "Z", "Mirror this axis"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + +static void rna_def_modifier_gpencilhook(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "HookGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Hook Modifier", "Hook modifier to modify the location of stroke points"); + RNA_def_struct_sdna(srna, "HookGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_HOOK); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Object", "Parent Object for hook, also recalculates and clears offset"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_pointer_funcs(prop, NULL, "rna_HookGpencilModifier_object_set", NULL, NULL); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); + + prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "subtarget"); + RNA_def_property_ui_text(prop, "Sub-Target", + "Name of Parent Bone for hook (if applicable), also recalculates and clears offset"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update"); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgname"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_HookGpencilModifier_vgname_set"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "pass_index"); + RNA_def_property_range(prop, 0, 100); + RNA_def_property_ui_text(prop, "Pass", "Pass index"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_HOOK_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_HOOK_INVERT_PASS); + RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_HOOK_INVERT_VGROUP); + RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "force"); + RNA_def_property_range(prop, 0, 1); + RNA_def_property_ui_text(prop, "Strength", "Relative force of the hook"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, modifier_gphook_falloff_items); /* share the enum */ + RNA_def_property_ui_text(prop, "Falloff Type", ""); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "falloff_radius", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "falloff"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, 100, 100, 2); + RNA_def_property_ui_text(prop, "Radius", "If not zero, the distance from the hook where influence ends"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "curfalloff"); + RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "cent"); + RNA_def_property_ui_text(prop, "Hook Center", ""); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "matrix_inverse", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "parentinv"); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(prop, "Matrix", "Reverse the transformation between this object and its target"); + RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "use_falloff_uniform", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_HOOK_UNIFORM_SPACE); + RNA_def_property_ui_text(prop, "Uniform Falloff", "Compensate for non-uniform object scale"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} +void RNA_def_greasepencil_modifier(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* data */ + srna = RNA_def_struct(brna, "GpencilModifier", NULL); + RNA_def_struct_ui_text(srna, "GpencilModifier", "Modifier affecting the grease pencil object"); + RNA_def_struct_refine_func(srna, "rna_GpencilModifier_refine"); + RNA_def_struct_path_func(srna, "rna_GpencilModifier_path"); + RNA_def_struct_sdna(srna, "GpencilModifierData"); + + /* strings */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GpencilModifier_name_set"); + RNA_def_property_ui_text(prop, "Name", "Modifier name"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL); + RNA_def_struct_name_property(srna, prop); + + /* enums */ + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, rna_enum_object_greasepencil_modifier_type_items); + RNA_def_property_ui_text(prop, "Type", ""); + + /* flags */ + prop = RNA_def_property(srna, "show_viewport", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eGpencilModifierMode_Realtime); + RNA_def_property_ui_text(prop, "Realtime", "Display modifier in viewport"); + RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0); + + prop = RNA_def_property(srna, "show_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eGpencilModifierMode_Render); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_ui_text(prop, "Render", "Use modifier during render"); + RNA_def_property_ui_icon(prop, ICON_SCENE, 0); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL); + + prop = RNA_def_property(srna, "show_in_editmode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eGpencilModifierMode_Editmode); + RNA_def_property_ui_text(prop, "Edit Mode", "Display modifier in Edit mode"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0); + + prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eGpencilModifierMode_Expanded); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_ui_text(prop, "Expanded", "Set modifier expanded in the user interface"); + RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); + + /* types */ + rna_def_modifier_gpencilnoise(brna); + rna_def_modifier_gpencilsmooth(brna); + rna_def_modifier_gpencilsubdiv(brna); + rna_def_modifier_gpencilsimplify(brna); + rna_def_modifier_gpencilthick(brna); + rna_def_modifier_gpenciloffset(brna); + rna_def_modifier_gpenciltint(brna); + rna_def_modifier_gpencilcolor(brna); + rna_def_modifier_gpencilinstance(brna); + rna_def_modifier_gpencilbuild(brna); + rna_def_modifier_gpencilopacity(brna); + rna_def_modifier_gpencillattice(brna); + rna_def_modifier_gpencilmirror(brna); + rna_def_modifier_gpencilhook(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 83d173de6c8..a88623e5b5b 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -153,6 +153,8 @@ void RNA_def_dynamic_paint(struct BlenderRNA *brna); void RNA_def_fluidsim(struct BlenderRNA *brna); void RNA_def_fcurve(struct BlenderRNA *brna); void RNA_def_gpencil(struct BlenderRNA *brna); +void RNA_def_greasepencil_modifier(struct BlenderRNA *brna); +void RNA_def_shader_fx(struct BlenderRNA *brna); void RNA_def_image(struct BlenderRNA *brna); void RNA_def_key(struct BlenderRNA *brna); void RNA_def_light(struct BlenderRNA *brna); @@ -283,6 +285,7 @@ void rna_TextureSlot_update(struct bContext *C, struct PointerRNA *ptr); bool rna_Armature_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Camera_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Curve_object_poll(struct PointerRNA *ptr, struct PointerRNA value); +bool rna_GPencil_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Light_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Lattice_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Mesh_object_poll(struct PointerRNA *ptr, struct PointerRNA value); @@ -291,6 +294,10 @@ bool rna_Mesh_object_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Action_id_poll(struct PointerRNA *ptr, struct PointerRNA value); bool rna_Action_actedit_assign_poll(struct PointerRNA *ptr, struct PointerRNA value); +/* Grease Pencil datablock polling functions - for filtering GP Object vs Annotation datablocks */ +bool rna_GPencil_datablocks_annotations_poll(struct PointerRNA *ptr, const struct PointerRNA value); +bool rna_GPencil_datablocks_obdata_poll(struct PointerRNA *ptr, const struct PointerRNA value); + char *rna_TextureSlot_path(struct PointerRNA *ptr); char *rna_Node_ImageUser_path(struct PointerRNA *ptr); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index febe74f63c9..50aa3cb5b81 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -231,6 +231,9 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char case ID_LT: type = OB_LATTICE; break; + case ID_GD: + type = OB_GPENCIL; + break; case ID_AR: type = OB_ARMATURE; break; @@ -266,6 +269,11 @@ static Material *rna_Main_materials_new(Main *bmain, const char *name) return (Material *)id; } +static void rna_Main_materials_gpencil_data(Main *UNUSED(bmain), struct PointerRNA *ma) +{ + BKE_material_init_gpencil_settings((Material *)ma); +} + static const EnumPropertyItem *rna_Main_nodetree_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { return rna_node_tree_type_itemf(NULL, NULL, r_free); @@ -783,6 +791,11 @@ void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_pointer(func, "material", "Material", "", "New material data-block"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "create_gpencil_data", "rna_Main_materials_gpencil_data"); + RNA_def_function_ui_description(func, "Add grease pencil material settings"); + parm = RNA_def_pointer(func, "material", "Material", "", "Material"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + func = RNA_def_function(srna, "remove", "rna_Main_ID_remove"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a material from the current blendfile"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 0a8ea99b8fb..56f5a12516b 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -72,6 +72,7 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = { #include "BKE_colorband.h" #include "BKE_context.h" #include "BKE_main.h" +#include "BKE_gpencil.h" #include "BKE_material.h" #include "BKE_texture.h" #include "BKE_node.h" @@ -85,6 +86,7 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = { #include "ED_node.h" #include "ED_image.h" #include "ED_screen.h" +#include "ED_gpencil.h" static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { @@ -104,6 +106,30 @@ static void rna_Material_update_previews(Main *UNUSED(bmain), Scene *UNUSED(scen WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma); } +static void rna_MaterialGpencil_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Material *ma = ptr->id.data; + PreviewImage *preview = ma->preview; + + rna_Material_update(bmain, scene, ptr); + + /* update previews (icon and thumbnail) */ + preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; + preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; + WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA, ma); +} + +static void rna_MaterialGpencil_nopreview_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Material *ma = ptr->id.data; + + rna_Material_update(bmain, scene, ptr); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA, ma); +} + static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Material *ma = ptr->id.data; @@ -243,6 +269,59 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C)); } +static bool rna_is_grease_pencil_get(PointerRNA *ptr) +{ + Material *ma = (Material *)ptr->data; + if (ma->gp_style != NULL) + return true; + + return false; +} + +static void rna_gpcolordata_uv_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + /* update all uv strokes of this color */ + Material *ma = ptr->id.data; + ED_gpencil_update_color_uv(bmain, ma); + + rna_MaterialGpencil_update(bmain, scene, ptr); +} + +static char *rna_GpencilColorData_path(PointerRNA *UNUSED(ptr)) +{ + return BLI_sprintfN("grease_pencil"); +} + +static int rna_GpencilColorData_is_stroke_visible_get(PointerRNA *ptr) +{ + MaterialGPencilStyle *pcolor = ptr->data; + return (pcolor->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH); +} + +static int rna_GpencilColorData_is_fill_visible_get(PointerRNA *ptr) +{ + MaterialGPencilStyle *pcolor = (MaterialGPencilStyle *)ptr->data; + return ((pcolor->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (pcolor->fill_style > 0)); +} + +static void rna_GpencilColorData_stroke_image_set(PointerRNA *ptr, PointerRNA value) +{ + MaterialGPencilStyle *pcolor = ptr->data; + ID *id = value.data; + + id_us_plus(id); + pcolor->sima = (struct Image *)id; +} + +static void rna_GpencilColorData_fill_image_set(PointerRNA *ptr, PointerRNA value) +{ + MaterialGPencilStyle *pcolor = (MaterialGPencilStyle *)ptr->data; + ID *id = value.data; + + id_us_plus(id); + pcolor->ima = (struct Image *)id; +} + #else static void rna_def_material_display(StructRNA *srna) @@ -296,6 +375,251 @@ static void rna_def_material_display(StructRNA *srna) RNA_def_property_update(prop, 0, "rna_Material_update"); } +static void rna_def_material_greasepencil(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* mode type styles */ + static EnumPropertyItem gpcolordata_mode_types_items[] = { + { GP_STYLE_MODE_LINE, "LINE", 0, "Line", "Draw strokes using a continuous line" }, + { GP_STYLE_MODE_DOTS, "DOTS", 0, "Dots", "Draw strokes using separated dots" }, + { GP_STYLE_MODE_BOX, "BOX", 0, "Boxes", "Draw strokes using separated rectangle boxes" }, + { 0, NULL, 0, NULL, NULL } + }; + + /* stroke styles */ + static EnumPropertyItem stroke_style_items[] = { + { GP_STYLE_STROKE_STYLE_SOLID, "SOLID", 0, "Solid", "Draw strokes with solid color" }, + { GP_STYLE_STROKE_STYLE_TEXTURE, "TEXTURE", 0, "Texture", "Draw strokes using texture" }, + { 0, NULL, 0, NULL, NULL } + }; + + /* fill styles */ + static EnumPropertyItem fill_style_items[] = { + { GP_STYLE_FILL_STYLE_SOLID, "SOLID", 0, "Solid", "Fill area with solid color" }, + { GP_STYLE_FILL_STYLE_GRADIENT, "GRADIENT", 0, "Gradient", "Fill area with gradient color" }, + { GP_STYLE_FILL_STYLE_CHESSBOARD, "CHESSBOARD", 0, "Checker Board", "Fill area with chessboard pattern" }, + { GP_STYLE_FILL_STYLE_TEXTURE, "TEXTURE", 0, "Texture", "Fill area with image texture" }, + { 0, NULL, 0, NULL, NULL } + }; + + static EnumPropertyItem fill_gradient_items[] = { + { GP_STYLE_GRADIENT_LINEAR, "LINEAR", 0, "Linear", "Fill area with gradient color" }, + { GP_STYLE_GRADIENT_RADIAL, "RADIAL", 0, "Radial", "Fill area with radial gradient" }, + { 0, NULL, 0, NULL, NULL } + }; + + srna = RNA_def_struct(brna, "MaterialGPencilStyle", NULL); + RNA_def_struct_sdna(srna, "MaterialGPencilStyle"); + RNA_def_struct_ui_text(srna, "Grease Pencil Color", ""); + RNA_def_struct_path_func(srna, "rna_GpencilColorData_path"); + + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "stroke_rgba"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Color", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Fill Drawing Color */ + prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "fill_rgba"); + RNA_def_property_array(prop, 4); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Secondary Drawing Color */ + prop = RNA_def_property(srna, "mix_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "mix_rgba"); + RNA_def_property_array(prop, 4); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Mix Color", "Color for mixing with primary filling color"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Mix factor */ + prop = RNA_def_property(srna, "mix_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "mix_factor"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Mix", "Mix Adjustment Factor"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Scale factor for uv coordinates */ + prop = RNA_def_property(srna, "pattern_scale", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "gradient_scale"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Scale", "Scale Factor for UV coordinates"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Shift factor to move pattern filling in 2d space */ + prop = RNA_def_property(srna, "pattern_shift", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "gradient_shift"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Shift", "Shift filling pattern in 2d space"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Gradient angle */ + prop = RNA_def_property(srna, "pattern_angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "gradient_angle"); + RNA_def_property_ui_text(prop, "Angle", "Pattern Orientation Angle"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Gradient radius */ + prop = RNA_def_property(srna, "pattern_radius", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "gradient_radius"); + RNA_def_property_range(prop, 0.0001f, 10.0f); + RNA_def_property_ui_text(prop, "Radius", "Pattern Radius"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Box size */ + prop = RNA_def_property(srna, "pattern_gridsize", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "pattern_gridsize"); + RNA_def_property_range(prop, 0.0001f, 10.0f); + RNA_def_property_ui_text(prop, "Size", "Box Size"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Texture angle */ + prop = RNA_def_property(srna, "texture_angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "texture_angle"); + RNA_def_property_ui_text(prop, "Angle", "Texture Orientation Angle"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Scale factor for texture */ + prop = RNA_def_property(srna, "texture_scale", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "texture_scale"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Scale", "Scale Factor for Texture"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Shift factor to move texture in 2d space */ + prop = RNA_def_property(srna, "texture_offset", PROP_FLOAT, PROP_COORDS); + RNA_def_property_float_sdna(prop, NULL, "texture_offset"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Offset", "Shift Texture in 2d Space"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Texture opacity size */ + prop = RNA_def_property(srna, "texture_opacity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "texture_opacity"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Opacity", "Texture Opacity"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* texture pixsize factor (used for UV along the stroke) */ + prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "texture_pixsize"); + RNA_def_property_range(prop, 1, 5000); + RNA_def_property_ui_text(prop, "UV Factor", "Texture Pixel Size factor along the stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_gpcolordata_uv_update"); + + /* Flags */ + prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_HIDE); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1); + RNA_def_property_ui_text(prop, "Hide", "Set color Visibility"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_nopreview_update"); + + prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_LOCKED); + RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1); + RNA_def_property_ui_text(prop, "Locked", "Protect color from further editing and/or frame changes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_nopreview_update"); + + prop = RNA_def_property(srna, "ghost", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_ONIONSKIN); + RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); + RNA_def_property_ui_text(prop, "Show in Ghosts", "Display strokes using this color when showing onion skins"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_nopreview_update"); + + prop = RNA_def_property(srna, "texture_clamp", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_TEX_CLAMP); + RNA_def_property_ui_text(prop, "Clamp", "Do not repeat texture and clamp to one instance only"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + prop = RNA_def_property(srna, "texture_mix", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_TEX_MIX); + RNA_def_property_ui_text(prop, "Mix Texture", "Mix texture image with filling colors"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + prop = RNA_def_property(srna, "flip", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_COLOR_FLIP_FILL); + RNA_def_property_ui_text(prop, "Flip", "Flip filling colors"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + prop = RNA_def_property(srna, "use_stroke_pattern", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_STROKE_PATTERN); + RNA_def_property_ui_text(prop, "Pattern", "Use Stroke Texture as a pattern to apply color"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + prop = RNA_def_property(srna, "use_fill_pattern", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STYLE_FILL_PATTERN); + RNA_def_property_ui_text(prop, "Pattern", "Use Fill Texture as a pattern to apply color"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* pass index for future compositing and editing tools */ + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "index"); + RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Color Index\" pass"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_nopreview_update"); + + /* mode type */ + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, gpcolordata_mode_types_items); + RNA_def_property_ui_text(prop, "Mode Type", "Select draw mode for stroke"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* stroke style */ + prop = RNA_def_property(srna, "stroke_style", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "stroke_style"); + RNA_def_property_enum_items(prop, stroke_style_items); + RNA_def_property_ui_text(prop, "Stroke Style", "Select style used to draw strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* stroke image texture */ + prop = RNA_def_property(srna, "stroke_image", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "sima"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_GpencilColorData_stroke_image_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Image", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* fill style */ + prop = RNA_def_property(srna, "fill_style", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "fill_style"); + RNA_def_property_enum_items(prop, fill_style_items); + RNA_def_property_ui_text(prop, "Fill Style", "Select style used to fill strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* gradient type */ + prop = RNA_def_property(srna, "gradient_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "gradient_type"); + RNA_def_property_enum_items(prop, fill_gradient_items); + RNA_def_property_ui_text(prop, "Gradient Type", "Select type of gradient used to fill strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* fill image texture */ + prop = RNA_def_property(srna, "fill_image", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "ima"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_GpencilColorData_fill_image_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Image", ""); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + + /* Read-only state props (for simpler UI code) */ + prop = RNA_def_property(srna, "is_stroke_visible", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_GpencilColorData_is_stroke_visible_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Is Stroke Visible", "True when opacity of stroke is set high enough to be visible"); + + prop = RNA_def_property(srna, "is_fill_visible", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_GpencilColorData_is_fill_visible_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible"); + +} + void RNA_def_material(BlenderRNA *brna) { StructRNA *srna; @@ -410,6 +734,19 @@ void RNA_def_material(BlenderRNA *brna) rna_def_material_display(srna); + /* grease pencil */ + prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gp_style"); + RNA_def_property_ui_text(prop, "Grease Pencil Settings", "Grease pencil color settings for material"); + + prop = RNA_def_property(srna, "is_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_is_grease_pencil_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Is Grease Pencil", "True if this material has grease pencil data"); + + rna_def_material_greasepencil(brna); + + RNA_api_material(srna); } diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index aded4229a3c..81c3c9b43b9 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -338,6 +338,7 @@ static void rna_def_movieclip(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b9a8f306baf..a6172bd9cc2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -8358,6 +8358,7 @@ static void rna_def_nodetree(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block"); RNA_def_property_update(prop, NC_NODE, NULL); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index ac1a6d512c3..d84827210bf 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -37,6 +37,8 @@ #include "DNA_scene_types.h" #include "DNA_meta_types.h" #include "DNA_workspace_types.h" +#include "DNA_gpencil_modifier_types.h" +#include "DNA_shader_fx_types.h" #include "BLI_utildefines.h" #include "BLI_listbase.h" @@ -71,7 +73,10 @@ const EnumPropertyItem rna_enum_object_mode_items[] = { {OB_MODE_WEIGHT_PAINT, "WEIGHT_PAINT", ICON_WPAINT_HLT, "Weight Paint", ""}, {OB_MODE_TEXTURE_PAINT, "TEXTURE_PAINT", ICON_TPAINT_HLT, "Texture Paint", ""}, {OB_MODE_PARTICLE_EDIT, "PARTICLE_EDIT", ICON_PARTICLEMODE, "Particle Edit", ""}, - {OB_MODE_GPENCIL, "GPENCIL_EDIT", ICON_GREASEPENCIL, "Edit Strokes", "Edit Grease Pencil Strokes"}, + {OB_MODE_GPENCIL_EDIT, "GPENCIL_EDIT", ICON_EDITMODE_HLT, "Edit Mode", "Edit Grease Pencil Strokes"}, + {OB_MODE_GPENCIL_SCULPT, "GPENCIL_SCULPT", ICON_SCULPTMODE_HLT, "Sculpt Mode", "Sculpt Grease Pencil Strokes"}, + {OB_MODE_GPENCIL_PAINT, "GPENCIL_PAINT", ICON_GREASEPENCIL, "Draw", "Paint Grease Pencil Strokes"}, + {OB_MODE_GPENCIL_WEIGHT, "GPENCIL_WEIGHT", ICON_WPAINT_HLT, "Weight Paint", "Grease Pencil Weight Paint Strokes" }, {0, NULL, 0, NULL, NULL} }; @@ -87,6 +92,11 @@ const EnumPropertyItem rna_enum_object_empty_drawtype_items[] = { {0, NULL, 0, NULL, NULL} }; +const EnumPropertyItem rna_enum_object_gpencil_type_items[] = { + { GP_EMPTY, "EMPTY", ICON_OUTLINER_OB_GREASEPENCIL, "Blank", "Create an empty grease pencil object" }, + { GP_MONKEY, "MONKEY", ICON_MONKEY, "Monkey", "Construct a Suzanne grease pencil object" }, + { 0, NULL, 0, NULL, NULL } +}; static const EnumPropertyItem parent_type_items[] = { {PAROBJECT, "OBJECT", 0, "Object", "The object is parented to an object"}, @@ -144,6 +154,7 @@ const EnumPropertyItem rna_enum_object_type_items[] = { {OB_ARMATURE, "ARMATURE", 0, "Armature", ""}, {OB_LATTICE, "LATTICE", 0, "Lattice", ""}, {OB_EMPTY, "EMPTY", 0, "Empty", ""}, + {OB_GPENCIL, "GPENCIL", 0, "GPencil", ""}, {0, "", 0, NULL, NULL}, {OB_CAMERA, "CAMERA", 0, "Camera", ""}, {OB_LAMP, "LIGHT", 0, "Light", ""}, @@ -175,6 +186,7 @@ const EnumPropertyItem rna_enum_object_axis_items[] = { #include "DNA_key_types.h" #include "DNA_constraint_types.h" +#include "DNA_gpencil_types.h" #include "DNA_ID.h" #include "DNA_lattice_types.h" #include "DNA_node_types.h" @@ -383,10 +395,24 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr) case OB_ARMATURE: return &RNA_Armature; case OB_SPEAKER: return &RNA_Speaker; case OB_LIGHTPROBE: return &RNA_LightProbe; + case OB_GPENCIL: return &RNA_GreasePencil; default: return &RNA_ID; } } +static bool rna_Object_data_poll(PointerRNA *ptr, const PointerRNA value) +{ + Object *ob = (Object *)ptr->data; + + if (ob->type == OB_GPENCIL) { + /* GP Object - Don't allow using "Annotation" GP datablocks here */ + bGPdata *gpd = value.data; + return (gpd->flag & GP_DATA_ANNOTATIONS) == 0; + } + + return true; +} + static void rna_Object_parent_set(PointerRNA *ptr, PointerRNA value) { Object *ob = (Object *)ptr->data; @@ -942,6 +968,21 @@ static void rna_MaterialSlot_material_set(PointerRNA *ptr, PointerRNA value) assign_material(G_MAIN, ob, value.data, index + 1, BKE_MAT_ASSIGN_EXISTING); } +static bool rna_MaterialSlot_material_poll(PointerRNA *ptr, PointerRNA value) +{ + Object *ob = (Object *)ptr->id.data; + Material *ma = (Material *)value.data; + + if (ob->type == OB_GPENCIL) { + /* GP Materials only */ + return (ma->gp_style != NULL); + } + else { + /* Everything except GP materials */ + return (ma->gp_style == NULL); + } +} + static int rna_MaterialSlot_link_get(PointerRNA *ptr) { Object *ob = (Object *)ptr->id.data; @@ -1007,7 +1048,6 @@ static char *rna_MaterialSlot_path(PointerRNA *ptr) Object *ob = (Object *)ptr->id.data; int index = (Material **)ptr->data - ob->mat; - /* from armature... */ return BLI_sprintfN("material_slots[%d]", index); } @@ -1275,6 +1315,61 @@ bool rna_Object_modifiers_override_apply( return true; } +static GpencilModifierData *rna_Object_greasepencil_modifier_new( + Object *object, bContext *C, ReportList *reports, + const char *name, int type) +{ + return ED_object_gpencil_modifier_add(reports, CTX_data_main(C), CTX_data_scene(C), object, name, type); +} + +static void rna_Object_greasepencil_modifier_remove( + Object *object, bContext *C, ReportList *reports, PointerRNA *gmd_ptr) +{ + GpencilModifierData *gmd = gmd_ptr->data; + if (ED_object_gpencil_modifier_remove(reports, CTX_data_main(C), object, gmd) == false) { + /* error is already set */ + return; + } + + RNA_POINTER_INVALIDATE(gmd_ptr); + + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); +} + +static void rna_Object_greasepencil_modifier_clear(Object *object, bContext *C) +{ + ED_object_gpencil_modifier_clear(CTX_data_main(C), object); + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); +} + +/* shader fx */ +static ShaderFxData *rna_Object_shaderfx_new( + Object *object, bContext *C, ReportList *reports, + const char *name, int type) +{ + return ED_object_shaderfx_add(reports, CTX_data_main(C), CTX_data_scene(C), object, name, type); +} + +static void rna_Object_shaderfx_remove( + Object *object, bContext *C, ReportList *reports, PointerRNA *gmd_ptr) +{ + ShaderFxData *gmd = gmd_ptr->data; + if (ED_object_shaderfx_remove(reports, CTX_data_main(C), object, gmd) == false) { + /* error is already set */ + return; + } + + RNA_POINTER_INVALIDATE(gmd_ptr); + + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); +} + +static void rna_Object_shaderfx_clear(Object *object, bContext *C) +{ + ED_object_shaderfx_clear(CTX_data_main(C), object); + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); +} + static void rna_Object_boundbox_get(PointerRNA *ptr, float *values) { Object *ob = (Object *)ptr->id.data; @@ -1453,6 +1548,11 @@ bool rna_Light_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) return ((Object *)value.id.data)->type == OB_LAMP; } +bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) +{ + return ((Object *)value.id.data)->type == OB_GPENCIL; +} + int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr) { SculptSession *ss = ((Object *)ptr->id.data)->sculpt; @@ -1601,7 +1701,7 @@ static void rna_def_material_slot(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_editable_func(prop, "rna_MaterialSlot_material_editable"); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); - RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL, NULL); + RNA_def_property_pointer_funcs(prop, "rna_MaterialSlot_material_get", "rna_MaterialSlot_material_set", NULL, "rna_MaterialSlot_material_poll"); RNA_def_property_ui_text(prop, "Material", "Material data-block used by this material slot"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_MaterialSlot_update"); @@ -1715,6 +1815,88 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove all modifiers from the object"); } +/* object.grease_pencil_modifiers */ +static void rna_def_object_grease_pencil_modifiers(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "ObjectGpencilModifiers"); + srna = RNA_def_struct(brna, "ObjectGpencilModifiers", NULL); + RNA_def_struct_sdna(srna, "Object"); + RNA_def_struct_ui_text(srna, "Object Grease Pencil Modifiers", "Collection of object grease pencil modifiers"); + + /* add greasepencil modifier */ + func = RNA_def_function(srna, "new", "rna_Object_greasepencil_modifier_new"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a new greasepencil_modifier"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the greasepencil_modifier"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* greasepencil_modifier to add */ + parm = RNA_def_enum(func, "type", rna_enum_object_greasepencil_modifier_type_items, 1, "", "Modifier type to add"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "greasepencil_modifier", "GpencilModifier", "", "Newly created modifier"); + RNA_def_function_return(func, parm); + + /* remove greasepencil_modifier */ + func = RNA_def_function(srna, "remove", "rna_Object_greasepencil_modifier_remove"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove an existing greasepencil_modifier from the object"); + /* greasepencil_modifier to remove */ + parm = RNA_def_pointer(func, "greasepencil_modifier", "GpencilModifier", "", "Modifier to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); + + /* clear all greasepencil modifiers */ + func = RNA_def_function(srna, "clear", "rna_Object_greasepencil_modifier_clear"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Remove all grease pencil modifiers from the object"); +} + +/* object.shaderfxs */ +static void rna_def_object_shaderfxs(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "ObjectShaderFx"); + srna = RNA_def_struct(brna, "ObjectShaderFx", NULL); + RNA_def_struct_sdna(srna, "Object"); + RNA_def_struct_ui_text(srna, "Object Shader Effects", "Collection of object effects"); + + /* add shader_fx */ + func = RNA_def_function(srna, "new", "rna_Object_shaderfx_new"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a new shader fx"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the effect"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* shader to add */ + parm = RNA_def_enum(func, "type", rna_enum_object_shaderfx_type_items, 1, "", "Effect type to add"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "shader_fx", "ShaderFx", "", "Newly created effect"); + RNA_def_function_return(func, parm); + + /* remove shader_fx */ + func = RNA_def_function(srna, "remove", "rna_Object_shaderfx_remove"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove an existing effect from the object"); + /* shader to remove */ + parm = RNA_def_pointer(func, "shader_fx", "ShaderFx", "", "Effect to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); + + /* clear all shader fx */ + func = RNA_def_function(srna, "clear", "rna_Object_shaderfx_clear"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Remove all effects from the object"); +} + /* object.particle_systems */ static void rna_def_object_particle_systems(BlenderRNA *brna, PropertyRNA *cprop) { @@ -1919,7 +2101,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "data", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "ID"); - RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", NULL); + RNA_def_property_pointer_funcs(prop, NULL, "rna_Object_data_set", "rna_Object_data_typef", "rna_Object_data_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_ui_text(prop, "Data", "Object data"); @@ -2017,7 +2199,8 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "active_material", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Material"); RNA_def_property_pointer_funcs(prop, "rna_Object_active_material_get", - "rna_Object_active_material_set", NULL, NULL); + "rna_Object_active_material_set", NULL, + "rna_MaterialSlot_material_poll"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); RNA_def_property_editable_func(prop, "rna_Object_active_material_editable"); @@ -2211,6 +2394,20 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC | PROPOVERRIDE_STATIC_INSERTION); rna_def_object_modifiers(brna, prop); + /* Grease Pencil modifiers. */ + prop = RNA_def_property(srna, "grease_pencil_modifiers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "greasepencil_modifiers", NULL); + RNA_def_property_struct_type(prop, "GpencilModifier"); + RNA_def_property_ui_text(prop, "Grease Pencil Modifiers", "Modifiers affecting the data of the grease pencil object"); + rna_def_object_grease_pencil_modifiers(brna, prop); + + /* Shader FX. */ + prop = RNA_def_property(srna, "shader_effects", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "shader_fx", NULL); + RNA_def_property_struct_type(prop, "ShaderFx"); + RNA_def_property_ui_text(prop, "Shader Effects", "Effects affecting display of object"); + rna_def_object_shaderfxs(brna, prop); + /* constraints */ prop = RNA_def_property(srna, "constraints", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Constraint"); @@ -2482,12 +2679,15 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); /* Grease Pencil */ +#if 1 /* FIXME: Remove this code when all Open-Movie assets have been fixed */ prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_obdata_poll"); /* XXX */ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block"); + RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block (deprecated)"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); +#endif /* pose */ prop = RNA_def_property(srna, "pose_library", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_palette.c b/source/blender/makesrna/intern/rna_palette.c index 4d6b94bf709..547cac9f38d 100644 --- a/source/blender/makesrna/intern/rna_palette.c +++ b/source/blender/makesrna/intern/rna_palette.c @@ -39,7 +39,6 @@ #include "BKE_paint.h" #include "BKE_report.h" - static PaletteColor *rna_Palette_color_new(Palette *palette) { PaletteColor *color = BKE_palette_color_add(palette); @@ -139,6 +138,7 @@ static void rna_def_palettecolor(BlenderRNA *brna) prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_float_sdna(prop, NULL, "rgb"); + RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Color", ""); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); @@ -153,6 +153,7 @@ static void rna_def_palettecolor(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "value"); RNA_def_property_ui_text(prop, "Weight", ""); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + } static void rna_def_palette(BlenderRNA *brna) @@ -167,6 +168,7 @@ static void rna_def_palette(BlenderRNA *brna) prop = RNA_def_property(srna, "colors", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "PaletteColor"); rna_def_palettecolors(brna, prop); + } void RNA_def_palette(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 915018612a1..9fde87be486 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -51,6 +51,7 @@ #include "BKE_paint.h" #include "ED_object.h" +#include "ED_gpencil.h" #include "GPU_extensions.h" @@ -530,6 +531,13 @@ static const EnumPropertyItem transform_orientation_items[] = { #include "FRS_freestyle.h" #endif +/* Grease Pencil update cache */ +static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + DEG_id_type_tag(bmain, ID_GD); + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + /* Grease Pencil Interpolation settings */ static char *rna_GPencilInterpolateSettings_path(PointerRNA *UNUSED(ptr)) { @@ -551,110 +559,8 @@ static void rna_GPencilInterpolateSettings_type_set(PointerRNA *ptr, int value) { settings->custom_ipo = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); } -} - -/* Grease pencil Drawing Brushes */ -static bGPDbrush *rna_GPencil_brush_new(ToolSettings *ts, const char *name, bool setactive) -{ - bGPDbrush *brush = BKE_gpencil_brush_addnew(ts, name, setactive != 0); - - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); - - return brush; -} - -static void rna_GPencil_brush_remove(ToolSettings *ts, ReportList *reports, PointerRNA *brush_ptr) -{ - bGPDbrush *brush = brush_ptr->data; - if (BLI_findindex(&ts->gp_brushes, brush) == -1) { - BKE_report(reports, RPT_ERROR, "Brush not found in grease pencil data"); - return; - } - - BKE_gpencil_brush_delete(ts, brush); - RNA_POINTER_INVALIDATE(brush_ptr); - - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -static PointerRNA rna_GPencilBrushes_active_get(PointerRNA *ptr) -{ - ToolSettings *ts = (ToolSettings *) ptr->data; - - bGPDbrush *brush; - - for (brush = ts->gp_brushes.first; brush; brush = brush->next) { - if (brush->flag & GP_BRUSH_ACTIVE) { - break; - } - } - - if (brush) { - return rna_pointer_inherit_refine(ptr, &RNA_GPencilBrush, brush); - } - - return rna_pointer_inherit_refine(ptr, NULL, NULL); -} - -static void rna_GPencilBrushes_active_set(PointerRNA *ptr, PointerRNA value) -{ - ToolSettings *ts = (ToolSettings *) ptr->data; - - bGPDbrush *brush; - - for (brush = ts->gp_brushes.first; brush; brush = brush->next) { - if (brush == value.data) { - brush->flag |= GP_BRUSH_ACTIVE; - } - else { - brush->flag &= ~GP_BRUSH_ACTIVE; - } - } - WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); -} - -static int rna_GPencilBrushes_index_get(PointerRNA *ptr) -{ - ToolSettings *ts = (ToolSettings *) ptr->data; - bGPDbrush *brush = BKE_gpencil_brush_getactive(ts); - return BLI_findindex(&ts->gp_brushes, brush); } - -static void rna_GPencilBrushes_index_set(PointerRNA *ptr, int value) -{ - ToolSettings *ts = (ToolSettings *) ptr->data; - - bGPDbrush *brush = BLI_findlink(&ts->gp_brushes, value); - - BKE_gpencil_brush_setactive(ts, brush); - WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); -} - -static void rna_GPencilBrushes_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) -{ - ToolSettings *ts = (ToolSettings *) ptr->data; - - *min = 0; - *max = max_ii(0, BLI_listbase_count(&ts->gp_brushes) - 1); - - *softmin = *min; - *softmax = *max; -} - -static void rna_GPencilBrush_name_set(PointerRNA *ptr, const char *value) -{ - ToolSettings *ts = ((Scene *) ptr->id.data)->toolsettings; - bGPDbrush *brush = ptr->data; - - /* copy the new name into the name slot */ - BLI_strncpy_utf8(brush->info, value, sizeof(brush->info)); - - BLI_uniquename(&ts->gp_brushes, brush, DATA_("GP_Brush"), '.', offsetof(bGPDbrush, info), sizeof(brush->info)); -} - -/* ----------------- end of Grease pencil drawing brushes ------------*/ - static void rna_ToolSettings_gizmo_flag_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { ToolSettings *ts = scene->toolsettings; @@ -2190,205 +2096,6 @@ static void rna_def_gpencil_interpolate(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } -/* Grease Pencil Drawing Brushes */ -static void rna_def_gpencil_brush(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "GPencilBrush", NULL); - RNA_def_struct_sdna(srna, "bGPDbrush"); - RNA_def_struct_ui_text(srna, "Grease Pencil Brush", - "Collection of brushes being used to control the line style of new strokes"); - RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); - - /* Name */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "info"); - RNA_def_property_ui_text(prop, "Name", "Brush name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilBrush_name_set"); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Line Thickness */ - prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL); - RNA_def_property_int_sdna(prop, NULL, "thickness"); - RNA_def_property_range(prop, 1, 300); - RNA_def_property_ui_range(prop, 1, 10, 1, 0); - RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Sensitivity factor for new strokes */ - prop = RNA_def_property(srna, "pen_sensitivity_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_sensitivity"); - RNA_def_property_range(prop, 0.1f, 3.0f); - RNA_def_property_ui_text(prop, "Sensitivity", "Pressure sensitivity factor for new strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Strength factor for new strokes */ - prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_strength"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Strength", "Color strength for new strokes (affect alpha factor of color)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Jitter factor for new strokes */ - prop = RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_jitter"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Jitter", "Jitter factor for new strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Randomnes factor for sensitivity and strength */ - prop = RNA_def_property(srna, "random_press", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_random_press"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Randomness", "Randomness factor for pressure and strength in new strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Randomnes factor for subdivision */ - prop = RNA_def_property(srna, "random_subdiv", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_random_sub"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Random Subdivision", "Randomness factor for new strokes after subdivision"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Angle when brush is full size */ - prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_float_sdna(prop, NULL, "draw_angle"); - RNA_def_property_range(prop, -M_PI_2, M_PI_2); - RNA_def_property_ui_text(prop, "Angle", - "Direction of the stroke at which brush gives maximal thickness " - "(0° for horizontal)"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Factor to change brush size depending of angle */ - prop = RNA_def_property(srna, "angle_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_angle_factor"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Angle Factor", - "Reduce brush thickness by this factor when stroke is perpendicular to 'Angle' direction"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Smoothing factor for new strokes */ - prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac"); - RNA_def_property_range(prop, 0.0, 2.0f); - RNA_def_property_ui_text(prop, "Smooth", - "Amount of smoothing to apply to newly created strokes, to reduce jitter/noise"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Iterations of the Smoothing factor */ - prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl"); - RNA_def_property_range(prop, 1, 3); - RNA_def_property_ui_text(prop, "Iterations", - "Number of times to smooth newly created strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Subdivision level for new strokes */ - prop = RNA_def_property(srna, "pen_subdivision_steps", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "sublevel"); - RNA_def_property_range(prop, 0, 3); - RNA_def_property_ui_text(prop, "Subdivision Steps", - "Number of times to subdivide newly created strokes, for less jagged strokes"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Curves for pressure */ - prop = RNA_def_property(srna, "curve_sensitivity", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "cur_sensitivity"); - RNA_def_property_struct_type(prop, "CurveMapping"); - RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "curve_strength", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "cur_strength"); - RNA_def_property_struct_type(prop, "CurveMapping"); - RNA_def_property_ui_text(prop, "Curve Strength", "Curve used for the strength"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "curve_jitter", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "cur_jitter"); - RNA_def_property_struct_type(prop, "CurveMapping"); - RNA_def_property_ui_text(prop, "Curve Jitter", "Curve used for the jitter effect"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - /* Flags */ - prop = RNA_def_property(srna, "use_pressure", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_PRESSURE); - RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); - RNA_def_property_ui_text(prop, "Use Pressure", "Use tablet pressure"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_STENGTH_PRESSURE); - RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); - RNA_def_property_ui_text(prop, "Use Pressure Strength", "Use tablet pressure for color strength"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_JITTER_PRESSURE); - RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); - RNA_def_property_ui_text(prop, "Use Pressure Jitter", "Use tablet pressure for jitter"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "use_random_pressure", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_RANDOM_PRESSURE); - RNA_def_property_ui_icon(prop, ICON_PARTICLES, 0); - RNA_def_property_ui_text(prop, "Random Pressure", "Use random value for pressure"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - - prop = RNA_def_property(srna, "use_random_strength", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_USE_RANDOM_STRENGTH); - RNA_def_property_ui_icon(prop, ICON_PARTICLES, 0); - RNA_def_property_ui_text(prop, "Random Strength", "Use random value for strength"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - -} - -/* Grease Pencil Drawing Brushes API */ -static void rna_def_gpencil_brushes(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "GreasePencilBrushes"); - srna = RNA_def_struct(brna, "GreasePencilBrushes", NULL); - RNA_def_struct_sdna(srna, "ToolSettings"); - RNA_def_struct_ui_text(srna, "Grease Pencil Brushes", "Collection of grease pencil brushes"); - - func = RNA_def_function(srna, "new", "rna_GPencil_brush_new"); - RNA_def_function_ui_description(func, "Add a new grease pencil brush"); - parm = RNA_def_string(func, "name", "GPencilBrush", MAX_NAME, "Name", "Name of the brush"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created brush to the active brush"); - parm = RNA_def_pointer(func, "palette", "GPencilBrush", "", "The newly created brush"); - RNA_def_function_return(func, parm); - - func = RNA_def_function(srna, "remove", "rna_GPencil_brush_remove"); - RNA_def_function_ui_description(func, "Remove a grease pencil brush"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_pointer(func, "brush", "GPencilBrush", "", "The brush to remove"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); - RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); - - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "GPencilBrush"); - RNA_def_property_pointer_funcs(prop, "rna_GPencilBrushes_active_get", "rna_GPencilBrushes_active_set", NULL, NULL); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Active Brush", "Current active brush"); - - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, - "rna_GPencilBrushes_index_get", - "rna_GPencilBrushes_index_set", - "rna_GPencilBrushes_index_range"); - RNA_def_property_ui_text(prop, "Active Brush Index", "Index of active brush"); -} - static void rna_def_transform_orientation(BlenderRNA *brna) { StructRNA *srna; @@ -2446,21 +2153,20 @@ static void rna_def_tool_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem gpencil_source_3d_items[] = { - {GP_TOOL_SOURCE_SCENE, "SCENE", 0, "Scene", - "Grease Pencil data attached to the current scene is used, " - "unless the active object already has Grease Pencil data (i.e. for old files)"}, - {GP_TOOL_SOURCE_OBJECT, "OBJECT", 0, "Object", - "Grease Pencil data-blocks attached to the active object are used " - "(required when using pre 2.73 add-ons, e.g. BSurfaces)"}, + static const EnumPropertyItem gpencil_stroke_placement_items[] = { + {GP_PROJECT_VIEWSPACE, "ORIGIN", ICON_OBJECT_ORIGIN, "Origin", "Draw stroke at Object origin"}, + {GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR, "CURSOR", ICON_CURSOR, "3D Cursor", "Draw stroke at 3D cursor location" }, + // {0, "VIEW", ICON_VISIBLE_IPO_ON, "View", "Stick stroke to the view "}, /* weird, GP_PROJECT_VIEWALIGN is inverted */ + {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW, "SURFACE", ICON_FACESEL, "Surface", "Stick stroke to surfaces"}, + //{GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_STROKE, "STROKE", ICON_GREASEPENCIL, "Stroke", "Stick stroke to other strokes"}, {0, NULL, 0, NULL, NULL} }; - static const EnumPropertyItem gpencil_stroke_placement_items[] = { - {GP_PROJECT_VIEWSPACE, "CURSOR", 0, "Cursor", "Draw stroke at the 3D cursor"}, - {0, "VIEW", 0, "View", "Stick stroke to the view "}, /* weird, GP_PROJECT_VIEWALIGN is inverted */ - {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW, "SURFACE", 0, "Surface", "Stick stroke to surfaces"}, - {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_STROKE, "STROKE", 0, "Stroke", "Stick stroke to other strokes"}, + static const EnumPropertyItem annotation_stroke_placement_items[] = { + {GP_PROJECT_VIEWSPACE | GP_PROJECT_CURSOR, "CURSOR", ICON_CURSOR, "3D Cursor", "Draw stroke at 3D cursor location" }, + {0, "VIEW", ICON_VISIBLE_IPO_ON, "View", "Stick stroke to the view "}, /* weird, GP_PROJECT_VIEWALIGN is inverted */ + {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW, "SURFACE", ICON_FACESEL, "Surface", "Stick stroke to surfaces"}, + {GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_STROKE, "STROKE", ICON_GREASEPENCIL, "Stroke", "Stick stroke to other strokes"}, {0, NULL, 0, NULL, NULL} }; @@ -2504,7 +2210,8 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data"); prop = RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "vpaint"); RNA_def_property_ui_text(prop, "Vertex Paint", ""); + RNA_def_property_pointer_sdna(prop, NULL, "vpaint"); + RNA_def_property_ui_text(prop, "Vertex Paint", ""); prop = RNA_def_property(srna, "weight_paint", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "wpaint"); @@ -2518,6 +2225,10 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "uvsculpt"); RNA_def_property_ui_text(prop, "UV Sculpt", ""); + prop = RNA_def_property(srna, "gpencil_paint", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gp_paint"); + RNA_def_property_ui_text(prop, "Grease Pencil Paint", ""); + prop = RNA_def_property(srna, "particle_edit", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "particle"); RNA_def_property_ui_text(prop, "Particle Edit", ""); @@ -2695,12 +2406,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ToolSettings_gizmo_flag_update"); /* Grease Pencil */ - prop = RNA_def_property(srna, "use_gpencil_continuous_drawing", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_PAINTSESSIONS_ON); - RNA_def_property_ui_text(prop, "Use Continuous Drawing", - "Allow drawing multiple strokes at a time with Grease Pencil"); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* xxx: need toolbar to be redrawn... */ - prop = RNA_def_property(srna, "use_gpencil_additive_drawing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_RETAIN_LAST); RNA_def_property_ui_text(prop, "Use Additive Drawing", @@ -2714,12 +2419,11 @@ static void rna_def_tool_settings(BlenderRNA *brna) "When draw new strokes, the new stroke is drawn below of all strokes in the layer"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - prop = RNA_def_property(srna, "grease_pencil_source", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_src"); - RNA_def_property_enum_items(prop, gpencil_source_3d_items); - RNA_def_property_ui_text(prop, "Grease Pencil Source", - "Data-block where active Grease Pencil data is found from"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + prop = RNA_def_property(srna, "use_gpencil_thumbnail_list", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_THUMBNAIL_LIST); + RNA_def_property_ui_text(prop, "Compact List", + "Show compact list of color instead of thumbnails"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "gpencil_sculpt", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gp_sculpt"); @@ -2733,13 +2437,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grease Pencil Interpolate", "Settings for Grease Pencil Interpolation tools"); - /* Grease Pencil - Drawing brushes */ - prop = RNA_def_property(srna, "gpencil_brushes", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "gp_brushes", NULL); - RNA_def_property_struct_type(prop, "GPencilBrush"); - RNA_def_property_ui_text(prop, "Grease Pencil Brushes", "Grease Pencil drawing brushes"); - rna_def_gpencil_brushes(brna, prop); - /* Grease Pencil - 3D View Stroke Placement */ prop = RNA_def_property(srna, "gpencil_stroke_placement_view3d", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_v3d_align"); @@ -2752,27 +2449,41 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* Grease Pencil - 2D Views Stroke Placement */ - prop = RNA_def_property(srna, "gpencil_stroke_placement_view2d", PROP_ENUM, PROP_NONE); + /* Annotations - 2D Views Stroke Placement */ + prop = RNA_def_property(srna, "annotation_stroke_placement_view2d", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_v2d_align"); - RNA_def_property_enum_items(prop, gpencil_stroke_placement_items); + RNA_def_property_enum_items(prop, annotation_stroke_placement_items); RNA_def_property_ui_text(prop, "Stroke Placement (2D View)", ""); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* Grease Pencil - Sequencer Preview Stroke Placement */ - prop = RNA_def_property(srna, "gpencil_stroke_placement_sequencer_preview", PROP_ENUM, PROP_NONE); + /* Annotations - Sequencer Preview Stroke Placement */ + prop = RNA_def_property(srna, "annotation_stroke_placement_sequencer_preview", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_seq_align"); - RNA_def_property_enum_items(prop, gpencil_stroke_placement_items); + RNA_def_property_enum_items(prop, annotation_stroke_placement_items); RNA_def_property_ui_text(prop, "Stroke Placement (Sequencer Preview)", ""); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); - /* Grease Pencil - Image Editor Stroke Placement */ - prop = RNA_def_property(srna, "gpencil_stroke_placement_image_editor", PROP_ENUM, PROP_NONE); + /* Annotations - Image Editor Stroke Placement */ + prop = RNA_def_property(srna, "annotation_stroke_placement_image_editor", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_ima_align"); - RNA_def_property_enum_items(prop, gpencil_stroke_placement_items); + RNA_def_property_enum_items(prop, annotation_stroke_placement_items); RNA_def_property_ui_text(prop, "Stroke Placement (Image Editor)", ""); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + /* Annotations - 3D View Stroke Placement */ + /* XXX: Do we need to decouple the stroke_endpoints setting too? */ + prop = RNA_def_property(srna, "annotation_stroke_placement_view3d", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "annotate_v3d_align"); + RNA_def_property_enum_items(prop, annotation_stroke_placement_items); + RNA_def_property_ui_text(prop, "Annotation Stroke Placement (3D View)", "How annotation strokes are orientated in 3D space"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + + /* Annotations - Stroke Thickness */ + prop = RNA_def_property(srna, "annotation_thickness", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "annotate_thickness"); + RNA_def_property_range(prop, 1, 10); + RNA_def_property_ui_text(prop, "Annotation Stroke Thickness", "Thickness of annotation strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Auto Keying */ prop = RNA_def_property(srna, "use_keyframe_insert_auto", PROP_BOOLEAN, PROP_NONE); @@ -5474,6 +5185,32 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Simplify Child Particles", "Global child particles percentage during rendering"); RNA_def_property_update(prop, 0, "rna_Scene_simplify_update"); + /* Grease Pencil - Simplify Options */ + prop = RNA_def_property(srna, "simplify_gpencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ENABLE); + RNA_def_property_ui_text(prop, "Simplify", "Simplify Grease Pencil Drawing"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "simplify_gpencil_onplay", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ON_PLAY); + RNA_def_property_ui_text(prop, "On Play", "Simplify Grease Pencil only when play animation"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "simplify_gpencil_view_fill", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_FILL); + RNA_def_property_ui_text(prop, "Fill", "Do not fill strokes on viewport"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "simplify_gpencil_remove_lines", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_REMOVE_FILL_LINE); + RNA_def_property_ui_text(prop, "Remove Lines", "Remove External Lines of Filling Strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "simplify_gpencil_view_modifier", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_MODIFIER); + RNA_def_property_ui_text(prop, "Fill", "Do not apply modifiers on viewport"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* persistent data */ prop = RNA_def_property(srna, "use_persistent_data", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_PERSISTENT_DATA); @@ -6550,8 +6287,9 @@ void RNA_def_scene(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil data-block"); + RNA_def_property_ui_text(prop, "Annotations", "Grease Pencil data-block used for annotations in the 3D view"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); /* active MovieClip */ @@ -6606,7 +6344,6 @@ void RNA_def_scene(BlenderRNA *brna) /* *** Non-Animated *** */ RNA_define_animate_sdna(false); rna_def_tool_settings(brna); - rna_def_gpencil_brush(brna); rna_def_gpencil_interpolate(brna); rna_def_unified_paint_settings(brna); rna_def_curve_paint_settings(brna); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 5b2a3c9c4f4..6a6c97b41ad 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -64,26 +64,29 @@ static const EnumPropertyItem particle_edit_hair_brush_items[] = { }; const EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = { - {GP_EDITBRUSH_TYPE_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth stroke points"}, - {GP_EDITBRUSH_TYPE_THICKNESS, "THICKNESS", 0, "Thickness", "Adjust thickness of strokes"}, - { GP_EDITBRUSH_TYPE_STRENGTH, "STRENGTH", 0, "Strength", "Adjust color strength of strokes" }, - { GP_EDITBRUSH_TYPE_GRAB, "GRAB", 0, "Grab", "Translate the set of points initially within the brush circle" }, - {GP_EDITBRUSH_TYPE_PUSH, "PUSH", 0, "Push", "Move points out of the way, as if combing them"}, - {GP_EDITBRUSH_TYPE_TWIST, "TWIST", 0, "Twist", "Rotate points around the midpoint of the brush"}, - {GP_EDITBRUSH_TYPE_PINCH, "PINCH", 0, "Pinch", "Pull points towards the midpoint of the brush"}, - {GP_EDITBRUSH_TYPE_RANDOMIZE, "RANDOMIZE", 0, "Randomize", "Introduce jitter/randomness into strokes"}, - //{GP_EDITBRUSH_TYPE_SUBDIVIDE, "SUBDIVIDE", 0, "Subdivide", "Increase point density for higher resolution strokes when zoomed in"}, - //{GP_EDITBRUSH_TYPE_SIMPLIFY, "SIMPLIFY", 0, "Simplify", "Reduce density of stroke points"}, - {GP_EDITBRUSH_TYPE_CLONE, "CLONE", 0, "Clone", "Paste copies of the strokes stored on the clipboard"}, + {GP_EDITBRUSH_TYPE_SMOOTH, "SMOOTH", ICON_GPBRUSH_SMOOTH, "Smooth", "Smooth stroke points"}, + {GP_EDITBRUSH_TYPE_THICKNESS, "THICKNESS", ICON_GPBRUSH_THICKNESS, "Thickness", "Adjust thickness of strokes"}, + {GP_EDITBRUSH_TYPE_STRENGTH, "STRENGTH", ICON_GPBRUSH_STRENGTH, "Strength", "Adjust color strength of strokes" }, + {GP_EDITBRUSH_TYPE_GRAB, "GRAB", ICON_GPBRUSH_GRAB, "Grab", "Translate the set of points initially within the brush circle" }, + {GP_EDITBRUSH_TYPE_PUSH, "PUSH", ICON_GPBRUSH_PUSH, "Push", "Move points out of the way, as if combing them"}, + {GP_EDITBRUSH_TYPE_TWIST, "TWIST", ICON_GPBRUSH_TWIST, "Twist", "Rotate points around the midpoint of the brush"}, + {GP_EDITBRUSH_TYPE_PINCH, "PINCH", ICON_GPBRUSH_PINCH, "Pinch", "Pull points towards the midpoint of the brush"}, + {GP_EDITBRUSH_TYPE_RANDOMIZE, "RANDOMIZE", ICON_GPBRUSH_RANDOMIZE, "Randomize", "Introduce jitter/randomness into strokes"}, + {GP_EDITBRUSH_TYPE_CLONE, "CLONE", ICON_GPBRUSH_CLONE, "Clone", "Paste copies of the strokes stored on the clipboard"}, + { 0, NULL, 0, NULL, NULL } +}; + +EnumPropertyItem rna_enum_gpencil_weight_brush_items[] = { + { GP_EDITBRUSH_TYPE_WEIGHT, "WEIGHT", ICON_GPBRUSH_WEIGHT, "Weight", "Weight Paint for Vertex Groups" }, { 0, NULL, 0, NULL, NULL } }; #ifndef RNA_RUNTIME static const EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { - { GP_LOCKAXIS_NONE, "GP_LOCKAXIS_NONE", 0, "None", "" }, - { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", 0, "X", "Project strokes to plane locked to X" }, - { GP_LOCKAXIS_Y, "GP_LOCKAXIS_Y", 0, "Y", "Project strokes to plane locked to Y" }, - { GP_LOCKAXIS_Z, "GP_LOCKAXIS_Z", 0, "Z", "Project strokes to plane locked to Z" }, + { GP_LOCKAXIS_NONE, "GP_LOCKAXIS_NONE", ICON_UNLOCKED, "None", "" }, + { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", ICON_NDOF_DOM, "X", "Project strokes to plane locked to X" }, + { GP_LOCKAXIS_Y, "GP_LOCKAXIS_Y", ICON_NDOF_DOM, "Y", "Project strokes to plane locked to Y" }, + { GP_LOCKAXIS_Z, "GP_LOCKAXIS_Z", ICON_NDOF_DOM, "Z", "Project strokes to plane locked to Z" }, { 0, NULL, 0, NULL, NULL } }; #endif @@ -108,13 +111,16 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #include "BKE_pbvh.h" #include "BKE_pointcache.h" #include "BKE_object.h" +#include "BKE_gpencil.h" + #include "DEG_depsgraph.h" #include "ED_particle.h" -static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { + DEG_id_type_tag(bmain, ID_GD); WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } @@ -265,6 +271,8 @@ static bool rna_Brush_mode_poll(PointerRNA *ptr, PointerRNA value) mode = OB_MODE_VERTEX_PAINT; else if (ptr->data == ts->wpaint) mode = OB_MODE_WEIGHT_PAINT; + else if (ptr->data == ts->gp_paint) + mode = OB_MODE_GPENCIL_PAINT; return brush->ob_mode & mode; } @@ -346,6 +354,11 @@ static char *rna_UvSculpt_path(PointerRNA *UNUSED(ptr)) return BLI_strdup("tool_settings.uv_sculpt"); } +static char *rna_GpPaint_path(PointerRNA *UNUSED(ptr)) +{ + return BLI_strdup("tool_settings.gp_paint"); +} + static char *rna_ParticleBrush_path(PointerRNA *UNUSED(ptr)) { return BLI_strdup("tool_settings.particle_edit.brush"); @@ -435,9 +448,14 @@ static PointerRNA rna_GPencilSculptSettings_brush_get(PointerRNA *ptr) GP_BrushEdit_Settings *gset = (GP_BrushEdit_Settings *)ptr->data; GP_EditBrush_Data *brush = NULL; - if ((gset->brushtype >= 0) && (gset->brushtype < TOT_GP_EDITBRUSH_TYPES)) - brush = &gset->brush[gset->brushtype]; - + if ((gset) && (gset->flag & GP_BRUSHEDIT_FLAG_WEIGHT_MODE)) { + if ((gset->weighttype >= GP_EDITBRUSH_TYPE_WEIGHT) && (gset->weighttype < TOT_GP_EDITBRUSH_TYPES)) + brush = &gset->brush[gset->weighttype]; + } + else { + if ((gset->brushtype >= 0) && (gset->brushtype < GP_EDITBRUSH_TYPE_WEIGHT)) + brush = &gset->brush[gset->brushtype]; + } return rna_pointer_inherit_refine(ptr, &RNA_GPencilSculptBrush, brush); } @@ -708,6 +726,14 @@ static void rna_def_uv_sculpt(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "UV Sculpting", ""); } +static void rna_def_gp_paint(BlenderRNA *brna) +{ + StructRNA *srna; + + srna = RNA_def_struct(brna, "GpPaint", "Paint"); + RNA_def_struct_path_func(srna, "rna_GpPaint_path"); + RNA_def_struct_ui_text(srna, "Grease Pencil Paint", ""); +} /* use for weight paint too */ static void rna_def_vertex_paint(BlenderRNA *brna) @@ -1059,8 +1085,8 @@ static void rna_def_particle_edit(BlenderRNA *brna) static void rna_def_gpencil_sculpt(BlenderRNA *brna) { static const EnumPropertyItem prop_direction_items[] = { - {0, "ADD", 0, "Add", "Add effect of brush"}, - {GP_EDITBRUSH_FLAG_INVERT, "SUBTRACT", 0, "Subtract", "Subtract effect of brush"}, + {0, "ADD", ICON_ZOOMIN, "Add", "Add effect of brush"}, + {GP_EDITBRUSH_FLAG_INVERT, "SUBTRACT", ICON_ZOOMOUT, "Subtract", "Subtract effect of brush"}, {0, NULL, 0, NULL, NULL}}; StructRNA *srna; @@ -1076,86 +1102,148 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "brushtype"); RNA_def_property_enum_items(prop, rna_enum_gpencil_sculpt_brush_items); RNA_def_property_ui_text(prop, "Tool", ""); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "weight_tool", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "weighttype"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_weight_brush_items); + RNA_def_property_ui_text(prop, "Tool", "Tool for weight painting"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_GPencil_update"); prop = RNA_def_property(srna, "brush", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "GPencilSculptBrush"); RNA_def_property_pointer_funcs(prop, "rna_GPencilSculptSettings_brush_get", NULL, NULL, NULL); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_ui_text(prop, "Brush", ""); prop = RNA_def_property(srna, "use_select_mask", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_SELECT_MASK); RNA_def_property_ui_text(prop, "Selection Mask", "Only sculpt selected stroke points"); RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); // FIXME: this needs a custom icon + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "affect_position", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_POSITION); RNA_def_property_ui_text(prop, "Affect Position", "The brush affects the position of the point"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "affect_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_STRENGTH); RNA_def_property_ui_text(prop, "Affect Strength", "The brush affects the color strength of the point"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "affect_thickness", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_THICKNESS); RNA_def_property_ui_text(prop, "Affect Thickness", "The brush affects the thickness of the point"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "affect_uv", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_APPLY_UV); + RNA_def_property_ui_text(prop, "Affect UV", "The brush affects the UV rotation of the point"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - prop = RNA_def_property(srna, "selection_alpha", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "alpha"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Alpha", "Alpha value for selected vertices"); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_GPencil_update"); + prop = RNA_def_property(srna, "use_multiframe_falloff", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSHEDIT_FLAG_FRAME_FALLOFF); + RNA_def_property_ui_text(prop, "Use Falloff", "Use falloff effect when edit in multiframe mode to compute brush effect by frame"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* custom falloff curve */ + prop = RNA_def_property(srna, "multiframe_falloff_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "cur_falloff"); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_ui_text(prop, "Curve", + "Custom curve to control falloff of brush effect by Grease Pencil frames"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* lock axis */ prop = RNA_def_property(srna, "lockaxis", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "lock_axis"); RNA_def_property_enum_items(prop, rna_enum_gpencil_lockaxis_items); RNA_def_property_ui_text(prop, "Lock", ""); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); /* brush */ srna = RNA_def_struct(brna, "GPencilSculptBrush", NULL); RNA_def_struct_sdna(srna, "GP_EditBrush_Data"); RNA_def_struct_path_func(srna, "rna_GPencilSculptBrush_path"); RNA_def_struct_ui_text(srna, "GPencil Sculpt Brush", "Stroke editing brush"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL); - RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS); - RNA_def_property_ui_range(prop, 1, 100, 10, 3); // XXX: too big + RNA_def_property_range(prop, 1, GP_MAX_BRUSH_PIXEL_RADIUS); + RNA_def_property_ui_range(prop, 1, 500, 10, 3); RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0.001, 1.0); RNA_def_property_ui_text(prop, "Strength", "Brush strength"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_pressure_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_USE_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_falloff", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_USE_FALLOFF); RNA_def_property_ui_text(prop, "Use Falloff", "Strength of brush decays with distance from cursor"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "affect_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_SMOOTH_PRESSURE); RNA_def_property_ui_text(prop, "Affect Pressure", "Affect pressure values as well when smoothing strokes"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, prop_direction_items); RNA_def_property_ui_text(prop, "Direction", ""); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + /* Cursor Color */ + static float default_1[3] = { 1.0f, 0.6f, 0.6f }; + static float default_2[3] = { 0.6f, 0.6f, 1.0f }; + + prop = RNA_def_property(srna, "cursor_color_add", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "curcolor_add"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_array_default(prop, default_1); + RNA_def_property_ui_text(prop, "Cursor Add", "Color for the cursor for addition"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "cursor_color_sub", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "curcolor_sub"); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_array_default(prop, default_2); + RNA_def_property_ui_text(prop, "Cursor Sub", "Color for the cursor for substration"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + + prop = RNA_def_property(srna, "use_cursor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_EDITBRUSH_FLAG_ENABLE_CURSOR); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Enable Cursor", "Enable cursor on screen"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + } void RNA_def_sculpt_paint(BlenderRNA *brna) @@ -1166,6 +1254,7 @@ void RNA_def_sculpt_paint(BlenderRNA *brna) rna_def_paint(brna); rna_def_sculpt(brna); rna_def_uv_sculpt(brna); + rna_def_gp_paint(brna); rna_def_vertex_paint(brna); rna_def_image_paint(brna); rna_def_particle_edit(brna); diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c new file mode 100644 index 00000000000..4956333b202 --- /dev/null +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -0,0 +1,538 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_shader_fx.c + * \ingroup RNA + */ + + +#include +#include +#include + +#include "DNA_shader_fx_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "BLT_translation.h" + +#include "BKE_animsys.h" +#include "BKE_shader_fx.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "rna_internal.h" + +#include "WM_api.h" +#include "WM_types.h" + +const EnumPropertyItem rna_enum_object_shaderfx_type_items[] = { + {eShaderFxType_Blur, "FX_BLUR", ICON_SOLO_ON, "Blur", "Apply Gaussian Blur to object" }, + {eShaderFxType_Colorize, "FX_COLORIZE", ICON_SOLO_ON, "Colorize", "Apply different tint effects" }, + {eShaderFxType_Flip, "FX_FLIP", ICON_SOLO_ON, "Flip", "Flip image" }, + {eShaderFxType_Light, "FX_LIGHT", ICON_SOLO_ON, "Light", "Simulate ilumination" }, + {eShaderFxType_Pixel, "FX_PIXEL", ICON_SOLO_ON, "Pixelate", "Pixelate image"}, + {eShaderFxType_Rim, "FX_RIM", ICON_SOLO_ON, "Rim", "Add a rim to the image" }, + {eShaderFxType_Swirl, "FX_SWIRL", ICON_SOLO_ON, "Swirl", "Create a rotation distortion"}, + {eShaderFxType_Wave, "FX_WAVE", ICON_SOLO_ON, "Wave Distortion", "Apply sinusoidal deformation"}, + {0, NULL, 0, NULL, NULL} +}; + +const EnumPropertyItem rna_enum_shaderfx_rim_modes_items[] = { + {eShaderFxRimMode_Normal, "NORMAL", 0, "Normal", "" }, + {eShaderFxRimMode_Overlay, "OVERLAY", 0, "Overlay", "" }, + {eShaderFxRimMode_Add, "ADD", 0, "Add", "" }, + {eShaderFxRimMode_Subtract, "SUBTRACT", 0, "Subtract", "" }, + {eShaderFxRimMode_Multiply, "MULTIPLY", 0, "Multiply", "" }, + {eShaderFxRimMode_Divide, "DIVIDE", 0, "Divide", "" }, + {0, NULL, 0, NULL, NULL } +}; + +const EnumPropertyItem rna_enum_shaderfx_colorize_modes_items[] = { + {eShaderFxColorizeMode_GrayScale, "GRAYSCALE", 0, "Gray Scale", "" }, + {eShaderFxColorizeMode_Sepia, "SEPIA", 0, "Sepia", "" }, + {eShaderFxColorizeMode_BiTone, "BITONE", 0, "Bi-Tone", "" }, + {eShaderFxColorizeMode_Transparent, "TRANSPARENT", 0, "Transparent", "" }, + {eShaderFxColorizeMode_Custom, "CUSTOM", 0, "Custom", "" }, + {0, NULL, 0, NULL, NULL } +}; + +#ifdef RNA_RUNTIME + +#include "BKE_shader_fx.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + +static StructRNA *rna_ShaderFx_refine(struct PointerRNA *ptr) +{ + ShaderFxData *md = (ShaderFxData *)ptr->data; + + switch ((ShaderFxType)md->type) { + case eShaderFxType_Blur: + return &RNA_ShaderFxBlur; + case eShaderFxType_Colorize: + return &RNA_ShaderFxColorize; + case eShaderFxType_Wave: + return &RNA_ShaderFxWave; + case eShaderFxType_Pixel: + return &RNA_ShaderFxPixel; + case eShaderFxType_Rim: + return &RNA_ShaderFxRim; + case eShaderFxType_Swirl: + return &RNA_ShaderFxSwirl; + case eShaderFxType_Flip: + return &RNA_ShaderFxFlip; + case eShaderFxType_Light: + return &RNA_ShaderFxLight; + /* Default */ + case eShaderFxType_None: + case NUM_SHADER_FX_TYPES: + return &RNA_ShaderFx; + } + + return &RNA_ShaderFx; +} + +static void rna_ShaderFx_name_set(PointerRNA *ptr, const char *value) +{ + ShaderFxData *gmd = ptr->data; + char oldname[sizeof(gmd->name)]; + + /* make a copy of the old name first */ + BLI_strncpy(oldname, gmd->name, sizeof(gmd->name)); + + /* copy the new name into the name slot */ + BLI_strncpy_utf8(gmd->name, value, sizeof(gmd->name)); + + /* make sure the name is truly unique */ + if (ptr->id.data) { + Object *ob = ptr->id.data; + BKE_shaderfx_unique_name(&ob->shader_fx, gmd); + } + + /* fix all the animation data which may link to this */ + BKE_animdata_fix_paths_rename_all(NULL, "shader_effects", oldname, gmd->name); +} + +static char *rna_ShaderFx_path(PointerRNA *ptr) +{ + ShaderFxData *gmd = ptr->data; + char name_esc[sizeof(gmd->name) * 2]; + + BLI_strescape(name_esc, gmd->name, sizeof(name_esc)); + return BLI_sprintfN("shader_effects[\"%s\"]", name_esc); +} + +static void rna_ShaderFx_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + DEG_id_tag_update(ptr->id.data, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NC_GPENCIL, ptr->id.data); +} + +static void rna_ShaderFx_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + rna_ShaderFx_update(bmain, scene, ptr); + DEG_relations_tag_update(bmain); +} + +/* Objects */ + +static void shaderfx_object_set(Object *self, Object **ob_p, int type, PointerRNA value) +{ + Object *ob = value.data; + + if (!self || ob != self) { + if (!ob || type == OB_EMPTY || ob->type == type) { + id_lib_extern((ID *)ob); + *ob_p = ob; + } + } +} + +#define RNA_FX_OBJECT_SET(_type, _prop, _obtype) \ +static void rna_##_type##ShaderFx_##_prop##_set(PointerRNA *ptr, PointerRNA value) \ +{ \ + _type##ShaderFxData *tmd = (_type##ShaderFxData *)ptr->data; \ + shaderfx_object_set(ptr->id.data, &tmd->_prop, _obtype, value); \ +} + +RNA_FX_OBJECT_SET(Light, object, OB_EMPTY); +RNA_FX_OBJECT_SET(Swirl, object, OB_EMPTY); + +#undef RNA_FX_OBJECT_SET + +#else + +static void rna_def_shader_fx_blur(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxBlur", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Gaussian Blur Effect", "Gaussian Blur effect"); + RNA_def_struct_sdna(srna, "BlurShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "factor", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "radius"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Factor", "Factor of Blur"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "samples"); + RNA_def_property_range(prop, 0, 32); + RNA_def_property_ui_range(prop, 0, 32, 2, -1); + RNA_def_property_int_default(prop, 4); + RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples (zero, disable blur)"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "coc", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "coc"); + RNA_def_property_range(prop, 0.001f, 1.0f); + RNA_def_property_float_default(prop, 0.025f); + RNA_def_property_ui_text(prop, "Precision", "Define circle of confusion for depth of field"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "use_dof_mode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_BLUR_DOF_MODE); + RNA_def_property_ui_text(prop, "Lock Focal Plane", "Blur using focal plane distance as factor to simulate depth of field effect (only in camera view)"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_colorize(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxColorize", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Colorize Effect", "Colorize effect"); + RNA_def_struct_sdna(srna, "ColorizeShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "factor"); + RNA_def_property_range(prop, 0, 1.0); + RNA_def_property_ui_text(prop, "Factor", "Mix factor"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "low_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "low_color"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Low color", "First color used for effect"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "high_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "high_color"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Hight color", "Second color used for effect"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, rna_enum_shaderfx_colorize_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Effect mode"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_wave(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_shaderfx_wave_type_items[] = { + { 0, "HORIZONTAL", 0, "Horizontal", "" }, + { 1, "VERTICAL", 0, "Vertical", "" }, + { 0, NULL, 0, NULL, NULL } + }; + + srna = RNA_def_struct(brna, "ShaderFxWave", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Wave Deformation Effect", "Wave Deformation effect"); + RNA_def_struct_sdna(srna, "WaveShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "orientation"); + RNA_def_property_enum_items(prop, prop_shaderfx_wave_type_items); + RNA_def_property_ui_text(prop, "Orientation", "Direction of the wave"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "amplitude"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_text(prop, "Amplitude", "Amplitude of Wave"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "period"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_text(prop, "Period", "Period of Wave"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "phase"); + RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); + RNA_def_property_ui_text(prop, "Phase", "Phase Shift of Wave"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_pixel(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxPixel", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Pixelate Effect", "Pixelate effect"); + RNA_def_struct_sdna(srna, "PixelShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "size"); + RNA_def_property_range(prop, 1, INT_MAX); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Size", "Pixel size"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "rgba"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Color", "Color used for lines"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "use_lines", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_PIXEL_USE_LINES); + RNA_def_property_ui_text(prop, "Lines", "Display lines between pixels"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_rim(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxRim", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Rim Effect", "Rim effect"); + RNA_def_struct_sdna(srna, "RimShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "offset", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "offset"); + RNA_def_property_range(prop, -INT_MAX, INT_MAX); + RNA_def_property_ui_text(prop, "Offset", "Offset of the rim"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "rim_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "rim_rgb"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Rim Color", "Color used for Rim"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "mask_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_float_sdna(prop, NULL, "mask_rgb"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Mask Color", "Color that must be keept"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, rna_enum_shaderfx_rim_modes_items); + RNA_def_property_ui_text(prop, "Mode", "Blend mode"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "blur", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "blur"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Blur", "Number of pixels for bluring rim (set to 0 to disable)"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "samples"); + RNA_def_property_range(prop, 0, 32); + RNA_def_property_ui_range(prop, 0, 32, 2, -1); + RNA_def_property_int_default(prop, 4); + RNA_def_property_ui_text(prop, "Samples", "Number of Blur Samples (zero, disable blur)"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_swirl(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxSwirl", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Swirl Effect", "Swirl effect"); + RNA_def_struct_sdna(srna, "SwirlShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "radius", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "radius"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Radius", "Radius to apply"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "angle"); + RNA_def_property_range(prop, DEG2RAD(-5 * 360), DEG2RAD(5 * 360)); + RNA_def_property_ui_range(prop, DEG2RAD(-5 * 360), DEG2RAD(5 * 360), 5, 2); + RNA_def_property_ui_text(prop, "Angle", "Angle of rotation"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "transparent", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SWIRL_MAKE_TRANSPARENT); + RNA_def_property_ui_text(prop, "Transparent", "Make image transparent outside of radius"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Object", "Object to determine center location"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_SwirlShaderFx_object_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_update(prop, 0, "rna_ShaderFx_dependency_update"); +} + +static void rna_def_shader_fx_flip(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxFlip", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Flip Effect", "Flip effect"); + RNA_def_struct_sdna(srna, "FlipShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "flip_horizontal", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_FLIP_HORIZONTAL); + RNA_def_property_ui_text(prop, "Horizontal", "Flip image horizontally"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "flip_vertical", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_FLIP_VERTICAL); + RNA_def_property_ui_text(prop, "Vertical", "Flip image vertically"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); +} + +static void rna_def_shader_fx_light(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "ShaderFxLight", "ShaderFx"); + RNA_def_struct_ui_text(srna, "Light Effect", "Light effect"); + RNA_def_struct_sdna(srna, "LightShaderFxData"); + RNA_def_struct_ui_icon(srna, ICON_SOLO_ON); + + prop = RNA_def_property(srna, "energy", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "energy"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 1, FLT_MAX, 1, 2); + RNA_def_property_ui_text(prop, "Energy", "Strength of light source"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "ambient", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "ambient"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0, FLT_MAX, 1, 2); + RNA_def_property_ui_text(prop, "Ambient", "Strength of ambient light source"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); + RNA_def_property_ui_text(prop, "Object", "Object to determine light source location"); + RNA_def_property_pointer_funcs(prop, NULL, "rna_LightShaderFx_object_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK); + RNA_def_property_update(prop, 0, "rna_ShaderFx_dependency_update"); +} + +void RNA_def_shader_fx(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* data */ + srna = RNA_def_struct(brna, "ShaderFx", NULL); + RNA_def_struct_ui_text(srna, "ShaderFx", "Effect affecting the grease pencil object"); + RNA_def_struct_refine_func(srna, "rna_ShaderFx_refine"); + RNA_def_struct_path_func(srna, "rna_ShaderFx_path"); + RNA_def_struct_sdna(srna, "ShaderFxData"); + + /* strings */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShaderFx_name_set"); + RNA_def_property_ui_text(prop, "Name", "Effect name"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL); + RNA_def_struct_name_property(srna, prop); + + /* enums */ + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, rna_enum_object_shaderfx_type_items); + RNA_def_property_ui_text(prop, "Type", ""); + + /* flags */ + prop = RNA_def_property(srna, "show_viewport", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Realtime); + RNA_def_property_ui_text(prop, "Realtime", "Display effect in viewport"); + RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 0); + + prop = RNA_def_property(srna, "show_render", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Render); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_ui_text(prop, "Render", "Use effect during render"); + RNA_def_property_ui_icon(prop, ICON_SCENE, 0); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, NULL); + + prop = RNA_def_property(srna, "show_in_editmode", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Editmode); + RNA_def_property_ui_text(prop, "Edit Mode", "Display effect in Edit mode"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); + RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0); + + prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Expanded); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); + RNA_def_property_ui_text(prop, "Expanded", "Set effect expanded in the user interface"); + RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); + + /* types */ + rna_def_shader_fx_blur(brna); + rna_def_shader_fx_colorize(brna); + rna_def_shader_fx_wave(brna); + rna_def_shader_fx_pixel(brna); + rna_def_shader_fx_rim(brna); + rna_def_shader_fx_swirl(brna); + rna_def_shader_fx_flip(brna); + rna_def_shader_fx_light(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 2f009238851..56491fd70e4 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -40,6 +40,7 @@ #include "BLI_math.h" #include "DNA_action_types.h" +#include "DNA_gpencil_types.h" #include "DNA_key_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" @@ -288,6 +289,7 @@ static const EnumPropertyItem buttons_context_items[] = { {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, {BCONTEXT_WORKSPACE, "WORKSPACE", ICON_SPLITSCREEN, "Workspace", "Workspace"}, + {BCONTEXT_SHADERFX, "SHADERFX", ICON_SOLO_ON, "Effects", "Object visual effects" }, {0, NULL, 0, NULL, NULL} }; @@ -308,6 +310,14 @@ const EnumPropertyItem rna_enum_file_sort_items[] = { {0, NULL, 0, NULL, NULL} }; +static const EnumPropertyItem rna_enum_gpencil_grid_axis_items[] = { + {V3D_GP_GRID_AXIS_LOCK, "LOCK", 0, "Lock", "Use current drawing locked axis" }, + {V3D_GP_GRID_AXIS_X, "X", 0, "X", ""}, + {V3D_GP_GRID_AXIS_Y, "Y", 0, "Y", ""}, + {V3D_GP_GRID_AXIS_Z, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "DNA_anim_types.h" @@ -475,6 +485,17 @@ static void rna_Space_view2d_sync_update(Main *UNUSED(bmain), Scene *UNUSED(scen } } +static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +{ + /* need set all caches as dirty to recalculate onion skinning */ + for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { + if (ob->type == OB_GPENCIL) { + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + } + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + /* Space 3D View */ static void rna_SpaceView3D_camera_update(Main *bmain, Scene *scene, PointerRNA *ptr) { @@ -1338,6 +1359,10 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf( RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER); } + if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SHADERFX); + } + if (sbuts->pathflag & (1 << BCONTEXT_DATA)) { RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA); (item + totitem - 1)->icon = sbuts->dataicon; @@ -2613,7 +2638,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) prop = RNA_def_property(srna, "show_overlays", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag2", V3D_RENDER_OVERRIDE); RNA_def_property_ui_text(prop, "Show Overlays", "Display overlays like gizmos and outlines"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update"); prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR); @@ -2831,6 +2856,86 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Weight Paint Opacity", "Opacity of the weight paint mode overlay"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + /* grease pencil paper settings */ + prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_ANNOTATION); + RNA_def_property_ui_text(prop, "Show Annotation", + "Show annotations for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "use_gpencil_paper", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_GP_SHOW_PAPER); + RNA_def_property_ui_text(prop, "Use Paper", + "Cover all viewport with a full color layer to improve visibility while drawing over complex scenes"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "use_gpencil_grid", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_GP_SHOW_GRID); + RNA_def_property_ui_text(prop, "Use Grid", + "Draw a grid over grease pencil paper"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "gpencil_grid_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "overlay.gpencil_grid_scale"); + RNA_def_property_range(prop, 0.01f, FLT_MAX); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_ui_text(prop, "Scale", "Grid scale"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "gpencil_grid_lines", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "overlay.gpencil_grid_lines"); + RNA_def_property_range(prop, 1, INT_MAX); + RNA_def_property_int_default(prop, GP_DEFAULT_GRID_LINES); + RNA_def_property_ui_text(prop, "Subdivisions", "Number of subdivisions in each side of symmetry line"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "gpencil_grid_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "overlay.gpencil_grid_axis"); + RNA_def_property_enum_items(prop, rna_enum_gpencil_grid_axis_items); + RNA_def_property_ui_text(prop, "Axis", "Axis to display grid"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "gpencil_grid_opacity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "overlay.gpencil_grid_opacity"); + RNA_def_property_range(prop, 0.1f, 1.0f); + RNA_def_property_float_default(prop, 0.9f); + RNA_def_property_ui_text(prop, "Opacity", "Grid opacity"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + /* Paper opacity factor */ + prop = RNA_def_property(srna, "gpencil_paper_opacity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "overlay.gpencil_paper_opacity"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_ui_text(prop, "Opacity", "Paper opacity"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + /* show edit lines */ + prop = RNA_def_property(srna, "use_gpencil_edit_lines", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_GP_SHOW_EDIT_LINES); + RNA_def_property_ui_text(prop, "Edit Lines", "Show edit lines when edit strokes"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update"); + + prop = RNA_def_property(srna, "use_gpencil_multiedit_line_only", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_GP_SHOW_MULTIEDIT_LINES); + RNA_def_property_ui_text(prop, "Lines Only", "Show only edit lines for additional frames"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update"); + + /* main grease pencil onion switch */ + prop = RNA_def_property(srna, "use_gpencil_onion_skin", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_GP_SHOW_ONION_SKIN); + RNA_def_property_ui_text(prop, "Onion Skins", "Show ghosts of the frames before and after the current frame"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPencil_update"); + + /* vertex opacity */ + prop = RNA_def_property(srna, "vertex_opacity", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vertex_opacity"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Vertex Opacity", "Opacity for edit vertices"); + RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_GPencil_update"); + } static void rna_def_space_view3d(BlenderRNA *brna) @@ -2957,12 +3062,6 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Clip End", "3D View far clipping distance"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", - "Show grease pencil for this view"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - prop = RNA_def_property(srna, "show_textured_solid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX); RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view"); @@ -3143,6 +3242,8 @@ static void rna_def_space_view3d(BlenderRNA *brna) {"show_object_viewport_lattice", "show_object_select_lattice"}}, {"Empty", (1 << OB_EMPTY), {"show_object_viewport_empty", "show_object_select_empty"}}, + {"Grease Pencil", (1 << OB_GPENCIL), + {"show_object_viewport_grease_pencil", "show_object_select_grease_pencil"}}, {"Camera", (1 << OB_CAMERA), {"show_object_viewport_camera", "show_object_select_camera"}}, {"Light", (1 << OB_LAMP), @@ -3382,10 +3483,10 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); - prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", - "Show grease pencil for this view"); + RNA_def_property_ui_text(prop, "Show Annotation", + "Show annotations for this view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); prop = RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE); @@ -3434,6 +3535,7 @@ static void rna_def_space_image(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); @@ -3587,10 +3689,10 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); - prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", - "Show grease pencil for this view"); + RNA_def_property_ui_text(prop, "Show Annotation", + "Show annotations for this view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE); @@ -3629,8 +3731,9 @@ static void rna_def_space_sequencer(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space"); + RNA_def_property_ui_text(prop, "Grease Pencil", "Grease Pencil data for this Preview region"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); prop = RNA_def_property(srna, "overlay_type", PROP_ENUM, PROP_NONE); @@ -4734,10 +4837,10 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, "rna_SpaceNodeEditor_show_backdrop_update"); - prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", - "Show grease pencil for this view"); + RNA_def_property_ui_text(prop, "Show Annotation", + "Show annotations for this view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); prop = RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE); @@ -4802,8 +4905,8 @@ static void rna_def_space_clip(BlenderRNA *brna) }; static const EnumPropertyItem gpencil_source_items[] = { - {SC_GPENCIL_SRC_CLIP, "CLIP", 0, "Clip", "Show grease pencil data-block which belongs to movie clip"}, - {SC_GPENCIL_SRC_TRACK, "TRACK", 0, "Track", "Show grease pencil data-block which belongs to active track"}, + {SC_GPENCIL_SRC_CLIP, "CLIP", 0, "Clip", "Show annotation data-block which belongs to movie clip"}, + {SC_GPENCIL_SRC_TRACK, "TRACK", 0, "Track", "Show annotation data-block which belongs to active track"}, {0, NULL, 0, NULL, NULL} }; @@ -4953,11 +5056,11 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); - /* show grease pencil */ - prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL); - RNA_def_property_ui_text(prop, "Show Grease Pencil", - "Show grease pencil for this view"); + /* show annotation */ + prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_ANNOTATION); + RNA_def_property_ui_text(prop, "Show Annotation", + "Show annotations for this view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); /* show filters */ diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 5da49ac5957..4c5af755b13 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1480,6 +1480,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "gpd"); RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_datablocks_annotations_poll"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this track"); RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index c9ce9ae7961..a5deb0a32f1 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -759,6 +759,7 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_string(func, "unlink", NULL, 0, "", "Operator identifier to unlink the ID block"); RNA_def_enum(func, "filter", id_template_filter_items, UI_TEMPLATE_ID_FILTER_ALL, "", "Optionally limit the items which can be selected"); + RNA_def_boolean(func, "live_icon", false, "", "Show preview instead of fixed icon"); func = RNA_def_function(srna, "template_ID_preview", "uiTemplateIDPreview"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); @@ -831,6 +832,31 @@ void RNA_api_ui_layout(StructRNA *srna) parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "template_greasepencil_modifier", "uiTemplateGpencilModifier"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Generates the UI layout for grease pencil modifiers"); + parm = RNA_def_pointer(func, "data", "GpencilModifier", "", "Modifier data"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "template_shaderfx", "uiTemplateShaderFx"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Generates the UI layout for shader effect"); + parm = RNA_def_pointer(func, "data", "ShaderFx", "", "Shader data"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "template_greasepencil_color", "uiTemplateGpencilColorPreview"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + api_ui_item_rna_common(func); + RNA_def_int(func, "rows", 0, 0, INT_MAX, "Number of thumbnail preview rows to display", "", 0, INT_MAX); + RNA_def_int(func, "cols", 0, 0, INT_MAX, "Number of thumbnail preview columns to display", "", 0, INT_MAX); + RNA_def_float(func, "scale", 1.0f, 0.1f, 1.5f, "Scale of the image thumbnails", "", 0.5f, 1.0f); + RNA_def_enum(func, "filter", id_template_filter_items, UI_TEMPLATE_ID_FILTER_ALL, + "", "Optionally limit the items which can be selected"); + func = RNA_def_function(srna, "template_constraint", "uiTemplateConstraint"); RNA_def_function_ui_description(func, "Generates the UI layout for constraints"); parm = RNA_def_pointer(func, "data", "Constraint", "", "Constraint data"); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 3c92b6c143b..4c3074bba4f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -4371,6 +4371,14 @@ static void rna_def_userdef_system(BlenderRNA *brna) "Enable OpenGL multi-sampling, only for systems that support it, requires restart"); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + /* grease pencil anti-aliasing */ + prop = RNA_def_property(srna, "gpencil_multi_sample", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_multisamples"); + RNA_def_property_enum_items(prop, multi_sample_levels); + RNA_def_property_ui_text(prop, "Gpencil MultiSample", + "Enable Grease Pencil OpenGL multi-sampling, only for systems that support it"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP); RNA_def_property_ui_text(prop, "Region Overlap", diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 5c3f510ffca..0b27cadd086 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -739,6 +739,9 @@ int RE_engine_render(Render *re, int do_all) type->render(engine, engine->depsgraph); + /* grease pencil render over previous render result */ + DRW_render_gpencil(engine, engine->depsgraph); + engine_depsgraph_free(engine); } FOREACH_VIEW_LAYER_TO_RENDER_END; diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt new file mode 100644 index 00000000000..2b33c9817c3 --- /dev/null +++ b/source/blender/shader_fx/CMakeLists.txt @@ -0,0 +1,64 @@ +# ***** 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) 2018, Blender Foundation +# All rights reserved. +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + intern + ../blenkernel + ../blenlib + ../blenfont + ../depsgraph + ../makesdna + ../makesrna + ../bmesh + ../render/extern/include + ../../../intern/elbeem/extern + ../../../intern/guardedalloc + ../../../intern/eigen +) + +set(INC_SYS + ${ZLIB_INCLUDE_DIRS} +) + +set(SRC + intern/FX_shader_util.h + + intern/FX_shader_util.c + intern/FX_shader_blur.c + intern/FX_shader_colorize.c + intern/FX_shader_flip.c + intern/FX_shader_light.c + intern/FX_shader_pixel.c + intern/FX_shader_rim.c + intern/FX_shader_swirl.c + intern/FX_shader_wave.c + + FX_shader_types.h +) + +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + +add_definitions(${GL_DEFINITIONS}) + +blender_add_lib(bf_shader_fx "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/shader_fx/FX_shader_types.h b/source/blender/shader_fx/FX_shader_types.h new file mode 100644 index 00000000000..b8d8f04e07f --- /dev/null +++ b/source/blender/shader_fx/FX_shader_types.h @@ -0,0 +1,47 @@ +/* + * ***** 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. + * + * Contributor(s): Ben Batt + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file FX_shader_types.h + * \ingroup shader_fx + */ + +#ifndef __FX_SHADER_TYPES_H__ +#define __FX_SHADER_TYPES_H__ + +#include "BKE_shader_fx.h" + +/* ****************** Type structures for all effects ****************** */ + +extern ShaderFxTypeInfo shaderfx_Type_None; +extern ShaderFxTypeInfo shaderfx_Type_Blur; +extern ShaderFxTypeInfo shaderfx_Type_Colorize; +extern ShaderFxTypeInfo shaderfx_Type_Flip; +extern ShaderFxTypeInfo shaderfx_Type_Light; +extern ShaderFxTypeInfo shaderfx_Type_Pixel; +extern ShaderFxTypeInfo shaderfx_Type_Rim; +extern ShaderFxTypeInfo shaderfx_Type_Swirl; +extern ShaderFxTypeInfo shaderfx_Type_Wave; + +/* FX_shaderfx_util.c */ +void shaderfx_type_init(ShaderFxTypeInfo *types[]); + +#endif /* __FX_SHADER_TYPES_H__ */ diff --git a/source/blender/shader_fx/intern/FX_shader_blur.c b/source/blender/shader_fx/intern/FX_shader_blur.c new file mode 100644 index 00000000000..128ebba8875 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_blur.c @@ -0,0 +1,66 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_blur.c + * \ingroup shader_fx + */ + +#include + +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + BlurShaderFxData *gpfx = (BlurShaderFxData *)fx; + ARRAY_SET_ITEMS(gpfx->radius, 1, 1); + gpfx->samples = 4; + gpfx->coc = 0.025f; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Blur = { + /* name */ "Blur", + /* structName */ "BlurShaderFxData", + /* structSize */ sizeof(BlurShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ eShaderFxTypeFlag_Single, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_colorize.c b/source/blender/shader_fx/intern/FX_shader_colorize.c new file mode 100644 index 00000000000..edf276b842c --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_colorize.c @@ -0,0 +1,69 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_colorize.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_shader_fx_types.h" + +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + ColorizeShaderFxData *gpfx = (ColorizeShaderFxData *)fx; + ARRAY_SET_ITEMS(gpfx->low_color, 0.0f, 0.0f, 0.0f, 1.0f); + ARRAY_SET_ITEMS(gpfx->high_color, 1.0f, 1.0f, 1.0f, 1.0f); + gpfx->mode = eShaderFxColorizeMode_GrayScale; + gpfx->factor = 0.5f; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Colorize = { + /* name */ "Colorize", + /* structName */ "ColorizeShaderFxData", + /* structSize */ sizeof(ColorizeShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ 0, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_flip.c b/source/blender/shader_fx/intern/FX_shader_flip.c new file mode 100644 index 00000000000..404e2f8160e --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_flip.c @@ -0,0 +1,69 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_flip.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" + +#include "BLI_math_base.h" +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + FlipShaderFxData *gpfx = (FlipShaderFxData *)fx; + gpfx->flag |= FX_FLIP_HORIZONTAL; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Flip = { + /* name */ "Flip", + /* structName */ "FlipShaderFxData", + /* structSize */ sizeof(FlipShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ eShaderFxTypeFlag_Single, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_light.c b/source/blender/shader_fx/intern/FX_shader_light.c new file mode 100644 index 00000000000..9a17ea8ae5f --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_light.c @@ -0,0 +1,104 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_light.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" + +#include "BLI_math_base.h" +#include "BLI_utildefines.h" + +#include "BKE_library_query.h" +#include "BKE_modifier.h" +#include "BKE_shader_fx.h" + +#include "FX_shader_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + +static void initData(ShaderFxData *fx) +{ + LightShaderFxData *gpfx = (LightShaderFxData *)fx; + gpfx->energy = 10.0f; + gpfx->ambient = 5.0f; + gpfx->object = NULL; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +static void updateDepsgraph(ShaderFxData *md, const ModifierUpdateDepsgraphContext *ctx) +{ + LightShaderFxData *fxd = (LightShaderFxData *)md; + if (fxd->object != NULL) { + DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_GEOMETRY, "Light ShaderFx"); + DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_TRANSFORM, "Light ShaderFx"); + } + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Light ShaderFx"); +} + +static bool isDisabled(ShaderFxData *fx, int UNUSED(userRenderParams)) +{ + LightShaderFxData *fxd = (LightShaderFxData *)fx; + + return !fxd->object; +} + +static void foreachObjectLink( + ShaderFxData *fx, Object *ob, + ShaderFxObjectWalkFunc walk, void *userData) +{ + LightShaderFxData *fxd = (LightShaderFxData *)fx; + + walk(userData, ob, &fxd->object, IDWALK_CB_NOP); +} + +ShaderFxTypeInfo shaderfx_Type_Light = { + /* name */ "Light", + /* structName */ "LightShaderFxData", + /* structSize */ sizeof(LightShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ 0, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_pixel.c b/source/blender/shader_fx/intern/FX_shader_pixel.c new file mode 100644 index 00000000000..a3ffd3a9b0d --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_pixel.c @@ -0,0 +1,66 @@ +/* + * ***** 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) 2017, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_pixel.c + * \ingroup shader_fx + */ + +#include + +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + PixelShaderFxData *gpfx = (PixelShaderFxData *)fx; + ARRAY_SET_ITEMS(gpfx->size, 5, 5); + ARRAY_SET_ITEMS(gpfx->rgba, 0.0f, 0.0f, 0.0f, 0.9f); + gpfx->flag |= FX_PIXEL_USE_LINES; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Pixel = { + /* name */ "Pixelate", + /* structName */ "PixelShaderFxData", + /* structSize */ sizeof(PixelShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ eShaderFxTypeFlag_Single, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_rim.c b/source/blender/shader_fx/intern/FX_shader_rim.c new file mode 100644 index 00000000000..611e6f91bf7 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_rim.c @@ -0,0 +1,70 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_rim.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_shader_fx_types.h" + +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + RimShaderFxData *gpfx = (RimShaderFxData *)fx; + ARRAY_SET_ITEMS(gpfx->offset, 50, -100); + ARRAY_SET_ITEMS(gpfx->rim_rgb, 1.0f, 1.0f, 0.5f, 0.9f); + ARRAY_SET_ITEMS(gpfx->mask_rgb, 0.0f, 0.0f, 0.0f, 1.0f); + gpfx->mode = eShaderFxRimMode_Multiply; + ARRAY_SET_ITEMS(gpfx->blur, 0, 0); +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Rim = { + /* name */ "Rim", + /* structName */ "RimShaderFxData", + /* structSize */ sizeof(RimShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ 0, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_swirl.c b/source/blender/shader_fx/intern/FX_shader_swirl.c new file mode 100644 index 00000000000..9667f466eec --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_swirl.c @@ -0,0 +1,103 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_swirl.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" + +#include "BLI_math_base.h" +#include "BLI_utildefines.h" + +#include "BKE_library_query.h" +#include "BKE_modifier.h" +#include "BKE_shader_fx.h" + +#include "FX_shader_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + +static void initData(ShaderFxData *md) +{ + SwirlShaderFxData *gpmd = (SwirlShaderFxData *)md; + gpmd->radius = 100; + gpmd->angle = M_PI_2; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +static void updateDepsgraph(ShaderFxData *fx, const ModifierUpdateDepsgraphContext *ctx) +{ + SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; + if (fxd->object != NULL) { + DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_GEOMETRY, "Swirl ShaderFx"); + DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_TRANSFORM, "Swirl ShaderFx"); + } + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Swirl ShaderFx"); +} + +static bool isDisabled(ShaderFxData *fx, int UNUSED(userRenderParams)) +{ + SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; + + return !fxd->object; +} + +static void foreachObjectLink( + ShaderFxData *fx, Object *ob, + ShaderFxObjectWalkFunc walk, void *userData) +{ + SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx; + + walk(userData, ob, &fxd->object, IDWALK_CB_NOP); +} + +ShaderFxTypeInfo shaderfx_Type_Swirl = { + /* name */ "Swirl", + /* structName */ "SwirlShaderFxData", + /* structSize */ sizeof(SwirlShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ 0, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ isDisabled, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/shader_fx/intern/FX_shader_util.c b/source/blender/shader_fx/intern/FX_shader_util.c new file mode 100644 index 00000000000..c55b9304503 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_util.c @@ -0,0 +1,56 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/shader_fx/intern/FX_shader_util.c + * \ingroup shader_fx + */ + + +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_shader_fx.h" + +#include "FX_shader_types.h" +#include "FX_shader_util.h" + +void shaderfx_type_init(ShaderFxTypeInfo *types[]) +{ +#define INIT_FX_TYPE(typeName) (types[eShaderFxType_##typeName] = &shaderfx_Type_##typeName) + INIT_FX_TYPE(Blur); + INIT_FX_TYPE(Colorize); + INIT_FX_TYPE(Flip); + INIT_FX_TYPE(Light); + INIT_FX_TYPE(Pixel); + INIT_FX_TYPE(Rim); + INIT_FX_TYPE(Swirl); + INIT_FX_TYPE(Wave); +#undef INIT_FX_TYPE +} + diff --git a/source/blender/shader_fx/intern/FX_shader_util.h b/source/blender/shader_fx/intern/FX_shader_util.h new file mode 100644 index 00000000000..e2fdcd6fb4c --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_util.h @@ -0,0 +1,36 @@ +/* + * ***** 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) Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/shader_fx/intern/FX_shader_util.h + * \ingroup shader_fx + */ + + +#ifndef __FX_SHADER_UTIL_H__ +#define __FX_SHADER_UTIL_H__ + +#endif /* __FX_SHADER_UTIL_H__ */ diff --git a/source/blender/shader_fx/intern/FX_shader_wave.c b/source/blender/shader_fx/intern/FX_shader_wave.c new file mode 100644 index 00000000000..ea4563a00e1 --- /dev/null +++ b/source/blender/shader_fx/intern/FX_shader_wave.c @@ -0,0 +1,71 @@ +/* + * ***** 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) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/shader_fx/intern/FX_shader_wave.c + * \ingroup shader_fx + */ + +#include + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" + +#include "BLI_utildefines.h" + +#include "FX_shader_types.h" + +static void initData(ShaderFxData *fx) +{ + WaveShaderFxData *gpfx = (WaveShaderFxData *)fx; + gpfx->amplitude = 10.0f; + gpfx->period = 20.0f; + gpfx->phase = 0.0f; + gpfx->orientation = 1; +} + +static void copyData(const ShaderFxData *md, ShaderFxData *target) +{ + BKE_shaderfx_copyData_generic(md, target); +} + +ShaderFxTypeInfo shaderfx_Type_Wave = { + /* name */ "Wave Distorsion", + /* structName */ "WaveShaderFxData", + /* structSize */ sizeof(WaveShaderFxData), + /* type */ eShaderFxType_GpencilType, + /* flags */ eShaderFxTypeFlag_Single, + + /* copyData */ copyData, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, +}; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index df869ba6b68..76a1482ac7c 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -440,7 +440,7 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr switch (GS(((ID *)ptr->id.data)->name)) { case ID_SCE: { - CTX_TEST_PTR_DATA_TYPE(C, "active_gpencil_brush", RNA_GPencilBrush, ptr, CTX_data_active_gpencil_brush(C)); + CTX_TEST_PTR_DATA_TYPE(C, "active_gpencil_brush", RNA_Brush, ptr, CTX_data_active_gpencil_brush(C)); CTX_TEST_PTR_ID(C, "scene", ptr->id.data); break; } diff --git a/source/creator/creator.c b/source/creator/creator.c index 18396149342..914211afd56 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -63,7 +63,9 @@ #include "BKE_global.h" #include "BKE_material.h" #include "BKE_modifier.h" +#include "BKE_gpencil_modifier.h" #include "BKE_node.h" +#include "BKE_shader_fx.h" #include "BKE_sound.h" #include "BKE_image.h" #include "BKE_particle.h" @@ -371,6 +373,8 @@ int main( BKE_cachefiles_init(); BKE_images_init(); BKE_modifier_init(); + BKE_gpencil_modifier_init(); + BKE_shaderfx_init(); DEG_register_node_types(); BKE_brush_system_init(); -- cgit v1.2.3 From f6300030e01609a8f80645fd8c6603aa75da80d5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 19:07:56 +1000 Subject: Cleanup: trailing space --- .../gpencil/shaders/fx/gpencil_fx_blur_frag.glsl | 6 +++--- .../shaders/fx/gpencil_fx_colorize_frag.glsl | 8 ++++---- .../gpencil/shaders/fx/gpencil_fx_flip_frag.glsl | 2 +- .../gpencil/shaders/fx/gpencil_fx_light_frag.glsl | 22 +++++++++++----------- .../gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl | 6 +++--- .../shaders/fx/gpencil_fx_rim_prepare_frag.glsl | 6 +++--- .../shaders/fx/gpencil_fx_rim_resolve_frag.glsl | 18 +++++++++--------- .../gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl | 10 +++++----- source/blender/editors/gpencil/gpencil_edit.c | 4 ++-- source/blender/editors/gpencil/gpencil_paint.c | 2 +- .../blender/editors/interface/interface_layout.c | 2 +- source/blender/editors/interface/resources.c | 2 +- source/blender/makesrna/intern/rna_shader_fx.c | 4 ++-- 13 files changed, 46 insertions(+), 46 deletions(-) diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl index 1d66ba3d4d4..1bf1d025430 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl @@ -21,10 +21,10 @@ void main() ivec2 uv = ivec2(gl_FragCoord.xy); vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); - + float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize); float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize); - + /* apply blurring, using a 9-tap filter with predefined gaussian weights */ /* depth */ float outdepth = 0; @@ -42,7 +42,7 @@ void main() gl_FragDepth = outdepth; - /* color */ + /* color */ vec4 outcolor = vec4(0.0); outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416; outcolor += texelFetch(strokeColor, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0) * 0.118318; diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl index 7d0ce4a804e..33b249ac09b 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl @@ -28,12 +28,12 @@ void main() vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0); float luminance = get_luminance(src_pixel); vec4 outcolor; - - /* is transparent */ + + /* is transparent */ if (src_pixel.a == 0.0f) { discard; } - + switch(mode) { case MODE_GRAYSCALE: { @@ -78,7 +78,7 @@ void main() { outcolor = src_pixel; } - + } gl_FragDepth = stroke_depth; diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl index 94fb3405c79..43589461cd1 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl @@ -27,7 +27,7 @@ void main() if (mode[1] > 0) { uv.y = wsize.y - uv.y; } - + ivec2 iuv = ivec2(uv.x, uv.y); stroke_depth = texelFetch(strokeDepth, iuv, 0).r; outcolor = texelFetch(strokeColor, iuv, 0); diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl index f3026c32fc8..6dcd0499baf 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl @@ -23,11 +23,11 @@ vec2 toScreenSpace(vec4 vertex) { /* need to calculate ndc because this is not done by vertex shader */ vec3 ndc = vec3(vertex).xyz / vertex.w; - + vec2 sc; sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x; sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y; - + return sc; } @@ -35,20 +35,20 @@ void main() { float stroke_depth; vec4 objcolor; - - vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + + vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); vec2 light2d = toScreenSpace(light_loc); /* calc pixel scale */ float pxscale = (ProjectionMatrix[3][3] == 0.0) ? (10.0 / (light_loc.z * defaultpixsize)) : (10.0 / defaultpixsize); pxscale = max(pxscale, 0.000001); - /* the height over plane is received in the w component of the loc + /* the height over plane is received in the w component of the loc * and needs a factor to adapt to pixels */ float peak = height * 10.0 * pxscale; - vec3 light3d = vec3(light2d.x, light2d.y, peak); - + vec3 light3d = vec3(light2d.x, light2d.y, peak); + vec2 uv = vec2(gl_FragCoord.xy); vec3 frag_loc = vec3(uv.x, uv.y, 0); vec3 norm = vec3(0, 0, 1.0); /* always z-up */ @@ -56,15 +56,15 @@ void main() ivec2 iuv = ivec2(uv.x, uv.y); stroke_depth = texelFetch(strokeDepth, iuv, 0).r; objcolor = texelFetch(strokeColor, iuv, 0); - + /* diffuse light */ vec3 lightdir = normalize(light3d - frag_loc); float diff = max(dot(norm, lightdir), 0.0); float dist = length(light3d - frag_loc) / pxscale; - float factor = diff * ((energy * 100.0) / (dist * dist)); - + float factor = diff * ((energy * 100.0) / (dist * dist)); + vec3 result = factor * max(ambient, 0.1) * vec3(objcolor); - + gl_FragDepth = stroke_depth; FragColor = vec4(result.r, result.g, result.b, objcolor.a); } diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl index d1a57a9a1b6..0b25dbbd012 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl @@ -23,15 +23,15 @@ void main() { vec2 uv = vec2(gl_FragCoord.xy); vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); - + float dx = (ProjectionMatrix[3][3] == 0.0) ? (nsize[0] / (nloc.z * defaultpixsize)) : (nsize[0] / defaultpixsize); float dy = (ProjectionMatrix[3][3] == 0.0) ? (nsize[1] / (nloc.z * defaultpixsize)) : (nsize[1] / defaultpixsize); dx = max(abs(dx), 3.0); dy = max(abs(dy), 3.0); - + vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy)); - + float stroke_depth = texelFetch(strokeDepth, ivec2(coord), 0).r; vec4 outcolor = texelFetch(strokeColor, ivec2(coord), 0); diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl index fe35d3832e1..6ea4faf11fd 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl @@ -26,7 +26,7 @@ void main() { vec2 uv = vec2(gl_FragCoord.xy); vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); - + float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize); float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize); @@ -35,7 +35,7 @@ void main() vec4 offset_pixel= texelFetch(strokeColor, ivec2(uv.x - dx, uv.y - dy), 0); vec4 outcolor; - /* is transparent */ + /* is transparent */ if (src_pixel.a == 0.0f) { discard; } @@ -56,7 +56,7 @@ void main() } else { outcolor = vec4(rim_color, 1.0); - } + } } gl_FragDepth = stroke_depth; diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl index 5e5edbd8325..20d6b8a91f8 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl @@ -19,14 +19,14 @@ out vec4 FragColor; float overlay_color(float a, float b) { - float rtn; + float rtn; if (a < 0.5) { rtn = 2.0 * a * b; } else { rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b); } - + return rtn; } @@ -53,16 +53,16 @@ vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color) else if (mode == MODE_DIVIDE) { outcolor = src_color / mix_color; } - else { + else { outcolor = mix_color; } - + /* use always the alpha of source color */ - + outcolor.a = src_color.a; /* use alpha to calculate the weight of the mixed color */ outcolor = mix(src_color, outcolor, mix_color.a); - + return outcolor; } @@ -75,8 +75,8 @@ void main() vec4 rim_pixel= texelFetch(strokeRim, uv.xy, 0); vec4 outcolor = src_pixel; - - /* is transparent */ + + /* is transparent */ if (src_pixel.a == 0.0f) { discard; } @@ -92,7 +92,7 @@ void main() outcolor = get_blend_color(mode, src_pixel, rim_pixel); } } - + gl_FragDepth = stroke_depth; FragColor = outcolor; } diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl index 6ce64350b3d..78aacafdcb7 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl @@ -23,11 +23,11 @@ vec2 toScreenSpace(vec4 vertex) { /* need to calculate ndc because this is not done by vertex shader */ vec3 ndc = vec3(vertex).xyz / vertex.w; - + vec2 sc; sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x; sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y; - + return sc; } @@ -37,15 +37,15 @@ void main() vec2 uv = vec2(gl_FragCoord.xy); float stroke_depth; vec4 outcolor; - - vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); + + vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); vec2 center = toScreenSpace(center3d); vec2 tc = uv - center; float dist = length(tc); float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) : (radius / defaultpixsize); pxradius = max(pxradius, 1); - + if (dist <= pxradius) { float percent = (pxradius - dist) / pxradius; float theta = percent * percent * angle * 8.0; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 4264645b52e..4a603e97615 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1785,13 +1785,13 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke /* Copy over the relevant point data */ new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment"); memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints); - + /* Copy over vertex weight data (if available) */ if (new_stroke->dvert != NULL) { /* Copy over the relevant vertex-weight points */ new_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * new_stroke->totpoints, "gp delete stroke fragment weight"); memcpy(new_stroke->dvert, gps->dvert + island->start_idx, sizeof(MDeformVert) * new_stroke->totpoints); - + /* Copy weights */ int e = island->start_idx; for (int i = 0; i < new_stroke->totpoints; i++) { diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 995ab91ff8b..fd5b2803650 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1690,7 +1690,7 @@ static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p) break; } - + /* unsupported views */ default: { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 89e1a8caec8..f143d418fe3 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1245,7 +1245,7 @@ void uiItemsFullEnumO( if (ui_layout_is_radial(layout)) { /* XXX: While "_all()" guarantees spatial stability, it's bad when an enum has > 8 items total, - * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the + * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the * introduction of GP editing modes) */ #if 0 diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index e6422c423b9..72023ebf2ae 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1573,7 +1573,7 @@ void init_userdef_do_versions(Main *bmain) for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) { memcpy(btheme, &U_theme_default, sizeof(*btheme)); } - + /* Annotations - new layer color * Replace anything that used to be set if it looks like was left * on the old default (i.e. black), which most users used diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c index 4956333b202..950aef9a8dd 100644 --- a/source/blender/makesrna/intern/rna_shader_fx.c +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -443,7 +443,7 @@ static void rna_def_shader_fx_light(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + srna = RNA_def_struct(brna, "ShaderFxLight", "ShaderFx"); RNA_def_struct_ui_text(srna, "Light Effect", "Light effect"); RNA_def_struct_sdna(srna, "LightShaderFxData"); @@ -517,7 +517,7 @@ void RNA_def_shader_fx(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edit Mode", "Display effect in Edit mode"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update"); RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0); - + prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", eShaderFxMode_Expanded); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC); -- cgit v1.2.3 From a823f58dfd039291fe14bdf7d281ecaa0311292e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 11:17:51 +0200 Subject: Subsurf: Disable oprtion for now Committed by accident, is too early for this yet. --- source/blender/modifiers/intern/MOD_subsurf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 7c605dd4f78..08dc7c92693 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -57,7 +57,7 @@ #include "intern/CCGSubSurf.h" -#define USE_OPENSUBDIV +// #define USE_OPENSUBDIV static void initData(ModifierData *md) { -- cgit v1.2.3 From ad5b611953b6c2b510982e25218552a12d70437c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 19:21:04 +1000 Subject: Cleanup: style --- source/blender/blenkernel/intern/rigidbody.c | 6 ++-- source/blender/blenkernel/intern/subdiv_mesh.c | 36 +++++++++++++--------- source/blender/blenloader/intern/versioning_280.c | 4 ++- .../editors/interface/interface_templates.c | 14 --------- source/blender/gpu/intern/gpu_context.cpp | 2 +- source/blender/windowmanager/intern/wm_window.c | 2 +- 6 files changed, 30 insertions(+), 34 deletions(-) diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index e6b8312734f..c542c3f927d 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -717,9 +717,9 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool /* --------------------- */ static void rigidbody_constraint_init_spring( - RigidBodyCon *rbc, void (*set_spring)(rbConstraint*,int,int), - void (*set_stiffness)(rbConstraint*,int,float), void (*set_damping)(rbConstraint*,int,float) -) { + RigidBodyCon *rbc, void (*set_spring)(rbConstraint *, int, int), + void (*set_stiffness)(rbConstraint *, int, float), void (*set_damping)(rbConstraint *, int, float)) +{ set_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X); set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x); set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x); diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 40c95964fb3..895d527ea5c 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -764,7 +764,8 @@ static void subdiv_evaluate_corner_vertices_regular( const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, - coarse_loop->v)) { + coarse_loop->v)) + { continue; } const MVert *coarse_vert = &coarse_mvert[coarse_loop->v]; @@ -798,7 +799,8 @@ static void subdiv_evaluate_corner_vertices_special( const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, - coarse_loop->v)) { + coarse_loop->v)) + { continue; } const MVert *coarse_vert = &coarse_mvert[coarse_loop->v]; @@ -847,7 +849,8 @@ static void subdiv_evaluate_edge_vertices_regular( const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, - coarse_loop->e)) { + coarse_loop->e)) + { continue; } vertex_interpolation_from_ptex(ctx, @@ -860,8 +863,8 @@ static void subdiv_evaluate_edge_vertices_regular( ctx->vertices_edge_offset + coarse_loop->e * num_subdiv_vertices_per_coarse_edge]; for (int vertex_index = 0; - vertex_index < num_subdiv_vertices_per_coarse_edge; - vertex_index++, subdiv_vert++) + vertex_index < num_subdiv_vertices_per_coarse_edge; + vertex_index++, subdiv_vert++) { float fac = (vertex_index + 1) * inv_resolution_1; if (flip) { @@ -918,7 +921,8 @@ static void subdiv_evaluate_edge_vertices_special( const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; if (BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, - coarse_loop->e)) { + coarse_loop->e)) + { continue; } vertex_interpolation_from_ptex(ctx, @@ -936,8 +940,8 @@ static void subdiv_evaluate_edge_vertices_special( veretx_delta = -1; } for (int vertex_index = 1; - vertex_index < num_vertices_per_ptex_edge; - vertex_index++, subdiv_vert += veretx_delta) + vertex_index < num_vertices_per_ptex_edge; + vertex_index++, subdiv_vert += veretx_delta) { float u = vertex_index * inv_ptex_resolution_1; subdiv_vertex_data_interpolate(ctx, @@ -953,8 +957,8 @@ static void subdiv_evaluate_edge_vertices_special( const int next_ptex_face_index = ptex_face_start_index + (corner + 1) % coarse_poly->totloop; for (int vertex_index = 1; - vertex_index < num_vertices_per_ptex_edge - 1; - vertex_index++, subdiv_vert += veretx_delta) + vertex_index < num_vertices_per_ptex_edge - 1; + vertex_index++, subdiv_vert += veretx_delta) { float v = 1.0f - vertex_index * inv_ptex_resolution_1; subdiv_vertex_data_interpolate(ctx, @@ -1416,7 +1420,8 @@ static void subdiv_create_edges_all_patches_special( subdiv_copy_edge_data(ctx, subdiv_edge, NULL); if (flip) { subdiv_edge->v1 = start_edge_vertex + (resolution - i - 3); - } else { + } + else { subdiv_edge->v1 = start_edge_vertex + i; } subdiv_edge->v2 = side_start_index + i; @@ -1433,7 +1438,8 @@ static void subdiv_create_edges_all_patches_special( subdiv_copy_edge_data(ctx, subdiv_edge, NULL); if (flip) { subdiv_edge->v1 = start_edge_vertex + (resolution - i - 3); - } else { + } + else { subdiv_edge->v1 = start_edge_vertex + i; } subdiv_edge->v2 = side_start_index + @@ -1762,7 +1768,8 @@ static void subdiv_create_loops_regular(SubdivMeshContext *ctx, e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - i - 1; - } else { + } + else { e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; @@ -2040,7 +2047,8 @@ static void subdiv_create_loops_special(SubdivMeshContext *ctx, e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + num_subdiv_edges_per_coarse_edge - i - 1; - } else { + } + else { e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 7339f1977ff..93577315b1c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1645,7 +1645,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - v3d->shading.background_type = (v3d->flag3 & V3D_SHOW_WORLD)? V3D_SHADING_BACKGROUND_WORLD: V3D_SHADING_BACKGROUND_THEME; + v3d->shading.background_type = ( + (v3d->flag3 & V3D_SHOW_WORLD) ? + V3D_SHADING_BACKGROUND_WORLD : V3D_SHADING_BACKGROUND_THEME); copy_v3_fl(v3d->shading.background_color, 0.05f); } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 513bfd32191..07d259dd047 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -4296,20 +4296,6 @@ eAutoPropButsReturn uiTemplateOperatorPropertyButs( PointerRNA ptr; struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = flag}; - - -#if 0 -static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop) -{ -} -#endif - - - - - - - RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); uiLayoutSetPropSep(layout, true); diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp index 3f2ce958332..8d8f4d12b04 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/gpu/intern/gpu_vertex_array_id.cpp +/** \file blender/gpu/intern/gpu_context.cpp * \ingroup gpu * * Manage GL vertex array IDs in a thread-safe way diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index dd4013efdf2..3083607b8a9 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -2169,7 +2169,7 @@ ViewLayer *WM_window_get_active_view_layer(const wmWindow *win) view_layer = BKE_view_layer_default_view(scene); if (view_layer) { - WM_window_set_active_view_layer((wmWindow*)win, view_layer); + WM_window_set_active_view_layer((wmWindow *)win, view_layer); } return view_layer; -- cgit v1.2.3 From 75f1fb6d86225c9b764f3909e83accc07685b009 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 11:32:38 +0200 Subject: Depsgraph: Fix crash on undo of new bone added Pose is not brought up to date for until exit of edit mode, so can not use. --- source/blender/blenkernel/intern/armature_update.c | 3 ++- source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 26fbd22c67e..03d370f6e7c 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -688,7 +688,8 @@ void BKE_pose_bone_done(struct Depsgraph *depsgraph, invert_m4_m4(imat, pchan->bone->arm_mat); mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat); } - if (DEG_is_active(depsgraph)) { + bArmature *arm = (bArmature *)ob->data; + if (DEG_is_active(depsgraph) && arm->edbo == NULL) { bPoseChannel *pchan_orig = pchan->orig_pchan; copy_m4_m4(pchan_orig->pose_mat, pchan->pose_mat); copy_m4_m4(pchan_orig->chan_mat, pchan->chan_mat); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index ee814e11d40..22c1167de2a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -548,9 +548,13 @@ void update_special_pointers(const Depsgraph *depsgraph, object_cow->runtime.mesh_orig = (Mesh *)object_cow->data; } if (object_cow->type == OB_ARMATURE) { - BKE_pose_remap_bone_pointers((bArmature *)object_cow->data, - object_cow->pose); - update_pose_orig_pointers(object_orig->pose, object_cow->pose); + const bArmature *armature_orig = (bArmature *)object_orig->data; + bArmature *armature_cow = (bArmature *)object_cow->data; + BKE_pose_remap_bone_pointers(armature_cow, object_cow->pose); + if (armature_orig->edbo == NULL) { + update_pose_orig_pointers(object_orig->pose, + object_cow->pose); + } } update_particle_system_orig_pointers(object_orig, object_cow); break; -- cgit v1.2.3 From 1fd27c2332a2d74d16cc8f339dd68fe1d06874a7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 11:38:10 +0200 Subject: Respect ID user count when creating pose on object copy This solves wrong user counter of custom shape when duplicating bone few times and then undoing all the duplications. --- source/blender/blenkernel/BKE_armature.h | 2 +- source/blender/blenkernel/intern/armature.c | 6 +++--- source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenkernel/intern/object.c | 10 ++++++---- source/blender/blenkernel/intern/scene.c | 2 +- .../blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc | 2 +- source/blender/editors/armature/armature_utils.c | 2 +- source/blender/editors/object/object_add.c | 2 +- source/blender/editors/object/object_relations.c | 2 +- source/blender/makesrna/intern/rna_object.c | 2 +- 10 files changed, 17 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 21d880cf2a7..9e100eb9111 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -100,7 +100,7 @@ void BKE_armature_where_is(struct bArmature *arm); void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion); void BKE_pose_clear_pointers(struct bPose *pose); void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose); -void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm); +void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, const bool do_id_user); void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 6be4574a62e..cea81a82f4b 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1960,7 +1960,7 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose) * * \param bmain May be NULL, only used to tag depsgraph as being dirty... */ -void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm) +void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user) { Bone *bone; bPose *pose; @@ -1989,7 +1989,7 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm) for (pchan = pose->chanbase.first; pchan; pchan = next) { next = pchan->next; if (pchan->bone == NULL) { - BKE_pose_channel_free(pchan); + BKE_pose_channel_free_ex(pchan, do_id_user); BKE_pose_channels_hash_free(pose); BLI_freelinkN(&pose->chanbase, pchan); } @@ -2291,7 +2291,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) return; if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) { /* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - hopefully this is OK. */ - BKE_pose_rebuild(NULL, ob, arm); + BKE_pose_rebuild(NULL, ob, arm, true); } ctime = BKE_scene_frame_get(scene); /* not accurate... */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 1d70d9db1e9..8922cd75618 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -2465,7 +2465,7 @@ void BKE_library_make_local( * Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL && ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(bmain, ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data, true); } } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index c88de006eba..9c7ce7698f7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1281,8 +1281,10 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con if (ob_src->pose) { copy_object_pose(ob_dst, ob_src, flag_subdata); /* backwards compat... non-armatures can get poses in older files? */ - if (ob_src->type == OB_ARMATURE) - BKE_pose_rebuild(bmain, ob_dst, ob_dst->data); + if (ob_src->type == OB_ARMATURE) { + const bool do_pose_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0; + BKE_pose_rebuild(bmain, ob_dst, ob_dst->data, do_pose_id_user); + } } defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase); BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps); @@ -1536,7 +1538,7 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob) if (target->type == OB_ARMATURE) { copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */ BKE_pose_rest(ob->pose); /* clear all transforms in channels */ - BKE_pose_rebuild(bmain, ob, ob->data); /* set all internal links */ + BKE_pose_rebuild(bmain, ob, ob->data, true); /* set all internal links */ armature_set_id_extern(ob); } @@ -2807,7 +2809,7 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph, * on file load */ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { /* No need to pass bmain here, we assume we do not need to rebuild DEG from here... */ - BKE_pose_rebuild(NULL, ob, ob->data); + BKE_pose_rebuild(NULL, ob, ob->data, true); } } } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7085b515ec1..ba25fc14ac9 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1336,7 +1336,7 @@ static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgrap for (ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) { if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild(bmain, ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data, true); } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 043148a0f70..88996dc1f56 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -162,7 +162,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object) /* Rebuild pose if not up to date. */ if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) { /* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */ - BKE_pose_rebuild(NULL, object, armature); + BKE_pose_rebuild(NULL, object, armature, true); /* XXX: Without this animation gets lost in certain circumstances * after loading file. Need to investigate further since it does * not happen with simple scenes.. diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index c93bfb5d8c3..2b28b76bcf6 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -681,7 +681,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm) /* so all users of this armature should get rebuilt */ for (obt = bmain->object.first; obt; obt = obt->id.next) { if (obt->data == arm) { - BKE_pose_rebuild(bmain, obt, arm); + BKE_pose_rebuild(bmain, obt, arm, true); } } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 87eddc2674c..d3181441168 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2332,7 +2332,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer ID_NEW_REMAP_US2(obn->data) else { obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data)); - BKE_pose_rebuild(bmain, obn, obn->data); + BKE_pose_rebuild(bmain, obn, obn->data, true); didit = 1; } id_us_min(id); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index a6751ee12a4..874b36ef42e 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1789,7 +1789,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer case OB_ARMATURE: DEG_id_tag_update(&ob->id, OB_RECALC_DATA); ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data)); - BKE_pose_rebuild(bmain, ob, ob->data); + BKE_pose_rebuild(bmain, ob, ob->data, true); break; case OB_SPEAKER: ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data)); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index d84827210bf..36c249228de 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -372,7 +372,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) BKE_curve_type_test(ob); } else if (ob->type == OB_ARMATURE) { - BKE_pose_rebuild(G_MAIN, ob, ob->data); + BKE_pose_rebuild(G_MAIN, ob, ob->data, true); } } } -- cgit v1.2.3 From d273f3ff7125ce5fe6366b7b55461951f7ce57e7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 31 Jul 2018 11:30:24 +0200 Subject: Cleanup: fix compiler warnings. --- source/blender/editors/gpencil/gpencil_edit.c | 15 +++++++-------- source/blender/editors/gpencil/gpencil_fill.c | 4 +--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 4a603e97615..93cf2f18233 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -2454,7 +2454,6 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, int id float pressure, float strength, float deltatime) { bGPDspoint *newpoint; - MDeformVert *dvert, *newdvert; gps->points = MEM_reallocN(gps->points, sizeof(bGPDspoint) * (gps->totpoints + 1)); if (gps->dvert != NULL) { @@ -2463,11 +2462,6 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, int id gps->totpoints++; newpoint = &gps->points[gps->totpoints - 1]; - if (gps->dvert != NULL) { - dvert = &gps->dvert[idx]; - newdvert = &gps->dvert[gps->totpoints - 1]; - } - newpoint->x = point->x * delta[0]; newpoint->y = point->y * delta[1]; newpoint->z = point->z * delta[2]; @@ -2476,8 +2470,13 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps, bGPDspoint *point, int id newpoint->strength = strength; newpoint->time = point->time + deltatime; - newdvert->totweight = dvert->totweight; - newdvert->dw = MEM_dupallocN(dvert->dw); + if (gps->dvert != NULL) { + MDeformVert *dvert = &gps->dvert[idx]; + MDeformVert *newdvert = &gps->dvert[gps->totpoints - 1]; + + newdvert->totweight = dvert->totweight; + newdvert->dw = MEM_dupallocN(dvert->dw); + } } /* Helper: join two strokes using the shortest distance (reorder stroke if necessary ) */ diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index b768ac2c44f..a0626dd69b1 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -911,9 +911,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) /* Helper: Draw status message while the user is running the operator */ static void gpencil_fill_status_indicators(bContext *C, tGPDfill *UNUSED(tgpf)) { - char status_str[UI_MAX_DRAW_STR]; - - BLI_snprintf(status_str, sizeof(status_str), IFACE_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back")); + const char *status_str = IFACE_("Fill: ESC/RMB cancel, LMB Fill, Shift Draw on Back"); ED_workspace_status_text(C, status_str); } -- cgit v1.2.3 From b2193e020bc0c1a9ef9969440ece453e49f8012c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 31 Jul 2018 11:45:15 +0200 Subject: Fix crash opening .blend files with palettes. Palettes were incorrectly set as having animation data. --- source/blender/blenkernel/intern/anim_sys.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 7dfedfe6c06..b02b6b6ce15 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -104,7 +104,6 @@ bool id_type_can_have_animdata(const short id_type) case ID_MSK: case ID_GD: case ID_CF: - case ID_PAL: return true; /* no AnimData */ -- cgit v1.2.3 From f06884b18ab5b619975689a0670f8f0f14f9c318 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 20:11:55 +1000 Subject: Cleanup: style, duplicate includes --- source/blender/blenkernel/BKE_gpencil_modifier.h | 2 +- source/blender/blenkernel/intern/gpencil.c | 6 +- .../blender/blenkernel/intern/gpencil_modifier.c | 6 +- source/blender/blenkernel/intern/object.c | 34 +++----- source/blender/blenkernel/intern/subdiv_mesh.c | 4 +- source/blender/blenloader/intern/versioning_280.c | 6 +- source/blender/depsgraph/DEG_depsgraph.h | 6 +- .../intern/builder/deg_builder_relations.cc | 18 ++-- .../draw/engines/gpencil/gpencil_cache_utils.c | 5 +- .../draw/engines/gpencil/gpencil_draw_cache_impl.c | 72 +++++++++------- .../draw/engines/gpencil/gpencil_draw_utils.c | 23 ++--- .../blender/draw/engines/gpencil/gpencil_engine.c | 98 ++++++++++++---------- .../blender/draw/engines/gpencil/gpencil_engine.h | 10 ++- .../blender/draw/engines/gpencil/gpencil_render.c | 19 +++-- .../draw/engines/gpencil/gpencil_shader_fx.c | 20 +++-- .../editors/animation/anim_channels_defines.c | 2 - source/blender/editors/animation/anim_filter.c | 2 +- source/blender/editors/gpencil/annotate_draw.c | 7 +- source/blender/editors/gpencil/drawgpencil.c | 2 +- source/blender/editors/gpencil/gpencil_brush.c | 9 +- source/blender/editors/gpencil/gpencil_data.c | 15 ++-- source/blender/editors/gpencil/gpencil_edit.c | 8 +- source/blender/editors/gpencil/gpencil_fill.c | 46 +++++----- source/blender/editors/gpencil/gpencil_intern.h | 14 ++-- source/blender/editors/gpencil/gpencil_ops.c | 12 +-- source/blender/editors/gpencil/gpencil_paint.c | 41 ++++----- source/blender/editors/gpencil/gpencil_primitive.c | 22 +++-- source/blender/editors/gpencil/gpencil_utils.c | 14 ++-- source/blender/editors/include/UI_interface.h | 2 +- .../editors/interface/interface_templates.c | 13 +-- source/blender/editors/object/object_add.c | 3 +- source/blender/editors/object/object_modes.c | 2 +- source/blender/editors/object/object_modifier.c | 19 +++-- .../blender/editors/space_buttons/space_buttons.c | 2 +- .../editors/space_view3d/view3d_gizmo_ruler.c | 1 - .../blender/editors/space_view3d/view3d_select.c | 17 ++-- source/blender/editors/transform/transform.c | 2 - .../editors/transform/transform_snap_object.c | 6 +- .../gpencil_modifiers/MOD_gpencil_modifiertypes.h | 10 +-- .../gpencil_modifiers/intern/MOD_gpencil_util.c | 2 +- .../gpencil_modifiers/intern/MOD_gpencil_util.h | 2 +- .../gpencil_modifiers/intern/MOD_gpencilbuild.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilhook.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilinstance.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencillattice.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilmirror.c | 10 +-- .../gpencil_modifiers/intern/MOD_gpencilnoise.c | 2 +- .../gpencil_modifiers/intern/MOD_gpenciloffset.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilopacity.c | 6 +- .../gpencil_modifiers/intern/MOD_gpencilsimplify.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilsmooth.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilsubdiv.c | 4 +- .../gpencil_modifiers/intern/MOD_gpencilthick.c | 4 +- .../gpencil_modifiers/intern/MOD_gpenciltint.c | 4 +- .../blender/makesdna/DNA_gpencil_modifier_types.h | 8 +- source/blender/makesdna/DNA_shader_fx_types.h | 8 +- source/blender/makesrna/intern/rna_gpencil.c | 5 +- .../blender/makesrna/intern/rna_gpencil_modifier.c | 1 - source/blender/makesrna/intern/rna_shader_fx.c | 1 - 60 files changed, 354 insertions(+), 335 deletions(-) diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h index cd6b6540012..be27560bbf2 100644 --- a/source/blender/blenkernel/BKE_gpencil_modifier.h +++ b/source/blender/blenkernel/BKE_gpencil_modifier.h @@ -22,7 +22,7 @@ #ifndef __BKE_GPENCIL_MODIFIER_H__ #define __BKE_GPENCIL_MODIFIER_H__ -/** \file BKE_greasepencil_modifier.h +/** \file BKE_gpencil_modifier.h * \ingroup bke */ diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index de3f891f9f9..c86f39f1d55 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -546,7 +546,7 @@ void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_d } BLI_assert(gps_src->totpoints == gps_dst->totpoints); - if ((gps_src->dvert == NULL) || (gps_dst->dvert == NULL)){ + if ((gps_src->dvert == NULL) || (gps_dst->dvert == NULL)) { return; } @@ -1050,7 +1050,7 @@ Material *BKE_gpencil_get_material_from_brush(Brush *brush) Material *ma = NULL; if ((brush != NULL) && (brush->gpencil_settings != NULL) && - (brush->gpencil_settings->material != NULL)) + (brush->gpencil_settings->material != NULL)) { ma = brush->gpencil_settings->material; } @@ -1076,7 +1076,7 @@ Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob) assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); } else if (ma->gp_style == NULL) { - BKE_material_init_gpencil_settings(ma); + BKE_material_init_gpencil_settings(ma); } return ma; diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index 2ba738902a0..3c2196afb18 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -384,8 +384,7 @@ void BKE_gpencil_stroke_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *g const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd); for (md = ob->greasepencil_modifiers.first; md; md = md->next) { - if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) - { + if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) { const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); if (GPENCIL_MODIFIER_EDIT(md, is_edit)) { @@ -407,8 +406,7 @@ void BKE_gpencil_geometry_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd); for (md = ob->greasepencil_modifiers.first; md; md = md->next) { - if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) - { + if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) { const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); if (GPENCIL_MODIFIER_EDIT(md, is_edit)) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9c7ce7698f7..41c23c46c44 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3821,24 +3821,18 @@ bool BKE_object_modifier_gpencil_use_time(Object *ob, GpencilModifierData *md) /* action - check for F-Curves with paths containing 'grease_pencil_modifiers[' */ if (adt->action) { - for (fcu = (FCurve *)adt->action->curves.first; - fcu != NULL; - fcu = (FCurve *)fcu->next) - { - if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + for (fcu = adt->action->curves.first; fcu != NULL; fcu = fcu->next) { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) { return true; + } } } - /* This here allows modifier properties to get driven and still update properly - * - */ - for (fcu = (FCurve *)adt->drivers.first; - fcu != NULL; - fcu = (FCurve *)fcu->next) - { - if (fcu->rna_path && strstr(fcu->rna_path, pattern)) + /* This here allows modifier properties to get driven and still update properly */ + for (fcu = adt->drivers.first; fcu != NULL; fcu = fcu->next) { + if (fcu->rna_path && strstr(fcu->rna_path, pattern)) { return true; + } } } @@ -3862,22 +3856,14 @@ bool BKE_object_shaderfx_use_time(Object *ob, ShaderFxData *fx) /* action - check for F-Curves with paths containing string[' */ if (adt->action) { - for (fcu = (FCurve *)adt->action->curves.first; - fcu != NULL; - fcu = (FCurve *)fcu->next) - { + for (fcu = adt->action->curves.first; fcu != NULL; fcu = fcu->next) { if (fcu->rna_path && strstr(fcu->rna_path, pattern)) return true; } } - /* This here allows properties to get driven and still update properly - * - */ - for (fcu = (FCurve *)adt->drivers.first; - fcu != NULL; - fcu = (FCurve *)fcu->next) - { + /* This here allows properties to get driven and still update properly */ + for (fcu = adt->drivers.first; fcu != NULL; fcu = fcu->next) { if (fcu->rna_path && strstr(fcu->rna_path, pattern)) return true; } diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 895d527ea5c..db7366a2414 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -277,7 +277,7 @@ static void subdiv_mesh_ctx_init_offsets(SubdivMeshContext *ctx) num_ptex_faces_per_poly * (num_inner_edges_per_ptex_face_get( no_quad_patch_resolution - 1) + - (no_quad_patch_resolution - 2) + + (no_quad_patch_resolution - 2) + num_subdiv_vertices_per_coarse_edge); if (no_quad_patch_resolution >= 3) { edge_offset += coarse_poly->totloop; @@ -2193,7 +2193,7 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) { const int resolution = ctx->settings->resolution; - const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; + const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; const MPoly *coarse_mpoly = coarse_mesh->mpoly; diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 93577315b1c..d2a1cc1f4f1 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -846,7 +846,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (ntree->type == NTREE_SHADER) { for (bNode *node = ntree->nodes.first; node; node = node->next) { if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && - STREQ(node->idname, "ShaderNodeOutputMetallic")) + STREQ(node->idname, "ShaderNodeOutputMetallic")) { BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname)); error |= NTREE_DOVERSION_NEED_OUTPUT; @@ -858,14 +858,14 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } else if (node->type == 196 /* SH_NODE_OUTPUT_EEVEE_MATERIAL */ && - STREQ(node->idname, "ShaderNodeOutputEeveeMaterial")) + STREQ(node->idname, "ShaderNodeOutputEeveeMaterial")) { node->type = SH_NODE_OUTPUT_MATERIAL; BLI_strncpy(node->idname, "ShaderNodeOutputMaterial", sizeof(node->idname)); } else if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ && - STREQ(node->idname, "ShaderNodeEeveeMetallic")) + STREQ(node->idname, "ShaderNodeEeveeMetallic")) { node->type = SH_NODE_BSDF_PRINCIPLED; BLI_strncpy(node->idname, "ShaderNodeBsdfPrincipled", sizeof(node->idname)); diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 2e566752a6f..7d827f48f9c 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -239,9 +239,9 @@ void DEG_make_inactive(struct Depsgraph *depsgraph); void DEG_debug_print_begin(struct Depsgraph *depsgraph); void DEG_debug_print_eval(struct Depsgraph *depsgraph, - const char* function_name, - const char* object_name, - const void* object_address); + const char *function_name, + const char *object_name, + const void *object_address); void DEG_debug_print_eval_subdata(struct Depsgraph *depsgraph, const char *function_name, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index c9a00b0bf0f..1d01b3e987b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2005,22 +2005,22 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata) TimeSourceKey time_key; ComponentKey geometry_key(obdata, DEG_NODE_TYPE_GEOMETRY); add_relation(time_key, - geometry_key, - "GP Frame Change"); + geometry_key, + "GP Frame Change"); /* Geometry cache also needs to be recalculated when Material - * settings change (e.g. when fill.opacity changes on/off, - * we need to rebuild the bGPDstroke->triangles caches) - */ + * settings change (e.g. when fill.opacity changes on/off, + * we need to rebuild the bGPDstroke->triangles caches) + */ for (int i = 0; i < gpd->totcol; i++) { Material *ma = gpd->mat[i]; if ((ma != NULL) && (ma->gp_style != NULL)) { OperationKey material_key(&ma->id, - DEG_NODE_TYPE_SHADING, - DEG_OPCODE_MATERIAL_UPDATE); + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_MATERIAL_UPDATE); add_relation(material_key, - geometry_key, - "Material -> GP Data"); + geometry_key, + "Material -> GP Data"); } } break; diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c index 4e01c42d33d..e8bb27b2724 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c @@ -38,8 +38,9 @@ #include "draw_cache_impl.h" /* add a gpencil object to cache to defer drawing */ -tGPencilObjectCache *gpencil_object_cache_add(tGPencilObjectCache *cache_array, Object *ob, bool is_temp, - int *gp_cache_size, int *gp_cache_used) +tGPencilObjectCache *gpencil_object_cache_add( + tGPencilObjectCache *cache_array, Object *ob, bool is_temp, + int *gp_cache_size, int *gp_cache_used) { const DRWContextState *draw_ctx = DRW_context_state_get(); tGPencilObjectCache *cache_elem = NULL; diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c index dd5db85f3f4..83a52e077ca 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c @@ -158,36 +158,42 @@ GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thi /* first point for adjacency (not drawn) */ if (i == 0) { if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[totpoints - 1], idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, &points[totpoints - 1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); idx++; } else { - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[1], idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, &points[1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); idx++; } } /* set point */ - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, pt, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); idx++; } if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { /* draw line to first point to complete the cycle */ - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[0], idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, &points[0], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); idx++; /* now add adjacency point (not drawn) */ - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[1], idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, &points[1], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); idx++; } /* last adjacency point (not drawn) */ else { - gpencil_set_stroke_point(vbo, gpf->runtime.viewmatrix, &points[totpoints - 2], idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, ink); + gpencil_set_stroke_point( + vbo, gpf->runtime.viewmatrix, &points[totpoints - 2], idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, ink); } return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO); @@ -237,30 +243,35 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], s if (i == 0) { if (totpoints > 1) { ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2); - gpencil_set_stroke_point(vbo, matrix, &pt2, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt2, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); } else { - gpencil_set_stroke_point(vbo, matrix, &pt, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); } idx++; } /* set point */ - gpencil_set_stroke_point(vbo, matrix, &pt, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); idx++; } /* last adjacency point (not drawn) */ if (totpoints > 2) { ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2); - gpencil_set_stroke_point(vbo, matrix, &pt2, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt2, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); } else { - gpencil_set_stroke_point(vbo, matrix, &pt, idx, - pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); } return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO); @@ -307,9 +318,10 @@ GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, float matrix[4][4], sh ED_gp_project_point_to_plane(ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt); /* set point */ - gpencil_set_stroke_point(vbo, matrix, &pt, idx, - pos_id, color_id, thickness_id, uvdata_id, - thickness, gpd->runtime.scolor); + gpencil_set_stroke_point( + vbo, matrix, &pt, idx, + pos_id, color_id, thickness_id, uvdata_id, + thickness, gpd->runtime.scolor); idx++; } @@ -600,9 +612,10 @@ GPUBatch *DRW_gpencil_get_edlin_geom(bGPDstroke *gps, float alpha, short UNUSED( return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); } -static void set_grid_point(GPUVertBuf *vbo, int idx, float col_grid[4], - uint pos_id, uint color_id, - float v1, float v2, int axis) +static void set_grid_point( + GPUVertBuf *vbo, int idx, float col_grid[4], + uint pos_id, uint color_id, + float v1, float v2, int axis) { GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid); @@ -618,8 +631,7 @@ static void set_grid_point(GPUVertBuf *vbo, int idx, float col_grid[4], pos[1] = v2; pos[2] = 0.0f; } - else - { + else { pos[0] = v1; pos[1] = 0.0f; pos[2] = v2; diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 76cb1405a71..04399d1cad7 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -63,8 +63,9 @@ #define PATTERN 5 /* Helper for doing all the checks on whether a stroke can be drawn */ -static bool gpencil_can_draw_stroke(struct MaterialGPencilStyle *gp_style, const bGPDstroke *gps, - const bool onion, const bool is_mat_preview) +static bool gpencil_can_draw_stroke( + struct MaterialGPencilStyle *gp_style, const bGPDstroke *gps, + const bool onion, const bool is_mat_preview) { /* skip stroke if it doesn't have any valid data */ if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) @@ -77,8 +78,8 @@ static bool gpencil_can_draw_stroke(struct MaterialGPencilStyle *gp_style, const /* check if the color is visible */ if ((gp_style == NULL) || - (gp_style->flag & GP_STYLE_COLOR_HIDE) || - (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) + (gp_style->flag & GP_STYLE_COLOR_HIDE) || + (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) { return false; } @@ -656,8 +657,8 @@ static void gpencil_add_editpoints_shgroup( } if (cache->batch_edlin[cache->cache_idx]) { if ((obact) && (obact == ob) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (v3d->flag3 & V3D_GP_SHOW_EDIT_LINES)) + ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_EDIT_LINES)) { DRW_shgroup_call_add( stl->g_data->shgrps_edit_line, @@ -947,7 +948,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T stl->storage->unit_matrix); if ((gpd->runtime.sbuffer_size >= 3) && (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) && - ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0)) + ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0)) { /* if not solid, fill is simulated with solid color */ if (gpd->runtime.bfill_style > 0) { @@ -1229,12 +1230,12 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene /* draw onion skins */ if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && - (!no_onion) && (overlay) && - (gpl->onion_flag & GP_LAYER_ONIONSKIN) && - ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + (!no_onion) && (overlay) && + (gpl->onion_flag & GP_LAYER_ONIONSKIN) && + ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { if ((!stl->storage->is_render) || - ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 71c99b2bcdf..d81cf8b7752 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -87,10 +87,11 @@ void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h txl->multisample_depth = GPU_texture_create_2D_multisample( rect_w, rect_h, GPU_DEPTH24_STENCIL8, NULL, samples, NULL); } - GPU_framebuffer_ensure_config(&fbl->multisample_fb, { - GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), - GPU_ATTACHMENT_TEXTURE(txl->multisample_color) - }); + GPU_framebuffer_ensure_config( + &fbl->multisample_fb, { + GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), + GPU_ATTACHMENT_TEXTURE(txl->multisample_color) + }); if (!GPU_framebuffer_check_valid(fbl->multisample_fb, NULL)) { GPU_framebuffer_free(fbl->multisample_fb); } @@ -121,39 +122,49 @@ static void GPENCIL_create_framebuffers(void *vedata) &draw_engine_gpencil_type); e_data.temp_color_tx_a = DRW_texture_pool_query_2D(size[0], size[1], fb_format, &draw_engine_gpencil_type); - GPU_framebuffer_ensure_config(&fbl->temp_fb_a, { - GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a), - GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a) - }); - - e_data.temp_depth_tx_b = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, - &draw_engine_gpencil_type); - e_data.temp_color_tx_b = DRW_texture_pool_query_2D(size[0], size[1], fb_format, - &draw_engine_gpencil_type); - GPU_framebuffer_ensure_config(&fbl->temp_fb_b, { - GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b), - GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b) - }); + GPU_framebuffer_ensure_config( + &fbl->temp_fb_a, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a) + }); + + e_data.temp_depth_tx_b = DRW_texture_pool_query_2D( + size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.temp_color_tx_b = DRW_texture_pool_query_2D( + size[0], size[1], fb_format, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config( + &fbl->temp_fb_b, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b) + }); /* used for rim FX effect */ - e_data.temp_depth_tx_rim = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, - &draw_engine_gpencil_type); - e_data.temp_color_tx_rim = DRW_texture_pool_query_2D(size[0], size[1], fb_format, - &draw_engine_gpencil_type); - GPU_framebuffer_ensure_config(&fbl->temp_fb_rim, { - GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_rim), - GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_rim), - }); + e_data.temp_depth_tx_rim = DRW_texture_pool_query_2D( + size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.temp_color_tx_rim = DRW_texture_pool_query_2D( + size[0], size[1], fb_format, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config( + &fbl->temp_fb_rim, { + GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_rim), + GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_rim), + }); /* background framebuffer to speed up drawing process (always 16 bits) */ - e_data.background_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, - &draw_engine_gpencil_type); - e_data.background_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, - &draw_engine_gpencil_type); - GPU_framebuffer_ensure_config(&fbl->background_fb, { - GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx), - GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx) - }); + e_data.background_depth_tx = DRW_texture_pool_query_2D( + size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + e_data.background_color_tx = DRW_texture_pool_query_2D( + size[0], size[1], GPU_RGBA32F, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config( + &fbl->background_fb, { + GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx), + GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx) + }); } } @@ -358,7 +369,7 @@ void GPENCIL_cache_init(void *vedata) (stl->storage->playing == 0)) { if (((obact_gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) && - (obact_gpd->runtime.sbuffer_size > 1)) + (obact_gpd->runtime.sbuffer_size > 1)) { stl->g_data->session_flag = GP_DRW_PAINT_PAINTING; } @@ -485,8 +496,9 @@ void GPENCIL_cache_populate(void *vedata, Object *ob) } /* allocate memory for saving gp objects for drawing later */ - stl->g_data->gp_object_cache = gpencil_object_cache_add(stl->g_data->gp_object_cache, ob, false, - &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used); + stl->g_data->gp_object_cache = gpencil_object_cache_add( + stl->g_data->gp_object_cache, ob, false, + &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used); /* generate instances as separate cache objects for instance modifiers * with the "Make as Objects" option enabled @@ -500,9 +512,9 @@ void GPENCIL_cache_populate(void *vedata, Object *ob) /* grid */ if ((v3d) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (v3d->flag3 & V3D_GP_SHOW_GRID) && - (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact)) + ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (v3d->flag3 & V3D_GP_SHOW_GRID) && + (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact)) { stl->g_data->batch_grid = DRW_gpencil_get_grid(); DRW_shgroup_call_add(stl->g_data->shgrps_grid, @@ -631,8 +643,8 @@ void GPENCIL_draw_scene(void *ved) /* paper pass to display a confortable area to draw over complex scenes with geometry */ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (v3d->flag3 & V3D_GP_SHOW_PAPER) && - (stl->g_data->gp_cache_used > 0)) + (v3d->flag3 & V3D_GP_SHOW_PAPER) && + (stl->g_data->gp_cache_used > 0)) { DRW_draw_pass(psl->paper_pass); } @@ -655,7 +667,7 @@ void GPENCIL_draw_scene(void *ved) /* grid pass */ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (v3d->flag3 & V3D_GP_SHOW_GRID)) + (v3d->flag3 & V3D_GP_SHOW_GRID)) { DRW_draw_pass(psl->grid_pass); } @@ -744,7 +756,7 @@ void GPENCIL_draw_scene(void *ved) /* grid pass */ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (v3d->flag3 & V3D_GP_SHOW_GRID)) + (v3d->flag3 & V3D_GP_SHOW_GRID)) { DRW_draw_pass(psl->grid_pass); } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 24a627f1012..5d276490663 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -279,8 +279,9 @@ typedef struct GpencilBatchCache { } GpencilBatchCache; /* general drawing functions */ -struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, struct DRWPass *pass, struct GPUShader *shader, - struct Object *ob, struct bGPdata *gpd, struct MaterialGPencilStyle *gp_style, int id, bool onion); +struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create( + struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, struct DRWPass *pass, struct GPUShader *shader, + struct Object *ob, struct bGPdata *gpd, struct MaterialGPencilStyle *gp_style, int id, bool onion); void DRW_gpencil_populate_datablock(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd); void DRW_gpencil_populate_buffer_strokes(struct GPENCIL_e_data *e_data, void *vedata, struct ToolSettings *ts, struct Object *ob); void DRW_gpencil_populate_multiedit(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd); @@ -300,8 +301,9 @@ struct GPUBatch *DRW_gpencil_get_buffer_point_geom(struct bGPdata *gpd, float ma struct GPUBatch *DRW_gpencil_get_grid(void); /* object cache functions */ -struct tGPencilObjectCache *gpencil_object_cache_add(struct tGPencilObjectCache *cache_array, struct Object *ob, - bool is_temp, int *gp_cache_size, int *gp_cache_used); +struct tGPencilObjectCache *gpencil_object_cache_add( + struct tGPencilObjectCache *cache_array, struct Object *ob, + bool is_temp, int *gp_cache_size, int *gp_cache_used); /* geometry batch cache functions */ void gpencil_batch_cache_check_free_slots(struct Object *ob); diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c index d76ea56894f..0b90de88ec1 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.c +++ b/source/blender/draw/engines/gpencil/gpencil_render.c @@ -84,14 +84,17 @@ void GPENCIL_render_init(GPENCIL_Data *ved, RenderEngine *engine, struct Depsgra DRW_gpencil_multisample_ensure(vedata, rect_w, rect_h); } - vedata->render_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8, - &draw_engine_gpencil_type); - vedata->render_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, - &draw_engine_gpencil_type); - GPU_framebuffer_ensure_config(&fbl->main, { - GPU_ATTACHMENT_TEXTURE(vedata->render_depth_tx), - GPU_ATTACHMENT_TEXTURE(vedata->render_color_tx) - }); + vedata->render_depth_tx = DRW_texture_pool_query_2D( + size[0], size[1], GPU_DEPTH24_STENCIL8, + &draw_engine_gpencil_type); + vedata->render_color_tx = DRW_texture_pool_query_2D( + size[0], size[1], GPU_RGBA32F, + &draw_engine_gpencil_type); + GPU_framebuffer_ensure_config( + &fbl->main, { + GPU_ATTACHMENT_TEXTURE(vedata->render_depth_tx), + GPU_ATTACHMENT_TEXTURE(vedata->render_color_tx) + }); /* Alloc transient data. */ if (!stl->g_data) { diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c index e453224020d..827f2e9344b 100644 --- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c @@ -211,8 +211,9 @@ static void DRW_gpencil_fx_blur( struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); - fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, - psl->fx_shader_pass_blend); + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_blur_sh, + psl->fx_shader_pass_blend); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); @@ -389,8 +390,9 @@ static void DRW_gpencil_fx_rim( struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get(); /* prepare pass */ - fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_prepare_sh, - psl->fx_shader_pass_blend); + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_rim_prepare_sh, + psl->fx_shader_pass_blend); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); @@ -408,8 +410,9 @@ static void DRW_gpencil_fx_rim( fxd->runtime.fx_sh = fx_shgrp; /* blur pass */ - fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, - psl->fx_shader_pass_blend); + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_blur_sh, + psl->fx_shader_pass_blend); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_rim); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_rim); @@ -423,8 +426,9 @@ static void DRW_gpencil_fx_rim( fxd->runtime.fx_sh_b = fx_shgrp; /* resolve pass */ - fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_resolve_sh, - psl->fx_shader_pass_blend); + fx_shgrp = DRW_shgroup_create( + e_data->gpencil_fx_rim_resolve_sh, + psl->fx_shader_pass_blend); DRW_shgroup_call_add(fx_shgrp, fxquad, NULL); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a); DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a); diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 2431bd50e1b..79b7c7988fd 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -84,8 +84,6 @@ #include "BIF_gl.h" -#include "DEG_depsgraph.h" - #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 1981814eb02..54590c5f66c 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -2615,7 +2615,7 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data /* grease pencil */ if ((ob->type == OB_GPENCIL) && - (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) + (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) { tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode); } diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c index dad5af7379c..4f6e2004197 100644 --- a/source/blender/editors/gpencil/annotate_draw.c +++ b/source/blender/editors/gpencil/annotate_draw.c @@ -787,9 +787,10 @@ static void gp_draw_data_layers( * It should also be noted that sbuffer contains temporary point types * i.e. tGPspoints NOT bGPDspoints */ - gp_draw_stroke_buffer(gpd->runtime.sbuffer, - gpd->runtime.sbuffer_size, lthick, - dflag, gpd->runtime.sbuffer_sflag, ink); + gp_draw_stroke_buffer( + gpd->runtime.sbuffer, + gpd->runtime.sbuffer_size, lthick, + dflag, gpd->runtime.sbuffer_sflag, ink); } } } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 5c56877cbe6..2c0b3e9900a 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -1047,7 +1047,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw) (gp_style->fill_rgba[3] > 0.0f) && ((gps->flag & GP_STROKE_NOFILL) == 0)) { - continue; + continue; } /* calculate thickness */ diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 52642fb2570..0fadef55b9d 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -755,10 +755,11 @@ static bool gp_brush_randomize_apply( const float inf = gp_brush_influence_calc(gso, radius, co) / 2.0f; const float fac = BLI_rng_get_float(gso->rng) * inf; /* need one flag enabled by default */ - if ((gso->settings->flag & (GP_BRUSHEDIT_FLAG_APPLY_POSITION | - GP_BRUSHEDIT_FLAG_APPLY_STRENGTH | - GP_BRUSHEDIT_FLAG_APPLY_THICKNESS | - GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0) + if ((gso->settings->flag & + (GP_BRUSHEDIT_FLAG_APPLY_POSITION | + GP_BRUSHEDIT_FLAG_APPLY_STRENGTH | + GP_BRUSHEDIT_FLAG_APPLY_THICKNESS | + GP_BRUSHEDIT_FLAG_APPLY_UV)) == 0) { gso->settings->flag |= GP_BRUSHEDIT_FLAG_APPLY_POSITION; } diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index dd1852ca8ce..c58c45b3117 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -67,7 +67,6 @@ #include "BKE_gpencil.h" #include "BKE_gpencil_modifier.h" #include "BKE_library.h" -#include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_material.h" @@ -462,8 +461,7 @@ void GPENCIL_OT_frame_duplicate(wmOperatorType *ot) { GP_FRAME_DUP_ACTIVE, "ACTIVE", 0, "Active", "Duplicate frame in active layer only" }, { GP_FRAME_DUP_ALL, "ALL", 0, "All", "Duplicate active frames in all layers" }, { 0, NULL, 0, NULL, NULL } - }; - + }; /* identifiers */ ot->name = "Duplicate Frame"; @@ -1401,8 +1399,8 @@ static bool gpencil_vertex_group_poll(bContext *C) if ((ob) && (ob->type == OB_GPENCIL)) { if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) { if (ELEM(ob->mode, - OB_MODE_GPENCIL_EDIT, - OB_MODE_GPENCIL_SCULPT)) + OB_MODE_GPENCIL_EDIT, + OB_MODE_GPENCIL_SCULPT)) { return true; } @@ -1418,8 +1416,7 @@ static bool gpencil_vertex_group_weight_poll(bContext *C) if ((ob) && (ob->type == OB_GPENCIL)) { if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) { - if (ob->mode == OB_MODE_GPENCIL_WEIGHT) - { + if (ob->mode == OB_MODE_GPENCIL_WEIGHT) { return true; } } @@ -1807,8 +1804,8 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) { if (base->object->type == OB_GPENCIL) { if ((base->object->rot[0] != 0) || - (base->object->rot[1] != 0) || - (base->object->rot[2] != 0)) + (base->object->rot[1] != 0) || + (base->object->rot[2] != 0)) { BKE_report(op->reports, RPT_ERROR, "Apply all rotations before join objects"); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 93cf2f18233..fdeadcc648a 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -62,7 +62,6 @@ #include "BKE_gpencil.h" #include "BKE_paint.h" #include "BKE_library.h" -#include "BKE_main.h" #include "BKE_material.h" #include "BKE_object.h" #include "BKE_report.h" @@ -861,8 +860,7 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op) for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) { if (ED_gpencil_stroke_can_use(C, gps)) { ma = give_current_material(ob, gps->mat_nr + 1); - if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, &gps->mat_nr) == false) - { + if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, &gps->mat_nr) == false) { BLI_ghash_insert(gp_strokes_copypastebuf_colors, &gps->mat_nr, ma); } } @@ -2153,7 +2151,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) } DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); - DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE); + DEG_id_tag_update(&obact->id, DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; } @@ -2757,7 +2755,7 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); - RegionView3D *rv3d = ar->regiondata; + RegionView3D *rv3d = ar->regiondata; View3D *v3d = sa->spacedata.first; GP_SpaceConversion gsc = {NULL}; diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index a0626dd69b1..20db5c1504f 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -125,8 +125,9 @@ typedef struct tGPDfill { /* draw a given stroke using same thickness and color for all points */ -static void gp_draw_basic_stroke(tGPDfill *tgpf, bGPDstroke *gps, const float diff_mat[4][4], - bool cyclic, float ink[4], int flag, float thershold) +static void gp_draw_basic_stroke( + tGPDfill *tgpf, bGPDstroke *gps, const float diff_mat[4][4], + bool cyclic, float ink[4], int flag, float thershold) { bGPDspoint *points = gps->points; @@ -228,8 +229,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) } /* check if the color is visible */ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); - if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE)) - { + if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE)) { continue; } @@ -247,7 +247,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) /* normal strokes */ if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { ED_gp_draw_fill(&tgpw); @@ -255,7 +255,7 @@ static void gp_draw_datablock(tGPDfill *tgpf, float ink[4]) /* 3D Lines with basic shapes and invisible lines */ if ((tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) + (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { gp_draw_basic_stroke(tgpf, gps, tgpw.diff_mat, gps->flag & GP_STROKE_CYCLIC, ink, tgpf->flag, tgpf->fill_threshold); @@ -313,8 +313,9 @@ static void gp_render_offscreen(tGPDfill *tgpf) glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ED_view3d_update_viewmat(tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, - NULL, winmat, NULL); + ED_view3d_update_viewmat( + tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, + NULL, winmat, NULL); /* set for opengl */ GPU_matrix_projection_set(tgpf->rv3d->winmat); GPU_matrix_set(tgpf->rv3d->viewmat); @@ -531,8 +532,7 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf) if (true) { /* Was: 'rgba' */ /* check if no border(red) or already filled color(green) */ - if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) - { + if ((rgba[0] != 1.0f) && (rgba[1] != 1.0f)) { /* fill current pixel */ set_pixel(ibuf, v, fill_col); @@ -627,7 +627,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf) int backtracked_co[2]; int current_check_co[2]; int prev_check_co[2]; - int backtracked_offset[1][2] = { { 0,0 } }; + int backtracked_offset[1][2] = {{0, 0}}; // bool boundary_found = false; bool start_found = false; const int NEIGHBOR_COUNT = 8; @@ -667,12 +667,11 @@ static void gpencil_get_outline_points(tGPDfill *tgpf) } } - while (true && start_found) - { + while (start_found) { int cur_back_offset = -1; for (int i = 0; i < NEIGHBOR_COUNT; i++) { if (backtracked_offset[0][0] == offset[i][0] && - backtracked_offset[0][1] == offset[i][1]) + backtracked_offset[0][1] == offset[i][1]) { /* Finding the bracktracked pixel offset index */ cur_back_offset = i; @@ -706,7 +705,7 @@ static void gpencil_get_outline_points(tGPDfill *tgpf) } /* current pixel is equal to starting pixel */ if (boundary_co[0] == start_co[0] && - boundary_co[1] == start_co[1]) + boundary_co[1] == start_co[1]) { BLI_stack_pop(tgpf->stack, &v); // boundary_found = true; @@ -753,8 +752,10 @@ static void gpencil_get_depth_array(tGPDfill *tgpf) for (i = 0, ptc = tgpf->sbuffer; i < totpoints; i++, ptc++) { copy_v2_v2_int(mval, &ptc->x); - if ((ED_view3d_autodist_depth(tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) && - (i && (ED_view3d_autodist_depth_seg(tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) + if ((ED_view3d_autodist_depth( + tgpf->ar, mval, depth_margin, tgpf->depth_arr + i) == 0) && + (i && (ED_view3d_autodist_depth_seg( + tgpf->ar, mval, mval_prev, depth_margin + 1, tgpf->depth_arr + i) == 0))) { interp_depth = true; } @@ -849,7 +850,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) gps->flag |= GP_STROKE_RECALC_CACHES; /* add stroke to frame */ - if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) || (tgpf->on_back == true)){ + if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) || (tgpf->on_back == true)) { BLI_addhead(&tgpf->gpf->strokes, gps); } else { @@ -862,10 +863,11 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) point2D = (tGPspoint *)tgpf->sbuffer; for (int i = 0; i < tgpf->sbuffer_size && point2D; i++, point2D++, pt++, dvert++) { /* convert screen-coordinates to 3D coordinates */ - gp_stroke_convertcoords_tpoint(tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob, - tgpf->gpl, point2D, - tgpf->depth_arr ? tgpf->depth_arr + i : NULL, - &pt->x); + gp_stroke_convertcoords_tpoint( + tgpf->scene, tgpf->ar, tgpf->v3d, tgpf->ob, + tgpf->gpl, point2D, + tgpf->depth_arr ? tgpf->depth_arr + i : NULL, + &pt->x); pt->pressure = 1.0f; pt->strength = 1.0f;; diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 0218530be4e..a51f9e7a065 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -216,10 +216,11 @@ void gp_apply_parent_point(struct Depsgraph *depsgraph, struct Object *obact, bG bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float screen_co[2], float r_out[3]); /* helper to convert 2d to 3d */ -void gp_stroke_convertcoords_tpoint(struct Scene *scene, struct ARegion *ar, - struct View3D *v3d, struct Object *ob, - bGPDlayer *gpl, const struct tGPspoint *point2D, - float *depth, float out[3]); +void gp_stroke_convertcoords_tpoint( + struct Scene *scene, struct ARegion *ar, + struct View3D *v3d, struct Object *ob, + bGPDlayer *gpl, const struct tGPspoint *point2D, + float *depth, float out[3]); /* Poll Callbacks ------------------------------------ */ /* gpencil_utils.c */ @@ -239,8 +240,9 @@ struct GHash *gp_copybuf_validate_colormap(struct bContext *C); /* Stroke Editing ------------------------------------ */ -void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, - int tag_flags, bool select); +void gp_stroke_delete_tagged_points( + bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, + int tag_flags, bool select); int gp_delete_selected_point_wrap(bContext *C); bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 991bfb622b7..e5ebfcecdf8 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -128,8 +128,8 @@ static bool gp_stroke_paintmode_draw_poll(bContext *C) bGPdata *gpd = CTX_data_gpencil_data(C); ToolSettings *ts = CTX_data_tool_settings(C); Brush *brush = BKE_brush_getactive_gpencil(ts); - return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) - && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) && + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)); } /* Poll callback for stroke painting (erase brush) */ @@ -139,8 +139,8 @@ static bool gp_stroke_paintmode_erase_poll(bContext *C) bGPdata *gpd = CTX_data_gpencil_data(C); ToolSettings *ts = CTX_data_tool_settings(C); Brush *brush = BKE_brush_getactive_gpencil(ts); - return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) - && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) && + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)); } /* Poll callback for stroke painting (fill) */ @@ -150,8 +150,8 @@ static bool gp_stroke_paintmode_fill_poll(bContext *C) bGPdata *gpd = CTX_data_gpencil_data(C); ToolSettings *ts = CTX_data_tool_settings(C); Brush *brush = BKE_brush_getactive_gpencil(ts); - return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) - && (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_FILL)); + return (gpd && (gpd->flag & GP_DATA_STROKE_PAINTMODE) && (brush) && + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_FILL)); } /* Poll callback for stroke sculpting mode */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index fd5b2803650..0c411db57b4 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -61,8 +61,6 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_gpencil.h" -#include "BKE_main.h" -#include "BKE_paint.h" #include "BKE_report.h" #include "BKE_layer.h" #include "BKE_material.h" @@ -624,7 +622,7 @@ static short gp_stroke_addpoint( } /* apply randomness to pressure */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_random_press > 0.0f)) + (brush->gpencil_settings->draw_random_press > 0.0f)) { float curvef = curvemapping_evaluateF(brush->gpencil_settings->curve_sensitivity, 0, pressure); float tmp_pressure = curvef * brush->gpencil_settings->draw_sensitivity; @@ -672,7 +670,7 @@ static short gp_stroke_addpoint( /* apply randomness to color strength */ if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_RANDOM) && - (brush->gpencil_settings->draw_random_strength > 0.0f)) + (brush->gpencil_settings->draw_random_strength > 0.0f)) { if (BLI_rng_get_float(p->rng) > 0.5f) { pt->strength -= pt->strength * brush->gpencil_settings->draw_random_strength * BLI_rng_get_float(p->rng); @@ -1381,13 +1379,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* 2) Tag any point with overly low influence for removal in the next pass */ if ((pt1->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || - (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) { pt1->flag |= GP_SPOINT_TAG; do_cull = true; } if ((pt2->pressure < cull_thresh) || (p->flags & GP_PAINTFLAG_HARD_ERASER) || - (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) + (eraser->gpencil_settings->eraser_mode == GP_BRUSH_ERASER_HARD)) { pt2->flag |= GP_SPOINT_TAG; do_cull = true; @@ -1500,14 +1498,14 @@ static Brush *gp_get_default_eraser(Main *bmain, ToolSettings *ts) Brush *brush_old = paint->brush; for (Brush *brush = bmain->brush.first; brush; brush = brush->id.next) { if ((brush->ob_mode == OB_MODE_GPENCIL_PAINT) && - (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { /* save first eraser to use later if no default */ if (brush_dft == NULL) { brush_dft = brush; } /* found default */ - if(brush->gpencil_settings->flag & GP_BRUSH_DEFAULT_ERASER) { + if (brush->gpencil_settings->flag & GP_BRUSH_DEFAULT_ERASER) { return brush; } } @@ -2201,7 +2199,7 @@ static void gpencil_draw_cursor_set(tGPsdata *p) { Brush *brush = p->brush; if ((p->paintmode == GP_PAINTMODE_ERASER) || - (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) + (brush->gpencil_settings->brush_type == GP_BRUSH_TYPE_ERASE)) { WM_cursor_modal_set(p->win, BC_CROSSCURSOR); /* XXX need a better cursor */ } @@ -2218,17 +2216,20 @@ static void gpencil_draw_status_indicators(bContext *C, tGPsdata *p) #if 0 /* FIXME, this never runs! */ switch (p->paintmode) { - case GP_PAINTMODE_DRAW_POLY: - /* Provide usage tips, since this is modal, and unintuitive without hints */ - ED_workspace_status_text(C, IFACE_("Annotation Create Poly: LMB click to place next stroke vertex | " - "ESC/Enter to end (or click outside this area)")); - break; - default: - /* Do nothing - the others are self explanatory, exit quickly once the mouse is released - * Showing any text would just be annoying as it would flicker. - */ - break; - } + case GP_PAINTMODE_DRAW_POLY: + /* Provide usage tips, since this is modal, and unintuitive without hints */ + ED_workspace_status_text( + C, IFACE_( + "Annotation Create Poly: LMB click to place next stroke vertex | " + "ESC/Enter to end (or click outside this area)" + )); + break; + default: + /* Do nothing - the others are self explanatory, exit quickly once the mouse is released + * Showing any text would just be annoying as it would flicker. + */ + break; + } #endif case GP_STATUS_IDLING: diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index ef09c5c3f76..9dbec666cc4 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -230,23 +230,27 @@ static void gpencil_primitive_status_indicators(bContext *C, tGPDprimitive *tgpi } else { if (tgpi->flag == IN_PROGRESS) { - BLI_snprintf(status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges, - tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + BLI_snprintf( + status_str, sizeof(status_str), "%s: %d (%d, %d) (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); } else { - BLI_snprintf(status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges, - tgpi->bottom[0], tgpi->bottom[1]); + BLI_snprintf( + status_str, sizeof(status_str), "%s: %d (%d, %d)", msg_str, (int)tgpi->tot_edges, + tgpi->bottom[0], tgpi->bottom[1]); } } } else { if (tgpi->flag == IN_PROGRESS) { - BLI_snprintf(status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str, - tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); + BLI_snprintf( + status_str, sizeof(status_str), "%s: (%d, %d) (%d, %d)", msg_str, + tgpi->top[0], tgpi->top[1], tgpi->bottom[0], tgpi->bottom[1]); } else { - BLI_snprintf(status_str, sizeof(status_str), "%s: (%d, %d)", msg_str, - tgpi->bottom[0], tgpi->bottom[1]); + BLI_snprintf( + status_str, sizeof(status_str), "%s: (%d, %d)", msg_str, + tgpi->bottom[0], tgpi->bottom[1]); } } ED_workspace_status_text(C, status_str); @@ -467,7 +471,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op) if (tgpi->type == GP_STROKE_CIRCLE) { RNA_int_set(op->ptr, "edges", 32); } - else if(tgpi->type == GP_STROKE_BOX) { + else if (tgpi->type == GP_STROKE_BOX) { RNA_int_set(op->ptr, "edges", 4); } else { /* LINE */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 7262c537321..cd352579b4a 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1426,9 +1426,9 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *customdata) * The decision was to use a fix size, instead of paintbrush->thickness value. */ if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) && - ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && - ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && - (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)) + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && + ((paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && + (paintbrush->gpencil_settings->brush_type == GP_BRUSH_TYPE_DRAW)) { radius = 2.0f; copy_v3_v3(color, gp_style->stroke_rgba); @@ -1491,7 +1491,7 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *customdata) /* Draw line for lazy mouse */ if ((last_mouse_position) && - (paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) + (paintbrush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); @@ -1501,8 +1501,10 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *customdata) immBegin(GPU_PRIM_LINES, 2); immVertex2f(pos, x, y); - immVertex2f(pos, last_mouse_position[0] + ar->winrct.xmin, - last_mouse_position[1] + ar->winrct.ymin); + immVertex2f( + pos, + last_mouse_position[0] + ar->winrct.xmin, + last_mouse_position[1] + ar->winrct.ymin); immEnd(); glDisable(GL_BLEND); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index fc3dd3f9968..d174a78ee23 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1023,7 +1023,7 @@ void uiTemplateHeader(uiLayout *layout, struct bContext *C); void uiTemplateID( uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, - int filter, const bool live_icon); + int filter, const bool live_icon); void uiTemplateIDBrowse( uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int filter); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 07d259dd047..e81ad1428d1 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -174,7 +174,7 @@ static uiBlock *template_common_search_menu( uiButSearchFunc search_func, void *search_arg, uiButHandleFunc handle_func, void *active_item, const int preview_rows, const int preview_cols, - float scale) + float scale) { static char search[256]; wmWindow *win = CTX_wm_window(C); @@ -644,7 +644,7 @@ static uiBut *template_id_def_new_but( static void template_ID( bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag, const char *newop, const char *openop, const char *unlinkop, - const bool live_icon) + const bool live_icon) { uiBut *but; uiBlock *block; @@ -875,7 +875,7 @@ static void ui_template_id( PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, int flag, int prv_rows, int prv_cols, int filter, bool use_tabs, - float scale, bool live_icon) + float scale, bool live_icon) { TemplateID *template_ui; PropertyRNA *prop; @@ -933,7 +933,7 @@ static void ui_template_id( void uiTemplateID( uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop, const char *openop, const char *unlinkop, - int filter, const bool live_icon) + int filter, const bool live_icon) { ui_template_id( layout, C, ptr, propname, @@ -1569,8 +1569,9 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr) /************************ Grease Pencil Modifier Template *************************/ -static uiLayout *gpencil_draw_modifier(uiLayout *layout, Object *ob, - GpencilModifierData *md) +static uiLayout *gpencil_draw_modifier( + uiLayout *layout, Object *ob, + GpencilModifierData *md) { const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); PointerRNA ptr; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index d3181441168..1ae441ee2f4 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1005,7 +1005,8 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) * for them to end up aligned oddly, but only for Monkey */ if ((RNA_struct_property_is_set(op->ptr, "view_align") == false) && - (type == GP_MONKEY)) { + (type == GP_MONKEY)) + { RNA_boolean_set(op->ptr, "view_align", true); } diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index 261f7f42bc0..b9bfb44f680 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -118,7 +118,7 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) break; case OB_GPENCIL: if (mode & (OB_MODE_EDIT | OB_MODE_GPENCIL_EDIT | OB_MODE_GPENCIL_PAINT | - OB_MODE_GPENCIL_SCULPT | OB_MODE_GPENCIL_WEIGHT)) + OB_MODE_GPENCIL_SCULPT | OB_MODE_GPENCIL_WEIGHT)) { return true; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index f83c6af08ee..43f651b0532 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -204,9 +204,10 @@ static bool object_has_modifier(const Object *ob, const ModifierData *exclude, * If the callback ever returns true, iteration will stop and the * function value will be true. Otherwise the function returns false. */ -bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, - bool (*callback)(Object *ob, void *callback_data), - void *callback_data) +bool ED_object_iter_other( + Main *bmain, Object *orig_ob, const bool include_orig, + bool (*callback)(Object *ob, void *callback_data), + void *callback_data) { ID *ob_data_id = orig_ob->data; int users = ob_data_id->us; @@ -220,10 +221,10 @@ bool ED_object_iter_other(Main *bmain, Object *orig_ob, const bool include_orig, int totfound = include_orig ? 0 : 1; for (ob = bmain->object.first; ob && totfound < users; - ob = ob->id.next) + ob = ob->id.next) { if (((ob != orig_ob) || include_orig) && - (ob->data == orig_ob->data)) + (ob->data == orig_ob->data)) { if (callback(ob, callback_data)) return true; @@ -318,7 +319,7 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md, } if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) && - BLI_listbase_is_empty(&ob->particlesystem)) + BLI_listbase_is_empty(&ob->particlesystem)) { ob->mode &= ~OB_MODE_PARTICLE_EDIT; } @@ -681,8 +682,8 @@ int ED_object_modifier_apply( return 0; } else if ((ob->mode & OB_MODE_SCULPT) && - (find_multires_modifier_before(scene, md)) && - (modifier_isSameTopology(md) == false)) + (find_multires_modifier_before(scene, md)) && + (modifier_isSameTopology(md) == false)) { BKE_report(reports, RPT_ERROR, "Constructive modifier cannot be applied to multi-res data in sculpt mode"); return 0; @@ -1525,7 +1526,7 @@ static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op)) BM_ITER_MESH (bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(bm_vert, BM_ELEM_SELECT) && - BLI_gset_add(visited, bm_vert)) + BLI_gset_add(visited, bm_vert)) { MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(bm_vert, cd_vert_skin_offset); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 62115aea11d..98ff2f67b58 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -527,7 +527,7 @@ static void buttons_area_listener( } break; case NC_GPENCIL: - switch(wmn->data) { + switch (wmn->data) { case ND_DATA: if (ELEM(wmn->action, NA_EDITED, NA_ADDED, NA_REMOVED)) ED_area_tag_redraw(sa); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index d5ef7cdf441..fb335d5f922 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -37,7 +37,6 @@ #include "BKE_object.h" #include "BKE_unit.h" #include "BKE_material.h" -#include "BKE_main.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index afff5eb7f66..2f65ad1fde4 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1683,22 +1683,23 @@ static bool ed_object_select_pick( The grease pencil modes are not real modes, but a hack to make the interface consistent, so need some tricks to keep UI synchronized */ // XXX: This stuff neeeds reviewing (Aligorith) -#if 0 - if (((oldbasact) && oldbasact->object->type == OB_GPENCIL) || (basact->object->type == OB_GPENCIL)) { + if (false && + (((oldbasact) && oldbasact->object->type == OB_GPENCIL) || + (basact->object->type == OB_GPENCIL))) + { /* set cursor */ - if (ELEM(basact->object->mode == OB_MODE_GPENCIL_PAINT, - OB_MODE_GPENCIL_SCULPT, - OB_MODE_GPENCIL_WEIGHT)) { + if (ELEM(basact->object->mode, + OB_MODE_GPENCIL_PAINT, + OB_MODE_GPENCIL_SCULPT, + OB_MODE_GPENCIL_WEIGHT)) + { ED_gpencil_toggle_brush_cursor(C, true, NULL); } else { /* TODO: maybe is better use restore */ ED_gpencil_toggle_brush_cursor(C, false, NULL); } - /* set workspace mode */ - BKE_workspace_object_mode_set(CTX_wm_workspace(C), scene, basact->object->mode); } -#endif } DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 9ad80f2ab12..b0de996ee0e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -103,8 +103,6 @@ #include "transform.h" -#include "DEG_depsgraph.h" - /* Disabling, since when you type you know what you are doing, and being able to set it to zero is handy. */ // #define USE_NUM_NO_ZERO diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index bc35e6e6b89..6dfcfe11af2 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -2282,9 +2282,9 @@ static short snapObject( break; case OB_GPENCIL: retval = snapEmpty( - snapdata, ob, obmat, - dist_px, - r_loc, r_no, r_index); + snapdata, ob, obmat, + dist_px, + r_loc, r_no, r_index); break; case OB_CAMERA: retval = snapCamera( diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h index ca941017ff9..73386601d10 100644 --- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h +++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h @@ -15,17 +15,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor(s): Ben Batt - * * ***** END GPL LICENSE BLOCK ***** */ -/** \file MOD_modifiertypes.h +/** \file MOD_gpencil_modifiertypes.h * \ingroup modifiers */ -#ifndef __MOD_GP_MODIFIERTYPES_H__ -#define __MOD_GP_MODIFIERTYPES_H__ +#ifndef __MOD_GPENCIL_MODIFIERTYPES_H__ +#define __MOD_GPENCIL_MODIFIERTYPES_H__ #include "BKE_gpencil_modifier.h" @@ -50,4 +48,4 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Offset; /* MOD_gpencil_util.c */ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]); -#endif /* __MOD_GP_MODIFIERTYPES_H__ */ +#endif /* __MOD_GPENCIL_MODIFIERTYPES_H__ */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 97d28863095..664f4b6976c 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/modifiers/intern/MOD_gpencil_util.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencil_util.c * \ingroup bke */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h index 50ac557042d..39a4947573e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/modifiers/intern/MOD_gpencil_util.h +/** \file blender/gpencil_modifiers/intern/MOD_gpencil_util.h * \ingroup modifiers */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index 6b959659a60..945afec002d 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilbuild.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilbuild.c * \ingroup modifiers */ @@ -519,7 +519,7 @@ static void generateStrokes( */ #if 0 static void bakeModifier( - Main *bmain, const Depsgraph *UNUSED(depsgraph), + Main *bmain, const Depsgraph *UNUSED(depsgraph), GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index af00b24715f..3cd298e9b87 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilcolor.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilcolor.c * \ingroup modifiers */ @@ -98,7 +98,7 @@ static void deformStroke( } static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { ColorGpencilModifierData *mmd = (ColorGpencilModifierData *)md; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index e036b6b78be..40e5e718bdc 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilhook.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilhook.c * \ingroup modifiers */ @@ -265,7 +265,7 @@ static void deformStroke( * (i.e. one where we don't have to worry about restoring state) */ static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { HookGpencilModifierData *mmd = (HookGpencilModifierData *)md; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c index 64f3fbc4a95..a35174d882f 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilinstance.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilinstance.c * \ingroup modifiers */ @@ -320,7 +320,7 @@ static void generateStrokes( /* Generic "bakeModifier" callback */ static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index 944e787020e..c4ff44af927 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencillattice.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencillattice.c * \ingroup modifiers */ @@ -111,7 +111,7 @@ static void deformStroke( * (i.e. one where we don't have to worry about restoring state) */ static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index 9b5186755d6..afecdd34a5c 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilmirror.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilmirror.c * \ingroup modifiers */ @@ -142,9 +142,9 @@ static void generateStrokes( tot_strokes = BLI_listbase_count(&gpf->strokes); for (i = 0, gps = gpf->strokes.first; i < tot_strokes; i++, gps = gps->next) { - if (is_stroke_affected_by_modifier(ob, - mmd->layername, mmd->pass_index, 1, gpl, gps, - mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) + if (is_stroke_affected_by_modifier( + ob, mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) { /* check each axis for mirroring */ for (int xi = 0; xi < 3; ++xi) { @@ -162,7 +162,7 @@ static void generateStrokes( } static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c index 37c8bf0b0f0..1edcaf84b81 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilnoise.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilnoise.c * \ingroup modifiers */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 8a96c705f08..50ff3f8766a 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpenciloffset.c +/** \file blender/gpencil_modifiers/intern/MOD_gpenciloffset.c * \ingroup modifiers */ @@ -105,7 +105,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index bdd651a69fc..361668f8725 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilopacity.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilopacity.c * \ingroup modifiers */ @@ -81,7 +81,7 @@ static void deformStroke( return; } - gp_style->fill_rgba[3]*= mmd->factor; + gp_style->fill_rgba[3] *= mmd->factor; /* if factor is > 1, then force opacity */ if (mmd->factor > 1.0f) { @@ -133,7 +133,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c index f0400e39b73..a8d10c973ce 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c @@ -23,7 +23,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilsimplify.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c * \ingroup modifiers */ @@ -85,7 +85,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index b83c8ed98b1..182bd974959 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilsmooth.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c * \ingroup modifiers */ @@ -114,7 +114,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c index 6fe9c34c06b..dba3e028904 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilsubdiv.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c * \ingroup modifiers */ @@ -155,7 +155,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c index 118cc33255f..fb63aa31364 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpencilthick.c +/** \file blender/gpencil_modifiers/intern/MOD_gpencilthick.c * \ingroup modifiers */ @@ -133,7 +133,7 @@ static void deformStroke( } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, + struct Main *UNUSED(bmain), Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { bGPdata *gpd = ob->data; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 9d1e9eccb8c..859e12adfb5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -24,7 +24,7 @@ * */ -/** \file blender/modifiers/intern/MOD_gpenciltint.c +/** \file blender/gpencil_modifiers/intern/MOD_gpenciltint.c * \ingroup modifiers */ @@ -106,7 +106,7 @@ static void deformStroke( } static void bakeModifier( - Main *bmain, Depsgraph *depsgraph, + Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { TintGpencilModifierData *mmd = (TintGpencilModifierData *)md; diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 150b4a2d9f1..1e3a4bf09f0 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -18,12 +18,12 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file DNA_greasepencil_modifier_types.h +/** \file DNA_gpencil_modifier_types.h * \ingroup DNA */ -#ifndef __DNA_GREASEPENCIL_TYPES_H__ -#define __DNA_GREASEPENCIL_TYPES_H__ +#ifndef __DNA_GPENCIL_MODIFIER_TYPES_H__ +#define __DNA_GPENCIL_MODIFIER_TYPES_H__ #include "DNA_defs.h" #include "DNA_listBase.h" @@ -401,4 +401,4 @@ typedef enum eSmoothGpencil_Flag { #define MOD_MESHSEQ_READ_ALL \ (MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR) -#endif /* __DNA_GREASEPENCIL_TYPES_H__ */ +#endif /* __DNA_GPENCIL_MODIFIER_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h index 15147cf2b6c..f3c9f06c8dc 100644 --- a/source/blender/makesdna/DNA_shader_fx_types.h +++ b/source/blender/makesdna/DNA_shader_fx_types.h @@ -22,8 +22,8 @@ * \ingroup DNA */ -#ifndef __DNA_SHADERFX_TYPES_H__ -#define __DNA_SHADERFX_TYPES_H__ +#ifndef __DNA_SHADER_FX_TYPES_H__ +#define __DNA_SHADER_FX_TYPES_H__ #include "DNA_defs.h" #include "DNA_listBase.h" @@ -130,7 +130,7 @@ typedef struct LightShaderFxData { int flag; /* flags */ float energy; float ambient; - float loc[4]; /* internal, not visible in rna */ + float loc[4]; /* internal, not visible in rna */ char pad[4]; ShaderFxData_runtime runtime; } LightShaderFxData; @@ -193,4 +193,4 @@ typedef struct WaveShaderFxData { char pad[4]; ShaderFxData_runtime runtime; } WaveShaderFxData; -#endif /* __DNA_SHADERFX_TYPES_H__ */ +#endif /* __DNA_SHADER_FX_TYPES_H__ */ diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index f84f31b02f1..4b69a395ab6 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -32,6 +32,7 @@ #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "DNA_object_types.h" #include "MEM_guardedalloc.h" @@ -47,9 +48,6 @@ #include "rna_internal.h" #include "WM_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "ED_gpencil.h" /* parent type */ static const EnumPropertyItem parent_type_items[] = { @@ -77,7 +75,6 @@ static EnumPropertyItem rna_enum_gpencil_onion_modes_items[] = { #ifdef RNA_RUNTIME -#include "BLI_math.h" #include "BLI_ghash.h" #include "WM_api.h" diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index df64121b2b4..8c4edf8030c 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -50,7 +50,6 @@ #include "BKE_mesh_remap.h" #include "BKE_multires.h" #include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */ -#include "BKE_gpencil_modifier.h" #include "RNA_access.h" #include "RNA_define.h" diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c index 950aef9a8dd..a005699dc32 100644 --- a/source/blender/makesrna/intern/rna_shader_fx.c +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -38,7 +38,6 @@ #include "BLT_translation.h" #include "BKE_animsys.h" -#include "BKE_shader_fx.h" #include "RNA_access.h" #include "RNA_define.h" -- cgit v1.2.3 From bf72d510d46a5547c739fb515fc9c68a8ad4b113 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 12:26:06 +0200 Subject: UI: Collapse Annotations panel by default --- release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 252f87d369f..7c3e7364ed1 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -699,6 +699,7 @@ class GPENCIL_UL_annotation_layer(UIList): class GreasePencilDataPanel: bl_label = "Annotations" bl_region_type = 'UI' + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -832,7 +833,6 @@ class GreasePencilToolsPanel: # For use in "2D" Editors without their own toolbar # subclass must set # bl_space_type = 'IMAGE_EDITOR' - # bl_options = {'DEFAULT_CLOSED'} bl_label = "Grease Pencil Settings" bl_region_type = 'UI' bl_options = {'DEFAULT_CLOSED'} -- cgit v1.2.3 From 20d525eb8bcc0652e9776c333b77df6ae9f842cd Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 12:37:58 +0200 Subject: Fix assert when load file with shading enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Credits for this fix goes to Clément Foucault. --- source/blender/draw/engines/gpencil/gpencil_engine.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index d81cf8b7752..0c76971ac4b 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -92,9 +92,6 @@ void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), GPU_ATTACHMENT_TEXTURE(txl->multisample_color) }); - if (!GPU_framebuffer_check_valid(fbl->multisample_fb, NULL)) { - GPU_framebuffer_free(fbl->multisample_fb); - } } } } -- cgit v1.2.3 From 0b85bb847c06b2115f135f82bce7bd762354acd4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 12:38:44 +0200 Subject: Cleanup: Remove overflow array element --- source/blender/shader_fx/intern/FX_shader_rim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/shader_fx/intern/FX_shader_rim.c b/source/blender/shader_fx/intern/FX_shader_rim.c index 611e6f91bf7..bea6f645033 100644 --- a/source/blender/shader_fx/intern/FX_shader_rim.c +++ b/source/blender/shader_fx/intern/FX_shader_rim.c @@ -40,8 +40,8 @@ static void initData(ShaderFxData *fx) { RimShaderFxData *gpfx = (RimShaderFxData *)fx; ARRAY_SET_ITEMS(gpfx->offset, 50, -100); - ARRAY_SET_ITEMS(gpfx->rim_rgb, 1.0f, 1.0f, 0.5f, 0.9f); - ARRAY_SET_ITEMS(gpfx->mask_rgb, 0.0f, 0.0f, 0.0f, 1.0f); + ARRAY_SET_ITEMS(gpfx->rim_rgb, 1.0f, 1.0f, 0.5f); + ARRAY_SET_ITEMS(gpfx->mask_rgb, 0.0f, 0.0f, 0.0f); gpfx->mode = eShaderFxRimMode_Multiply; ARRAY_SET_ITEMS(gpfx->blur, 0, 0); } -- cgit v1.2.3 From f945303877e65999fbae7a37ba5a223367259396 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 12:44:01 +0200 Subject: Cleanup: Fix weird comparisons --- source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c | 4 ++-- source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index 40e5e718bdc..46d452545e2 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -253,7 +253,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; /* verify vertex group */ - weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_HOOK_INVERT_VGROUP) == 0), vindex); + weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_HOOK_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index c4ff44af927..33bdb9c861d 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -98,7 +98,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; /* verify vertex group */ - weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_LATTICE_INVERT_VGROUP) == 0), vindex); + weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_LATTICE_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c index 1edcaf84b81..be361498578 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -154,7 +154,7 @@ static void deformStroke( } /* verify vertex group */ - weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_NOISE_INVERT_VGROUP) == 0), vindex); + weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_NOISE_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 50ff3f8766a..a31f889c48a 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -89,7 +89,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; /* verify vertex group */ - float weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_OFFSET_INVERT_VGROUP) == 0), vindex); + float weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_OFFSET_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 361668f8725..74b24acdfb6 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -101,7 +101,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; /* verify vertex group */ - float weight = get_modifier_point_weight(dvert, (!(mmd->flag & GP_OPACITY_INVERT_VGROUP) == 0), vindex); + float weight = get_modifier_point_weight(dvert, ((mmd->flag & GP_OPACITY_INVERT_VGROUP) != 0), vindex); if (weight < 0) { pt->strength += mmd->factor - 1.0f; } @@ -121,7 +121,7 @@ static void deformStroke( pt->strength *= mmd->factor; } else { - float weight = get_modifier_point_weight(dvert, (!(mmd->flag & GP_OPACITY_INVERT_VGROUP) == 0), vindex); + float weight = get_modifier_point_weight(dvert, ((mmd->flag & GP_OPACITY_INVERT_VGROUP) != 0), vindex); if (weight >= 0) { pt->strength *= mmd->factor * weight; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index 182bd974959..b5f2f0349af 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -86,7 +86,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; /* verify vertex group */ - weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_SMOOTH_INVERT_VGROUP) == 0), vindex); + weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_SMOOTH_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c index fb63aa31364..2c01fec1357 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -111,7 +111,7 @@ static void deformStroke( MDeformVert *dvert = &gps->dvert[i]; float curvef = 1.0f; /* verify vertex group */ - float weight = get_modifier_point_weight(dvert, (int)(!(mmd->flag & GP_THICK_INVERT_VGROUP) == 0), vindex); + float weight = get_modifier_point_weight(dvert, (int)((mmd->flag & GP_THICK_INVERT_VGROUP) != 0), vindex); if (weight < 0) { continue; } -- cgit v1.2.3 From 31fcd40efd3a98113cec837282c6dd2e1d34caa1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 20:44:49 +1000 Subject: Cleanup: use static variables --- source/blender/blenkernel/BKE_studiolight.h | 2 +- source/blender/blenkernel/intern/DerivedMesh.c | 1 + .../blender/blenkernel/intern/blender_user_menu.c | 1 + source/blender/draw/intern/draw_anim_viz.c | 4 ++- source/blender/draw/intern/draw_armature.c | 2 +- source/blender/draw/intern/draw_cache.c | 32 ++++++++++++---------- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/editors/gpencil/drawgpencil.c | 2 +- .../blender/editors/interface/interface_intern.h | 2 +- .../blender/editors/interface/interface_widgets.c | 2 +- source/blender/editors/mesh/editmesh_extrude.c | 10 +++---- source/blender/editors/space_node/drawnode.c | 2 +- .../editors/space_view3d/view3d_gizmo_navigate.c | 2 +- .../blender/editors/transform/transform_gizmo_3d.c | 2 +- source/blender/makesrna/intern/rna_context.c | 1 + source/blender/makesrna/intern/rna_rigidbody.c | 2 +- source/blender/makesrna/intern/rna_sculpt_paint.c | 4 +-- source/blender/makesrna/intern/rna_shader_fx.c | 4 +-- source/blender/makesrna/intern/rna_space.c | 2 +- .../windowmanager/gizmo/intern/wm_gizmo_group.c | 2 -- 20 files changed, 43 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h index fee01fa8abb..4a7f29d7190 100644 --- a/source/blender/blenkernel/BKE_studiolight.h +++ b/source/blender/blenkernel/BKE_studiolight.h @@ -99,7 +99,7 @@ enum StudioLightFlag { STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE = (1 << 10), STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 11), STUDIOLIGHT_UI_EXPANDED = (1 << 13), -} StudioLightFlag; +}; #define STUDIOLIGHT_FLAG_ALL (STUDIOLIGHT_INTERNAL | STUDIOLIGHT_EXTERNAL_FILE) #define STUDIOLIGHT_FLAG_ORIENTATIONS (STUDIOLIGHT_ORIENTATION_CAMERA | STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_VIEWNORMAL) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9c4aae7cda5..05253f7962a 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2098,6 +2098,7 @@ static void mesh_calc_modifiers( /* XXX: Is build_shapekey_layers ever even true? This should have crashed long ago... */ BLI_assert(!build_shapekey_layers); + UNUSED_VARS_NDEBUG(build_shapekey_layers); //if (build_shapekey_layers) // add_shapekey_layers(*r_deform_mesh, me, ob); diff --git a/source/blender/blenkernel/intern/blender_user_menu.c b/source/blender/blenkernel/intern/blender_user_menu.c index 3ec46e23cd1..2c18de70e6d 100644 --- a/source/blender/blenkernel/intern/blender_user_menu.c +++ b/source/blender/blenkernel/intern/blender_user_menu.c @@ -89,6 +89,7 @@ bUserMenuItem *BKE_blender_user_menu_item_add(ListBase *lb, int type) size = sizeof(bUserMenuItem_Prop); } else { + size = sizeof(bUserMenuItem); BLI_assert(0); } diff --git a/source/blender/draw/intern/draw_anim_viz.c b/source/blender/draw/intern/draw_anim_viz.c index f976c7b4d05..7ddcb306cea 100644 --- a/source/blender/draw/intern/draw_anim_viz.c +++ b/source/blender/draw/intern/draw_anim_viz.c @@ -90,10 +90,12 @@ typedef struct MPATH_Data { MPATH_StorageList *stl; } MPATH_Data; -struct { +#if 0 +static struct { GPUShader *mpath_line_sh; GPUShader *mpath_points_sh; } e_data = {0}; +#endif /* *************************** Path Cache *********************************** */ diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 8cd7431cfc0..a84b3fdeb41 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -460,7 +460,7 @@ static void drw_shgroup_bone_ik_spline_lines(const float start[3], const float e * \{ */ /* global here is reset before drawing each bone */ -struct { +static struct { const ThemeWireColor *bcolor; } g_color; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index ac84a847a1b..8ef5d600413 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -242,13 +242,15 @@ static GPUVertBuf *sphere_wire_vbo(const float rad) cv[0] = p[(i + j) % NSEGMENTS][0]; cv[1] = p[(i + j) % NSEGMENTS][1]; - if (axis == 0) - v[0] = cv[0], v[1] = cv[1], v[2] = 0.0f; - else if (axis == 1) - v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; - else - v[0] = 0.0f, v[1] = cv[0], v[2] = cv[1]; - + if (axis == 0) { + ARRAY_SET_ITEMS(v, cv[0], cv[1], 0.0f); + } + else if (axis == 1) { + ARRAY_SET_ITEMS(v, cv[0], 0.0f, cv[1]); + } + else { + ARRAY_SET_ITEMS(v, 0.0f, cv[0], cv[1]); + } GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + j + (NSEGMENTS * 2 * axis), v); } } @@ -825,17 +827,17 @@ GPUBatch *DRW_cache_empty_cone_get(void) cv[1] = p[(i) % NSEGMENTS][1]; /* cone sides */ - v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; + ARRAY_SET_ITEMS(v, cv[0], 0.0f, cv[1]); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); - v[0] = 0.0f, v[1] = 2.0f, v[2] = 0.0f; + ARRAY_SET_ITEMS(v, 0.0f, 2.0f, 0.0f); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); /* end ring */ - v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; + ARRAY_SET_ITEMS(v, cv[0], 0.0f, cv[1]); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); cv[0] = p[(i + 1) % NSEGMENTS][0]; cv[1] = p[(i + 1) % NSEGMENTS][1]; - v[0] = cv[0], v[1] = 0.0f, v[2] = cv[1]; + ARRAY_SET_ITEMS(v, cv[0], 0.0f, cv[1]); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); } @@ -1578,9 +1580,9 @@ GPUBatch *DRW_cache_lamp_spot_get(void) cv[1] = p[i % NSEGMENTS][1]; /* cone sides */ - v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; + ARRAY_SET_ITEMS(v, cv[0], cv[1], -1.0f); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4, v); - v[0] = 0.0f, v[1] = 0.0f, v[2] = 0.0f; + ARRAY_SET_ITEMS(v, 0.0f, 0.0f, 0.0f); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 1, v); GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4, n[(i) % NSEGMENTS]); @@ -1589,11 +1591,11 @@ GPUBatch *DRW_cache_lamp_spot_get(void) GPU_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 1, n[(i + 1) % NSEGMENTS]); /* end ring */ - v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; + ARRAY_SET_ITEMS(v, cv[0], cv[1], -1.0f); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 2, v); cv[0] = p[(i + 1) % NSEGMENTS][0]; cv[1] = p[(i + 1) % NSEGMENTS][1]; - v[0] = cv[0], v[1] = cv[1], v[2] = -1.0f; + ARRAY_SET_ITEMS(v, cv[0], cv[1], -1.0f); GPU_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v); GPU_vertbuf_attr_set(vbo, attr_id.n1, i * 4 + 2, n[(i) % NSEGMENTS]); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index e6e20934283..159f69d3226 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -95,7 +95,7 @@ /** Render State: No persistent data between draw calls. */ DRWManager DST = {NULL}; -ListBase DRW_engines = {NULL, NULL}; +static ListBase DRW_engines = {NULL, NULL}; extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */ diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 2c0b3e9900a..180fb65e743 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -574,7 +574,7 @@ static void gp_add_filldata_tobuffer( mul_v3_m4v3(fpt, diff_mat, &pt->x); /* if 2d, need conversion */ - if (!flag & GP_STROKE_3DSPACE) { + if (!(flag & GP_STROKE_3DSPACE)) { gp_calc_2d_stroke_fxy(fpt, flag, offsx, offsy, winx, winy, co); copy_v2_v2(fpt, co); fpt[2] = 0.0f; /* 2d always is z=0.0f */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index d4fccc48bfc..f7507223f31 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -780,7 +780,7 @@ void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *na #define UI_POPUP_MENU_TOP (int)(8 * UI_DPI_FAC) #define UI_PIXEL_AA_JITTER 8 -const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2]; +extern const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2]; /* interface_style.c */ void uiStyleInit(void); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 52e6e237a58..d0cdba49536 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1083,7 +1083,7 @@ static void widgetbase_set_uniform_colors_ubv( #define MAX_WIDGET_BASE_BATCH 6 #define MAX_WIDGET_PARAMETERS 11 -struct { +static struct { GPUBatch *batch; /* Batch type */ uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]; int count; diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 061cc3ebc32..c5ef2a06059 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -365,11 +365,11 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot) #ifdef USE_GIZMO -const float extrude_button_scale = 0.15f; -const float extrude_button_offset_scale = 1.5f; -const float extrude_arrow_scale = 1.0f; -const float extrude_arrow_xyz_axis_scale = 1.0f; -const float extrude_arrow_normal_axis_scale = 1.75f; +static const float extrude_button_scale = 0.15f; +static const float extrude_button_offset_scale = 1.5f; +static const float extrude_arrow_scale = 1.0f; +static const float extrude_arrow_xyz_axis_scale = 1.0f; +static const float extrude_arrow_normal_axis_scale = 1.75f; static const uchar shape_plus[] = { 0x5f, 0xfb, 0x40, 0xee, 0x25, 0xda, 0x11, 0xbf, 0x4, 0xa0, 0x0, 0x80, 0x4, 0x5f, 0x11, diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index f284fa015b8..a48a6faf69f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3422,7 +3422,7 @@ bool node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, flo static float arrow_verts[3][2] = {{-1.0f, 1.0f}, {0.0f, 0.0f}, {-1.0f, -1.0f}}; static float arrow_expand_axis[3][2] = {{0.7071f, 0.7071f}, {M_SQRT2, 0.0f}, {0.7071f, -0.7071f}}; -struct { +static struct { GPUBatch *batch; /* for batching line together */ GPUBatch *batch_single; /* for single line */ GPUVertBuf *inst_vbo; diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c index 388d9a29eff..5778f85a99c 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c @@ -131,7 +131,7 @@ struct NavigateGizmoInfo { #define SHAPE_VARS(shape_id) shape = shape_id, .shape_size = ARRAY_SIZE(shape_id) -struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = { +static struct NavigateGizmoInfo g_navigate_params[MPR_TOTAL] = { { .opname = "VIEW3D_OT_move", .gizmo = "GIZMO_GT_button_2d", diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 3b5d7d5871a..83dfa06f37d 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -107,7 +107,7 @@ #define MAN_SCALE_C (MAN_SCALE_X | MAN_SCALE_Y | MAN_SCALE_Z) /* threshold for testing view aligned gizmo axis */ -struct { +static struct { float min, max; } g_tw_axis_range[2] = { /* Regular range */ diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index 781be07f1dc..618cefe13e5 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -34,6 +34,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "rna_internal.h" /* own include */ diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 47075d0d4f7..899439e1a02 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -77,7 +77,7 @@ const EnumPropertyItem rna_enum_rigidbody_constraint_type_items[] = { {0, NULL, 0, NULL, NULL}}; /* bullet spring type */ -const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = { +static const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = { {RBC_SPRING_TYPE1, "SPRING1", ICON_NONE, "Blender 2.7", "Spring implementation used in blender 2.7. Damping is capped at 1.0"}, {RBC_SPRING_TYPE2, "SPRING2", ICON_NONE, "Blender 2.8", "New implementation available since 2.8"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 6a6c97b41ad..1f8f95cf380 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -76,12 +76,12 @@ const EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[] = { { 0, NULL, 0, NULL, NULL } }; -EnumPropertyItem rna_enum_gpencil_weight_brush_items[] = { +#ifndef RNA_RUNTIME +static EnumPropertyItem rna_enum_gpencil_weight_brush_items[] = { { GP_EDITBRUSH_TYPE_WEIGHT, "WEIGHT", ICON_GPBRUSH_WEIGHT, "Weight", "Weight Paint for Vertex Groups" }, { 0, NULL, 0, NULL, NULL } }; -#ifndef RNA_RUNTIME static const EnumPropertyItem rna_enum_gpencil_lockaxis_items[] = { { GP_LOCKAXIS_NONE, "GP_LOCKAXIS_NONE", ICON_UNLOCKED, "None", "" }, { GP_LOCKAXIS_X, "GP_LOCKAXIS_X", ICON_NDOF_DOM, "X", "Project strokes to plane locked to X" }, diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c index a005699dc32..da4470ccff7 100644 --- a/source/blender/makesrna/intern/rna_shader_fx.c +++ b/source/blender/makesrna/intern/rna_shader_fx.c @@ -60,7 +60,7 @@ const EnumPropertyItem rna_enum_object_shaderfx_type_items[] = { {0, NULL, 0, NULL, NULL} }; -const EnumPropertyItem rna_enum_shaderfx_rim_modes_items[] = { +static const EnumPropertyItem rna_enum_shaderfx_rim_modes_items[] = { {eShaderFxRimMode_Normal, "NORMAL", 0, "Normal", "" }, {eShaderFxRimMode_Overlay, "OVERLAY", 0, "Overlay", "" }, {eShaderFxRimMode_Add, "ADD", 0, "Add", "" }, @@ -70,7 +70,7 @@ const EnumPropertyItem rna_enum_shaderfx_rim_modes_items[] = { {0, NULL, 0, NULL, NULL } }; -const EnumPropertyItem rna_enum_shaderfx_colorize_modes_items[] = { +static const EnumPropertyItem rna_enum_shaderfx_colorize_modes_items[] = { {eShaderFxColorizeMode_GrayScale, "GRAYSCALE", 0, "Gray Scale", "" }, {eShaderFxColorizeMode_Sepia, "SEPIA", 0, "Sepia", "" }, {eShaderFxColorizeMode_BiTone, "BITONE", 0, "Bi-Tone", "" }, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 56491fd70e4..ab662e71380 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -244,7 +244,7 @@ const EnumPropertyItem rna_enum_shading_type_items[] = { {0, NULL, 0, NULL, NULL} }; -const EnumPropertyItem rna_enum_viewport_lighting_items[] = { +static const EnumPropertyItem rna_enum_viewport_lighting_items[] = { {V3D_LIGHTING_FLAT, "FLAT", 0, "Flat", "Display using flat lighting"}, {V3D_LIGHTING_STUDIO, "STUDIO", 0, "Studio", "Display using studio lighting"}, {V3D_LIGHTING_MATCAP, "MATCAP", 0, "MatCap", "Display using matcap material and lighting"}, diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 9cc096e1cdd..204662b5713 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -296,8 +296,6 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE BLI_assert(0); return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } - - return OPERATOR_PASS_THROUGH; } void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot) -- cgit v1.2.3 From d58dd3de3d7bf26f501af328a855214ced6b04d5 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 12:46:50 +0200 Subject: UI: Annotations panel tweak "New Note" and "New" datablock do the same, only show one. Minor code comments cleanup. --- .../bl_ui/properties_grease_pencil_common.py | 32 +++++++--------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 7c3e7364ed1..65e7abe24a4 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -321,8 +321,6 @@ class GreasePencilAppearancePanel: col.row().prop(brush, "cursor_color_sub", text="Subtract") -############################### - class GPENCIL_MT_pie_tool_palette(Menu): """A pie menu for quick access to Grease Pencil tools""" bl_label = "Grease Pencil Tools" @@ -508,7 +506,7 @@ class GPENCIL_MT_pie_tools_more(Menu): class GPENCIL_MT_pie_sculpt(Menu): - """A pie menu for accessing Grease Pencil stroke sculpting settings""" + """A pie menu for accessing Grease Pencil stroke sculpt settings""" bl_label = "Grease Pencil Sculpt" @classmethod @@ -557,9 +555,6 @@ class GPENCIL_MT_pie_sculpt(Menu): row.prop_enum(settings, "tool", value='RANDOMIZE') -############################### - - class GPENCIL_MT_snap(Menu): bl_label = "Snap" @@ -657,7 +652,7 @@ class GPENCIL_MT_gpencil_draw_specials(Menu): layout.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX' layout.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE' - # colors + # Colors. layout.separator() layout.operator("gpencil.colorpick", text="Colors", icon="GROUP_VCOL") @@ -720,23 +715,20 @@ class GreasePencilDataPanel: @staticmethod def draw(self, context): layout = self.layout - #layout.use_property_split = True layout.use_property_decorate = False - # owner of Grease Pencil data + # Grease Pencil owner. gpd_owner = context.gpencil_data_owner gpd = context.gpencil_data - # Owner Selector + # Owner selector. if context.space_data.type == 'CLIP_EDITOR': layout.row().prop(context.space_data, "grease_pencil_source", expand=True) - # Grease Pencil data selector + layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink") - # Grease Pencil data... - if (gpd is None) or (not gpd.layers): - layout.operator("gpencil.layer_add", text="New Note") - else: + # List of layers/notes. + if gpd or gpd.layers: self.draw_layers(context, layout, gpd) def draw_layers(self, context, layout, gpd): @@ -783,7 +775,6 @@ class GreasePencilDataPanel: row.operator("gpencil.active_frame_delete", text="", icon='X') - class GreasePencilOnionPanel: @staticmethod def draw_settings(layout, gp): @@ -794,7 +785,7 @@ class GreasePencilOnionPanel: row = col.row() row.prop(gp, "onion_factor", text="Opacity", slider=True) - # - Before Frames + # Frames before. sub = layout.column(align=True) row = sub.row(align=True) row.active = gp.use_ghost_custom_colors @@ -804,7 +795,7 @@ class GreasePencilOnionPanel: row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE') row.prop(gp, "ghost_before_range", text="Frames Before") - # - After Frames + # Frames after. sub = layout.column(align=True) row = sub.row(align=True) row.active = gp.use_ghost_custom_colors @@ -817,7 +808,7 @@ class GreasePencilOnionPanel: layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Color") layout.prop(gp, "use_ghosts_always", text="View In Render") - # - fade and loop + # Fade and loop. row = layout.row() row.active = gp.use_onion_skinning row.prop(gp, "use_onion_fade", text="Fade") @@ -827,8 +818,6 @@ class GreasePencilOnionPanel: subrow.prop(gp, "use_onion_loop", text="Loop") -############################### - class GreasePencilToolsPanel: # For use in "2D" Editors without their own toolbar # subclass must set @@ -869,7 +858,6 @@ class GreasePencilToolsPanel: gpencil_stroke_placement_settings(context, layout) -############################### classes = ( GPENCIL_MT_pie_tool_palette, -- cgit v1.2.3 From a3085190f80d6b61f1871040665ec926f52569d5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 20:52:36 +1000 Subject: Fix building w/ FreeBSD fileno could be a macro which can't take a void pointer. --- intern/clog/clog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/clog/clog.c b/intern/clog/clog.c index 2e5201d63b0..9a80d99fe73 100644 --- a/intern/clog/clog.c +++ b/intern/clog/clog.c @@ -470,7 +470,7 @@ void CLG_logf( static void CLG_ctx_output_set(CLogContext *ctx, void *file_handle) { ctx->output_file = file_handle; - ctx->output = fileno(file_handle); + ctx->output = fileno(ctx->output_file); #if defined(__unix__) || defined(__APPLE__) ctx->use_color = isatty(ctx->output); #endif -- cgit v1.2.3 From 8dcddbc09129140e47855b4a1fe85b3684636586 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 13:08:30 +0200 Subject: UI: Annotations tool color setting in toolbar --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index b682588629b..1bb5a93f7f8 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -200,9 +200,10 @@ class _defs_annotate: if gpd and gpl: layout.prop(gpd.layers, "active_note", text="") - layout.prop(gpl, "thickness", text="Thickness") + layout.prop(gpl, "color", text="") + layout.prop(gpl, "thickness") else: - layout.prop(user_prefs.edit, "grease_pencil_default_color", text="Color") + layout.prop(user_prefs.edit, "grease_pencil_default_color", text="") layout.prop(ts, "annotation_thickness", text="Thickness") # For 3D view, show the stroke placement settings -- cgit v1.2.3 From 7a91ae110397c29a5bb63ed0489d67acdc11ecb4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 13:21:04 +0200 Subject: Fix memory leak in DRW_cache_gpencil_axes_get The Batch was created using old function without GPU_BATCH_OWNS_VBO and the batch was not removed from memory --- source/blender/draw/intern/draw_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 8ef5d600413..c3fa9f5c1aa 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -605,7 +605,7 @@ GPUBatch *DRW_cache_gpencil_axes_get(void) GPU_vertbuf_attr_set(vbo, pos_id, i + 6, verts[indices[i]]); } - SHC.drw_gpencil_axes = GPU_batch_create(GPU_PRIM_LINES, vbo, NULL); + SHC.drw_gpencil_axes = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); } return SHC.drw_gpencil_axes; } -- cgit v1.2.3 From bb7b1cc884819d2a681f1c93b6bb9c015248aff0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 13:23:01 +0200 Subject: Fix T56170: Fake dependency cycle in new depsgraph + interleaved armature update + proxy Make proxy copy result more atomic operation. --- source/blender/blenkernel/BKE_action.h | 1 + source/blender/blenkernel/BKE_armature.h | 11 +++- source/blender/blenkernel/intern/action.c | 61 ++++++++++---------- source/blender/blenkernel/intern/armature_update.c | 65 +++++++++++++++++----- .../intern/builder/deg_builder_nodes_rig.cc | 17 ++++-- .../intern/builder/deg_builder_relations.cc | 4 -- .../intern/builder/deg_builder_relations_rig.cc | 9 +++ 7 files changed, 117 insertions(+), 51 deletions(-) diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 106866aff0a..263a54eab4e 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -201,6 +201,7 @@ void BKE_pose_remove_group_index(struct bPose *pose, const int index); void what_does_obaction(struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe); /* for proxy */ +void BKE_pose_copyesult_pchan_result(struct bPoseChannel *pchanto, const struct bPoseChannel *pchanfrom); bool BKE_pose_copy_result(struct bPose *to, struct bPose *from); /* clear all transforms */ void BKE_pose_rest(struct bPose *pose); diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 9e100eb9111..17329beb325 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -231,9 +231,16 @@ void BKE_pose_eval_flush( struct Scene *scene, struct Object *ob); -void BKE_pose_eval_proxy_copy( +void BKE_pose_eval_proxy_pose_init(struct Depsgraph *depsgraph, + struct Object *object); + +void BKE_pose_eval_proxy_pose_done(struct Depsgraph *depsgraph, + struct Object *object); + +void BKE_pose_eval_proxy_copy_bone( struct Depsgraph *depsgraph, - struct Object *ob); + struct Object *object, + int pchan_index); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index cbdabe2c440..6f97187f1e3 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1328,6 +1328,37 @@ void BKE_pose_rest(bPose *pose) } } +void BKE_pose_copyesult_pchan_result(bPoseChannel *pchanto, const bPoseChannel *pchanfrom) +{ + copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat); + copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat); + + /* used for local constraints */ + copy_v3_v3(pchanto->loc, pchanfrom->loc); + copy_qt_qt(pchanto->quat, pchanfrom->quat); + copy_v3_v3(pchanto->eul, pchanfrom->eul); + copy_v3_v3(pchanto->size, pchanfrom->size); + + copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head); + copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail); + + pchanto->roll1 = pchanfrom->roll1; + pchanto->roll2 = pchanfrom->roll2; + pchanto->curveInX = pchanfrom->curveInX; + pchanto->curveInY = pchanfrom->curveInY; + pchanto->curveOutX = pchanfrom->curveOutX; + pchanto->curveOutY = pchanfrom->curveOutY; + pchanto->ease1 = pchanfrom->ease1; + pchanto->ease2 = pchanfrom->ease2; + pchanto->scaleIn = pchanfrom->scaleIn; + pchanto->scaleOut = pchanfrom->scaleOut; + + pchanto->rotmode = pchanfrom->rotmode; + pchanto->flag = pchanfrom->flag; + pchanto->protectflag = pchanfrom->protectflag; + pchanto->bboneflag = pchanfrom->bboneflag; +} + /* both poses should be in sync */ bool BKE_pose_copy_result(bPose *to, bPose *from) { @@ -1346,34 +1377,8 @@ bool BKE_pose_copy_result(bPose *to, bPose *from) for (pchanfrom = from->chanbase.first; pchanfrom; pchanfrom = pchanfrom->next) { pchanto = BKE_pose_channel_find_name(to, pchanfrom->name); - if (pchanto) { - copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat); - copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat); - - /* used for local constraints */ - copy_v3_v3(pchanto->loc, pchanfrom->loc); - copy_qt_qt(pchanto->quat, pchanfrom->quat); - copy_v3_v3(pchanto->eul, pchanfrom->eul); - copy_v3_v3(pchanto->size, pchanfrom->size); - - copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head); - copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail); - - pchanto->roll1 = pchanfrom->roll1; - pchanto->roll2 = pchanfrom->roll2; - pchanto->curveInX = pchanfrom->curveInX; - pchanto->curveInY = pchanfrom->curveInY; - pchanto->curveOutX = pchanfrom->curveOutX; - pchanto->curveOutY = pchanfrom->curveOutY; - pchanto->ease1 = pchanfrom->ease1; - pchanto->ease2 = pchanfrom->ease2; - pchanto->scaleIn = pchanfrom->scaleIn; - pchanto->scaleOut = pchanfrom->scaleOut; - - pchanto->rotmode = pchanfrom->rotmode; - pchanto->flag = pchanfrom->flag; - pchanto->protectflag = pchanfrom->protectflag; - pchanto->bboneflag = pchanfrom->bboneflag; + if (pchanto != NULL) { + BKE_pose_copyesult_pchan_result(pchanto, pchanfrom); } } return true; diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 03d370f6e7c..d53c61255fe 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -558,6 +558,17 @@ void BKE_splineik_execute_tree( /* *************** Depsgraph evaluation callbacks ************ */ +static void pose_pchan_index_create(bPose *pose) +{ + const int num_channels = BLI_listbase_count(&pose->chanbase); + pose->chan_array = MEM_malloc_arrayN( + num_channels, sizeof(bPoseChannel *), "pose->chan_array"); + int pchan_index = 0; + for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) { + pose->chan_array[pchan_index++] = pchan; + } +} + BLI_INLINE bPoseChannel *pose_pchan_get_indexed(Object *ob, int pchan_index) { bPose *pose = ob->pose; @@ -585,16 +596,12 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, /* imat is needed for solvers. */ invert_m4_m4(ob->imat, ob->obmat); - const int num_channels = BLI_listbase_count(&pose->chanbase); - pose->chan_array = MEM_malloc_arrayN( - num_channels, sizeof(bPoseChannel *), "pose->chan_array"); - /* clear flags */ - int pchan_index = 0; for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) { pchan->flag &= ~(POSE_DONE | POSE_CHAIN | POSE_IKTREE | POSE_IKSPLINE); - pose->chan_array[pchan_index++] = pchan; } + + pose_pchan_index_create(pose); } void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, @@ -752,12 +759,44 @@ void BKE_pose_eval_flush(struct Depsgraph *depsgraph, pose->chan_array = NULL; } -void BKE_pose_eval_proxy_copy(struct Depsgraph *depsgraph, Object *ob) +void BKE_pose_eval_proxy_pose_init(struct Depsgraph *depsgraph, Object *object) { - BLI_assert(ID_IS_LINKED(ob) && ob->proxy_from != NULL); - DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); - if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) { - printf("Proxy copy error, lib Object: %s proxy Object: %s\n", - ob->id.name + 2, ob->proxy_from->id.name + 2); - } + BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL); + DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); + + pose_pchan_index_create(object->pose); +} + +void BKE_pose_eval_proxy_pose_done(struct Depsgraph *depsgraph, Object *object) +{ + BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL); + DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); + + bPose *pose = object->pose; + BLI_assert(pose->chan_array != NULL); + MEM_freeN(pose->chan_array); + pose->chan_array = NULL; +} + +void BKE_pose_eval_proxy_copy_bone( + struct Depsgraph *depsgraph, + Object *object, + int pchan_index) +{ + BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL); + DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); + bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index); + /* TODO(sergey): Use indexec lookup, once it's guaranteed to be kept + * around for the time while proxies are evaluating. + */ +#if 0 + bPoseChannel *pchan_from = pose_pchan_get_indexed( + object->proxy_from, pchan_index); +#else + bPoseChannel *pchan_from = BKE_pose_channel_find_name( + object->proxy_from->pose, pchan->name); +#endif + BLI_assert(pchan != NULL); + BLI_assert(pchan_from != NULL); + BKE_pose_copyesult_pchan_result(pchan, pchan_from); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 88996dc1f56..b1486e82af5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -314,12 +314,13 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object) } op_node = add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, - function_bind(BKE_pose_eval_proxy_copy, + function_bind(BKE_pose_eval_proxy_pose_init, _1, object_cow), DEG_OPCODE_POSE_INIT); op_node->set_as_entry(); + int pchan_index = 0; LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) { op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, @@ -334,10 +335,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object) NULL, DEG_OPCODE_BONE_READY); /* Bone is fully evaluated. */ - op_node = add_operation_node(&object->id, + op_node = add_operation_node( + &object->id, DEG_NODE_TYPE_BONE, pchan->name, - NULL, + function_bind(BKE_pose_eval_proxy_copy_bone, + _1, + object_cow, + pchan_index), DEG_OPCODE_BONE_DONE); op_node->set_as_exit(); @@ -349,10 +354,14 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object) DEG_OPCODE_PARAMETERS_EVAL, pchan->name); } + + pchan_index++; } op_node = add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, - NULL, + function_bind(BKE_pose_eval_proxy_pose_done, + _1, + object_cow), DEG_OPCODE_POSE_DONE); op_node->set_as_exit(); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 1d01b3e987b..4f94066f3bb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -587,10 +587,6 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) /* Proxy object to copy from. */ if (object->proxy_from != NULL) { build_object(NULL, object->proxy_from); - ComponentKey ob_pose_key(&object->proxy_from->id, DEG_NODE_TYPE_EVAL_POSE); - ComponentKey proxy_pose_key(&object->id, DEG_NODE_TYPE_EVAL_POSE); - add_relation(ob_pose_key, proxy_pose_key, "Proxy Pose"); - ComponentKey ob_transform_key(&object->proxy_from->id, DEG_NODE_TYPE_TRANSFORM); ComponentKey proxy_transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM); add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform"); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc index eaa17d27ffc..811986ea0e8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc @@ -469,11 +469,20 @@ void DepsgraphRelationBuilder::build_proxy_rig(Object *object) DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE); + OperationKey from_bone_done_key(&proxy_from->id, + DEG_NODE_TYPE_BONE, + pchan->name, + DEG_OPCODE_BONE_DONE); add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local"); add_relation(bone_local_key, bone_ready_key, "Local -> Ready"); add_relation(bone_ready_key, bone_done_key, "Ready -> Done"); add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done"); + /* Make sure bone in the proxy is not done before it's FROM is done. */ + add_relation(from_bone_done_key, + bone_done_key, + "From Bone Done -> Pose Done"); + if (pchan->prop != NULL) { OperationKey bone_parameters(&object->id, DEG_NODE_TYPE_PARAMETERS, -- cgit v1.2.3 From c1185f3d0dbbb51dea17cc2ac759776365927738 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 21:06:08 +1000 Subject: Cleanup: pep8, windows line endings --- release/scripts/modules/addon_utils.py | 16 +- .../startup/bl_ui/properties_data_gpencil.py | 8 +- .../startup/bl_ui/properties_data_modifier.py | 6 +- .../startup/bl_ui/properties_data_shaderfx.py | 3 +- .../bl_ui/properties_grease_pencil_common.py | 8 +- .../startup/bl_ui/properties_material_gpencil.py | 1 - .../scripts/startup/bl_ui/properties_particle.py | 14 +- .../bl_ui/properties_physics_dynamicpaint.py | 4 +- .../startup/bl_ui/properties_physics_rigidbody.py | 221 +++++++++++---------- release/scripts/startup/bl_ui/properties_scene.py | 7 +- release/scripts/startup/bl_ui/space_clip.py | 6 +- release/scripts/startup/bl_ui/space_image.py | 19 +- release/scripts/startup/bl_ui/space_node.py | 8 +- .../startup/bl_ui/space_toolsystem_toolbar.py | 6 +- release/scripts/startup/bl_ui/space_topbar.py | 1 - release/scripts/startup/bl_ui/space_view3d.py | 7 +- .../scripts/startup/bl_ui/space_view3d_toolbar.py | 26 ++- 17 files changed, 182 insertions(+), 179 deletions(-) diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py index 86185b96e9d..f73d23c150b 100644 --- a/release/scripts/modules/addon_utils.py +++ b/release/scripts/modules/addon_utils.py @@ -367,14 +367,14 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Silent default, we know these need updating. if module_name in { - "io_anim_bvh", - "io_mesh_ply", - "io_mesh_stl", - "io_mesh_uv_layout", - "io_scene_3ds", - "io_scene_fbx", - "io_scene_obj", - "io_scene_x3d", + "io_anim_bvh", + "io_mesh_ply", + "io_mesh_stl", + "io_mesh_uv_layout", + "io_scene_3ds", + "io_scene_fbx", + "io_scene_obj", + "io_scene_x3d", }: return None diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index 14407afa8f2..d46431afef4 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -21,13 +21,14 @@ import bpy from bpy.types import Menu, Panel, UIList from rna_prop_ui import PropertyPanel from .properties_grease_pencil_common import ( - GreasePencilDataPanel, - GreasePencilOnionPanel, - ) + GreasePencilDataPanel, + GreasePencilOnionPanel, +) ############################### # Base-Classes (for shared stuff - e.g. poll, attributes, etc.) + class DataButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -379,6 +380,7 @@ class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel): ############################### + classes = ( DATA_PT_gpencil, DATA_PT_gpencil_datapanel, diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 2328925bbad..7eeb45cc52e 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -28,6 +28,7 @@ class ModifierButtonsPanel: bl_context = "modifier" bl_options = {'HIDE_HEADER'} + class DATA_PT_modifiers(ModifierButtonsPanel, Panel): bl_label = "Modifiers" @@ -1857,7 +1858,7 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): if md.mode == 'CONCURRENT': col.prop(md, "concurrent_time_alignment") else: - col.separator() # For spacing + col.separator() # For spacing col.separator() col.separator() @@ -1929,7 +1930,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): layout.label(text="Object:") layout.prop(md, "object", text="") - def GP_HOOK(self, layout, ob, md): gpd = ob.data split = layout.split() @@ -1977,7 +1977,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "use_falloff_uniform") - def GP_OFFSET(self, layout, ob, md): gpd = ob.data split = layout.split() @@ -1989,7 +1988,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.prop(md, "rotation") - col.label("Layer:") row = col.row(align=True) row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL') diff --git a/release/scripts/startup/bl_ui/properties_data_shaderfx.py b/release/scripts/startup/bl_ui/properties_data_shaderfx.py index 5010f56d234..3798a273e09 100644 --- a/release/scripts/startup/bl_ui/properties_data_shaderfx.py +++ b/release/scripts/startup/bl_ui/properties_data_shaderfx.py @@ -28,6 +28,7 @@ class ShaderFxButtonsPanel: bl_context = "shaderfx" bl_options = {'HIDE_HEADER'} + class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): bl_label = "Effects" @@ -79,7 +80,7 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel): if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}: layout.prop(fx, "factor") - def FX_WAVE(self, layout,fx): + def FX_WAVE(self, layout, fx): layout.prop(fx, "orientation", expand=True) layout.separator() diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 65e7abe24a4..7426d2d463f 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -128,8 +128,8 @@ class GreasePencilDrawingToolsPanel: elif is_clip_editor: row.prop(context.space_data, "grease_pencil_source", expand=True) - #col.separator() - #col.separator() + # col.separator() + # col.separator() gpencil_stroke_placement_settings(context, col) @@ -404,7 +404,7 @@ class GPENCIL_MT_pie_settings_palette(Menu): pie = layout.menu_pie() gpd = context.gpencil_data gpl = context.active_gpencil_layer - palcolor = None #context.active_gpencil_palettecolor + palcolor = None # context.active_gpencil_palettecolor brush = context.active_gpencil_brush is_editmode = bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes) @@ -812,7 +812,7 @@ class GreasePencilOnionPanel: row = layout.row() row.active = gp.use_onion_skinning row.prop(gp, "use_onion_fade", text="Fade") - if hasattr(gp, "use_onion_loop"): # XXX + if hasattr(gp, "use_onion_loop"): # XXX subrow = layout.row() subrow.active = gp.onion_mode in ('RELATIVE', 'SELECTED') subrow.prop(gp, "use_onion_loop", text="Loop") diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 2d823594547..d83639a361c 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -84,7 +84,6 @@ class GPMaterialButtonsPanel: ob.active_material.grease_pencil) - class MATERIAL_PT_gpencil_slots(Panel): bl_label = "Grease Pencil Material Slots" bl_space_type = 'PROPERTIES' diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 75b2d76d9c4..393c9784be8 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -845,13 +845,13 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): part = particle_get_settings(context) boids = part.boids - col=layout.column() + col = layout.column() col.prop(boids, "use_flight") col.prop(boids, "use_land") col.prop(boids, "use_climb") - col=layout.column() + col = layout.column() col.active = boids.use_flight sub = col.column() @@ -866,7 +866,7 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): layout.separator() - col=layout.column() + col = layout.column() col.active = boids.use_land or boids.use_climb col.prop(boids, "land_speed_max") col.prop(boids, "land_jump_speed") @@ -879,6 +879,7 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): layout.prop(part, "collision_group") + class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): bl_label = "Battle" bl_parent_id = "PARTICLE_PT_physics" @@ -898,7 +899,7 @@ class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): part = particle_get_settings(context) boids = part.boids - col=layout.column() + col = layout.column() col.prop(boids, "health") col.prop(boids, "strength") @@ -906,6 +907,7 @@ class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): col.prop(boids, "accuracy") col.prop(boids, "range") + class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): bl_label = "Misc" bl_parent_id = "PARTICLE_PT_physics" @@ -925,7 +927,7 @@ class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): part = particle_get_settings(context) boids = part.boids - col=layout.column() + col = layout.column() col.prop(boids, "bank", slider=True) col.prop(boids, "pitch", slider=True) @@ -950,7 +952,6 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): psys = context.particle_system part = particle_get_settings(context) - row = layout.row() row.template_list("UI_UL_list", "particle_targets", psys, "targets", psys, "active_particle_target_index", rows=4) @@ -993,7 +994,6 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): sub.prop(key, "system", text="System") - class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): bl_label = "Deflection" bl_parent_id = "PARTICLE_PT_physics" diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 44d07ff53e6..3a475c82f5c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -97,7 +97,6 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): col.prop(surface, "image_resolution") col.prop(surface, "use_antialiasing") - sub = col.column(align=True) sub.prop(surface, "frame_start", text="Frame Start") sub.prop(surface, "frame_end", text="End") @@ -228,7 +227,6 @@ class PHYSICS_PT_dp_advanced_canvas_paint_dissolve(PhysicButtonsPanel, Panel): surface = canvas.canvas_surfaces.active self.layout.prop(surface, "use_dissolve", text="") - def draw(self, context): layout = self.layout @@ -398,7 +396,6 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): layout = self.layout - class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel): bl_label = "Spread" bl_parent_id = "PHYSICS_PT_dp_effects" @@ -455,6 +452,7 @@ class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel): effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT') + class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel): bl_label = "Shrink" bl_parent_id = "PHYSICS_PT_dp_effects" diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 00733e2fb12..d121b6a389d 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -39,7 +39,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout - layout.use_property_split = True + layout.use_property_split = True ob = context.object rbo = ob.rigid_body @@ -50,12 +50,11 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): if rbo.type == 'ACTIVE': layout.prop(rbo, "mass") - col = layout.column() - if rbo.type == 'ACTIVE': - col.prop(rbo, "enabled", text="Dynamic") - col.prop(rbo, "kinematic", text="Animated") - - + col = layout.column() + if rbo.type == 'ACTIVE': + col.prop(rbo, "enabled", text="Dynamic") + col.prop(rbo, "kinematic", text="Animated") + class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" @@ -73,7 +72,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): ob = context.object rbo = ob.rigid_body - layout.use_property_split = True + layout.use_property_split = True layout.prop(rbo, "collision_shape", text="Shape") @@ -84,50 +83,51 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): layout.prop(rbo, "use_deform", text="Deforming") -class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel): - bl_label = "Surface Response" - bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - - @classmethod - def poll(cls, context): - obj = context.object - return (obj and obj.rigid_body and - (context.engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - ob = context.object - rbo = ob.rigid_body - layout.use_property_split = True - - col = layout.column() +class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Surface Response" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() col.prop(rbo, "friction") col.prop(rbo, "restitution", text="Bounciness") -class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel): - bl_label = "Sensitivity" - bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - - @classmethod - def poll(cls, context): - obj = context.object - return (obj and obj.rigid_body and - (context.engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - ob = context.object - rbo = ob.rigid_body - layout.use_property_split = True - - col = layout.column() - + +class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Sensitivity" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + layout.use_property_split = True + + col = layout.column() + if rbo.collision_shape in {'MESH', 'CONE'}: col.prop(rbo, "collision_margin", text="Margin") else: @@ -136,25 +136,26 @@ class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, P sub.active = rbo.use_margin sub.prop(rbo, "collision_margin", text="Margin") -class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel): - bl_label = "Collision Collections" - bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - - @classmethod - def poll(cls, context): - obj = context.object - return (obj and obj.rigid_body and - (context.engine in cls.COMPAT_ENGINES)) - - def draw(self, context): - layout = self.layout - - ob = context.object - rbo = ob.rigid_body - - layout.prop(rbo, "collision_groups", text="") + +class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Collision Collections" + bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + rbo = ob.rigid_body + + layout.prop(rbo, "collision_groups", text="") class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): @@ -172,7 +173,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): def draw(self, context): layout = self.layout - layout.use_property_split = True + layout.use_property_split = True ob = context.object rbo = ob.rigid_body @@ -181,53 +182,53 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): # col.label(text="Activation:") # XXX: settings such as activate on collison/etc. - col = layout.column() - col.prop(rbo, "linear_damping", text="Translation Damping") - col.prop(rbo, "angular_damping", text="Rotation Damping") - - -class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel): - bl_label = "Deactivation" - bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' - bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - - @classmethod - def poll(cls, context): - obj = context.object - return (obj and obj.rigid_body and - obj.rigid_body.type == 'ACTIVE' and - (context.engine in cls.COMPAT_ENGINES)) - - def draw_header(self, context): - ob = context.object - rbo = ob.rigid_body - self.layout.prop(rbo, "use_deactivation", text="") - - def draw(self, context): - layout = self.layout - layout.use_property_split = True - - ob = context.object - rbo = ob.rigid_body - - layout.active = rbo.use_deactivation - - col = layout.column() - col.prop(rbo, "use_start_deactivated") - col.prop(rbo, "deactivate_linear_velocity", text="Linear Velocity") - col.prop(rbo, "deactivate_angular_velocity", text="Angular Velocity") - # TODO: other params such as time? + col = layout.column() + col.prop(rbo, "linear_damping", text="Translation Damping") + col.prop(rbo, "angular_damping", text="Rotation Damping") + + +class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel): + bl_label = "Deactivation" + bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + obj = context.object + return (obj and obj.rigid_body and + obj.rigid_body.type == 'ACTIVE' and + (context.engine in cls.COMPAT_ENGINES)) + + def draw_header(self, context): + ob = context.object + rbo = ob.rigid_body + self.layout.prop(rbo, "use_deactivation", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + rbo = ob.rigid_body + + layout.active = rbo.use_deactivation + + col = layout.column() + col.prop(rbo, "use_start_deactivated") + col.prop(rbo, "deactivate_linear_velocity", text="Linear Velocity") + col.prop(rbo, "deactivate_angular_velocity", text="Angular Velocity") + # TODO: other params such as time? classes = ( PHYSICS_PT_rigid_body, PHYSICS_PT_rigid_body_collisions, - PHYSICS_PT_rigid_body_collisions_surface, - PHYSICS_PT_rigid_body_collisions_sensitivity, - PHYSICS_PT_rigid_body_collisions_collections, + PHYSICS_PT_rigid_body_collisions_surface, + PHYSICS_PT_rigid_body_collisions_sensitivity, + PHYSICS_PT_rigid_body_collisions_collections, PHYSICS_PT_rigid_body_dynamics, - PHYSICS_PT_rigid_body_dynamics_deactivation, + PHYSICS_PT_rigid_body_dynamics_deactivation, ) if __name__ == "__main__": # only for live edit. diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 91be9bb5d0a..7832a5027d4 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -28,9 +28,9 @@ from rna_prop_ui import PropertyPanel from bl_operators.presets import PresetMenu from .properties_physics_common import ( - point_cache_ui, - effector_weights_ui, - ) + point_cache_ui, + effector_weights_ui, +) class SCENE_PT_units_length_presets(PresetMenu): @@ -104,6 +104,7 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel): col.prop(unit, "scale_length") col.prop(unit, "use_separate") + class SceneKeyingSetsPanel: @staticmethod diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 8e32d98529b..1564204c613 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -23,8 +23,9 @@ from bpy.types import Panel, Header, Menu, UIList from bpy.app.translations import pgettext_iface as iface_ from bl_operators.presets import PresetMenu from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilDataPanel) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel, +) class CLIP_UL_tracking_objects(UIList): @@ -1154,7 +1155,6 @@ class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_region_type = 'TOOLS' - class CLIP_MT_view(Menu): bl_label = "View" diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 501f58e9901..7a1d4117451 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -21,15 +21,15 @@ import bpy import math from bpy.types import Header, Menu, Panel, UIList from .properties_paint_common import ( - UnifiedPaintPanel, - brush_texture_settings, - brush_texpaint_common, - brush_mask_texture_settings, - ) + UnifiedPaintPanel, + brush_texture_settings, + brush_texpaint_common, + brush_mask_texture_settings, +) from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilDataPanel - ) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel, +) from bpy.app.translations import pgettext_iface as iface_ @@ -1342,12 +1342,13 @@ class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel): # NOTE: this is just a wrapper around the generic GP Panel # Grease Pencil drawing tools + + class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'IMAGE_EDITOR' bl_region_type = 'TOOLS' - classes = ( IMAGE_MT_view, IMAGE_MT_select, diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index affbf70b1a0..43a124cd48f 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -23,10 +23,10 @@ from bpy.types import Header, Menu, Panel from bpy.app.translations import pgettext_iface as iface_ from bl_operators.presets import PresetMenu from .properties_grease_pencil_common import ( - GreasePencilDrawingToolsPanel, - GreasePencilDataPanel, - GreasePencilToolsPanel - ) + GreasePencilDrawingToolsPanel, + GreasePencilDataPanel, + GreasePencilToolsPanel, +) class NODE_HT_header(Header): diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 1bb5a93f7f8..7eaf4762216 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -280,7 +280,7 @@ class _defs_annotate: return dict( text="Eraser", icon="ops.gpencil.draw.eraser", - cursor='CROSSHAIR', # XXX: Always show brush circle when enabled + cursor='CROSSHAIR', # XXX: Always show brush circle when enabled keymap=( ("gpencil.annotate", dict(mode='ERASER', wait_for_input=False), @@ -1030,6 +1030,7 @@ class _defs_uv_select: ), ) + class _defs_gpencil_paint: @classmethod def draw_color_selector(cls, context, layout): @@ -1049,7 +1050,7 @@ class _defs_gpencil_paint: if ob and ob.mode == 'GPENCIL_PAINT': brush = context.active_gpencil_brush gp_settings = brush.gpencil_settings - tool_settings= context.tool_settings + tool_settings = context.tool_settings if gp_settings.gpencil_brush_type == 'ERASE': row = layout.row() @@ -1076,7 +1077,6 @@ class _defs_gpencil_paint: _defs_gpencil_paint.draw_color_selector(context, layout) - @staticmethod def generate_from_brushes(context): return generate_from_brushes_ex( diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 0d837ae413a..6712e495498 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -512,7 +512,6 @@ class INFO_MT_help(Menu): "wm.url_open", text="Manual", icon='HELP', ).url = "https://docs.blender.org/manual/en/dev/" - layout.operator( "wm.url_open", text="Report a Bug", icon='URL', ).url = "https://developer.blender.org/maniphest/task/edit/form/1" diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index eb595e9f12d..fca37499da0 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3840,7 +3840,7 @@ class VIEW3D_PT_object_type_visibility(Panel): "armature", "lattice", "empty", - "grease_pencil", + "grease_pencil", "camera", "light", "light_probe", @@ -3902,7 +3902,7 @@ class VIEW3D_PT_shading_lighting(Panel): split = layout.split(0.9) col = split.column() sub = col.row() - sub.scale_y = 0.6 # smaller matcap/hdri preview + sub.scale_y = 0.6 # smaller matcap/hdri preview if shading.light == 'STUDIO': sub.template_icon_view(shading, "studio_light", scale=3) @@ -3941,7 +3941,7 @@ class VIEW3D_PT_shading_lighting(Panel): col = split.column() col.prop(shading, "studiolight_rotate_z", text="Rotation") col.prop(shading, "studiolight_background_alpha") - col = split.column() # to align properly with above + col = split.column() # to align properly with above class VIEW3D_PT_shading_color(Panel): @@ -4889,7 +4889,6 @@ class VIEW3D_PT_gpencil_multi_frame(Panel): layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True) - classes = ( VIEW3D_HT_header, VIEW3D_MT_editor_menus, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 70d8c4089d3..ceb0f244bac 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -20,16 +20,16 @@ import bpy from bpy.types import Menu, Panel, UIList from .properties_grease_pencil_common import ( - GreasePencilStrokeEditPanel, - GreasePencilStrokeSculptPanel, - GreasePencilAppearancePanel, - ) + GreasePencilStrokeEditPanel, + GreasePencilStrokeSculptPanel, + GreasePencilAppearancePanel, +) from .properties_paint_common import ( - UnifiedPaintPanel, - brush_texture_settings, - brush_texpaint_common, - brush_mask_texture_settings, - ) + UnifiedPaintPanel, + brush_texture_settings, + brush_texpaint_common, + brush_mask_texture_settings, +) from bl_operators.presets import PresetMenu @@ -69,9 +69,13 @@ def draw_vpaint_symmetry(layout, vpaint): col.prop(vpaint, "radial_symmetry", text="Radial") # Most of these panels should not be visible in GP edit modes + + def is_not_gpencil_edit_mode(context): - is_gpmode = context.active_object and \ - context.active_object.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'} + is_gpmode = ( + context.active_object and + context.active_object.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'} + ) return not is_gpmode -- cgit v1.2.3 From 29f13476f0d2a345b959e8ffbc2db7b9c42a19e0 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 31 Jul 2018 13:37:23 +0200 Subject: Fix (unreported) wrong logic in gpencil UI code. --- release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 7426d2d463f..42c75ec29ac 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -728,7 +728,7 @@ class GreasePencilDataPanel: layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink") # List of layers/notes. - if gpd or gpd.layers: + if gpd and gpd.layers: self.draw_layers(context, layout, gpd) def draw_layers(self, context, layout, gpd): -- cgit v1.2.3 From e5a1bf0b10389939d654e35ef76bb4ad27029617 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 14:31:34 +0200 Subject: UI: Metadata panel tweaks Rename "Seq. Strip" to Strip Name, "Sequence Strip" to Use Strip Metadata. Plus re-arrange of properties and separators for sections. Thanks @fsiddi for the feedback. --- release/scripts/startup/bl_ui/properties_render.py | 26 ++++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 1c26d172e4c..2b91eec67c4 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -219,23 +219,35 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel): split = layout.split() col = split.column(align=True) - col.prop(rd, "use_stamp_time", text="Time") col.prop(rd, "use_stamp_date", text="Date") - col.prop(rd, "use_stamp_render_time", text="RenderTime") + col.prop(rd, "use_stamp_time", text="Time") + + col.separator() + + col.prop(rd, "use_stamp_render_time", text="Render Time") col.prop(rd, "use_stamp_frame", text="Frame") - col.prop(rd, "use_stamp_scene", text="Scene") + col.prop(rd, "use_stamp_frame_range", text="Frame Range") col.prop(rd, "use_stamp_memory", text="Memory") col = split.column(align=True) col.prop(rd, "use_stamp_camera", text="Camera") col.prop(rd, "use_stamp_lens", text="Lens") - col.prop(rd, "use_stamp_filename", text="Filename") - col.prop(rd, "use_stamp_frame_range", text="Frame range") + + col.separator() + + col.prop(rd, "use_stamp_scene", text="Scene") col.prop(rd, "use_stamp_marker", text="Marker") - col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip") + + col.separator() + + col.prop(rd, "use_stamp_filename", text="Filename") + + col.separator() + + col.prop(rd, "use_stamp_sequencer_strip", text="Strip Name") if rd.use_sequencer: - col.prop(rd, "use_stamp_strip_meta", text="Sequence Strip") + col.prop(rd, "use_stamp_strip_meta", text="Use Strip Metadata") row = layout.split(percentage=0.3) row.prop(rd, "use_stamp_note", text="Note") -- cgit v1.2.3 From 2dbb1e9f0eec75e1fa11a573a151690c91a976dd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 31 Jul 2018 14:22:32 +0200 Subject: Fix cmake external library build for blosc/freetype on some systems. --- build_files/build_environment/cmake/blosc.cmake | 1 + build_files/build_environment/cmake/freetype.cmake | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/blosc.cmake b/build_files/build_environment/cmake/blosc.cmake index 606fe8c61cc..9a5ef745985 100644 --- a/build_files/build_environment/cmake/blosc.cmake +++ b/build_files/build_environment/cmake/blosc.cmake @@ -25,6 +25,7 @@ set(BLOSC_EXTRA_ARGS -DThreads_FOUND=1 -DPTHREAD_LIBS=${LIBDIR}/pthreads/lib/pthreadVC2.lib -DPTHREAD_INCLUDE_DIR=${LIBDIR}/pthreads/inc + -DDEACTIVATE_SNAPPY=ON ) ExternalProject_Add(external_blosc diff --git a/build_files/build_environment/cmake/freetype.cmake b/build_files/build_environment/cmake/freetype.cmake index 751b2b1f383..9afc902531b 100644 --- a/build_files/build_environment/cmake/freetype.cmake +++ b/build_files/build_environment/cmake/freetype.cmake @@ -16,7 +16,15 @@ # # ***** END GPL LICENSE BLOCK ***** -set(FREETYPE_EXTRA_ARGS -DCMAKE_RELEASE_POSTFIX:STRING=2ST -DCMAKE_DEBUG_POSTFIX:STRING=2ST_d -DWITH_BZip2=OFF -DWITH_HarfBuzz=OFF) +set(FREETYPE_EXTRA_ARGS + -DCMAKE_RELEASE_POSTFIX:STRING=2ST + -DCMAKE_DEBUG_POSTFIX:STRING=2ST_d + -DWITH_BZip2=OFF + -DWITH_HarfBuzz=OFF + -DFT_WITH_HARFBUZZ=OFF + -DFT_WITH_BZIP2=OFF + -DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE + -DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE) ExternalProject_Add(external_freetype URL ${FREETYPE_URI} -- cgit v1.2.3 From 1b0c1c551a6f25991dfa708ac33af6b1392e70e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 23:00:17 +1000 Subject: UI: remove grease pencil settings from topbar Top bar is only for settings that apply to the next action not a way to change existing data. If each stroke could have a different color this would work as expected, however it was adjusting the current layer color. --- .../startup/bl_ui/properties_grease_pencil_common.py | 6 ++++++ .../scripts/startup/bl_ui/space_toolsystem_toolbar.py | 18 ------------------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 42c75ec29ac..62e4c3db503 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -774,6 +774,12 @@ class GreasePencilDataPanel: row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED') row.operator("gpencil.active_frame_delete", text="", icon='X') + tool_settings = context.tool_settings + if gpd and gpl: + layout.prop(gpl, "thickness") + else: + layout.prop(tool_settings, "annotation_thickness", text="Thickness") + class GreasePencilOnionPanel: @staticmethod diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 7eaf4762216..90b04104444 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -186,26 +186,8 @@ class _defs_view3d_generic: class _defs_annotate: @classmethod def draw_settings_common(cls, context, layout, tool): - user_prefs = context.user_preferences ts = context.tool_settings - # XXX: These context checks are needed for layer-dependent settings, - # but this breaks for using topbar for 2D editor active tools, etc. - if type(context.gpencil_data_owner) is bpy.types.Object: - gpd = context.scene.grease_pencil - else: - gpd = context.gpencil_data - - gpl = gpd.layers.active if gpd else None - - if gpd and gpl: - layout.prop(gpd.layers, "active_note", text="") - layout.prop(gpl, "color", text="") - layout.prop(gpl, "thickness") - else: - layout.prop(user_prefs.edit, "grease_pencil_default_color", text="") - layout.prop(ts, "annotation_thickness", text="Thickness") - # For 3D view, show the stroke placement settings # XXX: How to tell what editor the active tool comes from? is_3d_view = True -- cgit v1.2.3 From ddd44315b805aab491c085e478226f916ce03176 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 15:13:08 +0200 Subject: UI: Grease Pencil Onion Skin minor tweaks Avoid double label for same properties in single-column. Onion Skinning: Group custom colors together, and frame before/after together. Small changes to tooltips. --- .../startup/bl_ui/properties_data_gpencil.py | 8 ++-- .../bl_ui/properties_grease_pencil_common.py | 46 ++++++++-------------- source/blender/makesrna/intern/rna_gpencil.c | 4 +- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index d46431afef4..90dc86a20bb 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -215,7 +215,7 @@ class DATA_PT_gpencil_layer_optionpanel(LayerDataButtonsPanel, Panel): layout.enabled = not gpl.lock col = layout.column(align=True) col.prop(gpl, "tint_color") - col.prop(gpl, "tint_factor", slider=True) + col.prop(gpl, "tint_factor", text="Factor", slider=True) # Offsets - Thickness col = layout.row(align=True) @@ -236,10 +236,10 @@ class DATA_PT_gpencil_parentpanel(LayerDataButtonsPanel, Panel): layout.use_property_decorate = False gpl = context.active_gpencil_layer - col = layout.column(align=True) + col = layout.column() col.active = not gpl.lock - col.prop(gpl, "parent", text="Parent") - col.prop(gpl, "parent_type", text="Parent Type") + col.prop(gpl, "parent") + col.prop(gpl, "parent_type", text="Type") parent = gpl.parent if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE': diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 62e4c3db503..412071a642e 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -785,43 +785,31 @@ class GreasePencilOnionPanel: @staticmethod def draw_settings(layout, gp): col = layout.column() - col.prop(gp, "onion_mode") + col.prop(gp, "onion_factor", text="Opacity", slider=True) - row = col.row() - row.prop(gp, "onion_factor", text="Opacity", slider=True) - - # Frames before. - sub = layout.column(align=True) - row = sub.row(align=True) - row.active = gp.use_ghost_custom_colors - row.prop(gp, "before_color", text="Color Before") - - row = sub.row(align=True) - row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE') - row.prop(gp, "ghost_before_range", text="Frames Before") + if gp.onion_mode in ('ABSOLUTE', 'RELATIVE'): + col = layout.column(align=True) + col.prop(gp, "ghost_before_range", text="Frames Before") + col.prop(gp, "ghost_after_range", text="After") - # Frames after. - sub = layout.column(align=True) - row = sub.row(align=True) - row.active = gp.use_ghost_custom_colors - row.prop(gp, "after_color", text="Color After") + layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Colors") - row = sub.row(align=True) - row.active = gp.onion_mode in ('ABSOLUTE', 'RELATIVE') - row.prop(gp, "ghost_after_range", text="Frames After") + if gp.use_ghost_custom_colors: + col = layout.column(align=True) + col.active = gp.use_ghost_custom_colors + col.prop(gp, "before_color", text="Color Before") + col.prop(gp, "after_color", text="After") - layout.prop(gp, "use_ghost_custom_colors", text="Use Custom Color") layout.prop(gp, "use_ghosts_always", text="View In Render") - # Fade and loop. - row = layout.row() - row.active = gp.use_onion_skinning - row.prop(gp, "use_onion_fade", text="Fade") + col = layout.column(align=True) + col.active = gp.use_onion_skinning + col.prop(gp, "use_onion_fade", text="Fade") if hasattr(gp, "use_onion_loop"): # XXX - subrow = layout.row() - subrow.active = gp.onion_mode in ('RELATIVE', 'SELECTED') - subrow.prop(gp, "use_onion_loop", text="Loop") + sub = layout.column() + sub.active = gp.onion_mode in ('RELATIVE', 'SELECTED') + sub.prop(gp, "use_onion_loop", text="Loop") class GreasePencilToolsPanel: diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 4b69a395ab6..c4aa90fb61b 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -1073,7 +1073,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) /* Onion-Skinning */ prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_LAYER_ONIONSKIN); - RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame"); + RNA_def_property_ui_text(prop, "Onion Skinning", "Display onion skins before and after the current frame"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Flags */ @@ -1303,7 +1303,7 @@ static void rna_def_gpencil_data(BlenderRNA *brna) prop = RNA_def_property(srna, "show_constant_thickness", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_KEEPTHICKNESS); - RNA_def_property_ui_text(prop, "Keep thickness", "Show stroke with same thickness when viewport zoom change"); + RNA_def_property_ui_text(prop, "Keep Thickness", "Maintain the thickness of the stroke when the viewport zoom changes"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "pixfactor", PROP_FLOAT, PROP_NONE); -- cgit v1.2.3 From 475e9003c06869df8182e7135fe9459d7309696c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 31 Jul 2018 15:29:51 +0200 Subject: Fix T55718: Blender 2.8 crashes when converting to Curve from Mesh. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only want to care about runtime.mesh_orig if… data is indeed a Mesh! ;) --- .../depsgraph/intern/eval/deg_eval_copy_on_write.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 22c1167de2a..9ed50fafc3d 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -757,7 +757,7 @@ static void deg_restore_object_runtime( Mesh *mesh_orig = object->runtime.mesh_orig; object->runtime = object_runtime_backup->runtime; object->runtime.mesh_orig = mesh_orig; - if (object->runtime.mesh_eval != NULL) { + if (object->type == OB_MESH && object->runtime.mesh_eval != NULL) { if (object->id.recalc & ID_RECALC_GEOMETRY) { /* If geometry is tagged for update it means, that part of * evaluated mesh are not valid anymore. In this case we can not @@ -773,14 +773,12 @@ static void deg_restore_object_runtime( /* Do same thing as object update: override actual object data * pointer with evaluated datablock. */ - if (object->type == OB_MESH) { - object->data = mesh_eval; - /* Evaluated mesh simply copied edit_btmesh pointer from - * original mesh during update, need to make sure no dead - * pointers are left behind. - */ - mesh_eval->edit_btmesh = mesh_orig->edit_btmesh; - } + object->data = mesh_eval; + /* Evaluated mesh simply copied edit_btmesh pointer from + * original mesh during update, need to make sure no dead + * pointers are left behind. + */ + mesh_eval->edit_btmesh = mesh_orig->edit_btmesh; } } object->base_flag = object_runtime_backup->base_flag; -- cgit v1.2.3 From ebca6f5f2087b545a196422f3c1e4e988a7cd93f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 31 Jul 2018 23:36:01 +1000 Subject: Fix grease pencil line toggle Replace with generic context toggle operator. --- source/blender/editors/gpencil/gpencil_edit.c | 38 ------------------------- source/blender/editors/gpencil/gpencil_intern.h | 1 - source/blender/editors/gpencil/gpencil_ops.c | 30 ++++++++----------- 3 files changed, 12 insertions(+), 57 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index fdeadcc648a..56d1d53ea40 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -486,44 +486,6 @@ void GPENCIL_OT_selection_opacity_toggle(wmOperatorType *ot) ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; } -/* toggle multi edit strokes support */ -static int gpencil_multiedit_toggle_exec(bContext *C, wmOperator *op) -{ - View3D *v3d = CTX_wm_view3d(C); - const bool lines = RNA_boolean_get(op->ptr, "lines"); - - /* Just toggle value */ - if (lines == 0) { - v3d->flag3 ^= V3D_GP_SHOW_EDIT_LINES; - } - else { - v3d->flag3 ^= V3D_GP_SHOW_MULTIEDIT_LINES; - } - - WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL); - WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL); - - return OPERATOR_FINISHED; -} - -void GPENCIL_OT_multiedit_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Edit Lines Toggle"; - ot->idname = "GPENCIL_OT_multiedit_toggle"; - ot->description = "Enable/disable edit lines support"; - - /* callbacks */ - ot->exec = gpencil_multiedit_toggle_exec; - ot->poll = gp_stroke_edit_poll; - - /* flags */ - ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; - - /* properties */ - RNA_def_boolean(ot->srna, "toggle_visibility", 0, "Toggle Visibility Only", "Toggle visibility of edit lines only"); -} - /* ************** Duplicate Selected Strokes **************** */ /* Make copies of selected point segments in a selected stroke */ diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index a51f9e7a065..52e7d1e1f30 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -291,7 +291,6 @@ void GPENCIL_OT_paintmode_toggle(struct wmOperatorType *ot); void GPENCIL_OT_sculptmode_toggle(struct wmOperatorType *ot); void GPENCIL_OT_weightmode_toggle(struct wmOperatorType *ot); void GPENCIL_OT_selection_opacity_toggle(struct wmOperatorType *ot); -void GPENCIL_OT_multiedit_toggle(struct wmOperatorType *ot); void GPENCIL_OT_select(struct wmOperatorType *ot); void GPENCIL_OT_select_all(struct wmOperatorType *ot); diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index e5ebfcecdf8..43ccc77e921 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -404,11 +404,10 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0); /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); - - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); /* Isolate Layer */ WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0); @@ -605,12 +604,10 @@ static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf) ed_keymap_gpencil_sculpt(keymap); /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); - - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); - + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); } /* Stroke Weight Paint Keymap - Only when weight is enabled */ @@ -637,12 +634,10 @@ static void ed_keymap_gpencil_weightpainting(wmKeyConfig *keyconf) RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.size"); /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 0); - - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_multiedit_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "toggle_visibility", 1); - + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); } /* ==================== */ @@ -678,7 +673,6 @@ void ED_operatortypes_gpencil(void) WM_operatortype_append(GPENCIL_OT_sculptmode_toggle); WM_operatortype_append(GPENCIL_OT_weightmode_toggle); WM_operatortype_append(GPENCIL_OT_selection_opacity_toggle); - WM_operatortype_append(GPENCIL_OT_multiedit_toggle); WM_operatortype_append(GPENCIL_OT_select); WM_operatortype_append(GPENCIL_OT_select_all); -- cgit v1.2.3 From a3893ed03eeb9dbdfad1f4414bf168601985b0cf Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 15:38:45 +0200 Subject: Enable ghost onion skin by default This option was changed by error when implement annotations. --- source/blender/blenkernel/intern/gpencil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index c86f39f1d55..18817f20d1c 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -419,13 +419,13 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti /* set default thickness of new strokes for this layer */ gpl->thickness = 3; - /* onion-skinning settings */ - gpl->onion_flag |= GP_LAYER_ONIONSKIN; } else { /* thickness parameter represents "thickness change", not absolute thickness */ gpl->thickness = 0; gpl->opacity = 1.0f; + /* onion-skinning settings */ + gpl->onion_flag |= GP_LAYER_ONIONSKIN; } /* auto-name */ -- cgit v1.2.3 From ff1ca80f01012eacb347a3e33c3afa87ba752097 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 15:57:11 +0200 Subject: Set overlay default values --- source/blender/blenloader/intern/versioning_defaults.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index a86986e2e09..da3787816d2 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -442,4 +442,21 @@ void BLO_update_defaults_startup_blend(Main *bmain) la->energy = 10.0; } } + /* default grease pencil settings */ + { + for (bScreen *sc = bmain->screen.first; sc; sc = sc->id.next) { + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->flag3 |= V3D_GP_SHOW_EDIT_LINES; + v3d->flag3 |= V3D_GP_SHOW_MULTIEDIT_LINES; + v3d->flag3 |= V3D_GP_SHOW_ONION_SKIN; + v3d->vertex_opacity = 0.9f; + break; + } + } + } + } + } } -- cgit v1.2.3 From d41f448b3bb34e56f2c4a082ccd1457e80ef1849 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 16:04:57 +0200 Subject: Change Brush smooth factor to 0.1 by default The old values were too high. --- source/blender/blenkernel/intern/brush.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 598eb9b5b54..c769978f9bb 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -289,7 +289,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; - brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->thick_smoothfac = 1.0f; brush->gpencil_settings->thick_smoothlvl = 3; @@ -321,7 +321,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; - brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->draw_subdivide = 1; brush->gpencil_settings->thick_smoothfac = 1.0f; @@ -350,7 +350,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; - brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->thick_smoothfac = 1.0f; brush->gpencil_settings->thick_smoothlvl = 3; @@ -387,7 +387,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; - brush->gpencil_settings->draw_smoothfac = 1.0f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 2; brush->gpencil_settings->thick_smoothfac = 0.5f; brush->gpencil_settings->thick_smoothlvl = 2; @@ -454,7 +454,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->draw_angle_factor = 1.0f; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; - brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->thick_smoothfac = 1.0f; brush->gpencil_settings->thick_smoothlvl = 3; @@ -477,7 +477,7 @@ void BKE_brush_gpencil_presets(bContext *C) brush->gpencil_settings->icon_id = GP_BRUSH_ICON_FILL; brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_FILL; - brush->gpencil_settings->draw_smoothfac = 0.5f; + brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->thick_smoothfac = 1.0f; brush->gpencil_settings->thick_smoothlvl = 3; -- cgit v1.2.3 From d803b4e43b11bffc819d130c811f0e6f03195d57 Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Tue, 31 Jul 2018 16:14:05 +0200 Subject: UI: Grease Pencil Simplify tweaks Single-column layout and tweaks to tooltips. --- release/scripts/startup/bl_ui/properties_scene.py | 20 +++++++++++--------- source/blender/makesrna/intern/rna_scene.c | 10 +++++----- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 7832a5027d4..e324e7a9882 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -569,7 +569,8 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel): class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel): - bl_label = "Simplify Grease Pencil" + bl_label = "Grease Pencil" + bl_parent_id = "SCENE_PT_simplify" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'} bl_options = {'DEFAULT_CLOSED'} @@ -579,21 +580,22 @@ class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True rd = context.scene.render layout.active = rd.simplify_gpencil - row = layout.row() - row.prop(rd, "simplify_gpencil_onplay", text="Only on Play") - - split = layout.split() - - col = split.column() - col.prop(rd, "simplify_gpencil_view_fill", text="Fill") - col.prop(rd, "simplify_gpencil_remove_lines", text="Remove Fill Lines") + col = layout.column() + col.prop(rd, "simplify_gpencil_onplay", text="Playback Only") col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") + col = layout.column(align=True) + col.prop(rd, "simplify_gpencil_view_fill") + sub = col.column() + sub.active = rd.simplify_gpencil_view_fill + sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines") + class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 9fde87be486..c8f1d810b00 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5188,27 +5188,27 @@ static void rna_def_scene_render_data(BlenderRNA *brna) /* Grease Pencil - Simplify Options */ prop = RNA_def_property(srna, "simplify_gpencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ENABLE); - RNA_def_property_ui_text(prop, "Simplify", "Simplify Grease Pencil Drawing"); + RNA_def_property_ui_text(prop, "Simplify", "Simplify Grease Pencil drawing"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "simplify_gpencil_onplay", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_ON_PLAY); - RNA_def_property_ui_text(prop, "On Play", "Simplify Grease Pencil only when play animation"); + RNA_def_property_ui_text(prop, "Simplify Playback", "Simplify Grease Pencil only during animation playback"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "simplify_gpencil_view_fill", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_FILL); - RNA_def_property_ui_text(prop, "Fill", "Do not fill strokes on viewport"); + RNA_def_property_ui_text(prop, "Disable Fill", "Disable fill strokes in the viewport"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "simplify_gpencil_remove_lines", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_REMOVE_FILL_LINE); - RNA_def_property_ui_text(prop, "Remove Lines", "Remove External Lines of Filling Strokes"); + RNA_def_property_ui_text(prop, "Disable Lines", "Disable external lines of fill strokes"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "simplify_gpencil_view_modifier", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_MODIFIER); - RNA_def_property_ui_text(prop, "Fill", "Do not apply modifiers on viewport"); + RNA_def_property_ui_text(prop, "Disable Modifiers", "Do not apply modifiers in the viewport"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* persistent data */ -- cgit v1.2.3 From 4684375bd45f7c6bebcfd5006a8bc86e777f971e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Wed, 1 Aug 2018 01:27:47 +1200 Subject: Fix: Motion Paths were still visible after clearing them After clearing motion paths from objects, those objects needed to be tagged for copy on write so that the copied data (i.e. viewport) recieve the changes (i.e. removed paths) Reported by Hjalti --- source/blender/editors/armature/pose_edit.c | 3 +++ source/blender/editors/object/object_edit.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 3ae578279ca..1dfb9ec984a 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -365,6 +365,9 @@ static void ED_pose_clear_paths(Object *ob, bool only_selected) /* if nothing was skipped, there should be no paths left! */ if (skipped == false) ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; + + /* tag armature object for copy on write - so removed paths don't still show */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } /* operator callback - wrapper for the backend function */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 48048319cb7..a6dad906579 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1378,6 +1378,9 @@ static void object_clear_mpath(Object *ob) animviz_free_motionpath(ob->mpath); ob->mpath = NULL; ob->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; + + /* tag object for copy on write - so removed paths don't still show */ + DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); } } -- cgit v1.2.3 From 9b817bc168903f9c44c2464b9b2f671ddf465f06 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 17:02:50 +0200 Subject: Fix set_pixel overflow in fill brush The value of the index was above the size of image --- source/blender/editors/gpencil/gpencil_fill.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 20db5c1504f..253f0db865e 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -372,6 +372,7 @@ static void get_pixel(ImBuf *ibuf, int idx, float r_col[4]) /* set pixel data (rgba) at index */ static void set_pixel(ImBuf *ibuf, int idx, const float col[4]) { + //BLI_assert(idx <= ibuf->x * ibuf->y); if (ibuf->rect) { uint *rrect = &ibuf->rect[idx]; uchar ccol[4]; @@ -587,20 +588,23 @@ static void gpencil_clean_borders(tGPDfill *tgpf) const float fill_col[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock); int idx; + int pixel = 0; /* horizontal lines */ - for (idx = 0; idx < ibuf->x; idx++) { + for (idx = 0; idx < ibuf->x - 1; idx++) { /* bottom line */ set_pixel(ibuf, idx, fill_col); /* top line */ - set_pixel(ibuf, idx + (ibuf->x * (ibuf->y - 1)), fill_col); + pixel = idx + (ibuf->x * (ibuf->y - 1)); + set_pixel(ibuf, pixel, fill_col); } /* vertical lines */ for (idx = 0; idx < ibuf->y; idx++) { /* left line */ set_pixel(ibuf, ibuf->x * idx, fill_col); /* right line */ - set_pixel(ibuf, ibuf->x * idx + (ibuf->x - 1), fill_col); + pixel = ibuf->x * idx + (ibuf->x - 1); + set_pixel(ibuf, pixel, fill_col); } /* release ibuf */ -- cgit v1.2.3 From 3ecba657bb79e010cffae4110ee74a063429f7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 31 Jul 2018 16:54:58 +0200 Subject: GPU: Replace malloc/calloc/realloc/free with MEM_* counterpart --- source/blender/gpu/intern/gpu_batch.c | 20 +++++++++--------- source/blender/gpu/intern/gpu_element.c | 10 +++++---- source/blender/gpu/intern/gpu_shader_interface.c | 27 ++++++++++++------------ source/blender/gpu/intern/gpu_vertex_buffer.c | 16 ++++++++------ 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 9b433a37a72..87ea112148c 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -30,6 +30,8 @@ * Contains VAOs + VBOs + Shader representing a drawable entity. */ +#include "MEM_guardedalloc.h" + #include "GPU_batch.h" #include "GPU_batch_presets.h" #include "GPU_matrix.h" @@ -59,8 +61,8 @@ void GPU_batch_vao_cache_clear(GPUBatch *batch) GPU_shaderinterface_remove_batch_ref((GPUShaderInterface *)batch->dynamic_vaos.interfaces[i], batch); } } - free(batch->dynamic_vaos.interfaces); - free(batch->dynamic_vaos.vao_ids); + MEM_freeN(batch->dynamic_vaos.interfaces); + MEM_freeN(batch->dynamic_vaos.vao_ids); } else { for (int i = 0; i < GPU_BATCH_VAO_STATIC_LEN; ++i) { @@ -85,7 +87,7 @@ GPUBatch *GPU_batch_create_ex( GPUPrimType prim_type, GPUVertBuf *verts, GPUIndexBuf *elem, uint owns_flag) { - GPUBatch *batch = calloc(1, sizeof(GPUBatch)); + GPUBatch *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch"); GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } @@ -146,7 +148,7 @@ void GPU_batch_discard(GPUBatch *batch) if (batch->free_callback) { batch->free_callback(batch, batch->callback_data); } - free(batch); + MEM_freeN(batch); } void GPU_batch_callback_free_set(GPUBatch *batch, void (*callback)(GPUBatch *, void *), void *user_data) @@ -255,8 +257,8 @@ static GLuint batch_vao_get(GPUBatch *batch) } /* Init dynamic arrays and let the branch below set the values. */ batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = calloc(batch->dynamic_vaos.count, sizeof(GPUShaderInterface *)); - batch->dynamic_vaos.vao_ids = calloc(batch->dynamic_vaos.count, sizeof(GLuint)); + batch->dynamic_vaos.interfaces = MEM_callocN(batch->dynamic_vaos.count * sizeof(GPUShaderInterface *), "dyn vaos interfaces"); + batch->dynamic_vaos.vao_ids = MEM_callocN(batch->dynamic_vaos.count * sizeof(GLuint), "dyn vaos ids"); } } @@ -270,10 +272,8 @@ static GLuint batch_vao_get(GPUBatch *batch) /* Not enough place, realloc the array. */ i = batch->dynamic_vaos.count; batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT; - batch->dynamic_vaos.interfaces = realloc(batch->dynamic_vaos.interfaces, sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count); - batch->dynamic_vaos.vao_ids = realloc(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); - memset(batch->dynamic_vaos.interfaces + i, 0, sizeof(GPUShaderInterface *) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); - memset(batch->dynamic_vaos.vao_ids + i, 0, sizeof(GLuint) * GPU_BATCH_VAO_DYN_ALLOC_COUNT); + batch->dynamic_vaos.interfaces = MEM_recallocN(batch->dynamic_vaos.interfaces, sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count); + batch->dynamic_vaos.vao_ids = MEM_recallocN(batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count); } batch->dynamic_vaos.interfaces[i] = batch->interface; batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc(); diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.c index 901e09443d1..56a0c90d5b5 100644 --- a/source/blender/gpu/intern/gpu_element.c +++ b/source/blender/gpu/intern/gpu_element.c @@ -29,6 +29,8 @@ * GPU element list (AKA index buffer) */ +#include "MEM_guardedalloc.h" + #include "GPU_element.h" #include "gpu_context_private.h" @@ -70,7 +72,7 @@ void GPU_indexbuf_init_ex( builder->max_index_len = index_len; builder->index_len = 0; // start empty builder->prim_type = prim_type; - builder->data = calloc(builder->max_index_len, sizeof(uint)); + builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data"); } void GPU_indexbuf_init(GPUIndexBufBuilder *builder, GPUPrimType prim_type, uint prim_len, uint vertex_len) @@ -243,7 +245,7 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder, GPUIndexBuf *elem GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder) { - GPUIndexBuf *elem = calloc(1, sizeof(GPUIndexBuf)); + GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf"); GPU_indexbuf_build_in_place(builder, elem); return elem; } @@ -290,7 +292,7 @@ void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *builder, GPUIndexBuf *elem) glBufferData(GL_ARRAY_BUFFER, GPU_indexbuf_size_get(elem), builder->data, GL_STATIC_DRAW); /* discard builder (one-time use) */ - free(builder->data); + MEM_freeN(builder->data); builder->data = NULL; /* other fields are safe to leave */ } @@ -305,5 +307,5 @@ void GPU_indexbuf_discard(GPUIndexBuf *elem) if (elem->vbo_id) { GPU_buf_free(elem->vbo_id); } - free(elem); + MEM_freeN(elem); } diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.c index 54c5f41bbd3..f6bbc228ae9 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.c +++ b/source/blender/gpu/intern/gpu_shader_interface.c @@ -29,6 +29,8 @@ * GPU shader interface (C --> GLSL) */ +#include "MEM_guardedalloc.h" + #include "GPU_shader_interface.h" #include "gpu_batch_private.h" @@ -154,7 +156,7 @@ GPU_INLINE void buckets_free(GPUShaderInput *buckets[GPU_NUM_SHADERINTERFACE_BUC GPUShaderInput *input = buckets[bucket_index]; while (input != NULL) { GPUShaderInput *input_next = input->next; - free(input); + MEM_freeN(input); input = input_next; } } @@ -178,12 +180,12 @@ static bool setup_builtin_uniform(GPUShaderInput *input, const char *name) static const GPUShaderInput *add_uniform(GPUShaderInterface *shaderface, const char *name) { - GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = MEM_mallocN(sizeof(GPUShaderInput), "GPUShaderInput Unif"); input->location = glGetUniformLocation(shaderface->program, name); uint name_len = strlen(name); - shaderface->name_buffer = realloc(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ + shaderface->name_buffer = MEM_reallocN(shaderface->name_buffer, shaderface->name_buffer_offset + name_len + 1); /* include NULL terminator */ char *name_buffer = shaderface->name_buffer + shaderface->name_buffer_offset; strcpy(name_buffer, name); @@ -208,7 +210,7 @@ static const GPUShaderInput *add_uniform(GPUShaderInterface *shaderface, const c GPUShaderInterface *GPU_shaderinterface_create(int32_t program) { - GPUShaderInterface *shaderface = calloc(1, sizeof(GPUShaderInterface)); + GPUShaderInterface *shaderface = MEM_callocN(sizeof(GPUShaderInterface), "GPUShaderInterface"); shaderface->program = program; #if DEBUG_SHADER_INTERFACE @@ -225,11 +227,11 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_len); const uint32_t name_buffer_len = attr_len * max_attrib_name_len + ubo_len * max_ubo_name_len; - shaderface->name_buffer = malloc(name_buffer_len); + shaderface->name_buffer = MEM_mallocN(name_buffer_len, "name_buffer"); /* Attributes */ for (uint32_t i = 0; i < attr_len; ++i) { - GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = MEM_mallocN(sizeof(GPUShaderInput), "GPUShaderInput Attr"); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char *name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; @@ -256,7 +258,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) } /* Uniform Blocks */ for (uint32_t i = 0; i < ubo_len; ++i) { - GPUShaderInput *input = malloc(sizeof(GPUShaderInput)); + GPUShaderInput *input = MEM_mallocN(sizeof(GPUShaderInput), "GPUShaderInput UBO"); GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset; char *name = shaderface->name_buffer + shaderface->name_buffer_offset; GLsizei name_len = 0; @@ -282,7 +284,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program) } /* Batches ref buffer */ shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = calloc(shaderface->batches_len, sizeof(GPUBatch *)); + shaderface->batches = MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *), "GPUShaderInterface batches"); return shaderface; } @@ -294,16 +296,16 @@ void GPU_shaderinterface_discard(GPUShaderInterface *shaderface) buckets_free(shaderface->attrib_buckets); buckets_free(shaderface->ubo_buckets); /* Free memory used by name_buffer. */ - free(shaderface->name_buffer); + MEM_freeN(shaderface->name_buffer); /* Remove this interface from all linked Batches vao cache. */ for (int i = 0; i < shaderface->batches_len; ++i) { if (shaderface->batches[i] != NULL) { gpu_batch_remove_interface_ref(shaderface->batches[i], shaderface); } } - free(shaderface->batches); + MEM_freeN(shaderface->batches); /* Free memory used by shader interface by its self. */ - free(shaderface); + MEM_freeN(shaderface); } const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *shaderface, const char *name) @@ -350,8 +352,7 @@ void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch /* Not enough place, realloc the array. */ i = shaderface->batches_len; shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT; - shaderface->batches = realloc(shaderface->batches, sizeof(GPUBatch *) * shaderface->batches_len); - memset(shaderface->batches + i, 0, sizeof(GPUBatch *) * GPU_SHADERINTERFACE_REF_ALLOC_COUNT); + shaderface->batches = MEM_recallocN(shaderface->batches, sizeof(GPUBatch *) * shaderface->batches_len); } shaderface->batches[i] = batch; } diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.c index d605378bf0e..05100b8a23f 100644 --- a/source/blender/gpu/intern/gpu_vertex_buffer.c +++ b/source/blender/gpu/intern/gpu_vertex_buffer.c @@ -29,6 +29,8 @@ * GPU vertex buffer */ +#include "MEM_guardedalloc.h" + #include "GPU_vertex_buffer.h" #include "gpu_context_private.h" @@ -53,7 +55,7 @@ static GLenum convert_usage_type_to_gl(GPUUsageType type) GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage) { - GPUVertBuf *verts = malloc(sizeof(GPUVertBuf)); + GPUVertBuf *verts = MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf"); GPU_vertbuf_init(verts, usage); return verts; } @@ -96,9 +98,9 @@ void GPU_vertbuf_discard(GPUVertBuf *verts) #endif } if (verts->data) { - free(verts->data); + MEM_freeN(verts->data); } - free(verts); + MEM_freeN(verts); } uint GPU_vertbuf_size_get(const GPUVertBuf *verts) @@ -123,7 +125,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) } /* discard previous data if any */ if (verts->data) { - free(verts->data); + MEM_freeN(verts->data); } #if VRAM_USAGE uint new_size = vertex_buffer_size(&verts->format, v_len); @@ -131,7 +133,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len) #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = malloc(sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); + verts->data = MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), "GPUVertBuf data"); } /* resize buffer keeping existing data */ @@ -148,7 +150,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len) #endif verts->dirty = true; verts->vertex_len = verts->vertex_alloc = v_len; - verts->data = realloc(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); + verts->data = MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts)); } /* Set vertex count but does not change allocation. @@ -250,7 +252,7 @@ static void VertBuffer_upload_data(GPUVertBuf *verts) glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_sz, verts->data); if (verts->usage == GPU_USAGE_STATIC) { - free(verts->data); + MEM_freeN(verts->data); verts->data = NULL; } verts->dirty = false; -- cgit v1.2.3 From 7e0eb0d071776ea938a70737fb3a0a9592264e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 31 Jul 2018 18:16:08 +0200 Subject: GPUFrameBuffer: Put active framebuffer in GPUContext instead of being ThreadLocal and leading to incorrect usage. We still enforce no framebuffer when changing context. We can lift this restriction later. --- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/gpu/GPU_framebuffer.h | 3 +- source/blender/gpu/intern/gpu_context.cpp | 12 ++++++ source/blender/gpu/intern/gpu_context_private.h | 3 ++ source/blender/gpu/intern/gpu_framebuffer.c | 54 ++++++++++++------------- source/blender/windowmanager/intern/wm_window.c | 12 +++--- 6 files changed, 50 insertions(+), 36 deletions(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 159f69d3226..0c731811f32 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1419,7 +1419,7 @@ void DRW_draw_render_loop_ex( DRW_hair_init(); /* No framebuffer allowed before drawing. */ - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); /* Init engines */ drw_engines_init(); diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 04357d6a927..ef49f9721dd 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -69,8 +69,7 @@ void GPU_framebuffer_restore(void); bool GPU_framebuffer_bound(GPUFrameBuffer *fb); bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]); -/* internal use only */ -unsigned int GPU_framebuffer_current_get(void); +GPUFrameBuffer *GPU_framebuffer_active_get(void); #define GPU_FRAMEBUFFER_FREE_SAFE(fb) do { \ if (fb != NULL) { \ diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp index 8d8f4d12b04..ce3eb64fa37 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -69,6 +69,7 @@ static std::mutex orphans_mutex; struct GPUContext { GLuint default_vao; + GPUFrameBuffer *current_fbo; std::unordered_set batches; /* Batches that have VAOs from this context */ #ifdef DEBUG std::unordered_set framebuffers; /* Framebuffers that have FBO from this context */ @@ -82,6 +83,7 @@ struct GPUContext { GPUContext() { thread_is_used = false; + current_fbo = 0; } #endif }; @@ -315,3 +317,13 @@ void gpu_context_remove_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb) UNUSED_VARS(ctx, fb); #endif } + +void gpu_context_active_framebuffer_set(GPUContext *ctx, GPUFrameBuffer *fb) +{ + ctx->current_fbo = fb; +} + +GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx) +{ + return ctx->current_fbo; +} diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h index 4881a892e38..762d9ff10c0 100644 --- a/source/blender/gpu/intern/gpu_context_private.h +++ b/source/blender/gpu/intern/gpu_context_private.h @@ -61,6 +61,9 @@ void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); void gpu_context_add_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); void gpu_context_remove_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); +void gpu_context_active_framebuffer_set(GPUContext *ctx, struct GPUFrameBuffer *fb); +struct GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index ba8dcb04269..56abe040f32 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -45,8 +45,6 @@ #include "gpu_private.h" #include "gpu_context_private.h" -static ThreadLocal(void *) g_currentfb; - typedef enum { GPU_FB_DEPTH_ATTACHMENT = 0, GPU_FB_DEPTH_STENCIL_ATTACHMENT, @@ -169,22 +167,29 @@ static void gpu_print_framebuffer_error(GLenum status, char err_out[256]) void gpu_framebuffer_module_init(void) { - BLI_thread_local_create(g_currentfb); } void gpu_framebuffer_module_exit(void) { - BLI_thread_local_delete(g_currentfb); } -static uint gpu_framebuffer_current_get(void) +GPUFrameBuffer *GPU_framebuffer_active_get(void) { - return GET_UINT_FROM_POINTER(BLI_thread_local_get(g_currentfb)); + GPUContext *ctx = GPU_context_active_get(); + if (ctx) { + return gpu_context_active_framebuffer_get(ctx); + } + else { + return 0; + } } -static void gpu_framebuffer_current_set(uint object) +static void gpu_framebuffer_current_set(GPUFrameBuffer *fb) { - BLI_thread_local_set(g_currentfb, SET_UINT_IN_POINTER(object)); + GPUContext *ctx = GPU_context_active_get(); + if (ctx) { + gpu_context_active_framebuffer_set(ctx, fb); + } } /* GPUFrameBuffer */ @@ -217,8 +222,8 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb) gpu_context_remove_framebuffer(fb->ctx, fb); } - if (gpu_framebuffer_current_get() == fb->object) { - gpu_framebuffer_current_set(0); + if (GPU_framebuffer_active_get() == fb) { + gpu_framebuffer_current_set(NULL); } MEM_freeN(fb); @@ -371,7 +376,7 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb) GLenum gl_attachments[GPU_FB_MAX_COLOR_ATTACHMENT]; int numslots = 0; - BLI_assert(gpu_framebuffer_current_get() == fb->object); + BLI_assert(GPU_framebuffer_active_get() == fb); /* Update attachments */ for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; ++type) { @@ -415,10 +420,10 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) if (fb->object == 0) gpu_framebuffer_init(fb); - if (gpu_framebuffer_current_get() != fb->object) + if (GPU_framebuffer_active_get() != fb) glBindFramebuffer(GL_FRAMEBUFFER, fb->object); - gpu_framebuffer_current_set(fb->object); + gpu_framebuffer_current_set(fb); if (fb->dirty_flag != 0) gpu_framebuffer_update_attachments(fb); @@ -439,20 +444,15 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) void GPU_framebuffer_restore(void) { - if (gpu_framebuffer_current_get() != 0) { + if (GPU_framebuffer_active_get() != NULL) { glBindFramebuffer(GL_FRAMEBUFFER, 0); - gpu_framebuffer_current_set(0); + gpu_framebuffer_current_set(NULL); } } bool GPU_framebuffer_bound(GPUFrameBuffer *fb) { - return (fb->object == gpu_framebuffer_current_get()) && (fb->object != 0); -} - -unsigned int GPU_framebuffer_current_get(void) -{ - return gpu_framebuffer_current_get(); + return (fb == GPU_framebuffer_active_get()) && (fb->object != 0); } bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]) @@ -543,7 +543,7 @@ void GPU_framebuffer_blit( { BLI_assert(blit_buffers != 0); - GLuint prev_fb = gpu_framebuffer_current_get(); + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); /* Framebuffers must be up to date. This simplify this function. */ if (fb_read->dirty_flag != 0 || fb_read->object == 0) { @@ -601,11 +601,11 @@ void GPU_framebuffer_blit( mask, GL_NEAREST); /* Restore previous framebuffer */ - if (fb_write->object == prev_fb) { + if (fb_write == prev_fb) { GPU_framebuffer_bind(fb_write); /* To update drawbuffers */ } else { - glBindFramebuffer(GL_FRAMEBUFFER, prev_fb); + glBindFramebuffer(GL_FRAMEBUFFER, prev_fb->object); gpu_framebuffer_current_set(prev_fb); } } @@ -619,13 +619,13 @@ void GPU_framebuffer_recursive_downsample( void (*callback)(void *userData, int level), void *userData) { /* Framebuffer must be up to date and bound. This simplify this function. */ - if (gpu_framebuffer_current_get() != fb->object || fb->dirty_flag != 0 || fb->object == 0) { + if (GPU_framebuffer_active_get() != fb || fb->dirty_flag != 0 || fb->object == 0) { GPU_framebuffer_bind(fb); } /* HACK: We make the framebuffer appear not bound in order to * not trigger any error in GPU_texture_bind(). */ - GLuint prev_fb = gpu_framebuffer_current_get(); - gpu_framebuffer_current_set(0); + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); + gpu_framebuffer_current_set(NULL); int i; int current_dim[2] = {fb->width, fb->height}; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 3083607b8a9..f391c92b4ca 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1113,7 +1113,7 @@ void wm_window_clear_drawable(wmWindowManager *wm) void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) { - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); if (win != wm->windrawable && win->ghostwin) { // win->lmbut = 0; /* keeps hanging when mousepressed while other window opened */ @@ -1134,7 +1134,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) void wm_window_reset_drawable(void) { BLI_assert(BLI_thread_is_main()); - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); wmWindowManager *wm = G_MAIN->wm.first; if (wm == NULL) @@ -2280,24 +2280,24 @@ void *WM_opengl_context_create(void) * So we should call this function only on the main thread. */ BLI_assert(BLI_thread_is_main()); - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); return GHOST_CreateOpenGLContext(g_system); } void WM_opengl_context_dispose(void *context) { - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); GHOST_DisposeOpenGLContext(g_system, (GHOST_ContextHandle)context); } void WM_opengl_context_activate(void *context) { - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); GHOST_ActivateOpenGLContext((GHOST_ContextHandle)context); } void WM_opengl_context_release(void *context) { - BLI_assert(GPU_framebuffer_current_get() == 0); + BLI_assert(GPU_framebuffer_active_get() == NULL); GHOST_ReleaseOpenGLContext((GHOST_ContextHandle)context); } -- cgit v1.2.3 From 6ba70d5996a4fdb82516d199dacfee066f2b3bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 31 Jul 2018 18:20:57 +0200 Subject: Fix crash when rendering viewport within another area This also Fix T55574 Crash on sequencer preview --- source/blender/editors/space_view3d/view3d_draw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0157bc567ca..46b53a369e3 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1412,6 +1412,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( ofs = NULL; } + GPUFrameBuffer *old_fb = GPU_framebuffer_active_get(); + + if (old_fb) { + GPU_framebuffer_restore(); + } + const bool own_ofs = (ofs == NULL); DRW_opengl_context_enable(); @@ -1556,6 +1562,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( DRW_opengl_context_disable(); + if (old_fb) { + GPU_framebuffer_bind(old_fb); + } + if (ibuf->rect_float && ibuf->rect) IMB_rect_from_float(ibuf); -- cgit v1.2.3 From d940a081a9f1f4106a5d2d155682695b0a6b0cb6 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 26 Jun 2018 13:53:54 -0400 Subject: Gitignore: Ignore diffs in all subdirs --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 814b7661bc6..ff0ba8c2350 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,8 @@ Desktop.ini /BUILD_NOTES.txt # local patches -/*.patch -/*.diff +*.patch +*.diff # in-source doc-gen /doc/doxygen/html/ -- cgit v1.2.3 From d5724bfaa760801377db4d5cc4071aef42491439 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 31 Jul 2018 13:03:48 -0400 Subject: Revert "Gitignore: Ignore diffs in all subdirs" This is an issue for some file in the extern dir This reverts commit d940a081a9f1f4106a5d2d155682695b0a6b0cb6. --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ff0ba8c2350..814b7661bc6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,8 @@ Desktop.ini /BUILD_NOTES.txt # local patches -*.patch -*.diff +/*.patch +/*.diff # in-source doc-gen /doc/doxygen/html/ -- cgit v1.2.3 From 3667a5402e3d548073b4a9c031868dd0e55ed72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 31 Jul 2018 20:10:14 +0200 Subject: KnifeTool: Use GPUBatch API instead of IMM to fix buffer overflow issue This also include a small optimisation (remove of a double loop and half of the memory allocation for hit points) This should fix T55946 Crash using knife tool on mesh with large number of vertices. Tried with a 500K vert suzanne and it seems fine. --- source/blender/editors/mesh/editmesh_knife.c | 57 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 61f55451b17..c98aef74ae7 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1040,7 +1040,6 @@ static void knife_init_colors(KnifeColors *colors) static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { const KnifeTool_OpData *kcd = arg; - GPU_depth_test(false); glPolygonOffset(1.0f, 1.0f); @@ -1052,7 +1051,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void knifetool_draw_angle_snapping(kcd); } - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -1113,40 +1113,43 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void if (kcd->totlinehit > 0) { KnifeLineHit *lh; - int i; + int i, v, vs; + float fcol[4]; GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - /* draw any snapped verts first */ - immUniformColor4ubv(kcd->colors.point_a); - GPU_point_size(11); - - immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); + GPUVertBuf *vert = GPU_vertbuf_create_with_format(format); + GPU_vertbuf_data_alloc(vert, kcd->totlinehit); lh = kcd->linehits; - for (i = 0; i < kcd->totlinehit; i++, lh++) { + for (i = 0, v = 0, vs = kcd->totlinehit - 1; i < kcd->totlinehit; i++, lh++) { if (lh->v) { - immVertex3fv(pos, lh->cagehit); + GPU_vertbuf_attr_set(vert, pos, v++, lh->cagehit); + } + else { + GPU_vertbuf_attr_set(vert, pos, vs--, lh->cagehit); } } - immEnd(); + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); + + /* draw any snapped verts first */ + rgba_uchar_to_float(fcol, kcd->colors.point_a); + GPU_batch_uniform_4fv(batch, "color", fcol); + GPU_matrix_bind(batch->interface); + GPU_point_size(11); + GPU_batch_draw_range_ex(batch, 0, v - 1, false); /* now draw the rest */ - immUniformColor4ubv(kcd->colors.curpoint_a); + rgba_uchar_to_float(fcol, kcd->colors.curpoint_a); + GPU_batch_uniform_4fv(batch, "color", fcol); GPU_point_size(7); + GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false); - immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); - - lh = kcd->linehits; - for (i = 0; i < kcd->totlinehit; i++, lh++) { - if (!lh->v) { - immVertex3fv(pos, lh->cagehit); - } - } - - immEnd(); + GPU_batch_program_use_end(batch); + GPU_batch_discard(batch); GPU_blend(false); } @@ -1158,7 +1161,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.line); GPU_line_width(1.0); - immBeginAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); + GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { @@ -1170,6 +1173,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void } immEnd(); + + GPU_batch_draw(batch); + GPU_batch_discard(batch); } if (kcd->totkvert > 0) { @@ -1179,7 +1185,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.point); GPU_point_size(5.0); - immBeginAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); + GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); BLI_mempool_iternew(kcd->kverts, &iter); for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { @@ -1190,6 +1196,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void } immEnd(); + + GPU_batch_draw(batch); + GPU_batch_discard(batch); } immUnbindProgram(); -- cgit v1.2.3 From 7b72be0134887622518f1fb6d6009fa67bf41593 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 31 Jul 2018 22:27:13 +0200 Subject: Fix T56181: Annotations hide proportionnal editing UI buttons --- release/scripts/startup/bl_ui/space_view3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index fca37499da0..83bc10a78d9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -181,7 +181,7 @@ class VIEW3D_HT_header(Header): # Proportional editing if obj: gpd = context.gpencil_data - if gpd is not None: + if gpd is not None and obj.type == 'GPENCIL': if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode: row = layout.row(align=True) row.prop(tool_settings, "proportional_edit", icon_only=True) -- cgit v1.2.3 From e8d58080df07d4b7d9372bfca0dd54ea2817394a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 08:08:59 +1000 Subject: DNA: remove View3D.flag3 Having 'flag, flag2, flag3' is getting out of hand especially when we support increasing the size of types. Make flag2 into an int. Note, this looses the 'show world' option, but it's not such an important setting. --- source/blender/editors/space_view3d/space_view3d.c | 2 +- source/blender/editors/space_view3d/view3d_draw.c | 4 ++-- source/blender/makesdna/DNA_view3d_types.h | 15 +++++++-------- source/blender/makesrna/intern/rna_space.c | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 63ae3bbb657..7f3a36c7ba6 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1238,7 +1238,7 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot switch (wmn->data) { case ND_WORLD_DRAW: case ND_WORLD: - if (v3d->flag3 & V3D_SHOW_WORLD) + if (v3d->flag2 & V3D_SHOW_WORLD) ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW); break; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index fbf2bd33638..1cf2e71f2bf 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3091,7 +3091,7 @@ void ED_view3d_draw_offscreen_init(Main *bmain, Scene *scene, View3D *v3d) */ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) { - if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) { + if (scene->world && (v3d->flag2 & V3D_SHOW_WORLD)) { RegionView3D *rv3d = ar->regiondata; GPUMaterial *gpumat = GPU_material_world(scene, scene->world); @@ -3497,7 +3497,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( v3d.flag2 |= V3D_SOLID_TEX; } if (draw_flags & V3D_OFSDRAW_USE_BACKGROUND) { - v3d.flag3 |= V3D_SHOW_WORLD; + v3d.flag2 |= V3D_SHOW_WORLD; } if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) { if (camera->type == OB_CAMERA) { diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 845e7ab3658..1b3eef0f3ec 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -182,10 +182,11 @@ typedef struct View3D { /** * The drawing mode for the 3d display. Set to OB_BOUNDBOX, OB_WIRE, OB_SOLID, * OB_TEXTURE, OB_MATERIAL or OB_RENDER */ - short drawtype; - short ob_centre_cursor; /* optional bool for 3d cursor to define center */ + char drawtype; + char ob_centre_cursor; /* optional bool for 3d cursor to define center */ short scenelock, around; - short flag, flag2; + short flag; + int flag2; float lens, grid; float near, far; @@ -201,7 +202,7 @@ typedef struct View3D { /* transform widget info */ char twtype, twmode, twflag; - short flag3; + short _pad1; /* afterdraw, for xray & transparent */ struct ListBase afterdraw_transp; @@ -297,7 +298,7 @@ typedef struct View3D { #define RV3D_VIEW_IS_AXIS(view) \ (((view) >= RV3D_VIEW_FRONT) && ((view) <= RV3D_VIEW_BOTTOM)) -/* View3d->flag2 (short) */ +/* View3d->flag2 (int) */ #define V3D_RENDER_OVERRIDE (1 << 2) #define V3D_SOLID_TEX (1 << 3) #define V3D_SHOW_GPENCIL (1 << 4) @@ -312,11 +313,9 @@ typedef struct View3D { #define V3D_SHOW_SOLID_MATCAP (1 << 13) /* runtime flag */ #define V3D_OCCLUDE_WIRE (1 << 14) #define V3D_SHADELESS_TEX (1 << 15) +#define V3D_SHOW_WORLD (1 << 16) -/* View3d->flag3 (short) */ -#define V3D_SHOW_WORLD (1 << 0) - /* View3D->around */ enum { /* center of the bounding box */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 813e847aae6..ae1761faec1 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2621,7 +2621,7 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_WORLD); RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); -- cgit v1.2.3 From 6a39d7255848511f231085bfb70c7daea8f0ca59 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 08:57:31 +1000 Subject: Cleanup: declare vars or make static --- source/blender/makesrna/intern/rna_rigidbody.c | 2 +- source/blender/python/generic/imbuf_py_api.h | 2 ++ source/blender/python/intern/bpy_driver.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 853b1d9978c..5b86ec6b10d 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -77,7 +77,7 @@ const EnumPropertyItem rna_enum_rigidbody_constraint_type_items[] = { {0, NULL, 0, NULL, NULL}}; /* bullet spring type */ -const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = { +static const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = { {RBC_SPRING_TYPE1, "SPRING1", ICON_NONE, "Blender 2.7", "Spring implementation used in blender 2.7. Damping is capped at 1.0"}, {RBC_SPRING_TYPE2, "SPRING2", ICON_NONE, "Blender 2.8", "New implementation available since 2.8"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/python/generic/imbuf_py_api.h b/source/blender/python/generic/imbuf_py_api.h index 92c1732a9c9..35adc541bfc 100644 --- a/source/blender/python/generic/imbuf_py_api.h +++ b/source/blender/python/generic/imbuf_py_api.h @@ -27,4 +27,6 @@ PyObject *BPyInit_imbuf(void); +extern PyTypeObject Py_ImBuf_Type; + #endif /* __IMBUF_PY_API_H__ */ diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index f6ff1b3f36b..e7608e93f58 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -252,7 +252,7 @@ static void pydriver_error(ChannelDriver *driver) #define OK_OP(op) [op] = 1 -const char secure_opcodes[255] = { +static const char secure_opcodes[255] = { OK_OP(POP_TOP), OK_OP(ROT_TWO), OK_OP(ROT_THREE), -- cgit v1.2.3 From f4a06b390ba779bd4dbd57ffb9121df53e343dc3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 12:19:46 +1000 Subject: Keymap: use Q key for quick menu in gpencil mode Note, the keys for changing line display are now more obscure (Shift-Q, Shift-Alt-Q), and might be changed. --- source/blender/editors/gpencil/gpencil_ops.c | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 43ccc77e921..3a86b0c13ef 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -248,7 +248,17 @@ static void ed_keymap_gpencil_selection(wmKeyMap *keymap) /* select more/less */ WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); +} +static void ed_keymap_gpencil_display(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); } static void ed_keymap_gpencil_sculpt(wmKeyMap *keymap) @@ -403,11 +413,8 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "GPENCIL_OT_selection_opacity_toggle", HKEY, KM_PRESS, KM_CTRL, 0); - /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); + /* Display. */ + ed_keymap_gpencil_display(keymap); /* Isolate Layer */ WM_keymap_add_item(keymap, "GPENCIL_OT_layer_isolate", PADASTERKEY, KM_PRESS, 0, 0); @@ -592,7 +599,6 @@ static void ed_keymap_gpencil_painting(wmKeyConfig *keyconf) static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf) { wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Sculpt Mode", 0, 0); - wmKeyMapItem *kmi; /* set poll callback - so that this keymap only gets enabled when stroke sculptmode is enabled */ keymap->poll = gp_stroke_sculptmode_poll; @@ -603,11 +609,8 @@ static void ed_keymap_gpencil_sculpting(wmKeyConfig *keyconf) /* sculpt */ ed_keymap_gpencil_sculpt(keymap); - /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); + /* Display. */ + ed_keymap_gpencil_display(keymap); } /* Stroke Weight Paint Keymap - Only when weight is enabled */ @@ -633,11 +636,8 @@ static void ed_keymap_gpencil_weightpainting(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.weight_brush.size"); - /* toogle multiedit support */ - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_edit_lines"); - kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", QKEY, KM_PRESS, KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "data_path", "space_data.overlay.use_gpencil_multiedit_line_only"); + /* Display. */ + ed_keymap_gpencil_display(keymap); } /* ==================== */ -- cgit v1.2.3 From e665e012e955460ab40aea54ad8533f697c4aa56 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 12:24:32 +1000 Subject: UI: correct grease pencil placement text --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 90b04104444..98530aea2d2 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -195,7 +195,7 @@ class _defs_annotate: layout.separator() row = layout.row(align=True) - row.prop(ts, "annotation_stroke_placement_view3d", text="Orientation") + row.prop(ts, "annotation_stroke_placement_view3d", text="Placement") if ts.gpencil_stroke_placement_view3d == 'CURSOR': row.prop(ts.gpencil_sculpt, "lockaxis") elif ts.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}: -- cgit v1.2.3 From 5f55bbf3d07db4f1b89921cbe742873fd5645e11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 16:02:20 +1000 Subject: RNA: add space_type to tool --- source/blender/makesrna/intern/rna_workspace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/makesrna/intern/rna_workspace.c b/source/blender/makesrna/intern/rna_workspace.c index 166d71689d1..88b79e8ee32 100644 --- a/source/blender/makesrna/intern/rna_workspace.c +++ b/source/blender/makesrna/intern/rna_workspace.c @@ -224,6 +224,12 @@ static void rna_def_workspace_tool(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Index", ""); RNA_def_property_int_funcs(prop, "rna_WorkspaceTool_index_get", NULL, NULL); + prop = RNA_def_property(srna, "space_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "space_type"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_enum_items(prop, rna_enum_space_type_items); + RNA_def_property_ui_text(prop, "Space Type", ""); + RNA_api_workspace_tool(srna); } -- cgit v1.2.3 From d6d29f9854298c2a8dda9bf0ed339fdfbd7f0337 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 16:04:21 +1000 Subject: UI: add 3D view check for grease pencil tool --- release/scripts/startup/bl_ui/space_toolsystem_toolbar.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 98530aea2d2..8ce4a52fbbc 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -188,10 +188,8 @@ class _defs_annotate: def draw_settings_common(cls, context, layout, tool): ts = context.tool_settings - # For 3D view, show the stroke placement settings - # XXX: How to tell what editor the active tool comes from? - is_3d_view = True - if is_3d_view: + space_type = tool.space_type + if space_type == 'VIEW_3D': layout.separator() row = layout.row(align=True) -- cgit v1.2.3 From 583b2f9a3d9d49a23e525b998c4b1893befa8dd0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Aug 2018 16:32:22 +1000 Subject: Cleanup: remove unused array member --- source/blender/blenlib/intern/math_geom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 61b8f6819cc..356740b138f 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2486,19 +2486,19 @@ bool isect_ray_aabb_v3_simple( const float bb_min[3], const float bb_max[3], float *tmin, float *tmax) { - double t[7]; + double t[6]; float hit_dist[2]; const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX; const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX; const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX; - t[1] = (double)(bb_min[0] - orig[0]) * invdirx; - t[2] = (double)(bb_max[0] - orig[0]) * invdirx; - t[3] = (double)(bb_min[1] - orig[1]) * invdiry; - t[4] = (double)(bb_max[1] - orig[1]) * invdiry; - t[5] = (double)(bb_min[2] - orig[2]) * invdirz; - t[6] = (double)(bb_max[2] - orig[2]) * invdirz; - hit_dist[0] = (float)fmax(fmax(fmin(t[1], t[2]), fmin(t[3], t[4])), fmin(t[5], t[6])); - hit_dist[1] = (float)fmin(fmin(fmax(t[1], t[2]), fmax(t[3], t[4])), fmax(t[5], t[6])); + t[0] = (double)(bb_min[0] - orig[0]) * invdirx; + t[1] = (double)(bb_max[0] - orig[0]) * invdirx; + t[2] = (double)(bb_min[1] - orig[1]) * invdiry; + t[3] = (double)(bb_max[1] - orig[1]) * invdiry; + t[4] = (double)(bb_min[2] - orig[2]) * invdirz; + t[5] = (double)(bb_max[2] - orig[2]) * invdirz; + hit_dist[0] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); + hit_dist[1] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) { return false; } -- cgit v1.2.3 From c06bed25c70cb80657447e510890b29ceb6bbc1b Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 1 Aug 2018 10:17:05 +0200 Subject: Fix T56187: Crash using cursor tool in Edit/Sculpt and Weight Paint mode The transform tried to calculate the multiframe falloff, but there was not any stroke to do that. --- source/blender/editors/transform/transform.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b0de996ee0e..85229ddd041 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4636,7 +4636,12 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) if (t->options & CTX_GPENCIL_STROKES) { /* grease pencil multiframe falloff */ bGPDstroke *gps = (bGPDstroke *)td->extra; - mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff); + if (gps != NULL) { + mul_v3_fl(tvec, td->factor * gps->runtime.multi_frame_falloff); + } + else { + mul_v3_fl(tvec, td->factor); + } } else { /* proportional editing falloff */ -- cgit v1.2.3 From af79ac944d7b14f8ce24548345cac5a34ff4de55 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 1 Aug 2018 10:39:16 +0200 Subject: Cleanup: Replace "Move Color" to "Assign Material" --- release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 4 ++-- source/blender/editors/gpencil/gpencil_data.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 412071a642e..b291cc7bd82 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -204,7 +204,7 @@ class GreasePencilStrokeEditPanel: layout.separator() col = layout.column(align=True) col.operator_menu_enum("gpencil.stroke_arrange", text="Arrange Strokes...", property="direction") - col.operator("gpencil.stroke_change_color", text="Move to Color") + col.operator("gpencil.stroke_change_color", text="Assign Material") layout.separator() col = layout.column(align=True) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83bc10a78d9..ab01560351c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3583,7 +3583,7 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator("gpencil.stroke_change_color", text="Change Color") + layout.operator("gpencil.stroke_change_color", text="Assign Material") layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") layout.separator() @@ -3633,7 +3633,7 @@ class VIEW3D_MT_sculpt_gpencil(Menu): layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator("gpencil.stroke_change_color", text="Change Color") + layout.operator("gpencil.stroke_change_color", text="Assign Material") layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") layout.separator() diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index c58c45b3117..01cf8aeb7f1 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1192,7 +1192,7 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot) /* identifiers */ ot->name = "Change Stroke Color"; ot->idname = "GPENCIL_OT_stroke_change_color"; - ot->description = "Move selected strokes to active color"; + ot->description = "Move selected strokes to active material"; /* callbacks */ ot->exec = gp_stroke_change_color_exec; -- cgit v1.2.3 From 20e5fc4d328bf566841f22b16de809da8de15bf7 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 1 Aug 2018 10:58:10 +0200 Subject: Fix context problem when render in background mode Bug reported by Sergey. --- source/blender/draw/intern/draw_manager.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 0c731811f32..ab50e6673f2 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1659,7 +1659,24 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph Render *render = engine->re; /* Changing Context */ /* GPXX Review this context */ - DRW_opengl_context_enable(); + if (G.background && DST.gl_context == NULL) { + WM_init_opengl(G_MAIN); + } + + void *re_gl_context = RE_gl_context_get(render); + void *re_gpu_context = NULL; + + /* Changing Context */ + if (re_gl_context != NULL) { + DRW_opengl_render_context_enable(re_gl_context); + /* We need to query gpu context after a gl context has been bound. */ + re_gpu_context = RE_gpu_context_get(render); + DRW_gawain_render_context_enable(re_gpu_context); + } + else { + DRW_opengl_context_enable(); + } + /* Reset before using it. */ drw_state_prepare_clean_for_draw(&DST); DST.options.is_image_render = true; -- cgit v1.2.3 From ddd62f1b1063d69df5171c7b3457ffcffcc6b0e4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 1 Aug 2018 11:21:37 +0200 Subject: Cleanup: Remove ToDo comment --- source/blender/draw/intern/draw_manager.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index ab50e6673f2..ba53c3aa664 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1658,7 +1658,6 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph RenderData *r = &scene->r; Render *render = engine->re; /* Changing Context */ - /* GPXX Review this context */ if (G.background && DST.gl_context == NULL) { WM_init_opengl(G_MAIN); } -- cgit v1.2.3 From ef8ab3b4c2aa4b709acf6b4c8263ceb6d6f515de Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Aug 2018 14:20:04 +0200 Subject: Fix issues after last 2.8 merge. --- source/blender/editors/mesh/editmesh_tools.c | 12 ++++++------ source/blender/modifiers/intern/MOD_bevel.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 0d11bf80366..d327e270a35 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7358,7 +7358,7 @@ static int edbm_point_normals_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool point_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool point_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); @@ -7380,7 +7380,7 @@ static void edbm_point_normals_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, point_normals_draw_check_prop, '\0', false); + uiDefAutoButsRNA(layout, &ptr, point_normals_draw_check_prop, NULL, '\0', false); } void MESH_OT_point_normals(struct wmOperatorType *ot) @@ -7751,7 +7751,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool average_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool average_normals_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); const int average_type = RNA_enum_get(ptr, "average_type"); @@ -7777,7 +7777,7 @@ static void edbm_average_normals_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, average_normals_draw_check_prop, '\0', false); + uiDefAutoButsRNA(layout, &ptr, average_normals_draw_check_prop, NULL, '\0', false); } void MESH_OT_average_normals(struct wmOperatorType *ot) @@ -7943,7 +7943,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static bool normals_tools_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop) +static bool normals_tools_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); const int mode = RNA_enum_get(ptr, "mode"); @@ -7966,7 +7966,7 @@ static void edbm_normals_tools_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, normals_tools_draw_check_prop, '\0', false); + uiDefAutoButsRNA(layout, &ptr, normals_tools_draw_check_prop, NULL, '\0', false); } void MESH_OT_normals_tools(struct wmOperatorType *ot) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 1ada8b215c5..cf0753334db 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -233,7 +233,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *bm) { const bool vertex_only = (bmd->flags & MOD_BEVEL_VERT) != 0; - if (bmd->value == 0 || bmd->clnordata.faceHash == NULL && vertex_only) + if (bmd->value == 0 || (bmd->clnordata.faceHash == NULL && vertex_only)) return; BM_mesh_normals_update(bm); -- cgit v1.2.3 From 9a43ebdd5b5e7c8f4a4202d7eb2bcb3e33a2d76e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Aug 2018 14:29:36 +0200 Subject: Fix more merge stupid leftover, and some build warnings. --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 1 - source/blender/modifiers/intern/MOD_bevel.c | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 6110d0fca61..66bf08ed8d8 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1615,7 +1615,6 @@ class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel): # Grease Pencil create shapes class VIEW3D_PT_tools_grease_pencil_shapes(View3DPanel, Panel): ->>>>>>> blender2.8 bl_space_type = 'VIEW_3D' bl_region_type = 'HEADER' bl_label = "Shapes" diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index cf0753334db..3db4089138b 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -143,13 +143,14 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl BMEdge *e_next; const BMEdge *e_org = l_cur->e; BMLoop *lfan_pivot, *lfan_pivot_next; + UNUSED_VARS_NDEBUG(v_pivot); lfan_pivot = l_cur; e_next = lfan_pivot->e; BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; int recon_face_count = 0; /* Reconstructed face */ - BMFace *recon_face; + BMFace *recon_face = NULL; while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); @@ -165,7 +166,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { int weight = BM_elem_float_data_get(&bm->edata, lfan_pivot->f, CD_BWEIGHT); if (weight) { - if (bmd->hnmode == MOD_BEVEL_HN_FACE) { + if (hnmode == MOD_BEVEL_HN_FACE) { float cur[3]; mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); @@ -180,7 +181,7 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl else if (bmd->lim_flags & MOD_BEVEL_VGROUP) { const bool has_vgroup = dvert != NULL; const bool vert_of_group = has_vgroup && defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL; - if (vert_of_group && bmd->hnmode == MOD_BEVEL_HN_FACE) { + if (vert_of_group && hnmode == MOD_BEVEL_HN_FACE) { float cur[3]; mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); -- cgit v1.2.3 From cc004fd13cc6d5cf77d8bb1e33594662d63c7b13 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Aug 2018 14:37:24 +0200 Subject: Some more minor typo fixes in comments. --- source/blender/blenkernel/intern/editmesh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index a7f93ca6c49..00e508e4d8f 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -251,10 +251,10 @@ void BKE_editmesh_lnorspace_update(BMEditMesh *em) { BMesh *bm = em->bm; - /* We need to create clnors data is none exist yet, otherwise there is no way to edit them. */ + /* We need to create clnors data if none exist yet, otherwise there is no way to edit them. */ /* Similar code to MESH_OT_customdata_custom_splitnormals_add operator, we want to keep same shading * in case we were using autosmooth so far... */ - /* Note: there is a problem here, which is that is someone starts a normal editing operation on previously + /* Note: there is a problem here, which is that if someone starts a normal editing operation on previously * autosmooth-ed mesh, and cancel that operation, generated clnors data remain, with related sharp edges * (and hence autosmooth is 'lost'). * Not sure how critical this is, and how to fix that issue? */ -- cgit v1.2.3 From c48eb521642b5d94e5f0eb8fd15f7d587f407078 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 1 Aug 2018 14:21:50 +0200 Subject: Fix Cycles headless render failing, after grease pencil merge. Now it should at least succeed when there are no grease pencil objects. --- source/blender/draw/intern/draw_manager.c | 24 ++++++++++++++-------- .../blender/render/intern/source/external_engine.c | 8 +++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index ba53c3aa664..5140e379aaf 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1619,11 +1619,11 @@ void DRW_draw_render_loop_offscreen( } /* helper to check if exit object type to render */ -static bool DRW_render_check_object_type(struct Depsgraph *depsgraph, short obtype) +static bool DRW_render_check_grease_pencil(Depsgraph *depsgraph) { DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) { - if ((ob->type == obtype) && (DRW_check_object_visible_within_active_context(ob))) { + if ((ob->type == OB_GPENCIL) && (DRW_check_object_visible_within_active_context(ob))) { return true; } } @@ -1632,13 +1632,11 @@ static bool DRW_render_check_object_type(struct Depsgraph *depsgraph, short obty return false; } -static void DRW_render_gpencil_to_image(RenderEngine *engine, struct Depsgraph *depsgraph, struct RenderLayer *render_layer, const rcti *rect) +static void DRW_render_gpencil_to_image(RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect) { if (draw_engine_gpencil_type.render_to_image) { - if (DRW_render_check_object_type(depsgraph, OB_GPENCIL)) { - ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type); - draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect); - } + ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type); + draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect); } } @@ -1652,6 +1650,12 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph return; } + /* Early out if there are no grease pencil objects, especially important + * to avoid failing in in background renders without OpenGL context. */ + if (!DRW_render_check_grease_pencil(depsgraph)) { + return; + } + Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RenderEngineType *engine_type = engine->type; @@ -1712,7 +1716,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph RenderResult *render_result = RE_engine_get_result(engine); RenderLayer *render_layer = render_result->layers.first; - DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); + DRW_render_gpencil_to_image(engine, render_layer, &render_rect); /* Force cache to reset. */ drw_viewport_cache_resize(); @@ -1814,7 +1818,9 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) RE_SetActiveRenderView(render, render_view->name); engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect); /* grease pencil: render result is merged in the previous render result. */ - DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); + if (DRW_render_check_grease_pencil(depsgraph)) { + DRW_render_gpencil_to_image(engine, render_layer, &render_rect); + } DST.buffer_finish_called = false; } diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 0b27cadd086..09ab3e39d5f 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -740,9 +740,15 @@ int RE_engine_render(Render *re, int do_all) type->render(engine, engine->depsgraph); /* grease pencil render over previous render result */ - DRW_render_gpencil(engine, engine->depsgraph); + if (!RE_engine_test_break(engine)) { + DRW_render_gpencil(engine, engine->depsgraph); + } engine_depsgraph_free(engine); + + if (RE_engine_test_break(engine)) { + break; + } } FOREACH_VIEW_LAYER_TO_RENDER_END; } -- cgit v1.2.3 From 9336aef4eb279804ee5cccec63d818810233e6c5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Aug 2018 16:12:36 +0200 Subject: Fix T56195: Typo in BLI_array_utils.h. --- source/blender/blenlib/BLI_array_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/BLI_array_utils.h b/source/blender/blenlib/BLI_array_utils.h index 9a510bcfc3b..da03063b245 100644 --- a/source/blender/blenlib/BLI_array_utils.h +++ b/source/blender/blenlib/BLI_array_utils.h @@ -41,7 +41,7 @@ void _bli_array_permute( const unsigned int *index, void *arr_temp); #define BLI_array_permute(arr, arr_len, order) \ _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, NULL) -#define BLI_array_permute_ex(arr, arr_len, index, arr_temp) \ +#define BLI_array_permute_ex(arr, arr_len, order, arr_temp) \ _bli_array_permute(arr, arr_len, sizeof(*(arr)), order, arr_temp) int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p); -- cgit v1.2.3 From 110abebe1d4a4fe4667b42ad47adcf33bfcafad0 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 1 Aug 2018 17:28:30 +0200 Subject: Fix missing poll function for flip_matcap operator (see T56183). --- source/blender/editors/space_view3d/view3d_header.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index c9277235d50..da449fac183 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -245,6 +245,7 @@ void VIEW3D_OT_toggle_matcap_flip(wmOperatorType *ot) /* api callbacks */ ot->exec = toggle_matcap_flip; + ot->poll = ED_operator_view3d_active; } /** \} */ -- cgit v1.2.3 From 63dc52c66e25b49c659c52e4064b78e0ed90f2f9 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 10:42:18 +0200 Subject: Subsurf: Cleanup, remove dead code --- source/blender/blenkernel/intern/subdiv_mesh.c | 42 -------------------------- 1 file changed, 42 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index db7366a2414..33813905105 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -379,47 +379,6 @@ static void loops_of_ptex_get( } } -/* ============================================================================= - * Edge custom data copy helpers. - */ - -#if 0 - -typedef struct EdgesOfPtex { - /* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */ - const MEdge *first_edge; - /* Last edge of the ptex, starts at ptex (0, 0) and goes in v direction. */ - const MEdge *last_edge; - /* For quad coarse faces only. */ - const MEdge *second_edge; - const MEdge *third_edge; -} EdgesOfPtex; - -static void edges_of_ptex_get( - const SubdivMeshContext *ctx, - EdgesOfPtex *edges_of_ptex, - const MPoly *coarse_poly, - const int ptex_face_index) -{ - const MEdge *coarse_medge = ctx->coarse_mesh->medge; - LoopsOfPtex loops_of_ptex; - loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, ptex_face_index); - edges_of_ptex->first_edge = &coarse_medge[loops_of_ptex.first_loop->e]; - edges_of_ptex->last_edge = &coarse_medge[loops_of_ptex.last_loop->e]; - if (coarse_poly->totloop == 4) { - edges_of_ptex->second_edge = - &coarse_medge[loops_of_ptex.second_loop->e]; - edges_of_ptex->third_edge = - &coarse_medge[loops_of_ptex.third_loop->e]; - } - else { - edges_of_ptex->second_edge = NULL; - edges_of_ptex->third_edge = NULL; - } -} - -#endif - /* ============================================================================= * Vertex custom data interpolation helpers. */ @@ -2258,7 +2217,6 @@ Mesh *BKE_subdiv_to_mesh( const SubdivToMeshSettings *settings, const Mesh *coarse_mesh) { - // printf("================ MESH SUBDIVISION ================\n"); BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH); /* Make sure evaluator is up to date with possible new topology, and that * is is refined for the new positions of coarse vertices. -- cgit v1.2.3 From 9e2f678ba25cb292257fc9949373917ec48a6d46 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 10:52:01 +0200 Subject: Fix mistake in atomic bitmap Internally values are stored as 32bit integers, no idea why i thought they were 8 bit. --- source/blender/blenlib/BLI_bitmap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index bf3329f8ed5..03390a0dbcd 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -72,9 +72,9 @@ typedef unsigned int BLI_bitmap; #define BLI_BITMAP_TEST_AND_SET_ATOMIC(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ - (atomic_fetch_and_or_uint8((uint8_t*)&(_bitmap)[(_index) >> _BITMAP_POWER], \ - (1u << ((_index) & _BITMAP_MASK))) & \ - (1u << ((_index) & _BITMAP_MASK)))) + (atomic_fetch_and_or_uint32((uint32_t*)&(_bitmap)[(_index) >> _BITMAP_POWER], \ + (1u << ((_index) & _BITMAP_MASK))) & \ + (1u << ((_index) & _BITMAP_MASK)))) #define BLI_BITMAP_TEST_BOOL(_bitmap, _index) \ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \ -- cgit v1.2.3 From 08e6bccdf4a2114847194fbe8adcb1fc83a1746f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 31 Jul 2018 15:09:29 +0200 Subject: Subsurf: Support subdivision of loose elements Applies to vertices and edges. Biggest annoyance here is that OpenSubdiv's topology converter expects that there is no loose geometry, otherwise it is getting confused. For now solution is to create some sort of mapping from real Mesh vertex and edge index to a non-loose-index. Now the annoying part is that this is an extra step to calculate before we can compare topology, meaning FPS will not be as great as if we knew for sure that topology didn't change. Loose edges subdivision is different from what it used to be with old subdivision code, but probably nice feature now is that endpoints of loose edges are stay at the coarse vertex locations. This allows to have things like plane with hair strands, without need to duplicate edge vertices at endpoints. All this required some re-work of topology refiner creation, which is now only passing edges and vertices which are adjacent to face. This is how topology refiner is supposed to be used, and this is how its validator also works. Vertices which are adjacent to loose edges are marked as infinite sharp. This seems to be good-enough approximation for now. In the future we might tweaks things a bit and push such vertices in average direction of loose edges, to match old subdivision code closer. --- .../internal/opensubdiv_converter_factory.cc | 14 +- intern/opensubdiv/internal/opensubdiv_internal.h | 3 - intern/opensubdiv/opensubdiv_converter_capi.h | 8 + .../blenkernel/intern/subdiv_converter_mesh.c | 330 +++++++++++++++------ source/blender/blenkernel/intern/subdiv_eval.c | 46 ++- source/blender/blenkernel/intern/subdiv_mesh.c | 175 +++++++++++ 6 files changed, 473 insertions(+), 103 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index 48516cc80b7..06707cbf418 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -346,16 +346,10 @@ inline bool TopologyRefinerFactory::assignComponentTags( const int num_vertices = converter->getNumVertices(converter); for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { ConstIndexArray vertex_edges = getBaseVertexEdges(refiner, vertex_index); - for (int i = 0; i < vertex_edges.size(); ++i) { - const int edge_index = vertex_edges[i]; - ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge_index); - if (edge_faces.size() == 0) { - setBaseVertexSharpness(refiner, vertex_index, - Crease::SHARPNESS_INFINITE); - break; - } - } - if (vertex_edges.size() == 2) { + if (converter->isInfiniteSharpVertex(converter, vertex_index)) { + setBaseVertexSharpness( + refiner, vertex_index, Crease::SHARPNESS_INFINITE); + } else if (vertex_edges.size() == 2) { const int edge0 = vertex_edges[0], edge1 = vertex_edges[1]; const float sharpness0 = converter->getEdgeSharpness(converter, edge0); const float sharpness1 = converter->getEdgeSharpness(converter, edge1); diff --git a/intern/opensubdiv/internal/opensubdiv_internal.h b/intern/opensubdiv/internal/opensubdiv_internal.h index b9d196bbe9e..16365896edf 100644 --- a/intern/opensubdiv/internal/opensubdiv_internal.h +++ b/intern/opensubdiv/internal/opensubdiv_internal.h @@ -24,9 +24,6 @@ // Never do for release builds. # undef OPENSUBDIV_VALIDATE_TOPOLOGY #else -// TODO(sergey): Always disabled for now, the check doesn't handle multiple -// non-manifolds from the OpenSubdiv side currently. -// # undef OPENSUBDIV_VALIDATE_TOPOLOGY # define OPENSUBDIV_VALIDATE_TOPOLOGY #endif diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index a939f1117e0..58a231deb30 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -19,6 +19,8 @@ #ifndef OPENSUBDIV_CONVERTER_CAPI_H_ #define OPENSUBDIV_CONVERTER_CAPI_H_ +#include // for bool + #include "opensubdiv_capi_type.h" #ifdef __cplusplus @@ -34,6 +36,7 @@ typedef struct OpenSubdiv_Converter { ////////////////////////////////////////////////////////////////////////////// // Global geometry counters. + // Number of faces/edges/vertices in the base mesh. int (*getNumFaces)(const struct OpenSubdiv_Converter* converter); int (*getNumEdges)(const struct OpenSubdiv_Converter* converter); @@ -92,6 +95,11 @@ typedef struct OpenSubdiv_Converter { const int vertex_index, int* vertex_faces); + // Check whether vertex is to be marked as an infinite sharp. + // This is a way to make sharp vertices which are adjacent to a loose edges. + bool (*isInfiniteSharpVertex)(const struct OpenSubdiv_Converter* converter, + const int vertex_index); + ////////////////////////////////////////////////////////////////////////////// // Face-varying data. diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 1a2c26b3564..50143dd46e1 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -31,6 +31,7 @@ #include "DNA_meshdata_types.h" #include "BLI_utildefines.h" +#include "BLI_bitmap.h" #include "BLI_math_vector.h" #include "BKE_customdata.h" @@ -68,6 +69,26 @@ typedef struct ConverterStorage { */ int *loop_uv_indices; int num_uv_coordinates; + + /* Indexed by coarse mesh elements, gives index of corresponding element + * with ignoring all non-manifold entities. + * + * NOTE: This isn't strictly speaking manifold, this is more like non-loose + * geometry index. As in, index of element as if there were no loose edges + * or vertices in the mesh. + */ + int *manifold_vertex_index; + int *manifold_edge_index; + /* Indexed by vertex index from mesh, corresponds to whether this vertex has + * infinite sharpness due to non-manifol topology. + */ + BLI_bitmap *infinite_sharp_vertices_map; + /* Reverse mapping to above. */ + int *manifold_vertex_index_reverse; + int *manifold_edge_index_reverse; + /* Number of non-loose elements. */ + int num_manifold_vertices; + int num_manifold_edges; } ConverterStorage; static OpenSubdiv_SchemeType get_scheme_type( @@ -98,70 +119,81 @@ static int get_num_faces(const OpenSubdiv_Converter *converter) static int get_num_edges(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; - return storage->mesh->totedge; + return storage->num_manifold_edges; } -static int get_num_verts(const OpenSubdiv_Converter *converter) +static int get_num_vertices(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; - return storage->mesh->totvert; + return storage->num_manifold_vertices; } -static int get_num_face_verts(const OpenSubdiv_Converter *converter, int face) +static int get_num_face_vertices(const OpenSubdiv_Converter *converter, + int manifold_face_index) { ConverterStorage *storage = converter->user_data; - return storage->mesh->mpoly[face].totloop; + return storage->mesh->mpoly[manifold_face_index].totloop; } -static void get_face_verts(const OpenSubdiv_Converter *converter, - int face, - int *face_verts) +static void get_face_vertices(const OpenSubdiv_Converter *converter, + int manifold_face_index, + int *manifold_face_vertices) { ConverterStorage *storage = converter->user_data; - const MPoly *mp = &storage->mesh->mpoly[face]; + const MPoly *poly = &storage->mesh->mpoly[manifold_face_index]; const MLoop *mloop = storage->mesh->mloop; - for (int loop = 0; loop < mp->totloop; loop++) { - face_verts[loop] = mloop[mp->loopstart + loop].v; + for (int corner = 0; corner < poly->totloop; corner++) { + manifold_face_vertices[corner] = storage->manifold_vertex_index[ + mloop[poly->loopstart + corner].v]; } } static void get_face_edges(const OpenSubdiv_Converter *converter, - int face, - int *face_edges) + int manifold_face_index, + int *manifold_face_edges) { ConverterStorage *storage = converter->user_data; - const MPoly *mp = &storage->mesh->mpoly[face]; + const MPoly *poly = &storage->mesh->mpoly[manifold_face_index]; const MLoop *mloop = storage->mesh->mloop; - for (int loop = 0; loop < mp->totloop; loop++) { - face_edges[loop] = mloop[mp->loopstart + loop].e; + for (int corner = 0; corner < poly->totloop; corner++) { + manifold_face_edges[corner] = + storage->manifold_edge_index[mloop[poly->loopstart + corner].e]; } } -static void get_edge_verts(const OpenSubdiv_Converter *converter, - int edge, - int *edge_verts) +static void get_edge_vertices(const OpenSubdiv_Converter *converter, + int manifold_edge_index, + int *manifold_edge_vertices) { ConverterStorage *storage = converter->user_data; - const MEdge *me = &storage->mesh->medge[edge]; - edge_verts[0] = me->v1; - edge_verts[1] = me->v2; + const int edge_index = + storage->manifold_edge_index_reverse[manifold_edge_index]; + const MEdge *edge = &storage->mesh->medge[edge_index]; + manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1]; + manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2]; } -static int get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge) +static int get_num_edge_faces(const OpenSubdiv_Converter *converter, + int manifold_edge_index) { ConverterStorage *storage = converter->user_data; + const int edge_index = + storage->manifold_edge_index_reverse[manifold_edge_index]; #ifdef USE_MESH_ELEMENT_MAPPING - return storage->edge_poly_map[edge].count; + return storage->edge_poly_map[edge_index].count; #else const Mesh *mesh = storage->mesh; const MPoly *mpoly = mesh->mpoly; const MLoop *mloop = mesh->mloop; int num = 0; - for (int poly = 0; poly < mesh->totpoly; poly++) { - const MPoly *mp = &mpoly[poly]; - for (int loop = 0; loop < mp->totloop; loop++) { - const MLoop *ml = &mloop[mp->loopstart + loop]; - if (ml->e == edge) { + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < poly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + if (storage->manifold_edge_index[loop->e] == -1) { + continue; + } + if (loop->e == edge_index) { ++num; break; } @@ -172,25 +204,30 @@ static int get_num_edge_faces(const OpenSubdiv_Converter *converter, int edge) } static void get_edge_faces(const OpenSubdiv_Converter *converter, - int edge, - int *edge_faces) + int manifold_edge_index, + int *manifold_edge_faces) { ConverterStorage *storage = converter->user_data; + const int edge_index = + storage->manifold_edge_index_reverse[manifold_edge_index]; #ifdef USE_MESH_ELEMENT_MAPPING - memcpy(edge_faces, - storage->edge_poly_map[edge].indices, - sizeof(int) * storage->edge_poly_map[edge].count); + memcpy(manifold_edge_faces, + storage->edge_poly_map[edge_index].indices, + sizeof(int) * storage->edge_poly_map[edge_index].count); #else const Mesh *mesh = storage->mesh; const MPoly *mpoly = mesh->mpoly; const MLoop *mloop = mesh->mloop; int num = 0; - for (int poly = 0; poly < mesh->totpoly; poly++) { - const MPoly *mp = &mpoly[poly]; - for (int loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *ml = &mloop[mp->loopstart + loop]; - if (ml->e == edge) { - edge_faces[num++] = poly; + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < mpoly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + if (storage->manifold_edge_index[loop->e] == -1) { + continue; + } + if (loop->e == edge_index) { + manifold_edge_faces[num++] = poly_index; break; } } @@ -198,26 +235,46 @@ static void get_edge_faces(const OpenSubdiv_Converter *converter, #endif } -static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int edge) +static float get_edge_sharpness(const OpenSubdiv_Converter *converter, + int manifold_edge_index) { ConverterStorage *storage = converter->user_data; + const int edge_index = + storage->manifold_edge_index_reverse[manifold_edge_index]; const MEdge *medge = storage->mesh->medge; - const float edge_crease = (float)medge[edge].crease / 255.0f; + const float edge_crease = (float)medge[edge_index].crease / 255.0f; return edge_crease * storage->settings.level; } -static int get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert) +static int get_num_vertex_edges(const OpenSubdiv_Converter *converter, + int manifold_vertex_index) { ConverterStorage *storage = converter->user_data; + const int vertex_index = + storage->manifold_vertex_index_reverse[manifold_vertex_index]; #ifdef USE_MESH_ELEMENT_MAPPING - return storage->vert_edge_map[vert].count; + const int num_vertex_edges = storage->vert_edge_map[vertex_index].count; + int num_manifold_vertex_edges = 0; + for (int i = 0; i < num_vertex_edges; i++) { + const int edge_index = storage->vert_edge_map[vertex_index].indices[i]; + const int manifold_edge_index = + storage->manifold_edge_index[edge_index]; + if (manifold_edge_index == -1) { + continue; + } + num_manifold_vertex_edges++; + } + return num_manifold_vertex_edges; #else const Mesh *mesh = storage->mesh; const MEdge *medge = mesh->medge; int num = 0; - for (int edge = 0; edge < mesh->totedge; edge++) { - const MEdge *me = &medge[edge]; - if (me->v1 == vert || me->v2 == vert) { + for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) { + const MEdge *edge = &medge[edge_index]; + if (storage->manifold_edge_index[edge_index] == -1) { + continue; + } + if (edge->v1 == vertex_index || edge->v2 == vertex_index) { ++num; } } @@ -225,43 +282,61 @@ static int get_num_vert_edges(const OpenSubdiv_Converter *converter, int vert) #endif } -static void get_vert_edges(const OpenSubdiv_Converter *converter, - int vert, - int *vert_edges) +static void get_vertex_edges(const OpenSubdiv_Converter *converter, + int manifold_vertex_index, + int *manifold_vertex_edges) { ConverterStorage *storage = converter->user_data; + const int vertex_index = + storage->manifold_vertex_index_reverse[manifold_vertex_index]; #ifdef USE_MESH_ELEMENT_MAPPING - memcpy(vert_edges, - storage->vert_edge_map[vert].indices, - sizeof(int) * storage->vert_edge_map[vert].count); + const int num_vertex_edges = storage->vert_edge_map[vertex_index].count; + int num_manifold_vertex_edges = 0; + for (int i = 0; i < num_vertex_edges; i++) { + const int edge_index = storage->vert_edge_map[vertex_index].indices[i]; + const int manifold_edge_index = + storage->manifold_edge_index[edge_index]; + if (manifold_edge_index == -1) { + continue; + } + manifold_vertex_edges[num_manifold_vertex_edges] = manifold_edge_index; + num_manifold_vertex_edges++; + } #else const Mesh *mesh = storage->mesh; const MEdge *medge = mesh->medge; int num = 0; - for (int edge = 0; edge < mesh->totedge; edge++) { - const MEdge *me = &medge[edge]; - if (me->v1 == vert || me->v2 == vert) { - vert_edges[num++] = edge; + for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) { + const MEdge *edge = &medge[edge_index]; + if (storage->manifold_edge_index[edge_index] == -1) { + continue; + } + if (edge->v1 == vertex_index || edge->v2 == vertex_index) { + manifold_vertex_edges[num++] = + storage->manifold_edge_index[edge_index]; } } #endif } -static int get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert) +static int get_num_vertex_faces(const OpenSubdiv_Converter *converter, + int manifold_vertex_index) { ConverterStorage *storage = converter->user_data; + const int vertex_index = + storage->manifold_vertex_index_reverse[manifold_vertex_index]; #ifdef USE_MESH_ELEMENT_MAPPING - return storage->vert_poly_map[vert].count; + return storage->vert_poly_map[vertex_index].count; #else const Mesh *mesh = storage->mesh; const MPoly *mpoly = mesh->mpoly; const MLoop *mloop = mesh->mloop; int num = 0; - for (int poly = 0; poly < mesh->totpoly; poly++) { - const MPoly *mp = &mpoly[poly]; - for (int loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *ml = &mloop[mp->loopstart + loop]; - if (ml->v == vert) { + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < mpoly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + if (loop->v == vertex_index) { ++num; break; } @@ -271,26 +346,28 @@ static int get_num_vert_faces(const OpenSubdiv_Converter *converter, int vert) #endif } -static void get_vert_faces(const OpenSubdiv_Converter *converter, - int vert, - int *vert_faces) +static void get_vertex_faces(const OpenSubdiv_Converter *converter, + int manifold_vertex_index, + int *manifold_vertex_faces) { ConverterStorage *storage = converter->user_data; + const int vertex_index = + storage->manifold_vertex_index_reverse[manifold_vertex_index]; #ifdef USE_MESH_ELEMENT_MAPPING - memcpy(vert_faces, - storage->vert_poly_map[vert].indices, - sizeof(int) * storage->vert_poly_map[vert].count); + memcpy(manifold_vertex_faces, + storage->vert_poly_map[vertex_index].indices, + sizeof(int) * storage->vert_poly_map[vertex_index].count); #else const Mesh *mesh = storage->mesh; const MPoly *mpoly = mesh->mpoly; const MLoop *mloop = mesh->mloop; int num = 0; - for (int poly = 0; poly < mesh->totpoly; poly++) { - const MPoly *mp = &mpoly[poly]; - for (int loop = 0; loop < mpoly->totloop; loop++) { - const MLoop *ml = &mloop[mp->loopstart + loop]; - if (ml->v == vert) { - vert_faces[num++] = poly; + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < mpoly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + if (loop->v == vertex_index) { + manifold_vertex_faces[num++] = poly_index; break; } } @@ -298,6 +375,16 @@ static void get_vert_faces(const OpenSubdiv_Converter *converter, #endif } +static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, + int manifold_vertex_index) +{ + ConverterStorage *storage = converter->user_data; + const int vertex_index = + storage->manifold_vertex_index_reverse[manifold_vertex_index]; + return BLI_BITMAP_TEST_BOOL(storage->infinite_sharp_vertices_map, + vertex_index); +} + static int get_num_uv_layers(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; @@ -382,6 +469,11 @@ static void free_user_data(const OpenSubdiv_Converter *converter) MEM_freeN(user_data->edge_poly_map); MEM_freeN(user_data->edge_poly_mem); #endif + MEM_freeN(user_data->manifold_vertex_index); + MEM_freeN(user_data->manifold_edge_index); + MEM_freeN(user_data->infinite_sharp_vertices_map); + MEM_freeN(user_data->manifold_vertex_index_reverse); + MEM_freeN(user_data->manifold_edge_index_reverse); MEM_freeN(user_data); } @@ -393,21 +485,22 @@ static void init_functions(OpenSubdiv_Converter *converter) converter->getNumFaces = get_num_faces; converter->getNumEdges = get_num_edges; - converter->getNumVertices = get_num_verts; + converter->getNumVertices = get_num_vertices; - converter->getNumFaceVertices = get_num_face_verts; - converter->getFaceVertices = get_face_verts; + converter->getNumFaceVertices = get_num_face_vertices; + converter->getFaceVertices = get_face_vertices; converter->getFaceEdges = get_face_edges; - converter->getEdgeVertices = get_edge_verts; + converter->getEdgeVertices = get_edge_vertices; converter->getNumEdgeFaces = get_num_edge_faces; converter->getEdgeFaces = get_edge_faces; converter->getEdgeSharpness = get_edge_sharpness; - converter->getNumVertexEdges = get_num_vert_edges; - converter->getVertexEdges = get_vert_edges; - converter->getNumVertexFaces = get_num_vert_faces; - converter->getVertexFaces = get_vert_faces; + converter->getNumVertexEdges = get_num_vertex_edges; + converter->getVertexEdges = get_vertex_edges; + converter->getNumVertexFaces = get_num_vertex_faces; + converter->getVertexFaces = get_vertex_faces; + converter->isInfiniteSharpVertex = is_infinite_sharp_vertex; converter->getNumUVLayers = get_num_uv_layers; converter->precalcUVLayer = precalc_uv_layer; @@ -444,6 +537,74 @@ static void create_element_maps_if_needed(ConverterStorage *storage) #endif } +static void initialize_manifold_index_array(const BLI_bitmap *used_map, + const int num_elements, + int **indices_r, + int **indices_reverse_r, + int *num_manifold_elements_r) +{ + int *indices = MEM_malloc_arrayN( + num_elements, sizeof(int), "manifold indices"); + int *indices_reverse = MEM_malloc_arrayN( + num_elements, sizeof(int), "manifold indices reverse"); + int offset = 0; + for (int i = 0; i < num_elements; i++) { + if (BLI_BITMAP_TEST_BOOL(used_map, i)) { + indices[i] = i - offset; + indices_reverse[i - offset] = i; + } + else { + indices[i] = -1; + offset++; + } + } + *indices_r = indices; + *indices_reverse_r = indices_reverse; + *num_manifold_elements_r = num_elements - offset; +} + +static void initialize_manifold_indices(ConverterStorage *storage) +{ + const Mesh *mesh = storage->mesh; + const MEdge *medge = mesh->medge; + const MLoop *mloop = mesh->mloop; + const MPoly *mpoly = mesh->mpoly; + /* Set bits of elements which are not loose. */ + BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map"); + BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map"); + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < poly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + BLI_BITMAP_ENABLE(vert_used_map, loop->v); + BLI_BITMAP_ENABLE(edge_used_map, loop->e); + } + } + initialize_manifold_index_array(vert_used_map, + mesh->totvert, + &storage->manifold_vertex_index, + &storage->manifold_vertex_index_reverse, + &storage->num_manifold_vertices); + initialize_manifold_index_array(edge_used_map, + mesh->totedge, + &storage->manifold_edge_index, + &storage->manifold_edge_index_reverse, + &storage->num_manifold_edges); + /* Initialize infinite sharp mapping. */ + storage->infinite_sharp_vertices_map = + BLI_BITMAP_NEW(mesh->totvert, "vert used map"); + for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) { + if (!BLI_BITMAP_TEST_BOOL(edge_used_map, edge_index)) { + const MEdge *edge = &medge[edge_index]; + BLI_BITMAP_ENABLE(storage->infinite_sharp_vertices_map, edge->v1); + BLI_BITMAP_ENABLE(storage->infinite_sharp_vertices_map, edge->v2); + } + } + /* Free working variables. */ + MEM_freeN(vert_used_map); + MEM_freeN(edge_used_map); +} + static void init_user_data(OpenSubdiv_Converter *converter, const SubdivSettings *settings, const Mesh *mesh) @@ -454,6 +615,7 @@ static void init_user_data(OpenSubdiv_Converter *converter, user_data->mesh = mesh; user_data->loop_uv_indices = NULL; create_element_maps_if_needed(user_data); + initialize_manifold_indices(user_data); converter->user_data = user_data; } #endif diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 4c2ed07cdfa..7c90a2a25cd 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -33,10 +33,13 @@ #include "DNA_meshdata_types.h" #include "BLI_utildefines.h" +#include "BLI_bitmap.h" #include "BLI_math_vector.h" #include "BKE_customdata.h" +#include "MEM_guardedalloc.h" + #ifdef WITH_OPENSUBDIV # include "opensubdiv_evaluator_capi.h" # include "opensubdiv_topology_refiner_capi.h" @@ -60,6 +63,42 @@ void BKE_subdiv_eval_begin(Subdiv *subdiv) } #ifdef WITH_OPENSUBDIV +static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh) +{ + const MVert *mvert = mesh->mvert; + const MLoop *mloop = mesh->mloop; + const MPoly *mpoly = mesh->mpoly; + /* Mark vertices which needs new coordinates. */ + /* TODO(sergey): This is annoying to calculate this on every update, + * maybe it's better to cache this mapping. Or make it possible to have + * OpenSubdiv's vertices match mesh ones? + */ + BLI_bitmap *vertex_used_map = + BLI_BITMAP_NEW(mesh->totvert, "vert used map"); + for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { + const MPoly *poly = &mpoly[poly_index]; + for (int corner = 0; corner < poly->totloop; corner++) { + const MLoop *loop = &mloop[poly->loopstart + corner]; + BLI_BITMAP_ENABLE(vertex_used_map, loop->v); + } + } + for (int vertex_index = 0, manifold_veretx_index = 0; + vertex_index < mesh->totvert; + vertex_index++) + { + if (!BLI_BITMAP_TEST_BOOL(vertex_used_map, vertex_index)) { + continue; + } + const MVert *vertex = &mvert[vertex_index]; + subdiv->evaluator->setCoarsePositions( + subdiv->evaluator, + vertex->co, + manifold_veretx_index, 1); + manifold_veretx_index++; + } + MEM_freeN(vertex_used_map); +} + static void set_face_varying_data_from_uv(Subdiv *subdiv, const MLoopUV *mloopuv, const int layer_index) @@ -94,12 +133,7 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) #ifdef WITH_OPENSUBDIV BKE_subdiv_eval_begin(subdiv); /* Set coordinates of base mesh vertices. */ - subdiv->evaluator->setCoarsePositionsFromBuffer( - subdiv->evaluator, - mesh->mvert, - offsetof(MVert, co), - sizeof(MVert), - 0, mesh->totvert); + set_coarse_positions(subdiv, mesh); /* Set face-varyign data to UV maps. */ const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 33813905105..befd2b9847c 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -33,6 +33,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_key_types.h" #include "BLI_alloca.h" #include "BLI_bitmap.h" @@ -40,6 +41,7 @@ #include "BLI_task.h" #include "BKE_mesh.h" +#include "BKE_key.h" #include "MEM_guardedalloc.h" @@ -183,6 +185,7 @@ static void subdiv_mesh_ctx_count(SubdivMeshContext *ctx) ctx->num_subdiv_vertices = coarse_mesh->totvert; ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); + /* Calculate extra vertices and edges createdd by non-loose geometry. */ for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; const int num_ptex_faces_per_poly = @@ -224,6 +227,12 @@ static void subdiv_mesh_ctx_count(SubdivMeshContext *ctx) num_polys_per_ptex_get(no_quad_patch_resolution); } } + /* Calculate extra edges createdd by loose edges. */ + for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) { + if (!BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) { + ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge; + } + } ctx->num_subdiv_loops = ctx->num_subdiv_polygons * 4; } @@ -2185,6 +2194,164 @@ static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index) } } +/* ============================================================================= + * Loose elements subdivision process. + */ + +static void subdiv_create_loose_vertices_task( + void *__restrict userdata, + const int vertex_index, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SubdivMeshContext *ctx = userdata; + if (BLI_BITMAP_TEST_BOOL(ctx->coarse_vertices_used_map, vertex_index)) { + /* Vertex is not loose, was handled when handling polygons. */ + return; + } + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MVert *coarse_mvert = coarse_mesh->mvert; + const MVert *coarse_vertex = &coarse_mvert[vertex_index]; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + MVert *subdiv_vertex = &subdiv_mvert[ + ctx->vertices_corner_offset + vertex_index]; + subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex); +} + +/* Get neighbor edges of the given one. + * - neighbors[0] is an edge adjacent to edge->v1. + * - neighbors[1] is an edge adjacent to edge->v1. + */ +static void find_edge_neighbors(const SubdivMeshContext *ctx, + const MEdge *edge, + const MEdge *neighbors[2]) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_medge = coarse_mesh->medge; + neighbors[0] = NULL; + neighbors[1] = NULL; + for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) { + if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) { + continue; + } + const MEdge *current_edge = &coarse_medge[edge_index]; + if (current_edge == edge) { + continue; + } + if (ELEM(edge->v1, current_edge->v1, current_edge->v2)) { + neighbors[0] = current_edge; + } + if (ELEM(edge->v2, current_edge->v1, current_edge->v2)) { + neighbors[1] = current_edge; + } + } +} + +static void points_for_loose_edges_interpolation_get( + SubdivMeshContext *ctx, + const MEdge *coarse_edge, + const MEdge *neighbors[2], + float points_r[4][3]) +{ + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MVert *coarse_mvert = coarse_mesh->mvert; + /* Middle points corresponds to the edge. */ + copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co); + copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co); + /* Start point, duplicate from edge start if no neighbor. */ + if (neighbors[0] != NULL) { + if (neighbors[0]->v1 == coarse_edge->v1) { + copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co); + } + else { + copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co); + } + } + else { + sub_v3_v3v3(points_r[0], points_r[1], points_r[2]); + add_v3_v3(points_r[0], points_r[1]); + } + /* End point, duplicate from edge end if no neighbor. */ + if (neighbors[1] != NULL) { + if (neighbors[1]->v1 == coarse_edge->v2) { + copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co); + } + else { + copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co); + } + } + else { + sub_v3_v3v3(points_r[3], points_r[2], points_r[1]); + add_v3_v3(points_r[3], points_r[2]); + } +} + +static void subdiv_create_vertices_of_loose_edges_task( + void *__restrict userdata, + const int edge_index, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SubdivMeshContext *ctx = userdata; + if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) { + /* Vertex is not loose, was handled when handling polygons. */ + return; + } + const int resolution = ctx->settings->resolution; + const int resolution_1 = resolution - 1; + const float inv_resolution_1 = 1.0f / (float)resolution_1; + const int num_subdiv_vertices_per_coarse_edge = resolution - 2; + const Mesh *coarse_mesh = ctx->coarse_mesh; + const MEdge *coarse_edge = &coarse_mesh->medge[edge_index]; + Mesh *subdiv_mesh = ctx->subdiv_mesh; + MVert *subdiv_mvert = subdiv_mesh->mvert; + /* Find neighbors of the current loose edge. */ + const MEdge *neighbors[2]; + find_edge_neighbors(ctx, coarse_edge, neighbors); + /* Get points for b-spline interpolation. */ + float points[4][3]; + points_for_loose_edges_interpolation_get( + ctx, coarse_edge, neighbors, points); + /* Subdivion verticies which corresponds to edge's v1 and v2. */ + MVert *subdiv_v1 = &subdiv_mvert[ + ctx->vertices_corner_offset + coarse_edge->v1]; + MVert *subdiv_v2 = &subdiv_mvert[ + ctx->vertices_corner_offset + coarse_edge->v2]; + /* First subdivided inner vertex of the edge. */ + MVert *subdiv_start_vertex = &subdiv_mvert[ + ctx->vertices_edge_offset + + edge_index * num_subdiv_vertices_per_coarse_edge]; + /* Perform interpolation. */ + for (int i = 0; i < resolution; i++) { + const float u = i * inv_resolution_1; + float weights[4]; + key_curve_position_weights(u, weights, KEY_BSPLINE); + + MVert *subdiv_vertex; + if (i == 0) { + subdiv_vertex = subdiv_v1; + } + else if (i == resolution - 1) { + subdiv_vertex = subdiv_v2; + } + else { + subdiv_vertex = &subdiv_start_vertex[i - 1]; + } + interp_v3_v3v3v3v3(subdiv_vertex->co, + points[0], + points[1], + points[2], + points[3], + weights); + /* Reset flags and such. */ + subdiv_vertex->flag = 0; + subdiv_vertex->bweight = 0.0f; + /* Reset normal. */ + subdiv_vertex->no[0] = 0.0f; + subdiv_vertex->no[1] = 0.0f; + subdiv_vertex->no[2] = 1.0f; + } +} + /* ============================================================================= * Subdivision process entry points. */ @@ -2245,6 +2412,14 @@ Mesh *BKE_subdiv_to_mesh( &ctx, subdiv_eval_task, ¶llel_range_settings); + BLI_task_parallel_range(0, coarse_mesh->totvert, + &ctx, + subdiv_create_loose_vertices_task, + ¶llel_range_settings); + BLI_task_parallel_range(0, coarse_mesh->totedge, + &ctx, + subdiv_create_vertices_of_loose_edges_task, + ¶llel_range_settings); BLI_task_parallel_range(0, coarse_mesh->totedge, &ctx, subdiv_create_boundary_edges_task, -- cgit v1.2.3 From ebbeddd2f4617505bb2e13b6d773a3da6bd327c4 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 15:13:24 +0200 Subject: Subsurf: Use edge sharpness directly from converter Seems it's behaving correct now, surely more tests needed, but this is required for now to move forward. --- intern/opensubdiv/internal/opensubdiv_converter_factory.cc | 2 +- intern/opensubdiv/internal/opensubdiv_converter_internal.cc | 9 --------- intern/opensubdiv/internal/opensubdiv_converter_internal.h | 4 ---- intern/opensubdiv/internal/opensubdiv_topology_refiner.cc | 2 +- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index 06707cbf418..02b6e93a1ae 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -336,7 +336,7 @@ inline bool TopologyRefinerFactory::assignComponentTags( const int num_edges = converter->getNumEdges(converter); for (int edge_index = 0; edge_index < num_edges; ++edge_index) { const float sharpness = - opensubdiv_capi::getCompatibleEdgeSharpness(converter, edge_index); + converter->getEdgeSharpness(converter, edge_index); setBaseEdgeSharpness(refiner, edge_index, sharpness); } // OpenSubdiv expects non-manifold vertices to be sharp but at the time it diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc index 32815dc34dc..2f7a7109ea1 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.cc @@ -84,13 +84,4 @@ getCAPIFVarLinearInterpolationFromOSD( return OSD_FVAR_LINEAR_INTERPOLATION_NONE; } -float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, - int edge_index) { - if (converter->getNumEdgeFaces(converter, edge_index) == 2) { - return converter->getEdgeSharpness(converter, edge_index); - } else { - return OpenSubdiv::Sdc::Crease::SHARPNESS_INFINITE; - } -} - } // namespace opensubdiv_capi diff --git a/intern/opensubdiv/internal/opensubdiv_converter_internal.h b/intern/opensubdiv/internal/opensubdiv_converter_internal.h index c47cdd1004d..411514c45dc 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_internal.h +++ b/intern/opensubdiv/internal/opensubdiv_converter_internal.h @@ -46,10 +46,6 @@ OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD( OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation); -// Get edge sharpness in a way which makes OpenSubdiv happy. -float getCompatibleEdgeSharpness(const OpenSubdiv_Converter* converter, - int edge_index); - } // namespace opensubdiv_capi #endif // OPENSUBDIV_CONVERTER_INTERNAL_H_ diff --git a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc index 93f6fdc14a1..5e1e0bd86b3 100644 --- a/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc +++ b/intern/opensubdiv/internal/opensubdiv_topology_refiner.cc @@ -340,7 +340,7 @@ bool checkEdgeSharpnessMatch( for (int edge_index = 0; edge_index < num_edges; ++edge_index) { const float sharpness = base_level.GetEdgeSharpness(edge_index); const float conv_sharpness = - opensubdiv_capi::getCompatibleEdgeSharpness(converter, edge_index); + converter->getEdgeSharpness(converter, edge_index); if (sharpness != conv_sharpness) { return false; } -- cgit v1.2.3 From ec4ba68730f8e286559b0de433dfd821e6eeee6d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 14:48:32 +0200 Subject: Subsurf: Fix/workaround crashes and failures with non-manifold geometry The idea is simple: do not provide full topology to OpenSubdiv, leave edges creation to OpenSubdiv itself. This solves issues with non-manifold meshes which were known to fail, including the ones from T52059. On a positive side we can simplify our side of converter, keeping code shorter. it is still possible that we'll need to ensure all loops has same winding, but that is less things to worry about. --- .../internal/opensubdiv_converter_factory.cc | 50 +++++++++++++++++----- intern/opensubdiv/opensubdiv_converter_capi.h | 11 +++++ .../blenkernel/intern/subdiv_converter_mesh.c | 8 +++- 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index 02b6e93a1ae..321f580af97 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -48,7 +48,7 @@ TopologyRefinerFactory::resizeComponentTopology( TopologyRefiner& refiner, const TopologyRefinerData& cb_data) { const OpenSubdiv_Converter* converter = cb_data.converter; - /// Faces and face-vertices. + // Faces and face-vertices. const int num_faces = converter->getNumFaces(converter); setNumBaseFaces(refiner, num_faces); for (int face_index = 0; face_index < num_faces; ++face_index) { @@ -56,6 +56,13 @@ TopologyRefinerFactory::resizeComponentTopology( converter->getNumFaceVertices(converter, face_index); setNumBaseFaceVertices(refiner, face_index, num_face_vertices); } + // Vertices. + const int num_vertices = converter->getNumVertices(converter); + setNumBaseVertices(refiner, num_vertices); + // If converter does not provide full topology, we are done. + if (!converter->specifiesFullTopology(converter)) { + return true; + } // Edges and edge-faces. const int num_edges = converter->getNumEdges(converter); setNumBaseEdges(refiner, num_edges); @@ -64,9 +71,7 @@ TopologyRefinerFactory::resizeComponentTopology( converter->getNumEdgeFaces(converter, edge_index); setNumBaseEdgeFaces(refiner, edge_index, num_edge_faces); } - // Vertices and vertex-faces and vertex-edges. - const int num_vertices = converter->getNumVertices(converter); - setNumBaseVertices(refiner, num_vertices); + // Vertex-faces and vertex-edges. for (int vertex_index = 0; vertex_index < num_vertices; ++vertex_index) { const int num_vert_edges = converter->getNumVertexEdges(converter, vertex_index); @@ -85,13 +90,21 @@ TopologyRefinerFactory::assignComponentTopology( const TopologyRefinerData& cb_data) { using Far::IndexArray; const OpenSubdiv_Converter* converter = cb_data.converter; + const bool full_topology_specified = + converter->specifiesFullTopology(converter); // Face relations. const int num_faces = converter->getNumFaces(converter); for (int face_index = 0; face_index < num_faces; ++face_index) { IndexArray dst_face_verts = getBaseFaceVertices(refiner, face_index); converter->getFaceVertices(converter, face_index, &dst_face_verts[0]); - IndexArray dst_face_edges = getBaseFaceEdges(refiner, face_index); - converter->getFaceEdges(converter, face_index, &dst_face_edges[0]); + if (full_topology_specified) { + IndexArray dst_face_edges = getBaseFaceEdges(refiner, face_index); + converter->getFaceEdges(converter, face_index, &dst_face_edges[0]); + } + } + // If converter does not provide full topology, we are done. + if (!full_topology_specified) { + return true; } // Edge relations. const int num_edges = converter->getNumEdges(converter); @@ -103,7 +116,7 @@ TopologyRefinerFactory::assignComponentTopology( IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge_index); converter->getEdgeFaces(converter, edge_index, &dst_edge_faces[0]); } -// TODO(sergey): Find a way to move this to an utility function. + // TODO(sergey): Find a way to move this to an utility function. #ifdef OPENSUBDIV_ORIENT_TOPOLOGY // Make face normals consistent. std::vector face_used(num_faces, false); @@ -333,11 +346,28 @@ inline bool TopologyRefinerFactory::assignComponentTags( const TopologyRefinerData& cb_data) { using OpenSubdiv::Sdc::Crease; const OpenSubdiv_Converter* converter = cb_data.converter; + const bool full_topology_specified = + converter->specifiesFullTopology(converter); const int num_edges = converter->getNumEdges(converter); for (int edge_index = 0; edge_index < num_edges; ++edge_index) { const float sharpness = converter->getEdgeSharpness(converter, edge_index); - setBaseEdgeSharpness(refiner, edge_index, sharpness); + if (sharpness < 1e-6f) { + continue; + } + if (full_topology_specified) { + setBaseEdgeSharpness(refiner, edge_index, sharpness); + } else { + int edge_vertices[2]; + converter->getEdgeVertices(converter, edge_index, edge_vertices); + const int base_edge_index = findBaseEdge( + refiner, edge_vertices[0], edge_vertices[1]); + if (base_edge_index == OpenSubdiv::Far::INDEX_INVALID) { + printf("OpenSubdiv Error: failed to find reconstructed edge\n"); + return false; + } + setBaseEdgeSharpness(refiner, base_edge_index, sharpness); + } } // OpenSubdiv expects non-manifold vertices to be sharp but at the time it // handles correct cases when vertex is a corner of plane. Currently mark @@ -351,8 +381,8 @@ inline bool TopologyRefinerFactory::assignComponentTags( refiner, vertex_index, Crease::SHARPNESS_INFINITE); } else if (vertex_edges.size() == 2) { const int edge0 = vertex_edges[0], edge1 = vertex_edges[1]; - const float sharpness0 = converter->getEdgeSharpness(converter, edge0); - const float sharpness1 = converter->getEdgeSharpness(converter, edge1); + const float sharpness0 = refiner._levels[0]->getEdgeSharpness(edge0); + const float sharpness1 = refiner._levels[0]->getEdgeSharpness(edge1); const float sharpness = std::min(sharpness0, sharpness1); setBaseVertexSharpness(refiner, vertex_index, sharpness); } diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 58a231deb30..1dd68f43c32 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -34,6 +34,17 @@ typedef struct OpenSubdiv_Converter { OpenSubdiv_FVarLinearInterpolation (*getFVarLinearInterpolation)( const struct OpenSubdiv_Converter* converter); + // Denotes whether this converter specifies full topology, which includes + // vertices, edges, faces, vertices+edges of a face and edges/faces of a + // vertex. + // Otherwise this converter will only provide number of vertices and faces, + // and vertices of faces. The rest of topology will be created by OpenSubdiv. + // + // NOTE: Even if converter does not provide full topology, it still needs + // to provide number of edges and vertices-of-edge. Those are used to assign + // topology tags. + bool (*specifiesFullTopology)(const struct OpenSubdiv_Converter* converter); + ////////////////////////////////////////////////////////////////////////////// // Global geometry counters. diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 50143dd46e1..83b1e4a6ce9 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -110,6 +110,12 @@ static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation( return BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings); } +static bool specifies_full_topology( + const OpenSubdiv_Converter *UNUSED(converter)) +{ + return false; +} + static int get_num_faces(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; @@ -480,8 +486,8 @@ static void free_user_data(const OpenSubdiv_Converter *converter) static void init_functions(OpenSubdiv_Converter *converter) { converter->getSchemeType = get_scheme_type; - converter->getFVarLinearInterpolation = get_fvar_linear_interpolation; + converter->specifiesFullTopology = specifies_full_topology; converter->getNumFaces = get_num_faces; converter->getNumEdges = get_num_edges; -- cgit v1.2.3 From 63058490a3da932d2c9224aa4555f23eebb77264 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 15:21:14 +0200 Subject: Subsurf: Cleanup, remove unused mappings and topology queries --- .../blenkernel/intern/subdiv_converter_mesh.c | 302 +++------------------ 1 file changed, 31 insertions(+), 271 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 83b1e4a6ce9..5e320678814 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -45,31 +45,15 @@ # include "opensubdiv_converter_capi.h" #endif -/* Use mesh element mapping structures during conversion. - * Uses more memory but is much faster than naive algorithm. - */ -#define USE_MESH_ELEMENT_MAPPING - #ifdef WITH_OPENSUBDIV typedef struct ConverterStorage { SubdivSettings settings; const Mesh *mesh; - -#ifdef USE_MESH_ELEMENT_MAPPING - MeshElemMap *vert_edge_map; - MeshElemMap *vert_poly_map; - MeshElemMap *edge_poly_map; - int *vert_edge_mem; - int *vert_poly_mem; - int *edge_poly_mem; -#endif - /* Indexed by loop index, value denotes index of face-varying vertex * which corresponds to the UV coordinate. */ int *loop_uv_indices; int num_uv_coordinates; - /* Indexed by coarse mesh elements, gives index of corresponding element * with ignoring all non-manifold entities. * @@ -78,7 +62,6 @@ typedef struct ConverterStorage { * or vertices in the mesh. */ int *manifold_vertex_index; - int *manifold_edge_index; /* Indexed by vertex index from mesh, corresponds to whether this vertex has * infinite sharpness due to non-manifol topology. */ @@ -154,19 +137,6 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, } } -static void get_face_edges(const OpenSubdiv_Converter *converter, - int manifold_face_index, - int *manifold_face_edges) -{ - ConverterStorage *storage = converter->user_data; - const MPoly *poly = &storage->mesh->mpoly[manifold_face_index]; - const MLoop *mloop = storage->mesh->mloop; - for (int corner = 0; corner < poly->totloop; corner++) { - manifold_face_edges[corner] = - storage->manifold_edge_index[mloop[poly->loopstart + corner].e]; - } -} - static void get_edge_vertices(const OpenSubdiv_Converter *converter, int manifold_edge_index, int *manifold_edge_vertices) @@ -179,68 +149,6 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2]; } -static int get_num_edge_faces(const OpenSubdiv_Converter *converter, - int manifold_edge_index) -{ - ConverterStorage *storage = converter->user_data; - const int edge_index = - storage->manifold_edge_index_reverse[manifold_edge_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - return storage->edge_poly_map[edge_index].count; -#else - const Mesh *mesh = storage->mesh; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; - int num = 0; - for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { - const MPoly *poly = &mpoly[poly_index]; - for (int corner = 0; corner < poly->totloop; corner++) { - const MLoop *loop = &mloop[poly->loopstart + corner]; - if (storage->manifold_edge_index[loop->e] == -1) { - continue; - } - if (loop->e == edge_index) { - ++num; - break; - } - } - } - return num; -#endif -} - -static void get_edge_faces(const OpenSubdiv_Converter *converter, - int manifold_edge_index, - int *manifold_edge_faces) -{ - ConverterStorage *storage = converter->user_data; - const int edge_index = - storage->manifold_edge_index_reverse[manifold_edge_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - memcpy(manifold_edge_faces, - storage->edge_poly_map[edge_index].indices, - sizeof(int) * storage->edge_poly_map[edge_index].count); -#else - const Mesh *mesh = storage->mesh; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; - int num = 0; - for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { - const MPoly *poly = &mpoly[poly_index]; - for (int corner = 0; corner < mpoly->totloop; corner++) { - const MLoop *loop = &mloop[poly->loopstart + corner]; - if (storage->manifold_edge_index[loop->e] == -1) { - continue; - } - if (loop->e == edge_index) { - manifold_edge_faces[num++] = poly_index; - break; - } - } - } -#endif -} - static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manifold_edge_index) { @@ -252,134 +160,6 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, return edge_crease * storage->settings.level; } -static int get_num_vertex_edges(const OpenSubdiv_Converter *converter, - int manifold_vertex_index) -{ - ConverterStorage *storage = converter->user_data; - const int vertex_index = - storage->manifold_vertex_index_reverse[manifold_vertex_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - const int num_vertex_edges = storage->vert_edge_map[vertex_index].count; - int num_manifold_vertex_edges = 0; - for (int i = 0; i < num_vertex_edges; i++) { - const int edge_index = storage->vert_edge_map[vertex_index].indices[i]; - const int manifold_edge_index = - storage->manifold_edge_index[edge_index]; - if (manifold_edge_index == -1) { - continue; - } - num_manifold_vertex_edges++; - } - return num_manifold_vertex_edges; -#else - const Mesh *mesh = storage->mesh; - const MEdge *medge = mesh->medge; - int num = 0; - for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) { - const MEdge *edge = &medge[edge_index]; - if (storage->manifold_edge_index[edge_index] == -1) { - continue; - } - if (edge->v1 == vertex_index || edge->v2 == vertex_index) { - ++num; - } - } - return num; -#endif -} - -static void get_vertex_edges(const OpenSubdiv_Converter *converter, - int manifold_vertex_index, - int *manifold_vertex_edges) -{ - ConverterStorage *storage = converter->user_data; - const int vertex_index = - storage->manifold_vertex_index_reverse[manifold_vertex_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - const int num_vertex_edges = storage->vert_edge_map[vertex_index].count; - int num_manifold_vertex_edges = 0; - for (int i = 0; i < num_vertex_edges; i++) { - const int edge_index = storage->vert_edge_map[vertex_index].indices[i]; - const int manifold_edge_index = - storage->manifold_edge_index[edge_index]; - if (manifold_edge_index == -1) { - continue; - } - manifold_vertex_edges[num_manifold_vertex_edges] = manifold_edge_index; - num_manifold_vertex_edges++; - } -#else - const Mesh *mesh = storage->mesh; - const MEdge *medge = mesh->medge; - int num = 0; - for (int edge_index = 0; edge_index < mesh->totedge; edge_index++) { - const MEdge *edge = &medge[edge_index]; - if (storage->manifold_edge_index[edge_index] == -1) { - continue; - } - if (edge->v1 == vertex_index || edge->v2 == vertex_index) { - manifold_vertex_edges[num++] = - storage->manifold_edge_index[edge_index]; - } - } -#endif -} - -static int get_num_vertex_faces(const OpenSubdiv_Converter *converter, - int manifold_vertex_index) -{ - ConverterStorage *storage = converter->user_data; - const int vertex_index = - storage->manifold_vertex_index_reverse[manifold_vertex_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - return storage->vert_poly_map[vertex_index].count; -#else - const Mesh *mesh = storage->mesh; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; - int num = 0; - for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { - const MPoly *poly = &mpoly[poly_index]; - for (int corner = 0; corner < mpoly->totloop; corner++) { - const MLoop *loop = &mloop[poly->loopstart + corner]; - if (loop->v == vertex_index) { - ++num; - break; - } - } - } - return num; -#endif -} - -static void get_vertex_faces(const OpenSubdiv_Converter *converter, - int manifold_vertex_index, - int *manifold_vertex_faces) -{ - ConverterStorage *storage = converter->user_data; - const int vertex_index = - storage->manifold_vertex_index_reverse[manifold_vertex_index]; -#ifdef USE_MESH_ELEMENT_MAPPING - memcpy(manifold_vertex_faces, - storage->vert_poly_map[vertex_index].indices, - sizeof(int) * storage->vert_poly_map[vertex_index].count); -#else - const Mesh *mesh = storage->mesh; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; - int num = 0; - for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { - const MPoly *poly = &mpoly[poly_index]; - for (int corner = 0; corner < mpoly->totloop; corner++) { - const MLoop *loop = &mloop[poly->loopstart + corner]; - if (loop->v == vertex_index) { - manifold_vertex_faces[num++] = poly_index; - break; - } - } - } -#endif -} static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, int manifold_vertex_index) @@ -467,16 +247,7 @@ static void free_user_data(const OpenSubdiv_Converter *converter) { ConverterStorage *user_data = converter->user_data; MEM_SAFE_FREE(user_data->loop_uv_indices); -#ifdef USE_MESH_ELEMENT_MAPPING - MEM_freeN(user_data->vert_edge_map); - MEM_freeN(user_data->vert_edge_mem); - MEM_freeN(user_data->vert_poly_map); - MEM_freeN(user_data->vert_poly_mem); - MEM_freeN(user_data->edge_poly_map); - MEM_freeN(user_data->edge_poly_mem); -#endif MEM_freeN(user_data->manifold_vertex_index); - MEM_freeN(user_data->manifold_edge_index); MEM_freeN(user_data->infinite_sharp_vertices_map); MEM_freeN(user_data->manifold_vertex_index_reverse); MEM_freeN(user_data->manifold_edge_index_reverse); @@ -495,17 +266,17 @@ static void init_functions(OpenSubdiv_Converter *converter) converter->getNumFaceVertices = get_num_face_vertices; converter->getFaceVertices = get_face_vertices; - converter->getFaceEdges = get_face_edges; + converter->getFaceEdges = NULL; converter->getEdgeVertices = get_edge_vertices; - converter->getNumEdgeFaces = get_num_edge_faces; - converter->getEdgeFaces = get_edge_faces; + converter->getNumEdgeFaces = NULL; + converter->getEdgeFaces = NULL; converter->getEdgeSharpness = get_edge_sharpness; - converter->getNumVertexEdges = get_num_vertex_edges; - converter->getVertexEdges = get_vertex_edges; - converter->getNumVertexFaces = get_num_vertex_faces; - converter->getVertexFaces = get_vertex_faces; + converter->getNumVertexEdges = NULL; + converter->getVertexEdges = NULL; + converter->getNumVertexFaces = NULL; + converter->getVertexFaces = NULL; converter->isInfiniteSharpVertex = is_infinite_sharp_vertex; converter->getNumUVLayers = get_num_uv_layers; @@ -517,55 +288,45 @@ static void init_functions(OpenSubdiv_Converter *converter) converter->freeUserData = free_user_data; } -static void create_element_maps_if_needed(ConverterStorage *storage) -{ -#ifdef USE_MESH_ELEMENT_MAPPING - const Mesh *mesh = storage->mesh; - BKE_mesh_vert_edge_map_create(&storage->vert_edge_map, - &storage->vert_edge_mem, - mesh->medge, - mesh->totvert, - mesh->totedge); - BKE_mesh_vert_poly_map_create(&storage->vert_poly_map, - &storage->vert_poly_mem, - mesh->mpoly, - mesh->mloop, - mesh->totvert, - mesh->totpoly, - mesh->totloop); - BKE_mesh_edge_poly_map_create(&storage->edge_poly_map, - &storage->edge_poly_mem, - mesh->medge, mesh->totedge, - mesh->mpoly, mesh->totpoly, - mesh->mloop, mesh->totloop); -#else - (void) storage; /* Ignored. */ -#endif -} - static void initialize_manifold_index_array(const BLI_bitmap *used_map, const int num_elements, int **indices_r, int **indices_reverse_r, int *num_manifold_elements_r) { - int *indices = MEM_malloc_arrayN( + int *indices = NULL; + if (indices_r != NULL) { + indices = MEM_malloc_arrayN( num_elements, sizeof(int), "manifold indices"); - int *indices_reverse = MEM_malloc_arrayN( + } + int *indices_reverse = NULL; + if (indices_reverse_r != NULL) { + indices_reverse = MEM_malloc_arrayN( num_elements, sizeof(int), "manifold indices reverse"); + } int offset = 0; for (int i = 0; i < num_elements; i++) { if (BLI_BITMAP_TEST_BOOL(used_map, i)) { - indices[i] = i - offset; - indices_reverse[i - offset] = i; + if (indices != NULL) { + indices[i] = i - offset; + } + if (indices_reverse != NULL) { + indices_reverse[i - offset] = i; + } } else { - indices[i] = -1; + if (indices != NULL) { + indices[i] = -1; + } offset++; } } - *indices_r = indices; - *indices_reverse_r = indices_reverse; + if (indices_r != NULL) { + *indices_r = indices; + } + if (indices_reverse_r != NULL) { + *indices_reverse_r = indices_reverse; + } *num_manifold_elements_r = num_elements - offset; } @@ -593,7 +354,7 @@ static void initialize_manifold_indices(ConverterStorage *storage) &storage->num_manifold_vertices); initialize_manifold_index_array(edge_used_map, mesh->totedge, - &storage->manifold_edge_index, + NULL, &storage->manifold_edge_index_reverse, &storage->num_manifold_edges); /* Initialize infinite sharp mapping. */ @@ -620,7 +381,6 @@ static void init_user_data(OpenSubdiv_Converter *converter, user_data->settings = *settings; user_data->mesh = mesh; user_data->loop_uv_indices = NULL; - create_element_maps_if_needed(user_data); initialize_manifold_indices(user_data); converter->user_data = user_data; } -- cgit v1.2.3 From 4fe14d6a26e101a32e6a0ec9722248d215287a9d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 15:43:57 +0200 Subject: Subsurf: Support subdivision of mesh with just loose elements --- source/blender/blenkernel/intern/subdiv.c | 22 +++++++++++++++++----- source/blender/blenkernel/intern/subdiv_eval.c | 8 +++++++- source/blender/modifiers/intern/MOD_subsurf.c | 6 +----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index d8e0c517d91..bae5491c079 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -29,6 +29,8 @@ #include "BKE_subdiv.h" +#include "DNA_mesh_types.h" + #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" @@ -52,11 +54,18 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, OpenSubdiv_TopologyRefinerSettings topology_refiner_settings; topology_refiner_settings.level = settings->level; topology_refiner_settings.is_adaptive = settings->is_adaptive; - struct OpenSubdiv_TopologyRefiner *osd_topology_refiner = - openSubdiv_createTopologyRefinerFromConverter( - converter, &topology_refiner_settings); - if (osd_topology_refiner == NULL) { - return NULL; + struct OpenSubdiv_TopologyRefiner *osd_topology_refiner = NULL; + if (converter->getNumVertices(converter) != 0) { + osd_topology_refiner = + openSubdiv_createTopologyRefinerFromConverter( + converter, &topology_refiner_settings); + + } + else { + /* TODO(sergey): Check whether original geometry had any vertices. + * The thing here is: OpenSubdiv can only deal with faces, but our + * side of subdiv also deals with loose vertices and edges. + */ } Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converetr"); subdiv->settings = *settings; @@ -75,6 +84,9 @@ Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, struct Mesh *mesh) { #ifdef WITH_OPENSUBDIV + if (mesh->totvert == 0) { + return NULL; + } OpenSubdiv_Converter converter; BKE_subdiv_converter_init_for_mesh(&converter, settings, mesh); Subdiv *subdiv = BKE_subdiv_new_from_converter(settings, &converter); diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 7c90a2a25cd..0f928331724 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -48,7 +48,10 @@ void BKE_subdiv_eval_begin(Subdiv *subdiv) { #ifdef WITH_OPENSUBDIV - if (subdiv->evaluator == NULL) { + if (subdiv->topology_refiner == NULL) { + /* Happens on input mesh with just loose geometry. */ + } + else if (subdiv->evaluator == NULL) { BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( subdiv->topology_refiner); @@ -132,6 +135,9 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) { #ifdef WITH_OPENSUBDIV BKE_subdiv_eval_begin(subdiv); + if (subdiv->evaluator == NULL) { + return; + } /* Set coordinates of base mesh vertices. */ set_coarse_positions(subdiv, mesh); /* Set face-varyign data to UV maps. */ diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index 08dc7c92693..1b25b4f62dc 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -236,11 +236,7 @@ static Mesh *applyModifier_subdiv(ModifierData *md, /* TODO(sergey): Try to re-use subdiv when possible. */ Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh); if (subdiv == NULL) { - /* Happens on bad topology. */ - /* TODO(sergey): This also happens on meshes without faces, so probably - * need to handle those differently (i.e. set modifier error when - * topology itself is bad, and not do anything when there are no faces). - */ + /* Happens on bad topology, ut also on empty input mesh. */ return result; } SubdivToMeshSettings mesh_settings; -- cgit v1.2.3 From 5b3b0ed54f20fedcd4d5324c17f3d5ea39f6274f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 16:04:22 +0200 Subject: Subsurf: Add API to provide vertex sharpness Currently unused, added for the future and API completeness. --- intern/opensubdiv/internal/opensubdiv_converter_factory.cc | 11 ++++++++--- intern/opensubdiv/opensubdiv_converter_capi.h | 4 ++++ source/blender/blenkernel/intern/subdiv_converter_mesh.c | 7 +++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc index 321f580af97..901a421314a 100644 --- a/intern/opensubdiv/internal/opensubdiv_converter_factory.cc +++ b/intern/opensubdiv/internal/opensubdiv_converter_factory.cc @@ -379,13 +379,18 @@ inline bool TopologyRefinerFactory::assignComponentTags( if (converter->isInfiniteSharpVertex(converter, vertex_index)) { setBaseVertexSharpness( refiner, vertex_index, Crease::SHARPNESS_INFINITE); - } else if (vertex_edges.size() == 2) { + continue; + } + float sharpness = converter->getVertexSharpness(converter, vertex_index); + if (vertex_edges.size() == 2) { const int edge0 = vertex_edges[0], edge1 = vertex_edges[1]; const float sharpness0 = refiner._levels[0]->getEdgeSharpness(edge0); const float sharpness1 = refiner._levels[0]->getEdgeSharpness(edge1); - const float sharpness = std::min(sharpness0, sharpness1); - setBaseVertexSharpness(refiner, vertex_index, sharpness); + // TODO(sergey): Find a better mixing between edge and vertex sharpness. + sharpness += std::min(sharpness0, sharpness1); + sharpness = std::min(sharpness, 1.0f); } + setBaseVertexSharpness(refiner, vertex_index, sharpness); } return true; } diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 1dd68f43c32..9f559ee208b 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -111,6 +111,10 @@ typedef struct OpenSubdiv_Converter { bool (*isInfiniteSharpVertex)(const struct OpenSubdiv_Converter* converter, const int vertex_index); + // If vertex is not infinitely sharp, this is it's actual sharpness. + float (*getVertexSharpness)(const struct OpenSubdiv_Converter* converter, + const int vertex_index); + ////////////////////////////////////////////////////////////////////////////// // Face-varying data. diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 5e320678814..b1e3be6c799 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -171,6 +171,12 @@ static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, vertex_index); } +static float get_vertex_sharpness(const OpenSubdiv_Converter *UNUSED(converter), + int UNUSED(manifold_vertex_index)) +{ + return 0.0f; +} + static int get_num_uv_layers(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; @@ -278,6 +284,7 @@ static void init_functions(OpenSubdiv_Converter *converter) converter->getNumVertexFaces = NULL; converter->getVertexFaces = NULL; converter->isInfiniteSharpVertex = is_infinite_sharp_vertex; + converter->getVertexSharpness = get_vertex_sharpness; converter->getNumUVLayers = get_num_uv_layers; converter->precalcUVLayer = precalc_uv_layer; -- cgit v1.2.3 From 86270b60dbeab29b4dc7dd9b596bcf0d533639d0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 1 Aug 2018 18:31:05 +0200 Subject: Subsurf: Evaluate all UV layers Before that it was only first UV layer which was properly evaluated, the rest were ignored. Now all layers are being properly handled. --- intern/opensubdiv/internal/opensubdiv_evaluator.cc | 12 +- .../internal/opensubdiv_evaluator_internal.cc | 291 ++++++++++++++------- .../internal/opensubdiv_evaluator_internal.h | 9 +- intern/opensubdiv/internal/opensubdiv_util.h | 5 + intern/opensubdiv/opensubdiv_evaluator_capi.h | 3 + source/blender/blenkernel/BKE_subdiv.h | 1 + .../blenkernel/intern/subdiv_converter_mesh.c | 2 +- source/blender/blenkernel/intern/subdiv_eval.c | 16 +- source/blender/blenkernel/intern/subdiv_mesh.c | 8 +- 9 files changed, 225 insertions(+), 122 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator.cc b/intern/opensubdiv/internal/opensubdiv_evaluator.cc index 29d42a903ba..49b8626448b 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator.cc @@ -42,9 +42,11 @@ void setVaryingData(OpenSubdiv_Evaluator* evaluator, } void setFaceVaryingData(OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const float* face_varying_data, const int start_vertex_index, const int num_vertices) { - evaluator->internal->eval_output->setFaceVaryingData(face_varying_data, + evaluator->internal->eval_output->setFaceVaryingData(face_varying_channel, + face_varying_data, start_vertex_index, num_vertices); } @@ -78,12 +80,14 @@ void setVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator, } void setFaceVaryingDataFromBuffer(OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const void* buffer, const int start_offset, const int stride, const int start_vertex_index, const int num_vertices) { evaluator->internal->eval_output->setFaceVaryingDataFromBuffer( + face_varying_channel, buffer, start_offset, stride, @@ -114,12 +118,12 @@ void evaluateVarying(OpenSubdiv_Evaluator* evaluator, } void evaluateFaceVarying(OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const int ptex_face_index, float face_u, float face_v, float face_varying[2]) { - evaluator->internal->eval_output->evaluateFaceVarying(ptex_face_index, - face_u, face_v, - face_varying); + evaluator->internal->eval_output->evaluateFaceVarying( + face_varying_channel, ptex_face_index, face_u, face_v, face_varying); } void assignFunctionPointers(OpenSubdiv_Evaluator* evaluator) { diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index d593518405f..31e68492587 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -39,6 +39,7 @@ #include "MEM_guardedalloc.h" #include "internal/opensubdiv_topology_refiner_internal.h" +#include "internal/opensubdiv_util.h" #include "opensubdiv_topology_refiner_capi.h" using OpenSubdiv::Osd::BufferDescriptor; @@ -147,6 +148,106 @@ class StackAllocatedBuffer { float data_[element_size * num_vertices]; }; +template +class FaceVaryingVolatileEval { + public: + typedef OpenSubdiv::Osd::EvaluatorCacheT EvaluatorCache; + + FaceVaryingVolatileEval(int face_varying_channel, + const StencilTable* face_varying_stencils, + int face_varying_width, + PATCH_TABLE* patch_table, + EvaluatorCache* evaluator_cache = NULL, + DEVICE_CONTEXT* device_context = NULL) + : face_varying_channel_(face_varying_channel), + src_face_varying_desc_(0, face_varying_width, face_varying_width), + patch_table_(patch_table), + evaluator_cache_(evaluator_cache), + device_context_(device_context) { + using OpenSubdiv::Osd::convertToCompatibleStencilTable; + num_coarse_face_varying_vertices_ = + face_varying_stencils->GetNumControlVertices(); + const int num_total_face_varying_vertices = + face_varying_stencils->GetNumControlVertices() + + face_varying_stencils->GetNumStencils(); + src_face_varying_data_ = + EVAL_VERTEX_BUFFER::Create(2, + num_total_face_varying_vertices, + device_context); + face_varying_stencils_ = convertToCompatibleStencilTable( + face_varying_stencils, device_context_); + } + + ~FaceVaryingVolatileEval() { + delete src_face_varying_data_; + delete face_varying_stencils_; + } + + void updateData(const float* src, int start_vertex, int num_vertices) { + src_face_varying_data_->UpdateData(src, + start_vertex, + num_vertices, + device_context_); + } + + void refine() { + BufferDescriptor dst_face_varying_desc = src_face_varying_desc_; + dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ * + src_face_varying_desc_.stride; + const EVALUATOR* eval_instance = OpenSubdiv::Osd::GetEvaluator( + evaluator_cache_, + src_face_varying_desc_, + dst_face_varying_desc, + device_context_); + EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_, + src_face_varying_data_, dst_face_varying_desc, + face_varying_stencils_, + eval_instance, + device_context_); + } + + void evalPatch(const PatchCoord& patch_coord, float face_varying[2]) { + StackAllocatedBuffer<2, 1> face_varying_data; + BufferDescriptor face_varying_desc(0, 2, 2); + SinglePatchCoordBuffer patch_coord_buffer(patch_coord); + const EVALUATOR* eval_instance = + OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, + src_face_varying_desc_, + face_varying_desc, + device_context_); + EVALUATOR::EvalPatchesFaceVarying( + src_face_varying_data_, src_face_varying_desc_, + &face_varying_data, face_varying_desc, + patch_coord_buffer.GetNumVertices(), + &patch_coord_buffer, + patch_table_, + face_varying_channel_, + eval_instance, + device_context_); + const float* refined_face_varying = face_varying_data.BindCpuBuffer(); + memcpy(face_varying, refined_face_varying, sizeof(float) * 2); + } + + protected: + int face_varying_channel_; + + BufferDescriptor src_face_varying_desc_; + + int num_coarse_face_varying_vertices_; + EVAL_VERTEX_BUFFER* src_face_varying_data_; + const STENCIL_TABLE* face_varying_stencils_; + + // NOTE: We reference this, do not own it. + PATCH_TABLE* patch_table_; + + EvaluatorCache* evaluator_cache_; + DEVICE_CONTEXT* device_context_; +}; + // Volatile evaluator which can be used from threads. // // TODO(sergey): Make it possible to evaluate coordinates in chunks. @@ -162,19 +263,22 @@ template EvaluatorCache; - - VolatileEvalOutput(const StencilTable* vertex_stencils, - const StencilTable* varying_stencils, - const StencilTable* face_varying_stencils, - const int face_varying_channel, - const int face_varying_width, - const PatchTable* patch_table, - EvaluatorCache* evaluator_cache = NULL, - DEVICE_CONTEXT* device_context = NULL) + typedef FaceVaryingVolatileEval FaceVaryingEval; + + VolatileEvalOutput( + const StencilTable* vertex_stencils, + const StencilTable* varying_stencils, + const vector& all_face_varying_stencils, + const int face_varying_width, + const PatchTable* patch_table, + EvaluatorCache* evaluator_cache = NULL, + DEVICE_CONTEXT* device_context = NULL) : src_desc_(0, 3, 3), src_varying_desc_(0, 3, 3), - src_face_varying_desc_(0, face_varying_width, face_varying_width), - face_varying_channel_(face_varying_channel), face_varying_width_(face_varying_width), evaluator_cache_(evaluator_cache), device_context_(device_context) { @@ -193,33 +297,31 @@ class VolatileEvalOutput { vertex_stencils, device_context_); varying_stencils_ = convertToCompatibleStencilTable( varying_stencils, device_context_); - if (face_varying_stencils != NULL) { - num_coarse_face_varying_vertices_ = - face_varying_stencils->GetNumControlVertices(); - const int num_total_face_varying_vertices = - face_varying_stencils->GetNumControlVertices() + - face_varying_stencils->GetNumStencils(); - src_face_varying_data_ = - EVAL_VERTEX_BUFFER::Create(2, - num_total_face_varying_vertices, - device_context_); - face_varying_stencils_ = convertToCompatibleStencilTable( - face_varying_stencils, device_context_); - } else { - num_coarse_face_varying_vertices_ = 0; - src_face_varying_data_ = NULL; - face_varying_stencils_ = NULL; + // Create evaluators for every face varying channel. + face_varying_evaluators.reserve(all_face_varying_stencils.size()); + int face_varying_channel = 0; + foreach (const StencilTable* face_varying_stencils, + all_face_varying_stencils) { + face_varying_evaluators.push_back( + new FaceVaryingEval(face_varying_channel, + face_varying_stencils, + face_varying_width, + patch_table_, + evaluator_cache_, + device_context_)); + ++face_varying_channel; } } ~VolatileEvalOutput() { delete src_data_; delete src_varying_data_; - delete src_face_varying_data_; delete patch_table_; delete vertex_stencils_; delete varying_stencils_; - delete face_varying_stencils_; + foreach (FaceVaryingEval* face_varying_evaluator, face_varying_evaluators) { + delete face_varying_evaluator; + } } // TODO(sergey): Implement binding API. @@ -235,13 +337,14 @@ class VolatileEvalOutput { device_context_); } - void updateFaceVaryingData(const float* src, + void updateFaceVaryingData(const int face_varying_channel, + const float* src, int start_vertex, int num_vertices) { - src_face_varying_data_->UpdateData(src, - start_vertex, - num_vertices, - device_context_); + assert(face_varying_channel >= 0); + assert(face_varying_channel < face_varying_evaluators.size()); + face_varying_evaluators[face_varying_channel]->updateData( + src, start_vertex, num_vertices); } bool hasVaryingData() const { @@ -251,7 +354,7 @@ class VolatileEvalOutput { } bool hasFaceVaryingData() const { - return face_varying_stencils_ != NULL; + return face_varying_evaluators.size() != 0; } void refine() { @@ -285,19 +388,10 @@ class VolatileEvalOutput { } // Evaluate face-varying data. if (hasFaceVaryingData()) { - BufferDescriptor dst_face_varying_desc = src_face_varying_desc_; - dst_face_varying_desc.offset += num_coarse_face_varying_vertices_ * - src_face_varying_desc_.stride; - eval_instance = OpenSubdiv::Osd::GetEvaluator( - evaluator_cache_, - src_face_varying_desc_, - dst_face_varying_desc, - device_context_); - EVALUATOR::EvalStencils(src_face_varying_data_, src_face_varying_desc_, - src_face_varying_data_, dst_face_varying_desc, - face_varying_stencils_, - eval_instance, - device_context_); + foreach (FaceVaryingEval* face_varying_evaluator, + face_varying_evaluators) { + face_varying_evaluator->refine(); + } } } @@ -384,47 +478,30 @@ class VolatileEvalOutput { memcpy(varying, refined_varying, sizeof(float) * 3); } - void evalPatchFaceVarying(const PatchCoord& patch_coord, + void evalPatchFaceVarying(const int face_varying_channel, + const PatchCoord& patch_coord, float face_varying[2]) { - StackAllocatedBuffer<2, 1> face_varying_data; - BufferDescriptor face_varying_desc(0, 2, 2); - SinglePatchCoordBuffer patch_coord_buffer(patch_coord); - const EVALUATOR* eval_instance = - OpenSubdiv::Osd::GetEvaluator(evaluator_cache_, - src_face_varying_desc_, - face_varying_desc, - device_context_); - EVALUATOR::EvalPatchesFaceVarying( - src_face_varying_data_, src_face_varying_desc_, - &face_varying_data, face_varying_desc, - patch_coord_buffer.GetNumVertices(), - &patch_coord_buffer, - patch_table_, - face_varying_channel_, - eval_instance, - device_context_); - const float* refined_face_varying = face_varying_data.BindCpuBuffer(); - memcpy(face_varying, refined_face_varying, sizeof(float) * 2); + assert(face_varying_channel >= 0); + assert(face_varying_channel < face_varying_evaluators.size()); + face_varying_evaluators[face_varying_channel]->evalPatch( + patch_coord, face_varying); } private: SRC_VERTEX_BUFFER* src_data_; SRC_VERTEX_BUFFER* src_varying_data_; - EVAL_VERTEX_BUFFER* src_face_varying_data_; PatchCoordBuffer* patch_coords_; PATCH_TABLE* patch_table_; BufferDescriptor src_desc_; BufferDescriptor src_varying_desc_; - BufferDescriptor src_face_varying_desc_; int num_coarse_vertices_; - int face_varying_channel_; - int face_varying_width_; - int num_coarse_face_varying_vertices_; const STENCIL_TABLE* vertex_stencils_; const STENCIL_TABLE* varying_stencils_; - const STENCIL_TABLE* face_varying_stencils_; + + int face_varying_width_; + vector face_varying_evaluators; EvaluatorCache* evaluator_cache_; DEVICE_CONTEXT* device_context_; @@ -442,8 +519,7 @@ class CpuEvalOutput : public VolatileEvalOutput& all_face_varying_stencils, const int face_varying_width, const PatchTable* patch_table, EvaluatorCache* evaluator_cache = NULL) @@ -453,8 +529,7 @@ class CpuEvalOutput : public VolatileEvalOutput (vertex_stencils, varying_stencils, - face_varying_stencils, - face_varying_channel, + all_face_varying_stencils, face_varying_width, patch_table, evaluator_cache) { @@ -490,11 +565,13 @@ void CpuEvalOutputAPI::setVaryingData(const float* varying_data, num_vertices); } -void CpuEvalOutputAPI::setFaceVaryingData(const float* face_varying_data, +void CpuEvalOutputAPI::setFaceVaryingData(const int face_varying_channel, + const float* face_varying_data, const int start_vertex_index, const int num_vertices) { // TODO(sergey): Add sanity check on indices. - implementation_->updateFaceVaryingData(face_varying_data, + implementation_->updateFaceVaryingData(face_varying_channel, + face_varying_data, start_vertex_index, num_vertices); } @@ -535,6 +612,7 @@ void CpuEvalOutputAPI::setVaryingDataFromBuffer( } void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer( + const int face_varying_channel, const void* buffer, const int start_offset, const int stride, @@ -546,6 +624,7 @@ void CpuEvalOutputAPI::setFaceVaryingDataFromBuffer( for (int i = 0; i < num_vertices; ++i) { const int current_vertex_index = start_vertex_index + i; implementation_->updateFaceVaryingData( + face_varying_channel, reinterpret_cast(current_buffer), current_vertex_index, 1); current_buffer += stride; @@ -585,7 +664,8 @@ void CpuEvalOutputAPI::evaluateVarying(const int ptex_face_index, implementation_->evalPatchVarying(patch_coord, varying); } -void CpuEvalOutputAPI::evaluateFaceVarying(const int ptex_face_index, +void CpuEvalOutputAPI::evaluateFaceVarying(const int face_varying_channel, + const int ptex_face_index, float face_u, float face_v, float face_varying[2]) { assert(face_u >= 0.0f); @@ -595,7 +675,8 @@ void CpuEvalOutputAPI::evaluateFaceVarying(const int ptex_face_index, const PatchTable::PatchHandle* handle = patch_map_->FindPatch(ptex_face_index, face_u, face_v); PatchCoord patch_coord(*handle, face_u, face_v); - implementation_->evalPatchFaceVarying(patch_coord, face_varying); + implementation_->evalPatchFaceVarying( + face_varying_channel, patch_coord, face_varying); } } // namespace opensubdiv_capi @@ -614,6 +695,7 @@ OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal() { OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( OpenSubdiv_TopologyRefiner* topology_refiner) { + using opensubdiv_capi::vector; TopologyRefiner* refiner = topology_refiner->internal->osd_topology_refiner; if (refiner == NULL) { // Happens on bad topology. @@ -621,8 +703,8 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( } // TODO(sergey): Base this on actual topology. // const bool bas_varying_data = false; - const bool has_face_varying_data = - (refiner->GetNumFVarChannels() != 0); + const int num_face_varying_channels = refiner->GetNumFVarChannels(); + const bool has_face_varying_data = (num_face_varying_channels != 0); const int level = topology_refiner->getSubdivisionLevel(topology_refiner); // TODO(sergey): Query from topology refiner. const bool is_adaptive = topology_refiner->getIsAdaptive(topology_refiner); @@ -659,19 +741,20 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( varying_stencils = StencilTableFactory::Create(*refiner, varying_stencil_options); // Face warying stencil. - const StencilTable* face_varying_stencils = NULL; +vector all_face_varying_stencils; #ifdef OPENSUBDIV_HAS_FVAR_EVALUATION - if (has_face_varying_data) { + all_face_varying_stencils.reserve(num_face_varying_channels); + for (int face_varying_channel = 0; + face_varying_channel < num_face_varying_channels; + ++face_varying_channel) { StencilTableFactory::Options face_varying_stencil_options; face_varying_stencil_options.generateOffsets = true; face_varying_stencil_options.generateIntermediateLevels = is_adaptive; face_varying_stencil_options.interpolationMode = StencilTableFactory::INTERPOLATE_FACE_VARYING; - // TODO(sergey): Make it configurable which face varying channel is being - // interpolated. - face_varying_stencil_options.fvarChannel = 0; - face_varying_stencils = - StencilTableFactory::Create(*refiner, face_varying_stencil_options); + face_varying_stencil_options.fvarChannel = face_varying_channel; + all_face_varying_stencils.push_back( + StencilTableFactory::Create(*refiner, face_varying_stencil_options)); } #endif // Generate bi-cubic patch table for the limit surface. @@ -705,16 +788,20 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( varying_stencils = table; } #ifdef OPENSUBDIV_HAS_FVAR_EVALUATION - const StencilTable* local_point_face_varying_stencil_table = - patch_table->GetLocalPointFaceVaryingStencilTable(); - if (local_point_face_varying_stencil_table != NULL) { + for (int face_varying_channel = 0; + face_varying_channel < num_face_varying_channels; + ++face_varying_channel) { const StencilTable* table = StencilTableFactory::AppendLocalPointStencilTableFaceVarying( *refiner, - face_varying_stencils, - local_point_face_varying_stencil_table); - delete face_varying_stencils; - face_varying_stencils = table; + all_face_varying_stencils[face_varying_channel], + patch_table->GetLocalPointFaceVaryingStencilTable( + face_varying_channel), + face_varying_channel); + if (table != NULL) { + delete all_face_varying_stencils[face_varying_channel]; + all_face_varying_stencils[face_varying_channel] = table; + } } #endif // Create OpenSubdiv's CPU side evaluator. @@ -722,8 +809,8 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( opensubdiv_capi::CpuEvalOutput* eval_output = new opensubdiv_capi::CpuEvalOutput(vertex_stencils, varying_stencils, - face_varying_stencils, - 0, 2, + all_face_varying_stencils, + 2, patch_table); OpenSubdiv::Far::PatchMap* patch_map = new PatchMap(*patch_table); // Wrap everything we need into an object which we control from our side. @@ -736,7 +823,9 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( // TOOD(sergey): Look into whether we've got duplicated stencils arrays. delete vertex_stencils; delete varying_stencils; - delete face_varying_stencils; + foreach (const StencilTable* table, all_face_varying_stencils) { + delete table; + } return evaluator_descr; } diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h index cc69db6abc6..7d9178f38dc 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.h @@ -57,7 +57,8 @@ class CpuEvalOutputAPI { // // TODO(sergey): Find a better name for vertex here. It is not the vertex of // geometry, but a vertex of UV map. - void setFaceVaryingData(const float* varying_data, + void setFaceVaryingData(const int face_varying_channel, + const float* varying_data, const int start_vertex_index, const int num_vertices); // Set coarse vertex position from a continuous memory buffer where @@ -82,7 +83,8 @@ class CpuEvalOutputAPI { // // TODO(sergey): Find a better name for vertex here. It is not the vertex of // geometry, but a vertex of UV map. - void setFaceVaryingDataFromBuffer(const void* buffer, + void setFaceVaryingDataFromBuffer(const int face_varying_channel, + const void* buffer, const int start_offset, const int stride, const int start_vertex_index, @@ -104,7 +106,8 @@ class CpuEvalOutputAPI { // Evaluate facee-varying data at a given bilinear coordinate of given // ptex face. - void evaluateFaceVarying(const int ptes_face_index, + void evaluateFaceVarying(const int face_varying_channel, + const int ptes_face_index, float face_u, float face_v, float face_varying[2]); diff --git a/intern/opensubdiv/internal/opensubdiv_util.h b/intern/opensubdiv/internal/opensubdiv_util.h index 6ed19b37e33..db55504215d 100644 --- a/intern/opensubdiv/internal/opensubdiv_util.h +++ b/intern/opensubdiv/internal/opensubdiv_util.h @@ -25,6 +25,11 @@ namespace opensubdiv_capi { +using std::string; +using std::vector; + +#define foreach(x, y) for(x : y) + #define STRINGIFY_ARG(x) "" #x #define STRINGIFY_APPEND(a, b) "" a #b #define STRINGIFY(x) STRINGIFY_APPEND("", x) diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.h b/intern/opensubdiv/opensubdiv_evaluator_capi.h index 07a55cfd349..eda5d614635 100644 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.h +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.h @@ -41,6 +41,7 @@ typedef struct OpenSubdiv_Evaluator { // TODO(sergey): Find a better name for vertex here. It is not the vertex of // geometry, but a vertex of UV map. void (*setFaceVaryingData)(struct OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const float* face_varying_data, const int start_vertex_index, const int num_vertices); @@ -70,6 +71,7 @@ typedef struct OpenSubdiv_Evaluator { // TODO(sergey): Find a better name for vertex here. It is not the vertex of // geometry, but a vertex of UV map. void (*setFaceVaryingDataFromBuffer)(struct OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const void* buffer, const int start_offset, const int stride, @@ -95,6 +97,7 @@ typedef struct OpenSubdiv_Evaluator { // Evaluate face-varying data at a given bilinear coordinate of given // ptex face. void (*evaluateFaceVarying)(struct OpenSubdiv_Evaluator* evaluator, + const int face_varying_channel, const int ptex_face_index, float face_u, float face_v, float face_varying[2]); diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index ad829946db8..cd1e3adbc21 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -158,6 +158,7 @@ void BKE_subdiv_eval_limit_point_and_short_normal( void BKE_subdiv_eval_face_varying( Subdiv *subdiv, + const int face_varying_channel, const int ptex_face_index, const float u, const float v, float varying[2]); diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index b1e3be6c799..963f403e8d3 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -157,7 +157,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, storage->manifold_edge_index_reverse[manifold_edge_index]; const MEdge *medge = storage->mesh->medge; const float edge_crease = (float)medge[edge_index].crease / 255.0f; - return edge_crease * storage->settings.level; + return edge_crease * storage->settings.level * 10; } diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 0f928331724..fa9488f15b6 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -122,10 +122,11 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, vertex_index < num_face_vertices; vertex_index++, mluv++) { - evaluator->setFaceVaryingData(evaluator, - mluv->uv, - uv_indicies[vertex_index], - 1); + evaluator->setFaceVaryingData(evaluator, + layer_index, + mluv->uv, + uv_indicies[vertex_index], + 1); } } } @@ -147,11 +148,6 @@ void BKE_subdiv_eval_update_from_mesh(Subdiv *subdiv, const Mesh *mesh) const MLoopUV *mloopuv = CustomData_get_layer_n( &mesh->ldata, CD_MLOOPUV, layer_index); set_face_varying_data_from_uv(subdiv, mloopuv, layer_index); - /* NOTE: Currently evaluator can only handle single face varying layer. - * This is a limitation of C-API and some underlying helper classes from - * our side which will get fixed. - */ - break; } /* Update evaluator to the new coarse geometry. */ BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_REFINE); @@ -223,12 +219,14 @@ void BKE_subdiv_eval_limit_point_and_short_normal( void BKE_subdiv_eval_face_varying( Subdiv *subdiv, + const int face_varying_channel, const int ptex_face_index, const float u, const float v, float face_varying[2]) { #ifdef WITH_OPENSUBDIV subdiv->evaluator->evaluateFaceVarying(subdiv->evaluator, + face_varying_channel, ptex_face_index, u, v, face_varying); diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index befd2b9847c..a58dbdcff84 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -1509,25 +1509,25 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index]; BKE_subdiv_eval_face_varying(subdiv, + layer_index, ptex_face_index, u, v, subdiv_loopuv[0].uv); BKE_subdiv_eval_face_varying(subdiv, + layer_index, ptex_face_index, u + du, v, subdiv_loopuv[1].uv); BKE_subdiv_eval_face_varying(subdiv, + layer_index, ptex_face_index, u + du, v + dv, subdiv_loopuv[2].uv); BKE_subdiv_eval_face_varying(subdiv, + layer_index, ptex_face_index, u, v + dv, subdiv_loopuv[3].uv); - /* TODO(sergey): Currently evaluator only has single UV layer, so can - * not evaluate more than that. Need to be solved. - */ - break; } } -- cgit v1.2.3 From e50a3dd4c4e9a9898df31e444d1002770b4efb9c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 1 Aug 2018 19:31:27 +0200 Subject: Fix T56197: Cycles OpenCL build error after recent changes. --- intern/cycles/util/util_defines.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/intern/cycles/util/util_defines.h b/intern/cycles/util/util_defines.h index 1a09f659eb1..8bce4aca699 100644 --- a/intern/cycles/util/util_defines.h +++ b/intern/cycles/util/util_defines.h @@ -88,9 +88,13 @@ #endif #if defined(__GNUC__) || defined(__clang__) +# if defined(__cplusplus) /* Some magic to be sure we don't have reference in the type. */ template static inline T decltype_helper(T x) { return x; } -# define TYPEOF(x) decltype(decltype_helper(x)) +# define TYPEOF(x) decltype(decltype_helper(x)) +# else +# define TYPEOF(x) typeof(x) +# endif #endif /* Causes warning: -- cgit v1.2.3 From c6f55fb0db126281309a2082abf2f480a4671dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 18:02:57 +0200 Subject: GPUUniformBuffer: Fix bad memcpy error catched by asan We need to copy the size of the gputype not the padded type. --- source/blender/gpu/intern/gpu_uniformbuffer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c index 9b8441efd08..3f5706c1f7b 100644 --- a/source/blender/gpu/intern/gpu_uniformbuffer.c +++ b/source/blender/gpu/intern/gpu_uniformbuffer.c @@ -159,9 +159,8 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou float *offset = ubo->data; for (LinkData *link = inputs->first; link; link = link->next) { GPUInput *input = link->data; - const GPUType gputype = get_padded_gpu_type(link); - memcpy(offset, input->dynamicvec, gputype * sizeof(float)); - offset += gputype; + memcpy(offset, input->dynamicvec, input->type * sizeof(float)); + offset += get_padded_gpu_type(link); } /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one, -- cgit v1.2.3 From 4510f30026da8eb090062687f386b9e3a7cf3fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 18:07:19 +0200 Subject: GPUMaterial: Fix nearest sampling texelFetch return vec4(0.0) if the target pixel is outside the texture rect. So we mimic the default repeate mode that we have for linear interpolation. Fix T56156 Mapping-Node doesn't work --- source/blender/gpu/shaders/gpu_shader_material.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 464851bae21..8cc603696df 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1809,7 +1809,7 @@ void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alp void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha) { - ivec2 pix = ivec2(co.xy * textureSize(ima, 0).xy); + ivec2 pix = ivec2(fract(co.xy) * textureSize(ima, 0).xy); color = texelFetch(ima, pix, 0); alpha = color.a; } -- cgit v1.2.3 From ad64cb63448d69ec1667bfa2e4941dfb996841dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 19:25:58 +0200 Subject: GPUMaterial: Make Localize tree live longer This is in order to reference the localized node->storage when populating the UBO data. --- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/gpu/intern/gpu_material.c | 9 ++++++++- source/blender/nodes/shader/node_shader_tree.c | 8 ++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index cf55885a5ef..901822583cb 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -811,7 +811,7 @@ void ntreeShaderEndExecTree(struct bNodeTreeExec *exec); bool ntreeShaderExecTree(struct bNodeTree *ntree, int thread); struct bNode *ntreeShaderOutputNode(struct bNodeTree *ntree, int target); -void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, +void ntreeGPUMaterialNodes(struct bNodeTree *localtree, struct GPUMaterial *mat, bool *has_surface_output, bool *has_volume_output); /** \} */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 2264836f24a..5e0d9275aa2 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -595,7 +595,9 @@ GPUMaterial *GPU_material_from_nodetree( mat->engine_type = engine_type; mat->options = options; - ntreeGPUMaterialNodes(ntree, mat, &has_surface_output, &has_volume_output); + /* localize tree to create links for reroute and mute */ + bNodeTree *localtree = ntreeLocalize(ntree); + ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output); if (has_surface_output) { mat->domain |= GPU_DOMAIN_SURFACE; @@ -640,6 +642,11 @@ GPUMaterial *GPU_material_from_nodetree( mat->status = GPU_MAT_FAILED; } + /* Only free after GPU_pass_shader_get where GPUUniformBuffer + * read data from the local tree. */ + ntreeFreeTree(localtree); + MEM_freeN(localtree); + /* note that even if building the shader fails in some way, we still keep * it to avoid trying to compile again and again, and simply do not use * the actual shader on drawing */ diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 919af171756..6f2c7835a3c 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -583,10 +583,9 @@ static void ntree_shader_tag_sss_node(bNodeTree *ntree, bNode *output_node) nodeChainIter(ntree, output_node, ntree_tag_sss_bsdf_cb, &sss_id, true); } -void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, bool *has_surface_output, bool *has_volume_output) +/* This one needs to work on a local tree. */ +void ntreeGPUMaterialNodes(bNodeTree *localtree, GPUMaterial *mat, bool *has_surface_output, bool *has_volume_output) { - /* localize tree to create links for reroute and mute */ - bNodeTree *localtree = ntreeLocalize(ntree); bNode *output = ntreeShaderOutputNode(localtree, SHD_OUTPUT_EEVEE); bNodeTreeExec *exec; @@ -618,9 +617,6 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, bool *has_surface *has_volume_output = (nodeCountSocketLinks(localtree, volume_sock) > 0); } } - - ntreeFreeTree(localtree); - MEM_freeN(localtree); } bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key) -- cgit v1.2.3 From e8dd5e5cc6b7366c36f19035f94864a1b320cb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 19:37:18 +0200 Subject: GPUMaterial: Make Mapping node use UBO storage This means tweaking parameter is now interactive and does not need to recompile the shaders. --- source/blender/gpu/shaders/gpu_shader_material.glsl | 8 +++----- source/blender/nodes/shader/node_shader_util.c | 19 ++++++++++++------- .../blender/nodes/shader/nodes/node_shader_mapping.c | 19 ++++++++++++------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 8cc603696df..064ee42907e 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -238,13 +238,11 @@ void point_map_to_tube(vec3 vin, out vec3 vout) vout = vec3(u, v, 0.0); } -void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec) +void mapping(vec3 vec, vec4 m0, vec4 m1, vec4 m2, vec4 m3, vec3 minvec, vec3 maxvec, out vec3 outvec) { + mat4 mat = mat4(m0, m1, m2, m3); outvec = (mat * vec4(vec, 1.0)).xyz; - if (domin == 1.0) - outvec = max(outvec, minvec); - if (domax == 1.0) - outvec = min(outvec, maxvec); + outvec = clamp(outvec, minvec, maxvec); } void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist) diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 9190f0d53cd..63c1cac566d 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -253,13 +253,18 @@ void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0; if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) { - GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat); - GPUNodeLink *tmin = GPU_uniform(texmap->min); - GPUNodeLink *tmax = GPU_uniform(texmap->max); - GPUNodeLink *tdomin = GPU_uniform(&domin); - GPUNodeLink *tdomax = GPU_uniform(&domax); - - GPU_link(mat, "mapping", in[0].link, tmat, tmin, tmax, tdomin, tdomax, &in[0].link); + static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; + static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3; + + tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3); + tmax = GPU_uniform_buffer((domax) ? texmap->max : max, GPU_VEC3); + tmat0 = GPU_uniform_buffer((float *)texmap->mat[0], GPU_VEC4); + tmat1 = GPU_uniform_buffer((float *)texmap->mat[1], GPU_VEC4); + tmat2 = GPU_uniform_buffer((float *)texmap->mat[2], GPU_VEC4); + tmat3 = GPU_uniform_buffer((float *)texmap->mat[3], GPU_VEC4); + + GPU_link(mat, "mapping", in[0].link, tmat0, tmat1, tmat2, tmat3, tmin, tmax, &in[0].link); if (texmap->type == TEXMAP_TYPE_NORMAL) GPU_link(mat, "texco_norm", in[0].link, &in[0].link); diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index a84e88e9551..2541b3bc842 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -88,13 +88,18 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS TexMapping *texmap = node->storage; float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0; float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0; - GPUNodeLink *tmat = GPU_uniform((float *)texmap->mat); - GPUNodeLink *tmin = GPU_uniform(texmap->min); - GPUNodeLink *tmax = GPU_uniform(texmap->max); - GPUNodeLink *tdomin = GPU_uniform(&domin); - GPUNodeLink *tdomax = GPU_uniform(&domax); - - GPU_stack_link(mat, node, "mapping", in, out, tmat, tmin, tmax, tdomin, tdomax); + static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX, 0.0}; + static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX, 0.0}; + GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3; + + tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3); + tmax = GPU_uniform_buffer((domax) ? texmap->max : max, GPU_VEC3); + tmat0 = GPU_uniform_buffer((float *)texmap->mat[0], GPU_VEC4); + tmat1 = GPU_uniform_buffer((float *)texmap->mat[1], GPU_VEC4); + tmat2 = GPU_uniform_buffer((float *)texmap->mat[2], GPU_VEC4); + tmat3 = GPU_uniform_buffer((float *)texmap->mat[3], GPU_VEC4); + + GPU_stack_link(mat, node, "mapping", in, out, tmat0, tmat1, tmat2, tmat3, tmin, tmax); if (texmap->type == TEXMAP_TYPE_NORMAL) GPU_link(mat, "texco_norm", out[0].link, &out[0].link); -- cgit v1.2.3 From 48e661e05de59a055a261430e877f7d8bc4d4c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 21:45:43 +0200 Subject: GPUMaterial: Fix assert when shader failed to compile. --- source/blender/gpu/intern/gpu_shader.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 0d5183d82ab..5346d3f1aee 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -580,7 +580,10 @@ void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader)) void GPU_shader_free(GPUShader *shader) { +#if 0 /* Would be nice to have, but for now the Deferred compilation + * does not have a GPUContext. */ BLI_assert(GPU_context_active_get() != NULL); +#endif BLI_assert(shader); if (shader->vertex) -- cgit v1.2.3 From 504454ee5ec608de89b07476a8abb91b70ca12a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 1 Aug 2018 22:08:08 +0200 Subject: GPUMaterial: Normal Map Node: Make default inputs interactives --- source/blender/nodes/shader/nodes/node_shader_normal_map.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 3c0fb145987..e4b5aaef72d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -63,11 +63,21 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U if (in[0].link) strength = in[0].link; + else if (node->original) { + bNodeSocket *socket = BLI_findlink(&node->original->inputs, 0); + bNodeSocketValueFloat *socket_data = socket->default_value; + strength = GPU_uniform_buffer(&socket_data->value, GPU_FLOAT); + } else strength = GPU_uniform(in[0].vec); if (in[1].link) realnorm = in[1].link; + else if (node->original) { + bNodeSocket *socket = BLI_findlink(&node->original->inputs, 1); + bNodeSocketValueRGBA *socket_data = socket->default_value; + realnorm = GPU_uniform_buffer(socket_data->value, GPU_VEC3); + } else realnorm = GPU_uniform(in[1].vec); -- cgit v1.2.3 From 918288138d19c7cd7936705bef7947d941abe708 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 08:26:24 +1000 Subject: Cleanup: warnings, trailing space --- source/blender/blenkernel/BKE_shader_fx.h | 8 ++++---- source/blender/blenkernel/intern/subdiv_eval.c | 2 +- .../engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl | 3 --- source/blender/nodes/shader/nodes/node_shader_mapping.c | 4 ++-- source/blender/shader_fx/CMakeLists.txt | 2 +- source/blender/shader_fx/intern/FX_shader_util.c | 1 - 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h index 11c5983106a..d2c8cfb457c 100644 --- a/source/blender/blenkernel/BKE_shader_fx.h +++ b/source/blender/blenkernel/BKE_shader_fx.h @@ -48,7 +48,7 @@ struct bGPDstroke; struct ModifierUpdateDepsgraphContext; #define SHADER_FX_ACTIVE(_fx, _is_render) (((_fx->mode & eShaderFxMode_Realtime) && (_is_render == false)) || \ - ((_fx->mode & eShaderFxMode_Render) && (_is_render == true))) + ((_fx->mode & eShaderFxMode_Render) && (_is_render == true))) #define SHADER_FX_EDIT(_fx, _is_edit) (((_fx->mode & eShaderFxMode_Editmode) == 0) && (_is_edit)) typedef enum { @@ -63,7 +63,7 @@ typedef enum { eShaderFxTypeFlag_SupportsEditmode = (1 << 0), /* For effects that support editmode this determines if the - * effect should be enabled by default in editmode. + * effect should be enabled by default in editmode. */ eShaderFxTypeFlag_EnableInEditmode = (1 << 2), @@ -101,7 +101,7 @@ typedef struct ShaderFxTypeInfo { /* Initialize new instance data for this effect type, this function * should set effect variables to their default values. - * + * * This function is optional. */ void (*initData)(struct ShaderFxData *fx); @@ -129,7 +129,7 @@ typedef struct ShaderFxTypeInfo { */ void (*updateDepsgraph)(struct ShaderFxData *fx, const struct ModifierUpdateDepsgraphContext *ctx); - + /* Should return true if the effect needs to be recalculated on time * changes. * diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index fa9488f15b6..8621b1f87f9 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -231,7 +231,7 @@ void BKE_subdiv_eval_face_varying( u, v, face_varying); #else - UNUSED_VARS(subdiv, ptex_face_index, u, v, face_varying); + UNUSED_VARS(subdiv, face_varying_channel, ptex_face_index, u, v, face_varying); #endif } diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl index 20d6b8a91f8..0a7eb65d564 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl @@ -96,6 +96,3 @@ void main() gl_FragDepth = stroke_depth; FragColor = outcolor; } - - - diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index 2541b3bc842..98dcd58b983 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -88,8 +88,8 @@ static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS TexMapping *texmap = node->storage; float domin = (texmap->flag & TEXMAP_CLIP_MIN) != 0; float domax = (texmap->flag & TEXMAP_CLIP_MAX) != 0; - static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX, 0.0}; - static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX, 0.0}; + static float max[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; + static float min[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; GPUNodeLink *tmin, *tmax, *tmat0, *tmat1, *tmat2, *tmat3; tmin = GPU_uniform_buffer((domin) ? texmap->min : min, GPU_VEC3); diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt index 2b33c9817c3..dacc0b3f063 100644 --- a/source/blender/shader_fx/CMakeLists.txt +++ b/source/blender/shader_fx/CMakeLists.txt @@ -19,7 +19,7 @@ # # ***** END GPL LICENSE BLOCK ***** -set(INC +set(INC . intern ../blenkernel diff --git a/source/blender/shader_fx/intern/FX_shader_util.c b/source/blender/shader_fx/intern/FX_shader_util.c index c55b9304503..64a1553adec 100644 --- a/source/blender/shader_fx/intern/FX_shader_util.c +++ b/source/blender/shader_fx/intern/FX_shader_util.c @@ -53,4 +53,3 @@ void shaderfx_type_init(ShaderFxTypeInfo *types[]) INIT_FX_TYPE(Wave); #undef INIT_FX_TYPE } - -- cgit v1.2.3 From 872c5d2763f29110504c45d51f77ae1af540bfef Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Thu, 2 Aug 2018 00:52:08 +0200 Subject: UI: Remove OpenGL Render operators from Render menu Rendering OpenGL/Preview is accessible from each editor. Render settings are accessible from the Film menu when in OpenGL/Preview engine. It wasn't always predictable especially with Workspaces without or with many viewports. Also reordering of items, renaming and removal of superfluous icons. --- release/scripts/startup/bl_ui/space_topbar.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 6712e495498..ecb59e322c2 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -394,26 +394,20 @@ class INFO_MT_render(Menu): props = layout.operator("render.render", text="Render Animation", icon='RENDER_ANIMATION') props.animation = True props.use_viewport = True - layout.operator("sound.mixdown", text="Render Audio", icon='PLAY_AUDIO') layout.separator() - layout.prop_menu_enum(rd, "display_mode", text="Display Mode") - layout.prop(rd, "use_lock_interface", text="Lock Interface") + layout.operator("sound.mixdown", text="Render Audio...") layout.separator() - props = layout.operator("render.opengl", text="OpenGL Render Image", icon='RENDER_STILL') - props.view_context = False - props = layout.operator("render.opengl", text="OpenGL Render Animation", icon='RENDER_ANIMATION') - props.view_context = False - props.animation = True - layout.menu("INFO_MT_opengl_render") + layout.operator("render.view_show", text="View Render") + layout.operator("render.play_rendered_anim", text="View Animation") + layout.prop_menu_enum(rd, "display_mode", text="Display Mode") layout.separator() - layout.operator("render.view_show") - layout.operator("render.play_rendered_anim", icon='PLAY') + layout.prop(rd, "use_lock_interface", text="Lock Interface") class INFO_MT_opengl_render(Menu): @@ -616,7 +610,6 @@ classes = ( INFO_MT_edit, INFO_MT_game, INFO_MT_render, - INFO_MT_opengl_render, INFO_MT_window, INFO_MT_help, ) -- cgit v1.2.3 From a4623bdfed5bd6121d0d09a9d7f077e379718b9f Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Thu, 2 Aug 2018 00:52:45 +0200 Subject: UI: Group similar Grease Pencil brush settings --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index ceb0f244bac..dd071f357af 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1522,14 +1522,17 @@ class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel): gp_settings = brush.gpencil_settings layout.active = gp_settings.enable_settings - layout.prop(gp_settings, "pen_smooth_factor") - layout.prop(gp_settings, "pen_smooth_steps") + col = layout.column(align=True) + col.prop(gp_settings, "pen_smooth_factor") + col.prop(gp_settings, "pen_thick_smooth_factor") - layout.prop(gp_settings, "pen_thick_smooth_factor") - layout.prop(gp_settings, "pen_thick_smooth_steps") + col = layout.column(align=True) + col.prop(gp_settings, "pen_smooth_steps") + col.prop(gp_settings, "pen_thick_smooth_steps") - layout.prop(gp_settings, "pen_subdivision_steps") - layout.prop(gp_settings, "random_subdiv", text="Randomness", slider=True) + col = layout.column(align=True) + col.prop(gp_settings, "pen_subdivision_steps") + col.prop(gp_settings, "random_subdiv", text="Randomness", slider=True) class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): -- cgit v1.2.3 From ab49b7d73967b61e05108156980c204065cbfebf Mon Sep 17 00:00:00 2001 From: Pablo Vazquez Date: Thu, 2 Aug 2018 01:26:58 +0200 Subject: UI: Slightly larger action zone for corner resizing Pretty minor, from 0.6 to 0.8, but the improvement is noticeable especially when using a stylus, without overlapping too much with the buttons and dropdowns in headers. --- source/blender/editors/screen/screen_intern.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index cd71c07a3c0..9f845bf04ba 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -37,7 +37,7 @@ struct Main; /* internal exports only */ -#define AZONESPOT (0.6f * U.widget_unit) +#define AZONESPOT (0.8f * U.widget_unit) #define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ #define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */ -- cgit v1.2.3 From 8a0760eba2fe8ce31b0d054c498e9a264795c2b4 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 2 Aug 2018 14:44:17 +1200 Subject: Armature Panel Tweaks - Motion Paths/Ghosting Since most animators find Motion Paths more useful than Armature Ghosting: * Move Motion Paths before Ghosting settings (less scrolling) * Collapse Ghosting panel by default * Open Motion Paths panel by default instead --- release/scripts/startup/bl_ui/properties_animviz.py | 2 +- release/scripts/startup/bl_ui/properties_data_armature.py | 3 ++- release/scripts/startup/bl_ui/properties_object.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 901e15c181a..4033d5c2448 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -29,7 +29,7 @@ class MotionPathButtonsPanel: bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_label = "Motion Paths" - bl_options = {'DEFAULT_CLOSED'} + # bl_options = {'DEFAULT_CLOSED'} def draw_settings(self, context, avs, mpath, bones=False): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index 63d80638ae2..8ea20ada390 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -211,6 +211,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel): # TODO: this panel will soon be deprecated too class DATA_PT_ghost(ArmatureButtonsPanel, Panel): bl_label = "Ghost" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout @@ -340,9 +341,9 @@ classes = ( DATA_MT_bone_group_specials, DATA_PT_bone_groups, DATA_PT_pose_library, + DATA_PT_motion_paths, DATA_PT_ghost, DATA_PT_iksolver_itasc, - DATA_PT_motion_paths, DATA_PT_custom_props_arm, ) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 64bc8d52068..79b2f7b8df8 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -329,6 +329,7 @@ from .properties_animviz import ( class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel): #bl_label = "Object Motion Paths" bl_context = "object" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): -- cgit v1.2.3 From 0fdd058991afe68d4cabd60b8d936b6ae8266524 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 2 Aug 2018 14:46:15 +1200 Subject: Dev Tooling: Instrument motion path calculation operator (for bones) to collect timing data This will be useful for checking on the progress of our optimisation efforts, and to generate some nice stats for later. --- source/blender/editors/armature/pose_edit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 1dfb9ec984a..a2cd3c57101 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -70,6 +70,15 @@ #include "armature_intern.h" + +#define DEBUG_TIME + +#include "PIL_time.h" +#ifdef DEBUG_TIME +# include "PIL_time_utildefines.h" +#endif + + /* matches logic with ED_operator_posemode_context() */ Object *ED_pose_object_from_context(bContext *C) { @@ -256,10 +265,18 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op) } CTX_DATA_END; +#ifdef DEBUG_TIME + TIMEIT_START(recalc_pose_paths); +#endif + /* calculate the bones that now have motionpaths... */ /* TODO: only make for the selected bones? */ ED_pose_recalculate_paths(C, scene, ob); +#ifdef DEBUG_TIME + TIMEIT_END(recalc_pose_paths); +#endif + /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); -- cgit v1.2.3 From 503866c68154ef09e6199068391515f81eebaa2d Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 2 Aug 2018 16:34:27 +1200 Subject: Fix T56199: Crash on Annotation in (VSE) Image Preview In some cases (e.g. using old userpref settings/keymaps) it was possible to trigger a crash when the wrong GP/Annotation operators were triggered in the wrong contexts (e.g. using the old GPENCIL_OT_paint in annotation-only contexts like all the 2D editors). This commit resolves several issues that were caused by sloppy code-churn + features that had been hacked on. --- source/blender/editors/gpencil/annotate_paint.c | 21 ++++++--- source/blender/editors/gpencil/gpencil_paint.c | 60 +++++++++++++------------ 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 6325052fccd..b551f3d630b 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -1206,9 +1206,19 @@ static tGPsdata *gp_session_initpaint(bContext *C) /* create new context data */ p = MEM_callocN(sizeof(tGPsdata), "Annotation Drawing Data"); - gp_session_initdata(C, p); + /* Try to initialise context data + * WARNING: This may not always succeed (e.g. using GP in an annotation-only context) + */ + if (gp_session_initdata(C, p) == 0) { + /* Invalid state - Exit + * NOTE: It should be safe to just free the data, since failing context checks should + * only happen when no data has been allocated. + */ + MEM_freeN(p); + return NULL; + } - /* radius for eraser circle is defined in userprefs now */ + /* Radius for eraser circle is defined in userprefs */ /* NOTE: we do this here, so that if we exit immediately, * erase size won't get lost */ @@ -1548,9 +1558,6 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) { tGPsdata *p = op->customdata; - /* clear undo stack */ - gpencil_undo_finish(); - /* restore cursor to indicate end of drawing */ WM_cursor_modal_restore(CTX_wm_window(C)); @@ -1568,10 +1575,14 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) */ U.gp_eraser = p->radius; + /* clear undo stack */ + gpencil_undo_finish(); + /* cleanup */ gp_paint_cleanup(p); gp_session_cleanup(p); gp_session_free(p); + p = NULL; } op->customdata = NULL; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 0c411db57b4..6a0bf0c4a47 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1746,18 +1746,20 @@ static tGPsdata *gp_session_initpaint(bContext *C, wmOperator *op) { tGPsdata *p = NULL; - /* create new context data */ + /* Create new context data */ p = MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data"); - gp_session_initdata(C, op, p); - -#if 0 - /* radius for eraser circle is defined in userprefs now */ - /* NOTE: we do this here, so that if we exit immediately, - * erase size won't get lost + /* Try to initialise context data + * WARNING: This may not always succeed (e.g. using GP in an annotation-only context) */ - p->radius = U.gp_eraser; -#endif + if (gp_session_initdata(C, op, p) == 0) { + /* Invalid state - Exit + * NOTE: It should be safe to just free the data, since failing context checks should + * only happen when no data has been allocated. + */ + MEM_freeN(p); + return NULL; + } /* Random generator, only init once. */ uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); @@ -2092,26 +2094,7 @@ static bool gpencil_is_tablet_eraser_active(const wmEvent *event) static void gpencil_draw_exit(bContext *C, wmOperator *op) { tGPsdata *p = op->customdata; - bGPdata *gpd = CTX_data_gpencil_data(C); - - /* clear undo stack */ - gpencil_undo_finish(); - - /* restore cursor to indicate end of drawing */ - if (p->sa->spacetype != SPACE_VIEW3D) { - WM_cursor_modal_restore(CTX_wm_window(C)); - } - else { - /* or restore paint if 3D view */ - if ((p) && (p->paintmode == GP_PAINTMODE_ERASER)) { - WM_cursor_modal_set(p->win, CURSOR_STD); - } - /* drawing batch cache is dirty now */ - if (gpd) { - gp_update_cache(gpd); - } - } /* don't assume that operator data exists at all */ if (p) { /* check size of buffer before cleanup, to determine if anything happened here */ @@ -2128,6 +2111,26 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) p->eraser->size = p->radius; } + /* restore cursor to indicate end of drawing */ + if (p->sa->spacetype != SPACE_VIEW3D) { + WM_cursor_modal_restore(CTX_wm_window(C)); + } + else { + /* or restore paint if 3D view */ + if ((p) && (p->paintmode == GP_PAINTMODE_ERASER)) { + WM_cursor_modal_set(p->win, CURSOR_STD); + } + + /* drawing batch cache is dirty now */ + bGPdata *gpd = CTX_data_gpencil_data(C); + if (gpd) { + gp_update_cache(gpd); + } + } + + /* clear undo stack */ + gpencil_undo_finish(); + /* cleanup */ gp_paint_cleanup(p); gp_session_cleanup(p); @@ -2135,6 +2138,7 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) /* finally, free the temp data */ gp_session_free(p); + p = NULL; } op->customdata = NULL; -- cgit v1.2.3 From cb6d7cb0b255b9018620c4b11da8ed0044b1288f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 17:49:03 +1000 Subject: RNA: make particle enum public --- source/blender/makesrna/RNA_enum_types.h | 2 ++ source/blender/makesrna/intern/rna_sculpt_paint.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index bbd4ac3753f..64740098db4 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -112,6 +112,8 @@ extern const EnumPropertyItem rna_enum_brush_sculpt_tool_items[]; extern const EnumPropertyItem rna_enum_brush_vertex_tool_items[]; extern const EnumPropertyItem rna_enum_brush_image_tool_items[]; +extern const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[]; +extern const EnumPropertyItem rna_enum_particle_edit_disconnected_hair_brush_items[]; extern const EnumPropertyItem rna_enum_gpencil_sculpt_brush_items[]; extern const EnumPropertyItem rna_enum_uv_sculpt_tool_items[]; diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c111263cb7d..92f05bf366f 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -51,7 +51,7 @@ #include "bmesh.h" -static const EnumPropertyItem particle_edit_hair_brush_items[] = { +const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[] = { {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"}, {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"}, {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs"}, @@ -120,7 +120,7 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } -static const EnumPropertyItem particle_edit_disconnected_hair_brush_items[] = { +const EnumPropertyItem rna_enum_particle_edit_disconnected_hair_brush_items[] = { {PE_BRUSH_NONE, "NONE", 0, "None", "Don't use any brush"}, {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"}, {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs"}, @@ -186,8 +186,9 @@ static void rna_ParticleEdit_tool_set(PointerRNA *ptr, int value) pset->brushtype = value; } -static const EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *UNUSED(r_free)) +static const EnumPropertyItem *rna_ParticleEdit_tool_itemf( + bContext *C, PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), bool *UNUSED(r_free)) { Scene *scene = CTX_data_scene(C); Object *ob = (scene->basact) ? scene->basact->object : NULL; @@ -204,10 +205,10 @@ static const EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerR if (psys) { if (psys->flag & PSYS_GLOBAL_HAIR) { - return particle_edit_disconnected_hair_brush_items; + return rna_enum_particle_edit_disconnected_hair_brush_items; } else { - return particle_edit_hair_brush_items; + return rna_enum_particle_edit_hair_brush_items; } } @@ -888,7 +889,7 @@ static void rna_def_particle_edit(BlenderRNA *brna) prop = RNA_def_property(srna, "tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "brushtype"); - RNA_def_property_enum_items(prop, particle_edit_hair_brush_items); + RNA_def_property_enum_items(prop, rna_enum_particle_edit_hair_brush_items); RNA_def_property_enum_funcs(prop, NULL, "rna_ParticleEdit_tool_set", "rna_ParticleEdit_tool_itemf"); RNA_def_property_ui_text(prop, "Tool", ""); -- cgit v1.2.3 From d79df6c0bc65e4c94a6fd24160445b98eb408949 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 16:24:22 +1000 Subject: Tool System: sync changes from changes to brushes Changing a brush now updates the tool. --- .../startup/bl_ui/space_toolsystem_common.py | 2 ++ .../startup/bl_ui/space_toolsystem_toolbar.py | 3 ++ source/blender/makesrna/intern/rna_workspace_api.c | 32 ++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 4f6e42d4a98..91ded3e4456 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -275,6 +275,7 @@ class ToolSelectPanelHelper: mode = context.mode tool = context.workspace.tools.from_space_view3d_mode(mode, create) if tool is not None: + tool.refresh_from_context() return tool elif space_type == 'IMAGE_EDITOR': space_data = context.space_data @@ -282,6 +283,7 @@ class ToolSelectPanelHelper: mode = space_data.mode tool = context.workspace.tools.from_space_image_mode(mode, create) if tool is not None: + tool.refresh_from_context() return tool return None diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 8ce4a52fbbc..c1d417ef12d 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -66,6 +66,7 @@ def generate_from_brushes_ex( category = brush_type[0] name = brush.name + """ # rename default brushes for tool bar if name.startswith("Draw "): text = name.replace("Draw ", "") @@ -75,6 +76,8 @@ def generate_from_brushes_ex( text = name.replace(" Area", "") else: text = name + """ + text = name # define icon gp_icon = brush.gpencil_settings.gp_icon diff --git a/source/blender/makesrna/intern/rna_workspace_api.c b/source/blender/makesrna/intern/rna_workspace_api.c index 98e84f60b33..4469b88da6d 100644 --- a/source/blender/makesrna/intern/rna_workspace_api.c +++ b/source/blender/makesrna/intern/rna_workspace_api.c @@ -41,6 +41,8 @@ #ifdef RNA_RUNTIME +#include "BKE_paint.h" + #include "ED_screen.h" static void rna_WorkspaceTool_setup( @@ -68,6 +70,34 @@ static void rna_WorkspaceTool_setup( WM_toolsystem_ref_set_from_runtime(C, (WorkSpace *)id, tref, &tref_rt, name); } +static void rna_WorkspaceTool_refresh_from_context( + ID *id, + bToolRef *tref, + Main *bmain) +{ + bToolRef_Runtime *tref_rt = tref->runtime; + if ((tref_rt == NULL) || (tref_rt->data_block[0] == '\0')) { + return; + } + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + WorkSpace *workspace = WM_window_get_active_workspace(win); + if (&workspace->id == id) { + Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Paint *paint = BKE_paint_get_active(scene, view_layer); + if (paint) { + const ID *brush = (ID *)paint->brush; + if (!STREQ(tref_rt->data_block, brush->name + 2)) { + STRNCPY(tref_rt->data_block, brush->name + 2); + STRNCPY(tref->idname, brush->name + 2); + printf("Found\n"); + } + } + } + } +} + static PointerRNA rna_WorkspaceTool_operator_properties( bToolRef *tref, const char *idname) @@ -124,6 +154,8 @@ void RNA_api_workspace_tool(StructRNA *srna) RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "refresh_from_context", "rna_WorkspaceTool_refresh_from_context"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN); } #endif -- cgit v1.2.3 From 3a93314753cabe176bde1cdb084afa551323321b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 17:41:11 +1000 Subject: Tool System: initial particle system support --- .../startup/bl_ui/space_toolsystem_toolbar.py | 44 +++++++++++++++++++--- source/blender/makesrna/intern/rna_workspace_api.c | 31 +++++++++++---- .../blender/windowmanager/intern/wm_toolsystem.c | 44 +++++++++++++++------- 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c1d417ef12d..5ccd3ee123b 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -40,9 +40,6 @@ def generate_from_brushes_ex( brush_category_attr, brush_category_layout, ): - def draw_settings(context, layout, tool): - _defs_gpencil_paint.draw_settings_common(context, layout, tool) - # Categories brush_categories = {} if context.mode != 'GPENCIL_PAINT': @@ -60,6 +57,9 @@ def generate_from_brushes_ex( ) ) else: + def draw_settings(context, layout, tool): + _defs_gpencil_paint.draw_settings_common(context, layout, tool) + for brush_type in brush_category_layout: for brush in context.blend_data.brushes: if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]: @@ -141,6 +141,28 @@ def generate_from_brushes_ex( return tool_defs +def generate_from_enum_ex( + context, *, + icon_prefix, + data, + attr, +): + tool_defs = [] + for enum in data.rna_type.properties[attr].enum_items_static: + name = enum.name + identifier = enum.identifier + tool_defs.append( + ToolDef.from_dict( + dict( + text=name, + icon=icon_prefix + identifier.lower(), + data_block=identifier, + ) + ) + ) + return tuple(tool_defs) + + class _defs_view3d_generic: @ToolDef.from_fn def cursor(): @@ -832,6 +854,18 @@ class _defs_pose: ) +class _defs_particle: + + @staticmethod + def generate_from_brushes(context): + return generate_from_enum_ex( + context, + icon_prefix="brush.particle.", + data=context.tool_settings.particle_edit, + attr="tool", + ) + + class _defs_sculpt: @staticmethod @@ -1542,9 +1576,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_edit_curve.extrude_cursor, ], 'PARTICLE': [ - # TODO(campbell): use cursor click tool to allow paint tools to run, - # we need to integrate particle system tools properly. - _defs_view3d_generic.cursor_click, + _defs_particle.generate_from_brushes, ], 'SCULPT': [ _defs_sculpt.generate_from_brushes, diff --git a/source/blender/makesrna/intern/rna_workspace_api.c b/source/blender/makesrna/intern/rna_workspace_api.c index 4469b88da6d..aac38d05cd8 100644 --- a/source/blender/makesrna/intern/rna_workspace_api.c +++ b/source/blender/makesrna/intern/rna_workspace_api.c @@ -84,14 +84,31 @@ static void rna_WorkspaceTool_refresh_from_context( WorkSpace *workspace = WM_window_get_active_workspace(win); if (&workspace->id == id) { Scene *scene = WM_window_get_active_scene(win); + ToolSettings *ts = scene->toolsettings; ViewLayer *view_layer = WM_window_get_active_view_layer(win); - Paint *paint = BKE_paint_get_active(scene, view_layer); - if (paint) { - const ID *brush = (ID *)paint->brush; - if (!STREQ(tref_rt->data_block, brush->name + 2)) { - STRNCPY(tref_rt->data_block, brush->name + 2); - STRNCPY(tref->idname, brush->name + 2); - printf("Found\n"); + Object *ob = OBACT(view_layer); + if (ob == NULL) { + /* pass */ + } + else if (ob->mode & OB_MODE_PARTICLE_EDIT) { + const EnumPropertyItem *items = rna_enum_particle_edit_hair_brush_items; + const int i = RNA_enum_from_value(items, ts->particle.brushtype); + const EnumPropertyItem *item = &items[i]; + if (!STREQ(tref_rt->data_block, item->identifier)) { + STRNCPY(tref_rt->data_block, item->identifier); + STRNCPY(tref->idname, item->name); + } + } + else { + Paint *paint = BKE_paint_get_active(scene, view_layer); + if (paint) { + const ID *brush = (ID *)paint->brush; + if (brush) { + if (!STREQ(tref_rt->data_block, brush->name + 2)) { + STRNCPY(tref_rt->data_block, brush->name + 2); + STRNCPY(tref->idname, brush->name + 2); + } + } } } } diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c index dcb33376f05..0aa5e16a519 100644 --- a/source/blender/windowmanager/intern/wm_toolsystem.c +++ b/source/blender/windowmanager/intern/wm_toolsystem.c @@ -49,6 +49,7 @@ #include "BKE_workspace.h" #include "RNA_access.h" +#include "RNA_enum_types.h" #include "WM_api.h" #include "WM_types.h" @@ -184,20 +185,37 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre if (tref_rt->data_block[0]) { Main *bmain = CTX_data_main(C); + if ((tref->space_type == SPACE_VIEW3D) && + (tref->mode == CTX_MODE_PARTICLE)) - /* Currently only brush data-blocks supported. */ - struct Brush *brush = (struct Brush *)BKE_libblock_find_name(bmain, ID_BR, tref_rt->data_block); - - if (brush) { - wmWindowManager *wm = bmain->wm.first; - for (wmWindow *win = wm->windows.first; win; win = win->next) { - if (workspace == WM_window_get_active_workspace(win)) { - Scene *scene = WM_window_get_active_scene(win); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - Paint *paint = BKE_paint_get_active(scene, view_layer); - if (paint) { - if (brush) { - BKE_paint_brush_set(paint, brush); + { + const EnumPropertyItem *items = rna_enum_particle_edit_hair_brush_items; + const int i = RNA_enum_from_identifier(items, tref_rt->data_block); + if (i != -1) { + const int value = items[i].value; + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (workspace == WM_window_get_active_workspace(win)) { + Scene *scene = WM_window_get_active_scene(win); + ToolSettings *ts = scene->toolsettings; + ts->particle.brushtype = value; + } + } + } + } + else { + struct Brush *brush = (struct Brush *)BKE_libblock_find_name(bmain, ID_BR, tref_rt->data_block); + if (brush) { + wmWindowManager *wm = bmain->wm.first; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (workspace == WM_window_get_active_workspace(win)) { + Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Paint *paint = BKE_paint_get_active(scene, view_layer); + if (paint) { + if (brush) { + BKE_paint_brush_set(paint, brush); + } } } } -- cgit v1.2.3 From 200212079dbadacbe9ddab6a2b5b5ee6824bf76c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 2 Aug 2018 12:22:55 +0200 Subject: Subsurf: Better crease which represents sharp edges Enabled infinite sharp patches for topology refiner and evaluator, which allows to have sharp edge at first subdivision level. Also tweaked crease export from Blender to OpenSubdiv to have more artistic control over the whole 0..1 range. --- intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc | 4 ++-- source/blender/blenkernel/intern/subdiv_converter_mesh.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc index 31e68492587..33df7a45e39 100644 --- a/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc +++ b/intern/opensubdiv/internal/opensubdiv_evaluator_internal.cc @@ -713,7 +713,7 @@ OpenSubdiv_EvaluatorInternal* openSubdiv_createEvaluatorInternal( if (is_adaptive) { TopologyRefiner::AdaptiveOptions options(level); options.considerFVarChannels = has_face_varying_data; - options.useInfSharpPatch = false; + options.useInfSharpPatch = true; refiner->RefineAdaptive(options); } else { TopologyRefiner::UniformOptions options(level); @@ -763,7 +763,7 @@ vector all_face_varying_stencils; // subsurf code. PatchTableFactory::Options patch_options(level); patch_options.SetEndCapType(PatchTableFactory::Options::ENDCAP_BSPLINE_BASIS); - patch_options.useInfSharpPatch = false; + patch_options.useInfSharpPatch = true; patch_options.generateFVarTables = has_face_varying_data; patch_options.generateFVarLegacyLinearPatches = false; const PatchTable* patch_table = PatchTableFactory::Create( diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 963f403e8d3..c5fb8afb6cd 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -157,7 +157,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, storage->manifold_edge_index_reverse[manifold_edge_index]; const MEdge *medge = storage->mesh->medge; const float edge_crease = (float)medge[edge_index].crease / 255.0f; - return edge_crease * storage->settings.level * 10; + return edge_crease * edge_crease * 10.0f; } -- cgit v1.2.3 From 35a5fccf777b52f4fe8cf84e82df7a9f43b188df Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 21:27:12 +1000 Subject: UI: show particle radius & strength in topbar --- release/scripts/startup/bl_ui/space_topbar.py | 11 +++++++++++ release/scripts/startup/bl_ui/space_view3d_toolbar.py | 19 ++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index ecb59e322c2..57265b9c130 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -224,6 +224,17 @@ class _draw_left_context_mode: UnifiedPaintPanel.prop_unified_size(layout, context, brush, "size", slider=True, text="Radius") UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") + def PARTICLE(context, layout): + settings = context.tool_settings.particle_edit + brush = settings.brush + tool = settings.tool + if tool != 'NONE': + layout.prop(brush, "size", slider=True) + if tool == 'ADD': + layout.prop(brush, "count") + else: + layout.prop(brush, "strength", slider=True) + class INFO_MT_editor_menus(Menu): bl_idname = "INFO_MT_editor_menus" diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index dd071f357af..ccec7ab941a 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -289,16 +289,21 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): if context.particle_edit_object: tool = settings.tool - layout.column().prop(settings, "tool", expand=True) - if tool != 'NONE': - col = layout.column() - col.prop(brush, "size", slider=True) - if tool != 'ADD': - col.prop(brush, "strength", slider=True) + if self.is_popover: + # Topbar shows these already. + pass + else: + if tool != 'NONE': + layout.column().prop(settings, "tool", expand=True) + col = layout.column() + col.prop(brush, "size", slider=True) + if tool == 'ADD': + col.prop(brush, "count") + else: + col.prop(brush, "strength", slider=True) if tool == 'ADD': - col.prop(brush, "count") col = layout.column() col.prop(settings, "use_default_interpolate") col.prop(brush, "steps", slider=True) -- cgit v1.2.3 From f36855f0fd8fb5f7150110fdb0d88fb03c898ee5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 22:10:38 +1000 Subject: UI: show all particle brush settings in topbar Also show particle brush in tool-properties panel. --- release/scripts/startup/bl_ui/space_topbar.py | 10 ++++++++++ .../scripts/startup/bl_ui/space_view3d_toolbar.py | 21 ++++++++------------- .../blender/editors/space_buttons/space_buttons.c | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 57265b9c130..a417ef856f9 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -225,6 +225,7 @@ class _draw_left_context_mode: UnifiedPaintPanel.prop_unified_strength(layout, context, brush, "strength", slider=True, text="Strength") def PARTICLE(context, layout): + # See: 'VIEW3D_PT_tools_brush', basically a duplicate settings = context.tool_settings.particle_edit brush = settings.brush tool = settings.tool @@ -235,6 +236,15 @@ class _draw_left_context_mode: else: layout.prop(brush, "strength", slider=True) + if tool == 'ADD': + layout.prop(settings, "use_default_interpolate") + layout.prop(brush, "steps", slider=True) + layout.prop(settings, "default_key_count", slider=True) + elif tool == 'LENGTH': + layout.row().prop(brush, "length_mode", expand=True) + elif tool == 'PUFF': + layout.row().prop(brush, "puff_mode", expand=True) + layout.prop(brush, "use_puff_volume") class INFO_MT_editor_menus(Menu): bl_idname = "INFO_MT_editor_menus" diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index ccec7ab941a..ca55429c929 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -289,19 +289,14 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): if context.particle_edit_object: tool = settings.tool - - if self.is_popover: - # Topbar shows these already. - pass - else: - if tool != 'NONE': - layout.column().prop(settings, "tool", expand=True) - col = layout.column() - col.prop(brush, "size", slider=True) - if tool == 'ADD': - col.prop(brush, "count") - else: - col.prop(brush, "strength", slider=True) + if tool != 'NONE': + layout.column().prop(settings, "tool") + col = layout.column() + col.prop(brush, "size", slider=True) + if tool == 'ADD': + col.prop(brush, "count") + else: + col.prop(brush, "strength", slider=True) if tool == 'ADD': col = layout.column() diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 98ff2f67b58..0350e3fcd14 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -244,7 +244,7 @@ static void buttons_main_region_layout_tool(const bContext *C, ARegion *ar) ARRAY_SET_ITEMS(contexts, ".paint_common", ".imagepaint"); break; case CTX_MODE_PARTICLE: - ARRAY_SET_ITEMS(contexts, ".particlemode"); + ARRAY_SET_ITEMS(contexts, ".paint_common", ".particlemode"); break; case CTX_MODE_OBJECT: ARRAY_SET_ITEMS(contexts, ".objectmode"); -- cgit v1.2.3 From 75d0830dc0143ae310680b7e0c4513e226a27443 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 2 Aug 2018 22:28:48 +1000 Subject: Cleanup: use dictionary for icon lookup --- .../startup/bl_ui/space_toolsystem_toolbar.py | 40 ++++++++-------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 5ccd3ee123b..629fd2a7557 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -65,7 +65,9 @@ def generate_from_brushes_ex( if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]: category = brush_type[0] name = brush.name + text = name + # XXX, disabled since changing the brush needs to sync back to the tool. """ # rename default brushes for tool bar if name.startswith("Draw "): @@ -77,31 +79,19 @@ def generate_from_brushes_ex( else: text = name """ - text = name - - # define icon - gp_icon = brush.gpencil_settings.gp_icon - if gp_icon == 'PENCIL': - icon_name = 'draw_pencil' - elif gp_icon == 'PEN': - icon_name = 'draw_pen' - elif gp_icon == 'INK': - icon_name = 'draw_ink' - elif gp_icon == 'INKNOISE': - icon_name = 'draw_noise' - elif gp_icon == 'BLOCK': - icon_name = 'draw_block' - elif gp_icon == 'MARKER': - icon_name = 'draw_marker' - elif gp_icon == 'FILL': - icon_name = 'draw_fill' - elif gp_icon == 'SOFT': - icon_name = 'draw.eraser_soft' - elif gp_icon == 'HARD': - icon_name = 'draw.eraser_hard' - elif gp_icon == 'STROKE': - icon_name = 'draw.eraser_stroke' - + # Define icon. + icon_name = { + 'PENCIL': 'draw_pencil', + 'PEN': 'draw_pen', + 'INK': 'draw_ink', + 'INKNOISE': 'draw_noise', + 'BLOCK': 'draw_block', + 'MARKER': 'draw_marker', + 'FILL': 'draw_fill', + 'SOFT': 'draw.eraser_soft', + 'HARD': 'draw.eraser_hard', + 'STROKE': 'draw.eraser_stroke', + }[category] brush_categories.setdefault(category, []).append( ToolDef.from_dict( dict( -- cgit v1.2.3 From 777e1b9654ca50af5e52052c05f6ca556e46ba9c Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 2 Aug 2018 16:22:53 +0200 Subject: UI: Move thickness before frame lock in Annotation Panel The thickness is more important and must be below list of annotation layers. --- .../startup/bl_ui/properties_grease_pencil_common.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index b291cc7bd82..9f2edefc3c2 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -756,12 +756,14 @@ class GreasePencilDataPanel: sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP' sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN' + tool_settings = context.tool_settings + if gpd and gpl: + layout.prop(gpl, "thickness") + else: + layout.prop(tool_settings, "annotation_thickness", text="Thickness") + if gpl: # layout.prop(gpl, "opacity", text="Opacity", slider=True) - # layout.prop(gpl, "thickness", text="Thickness") - # - # layout.separator() - # Full-Row - Frame Locking (and Delete Frame) row = layout.row(align=True) row.active = not gpl.lock @@ -774,11 +776,6 @@ class GreasePencilDataPanel: row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED') row.operator("gpencil.active_frame_delete", text="", icon='X') - tool_settings = context.tool_settings - if gpd and gpl: - layout.prop(gpl, "thickness") - else: - layout.prop(tool_settings, "annotation_thickness", text="Thickness") class GreasePencilOnionPanel: -- cgit v1.2.3 From 771973869d293f188687ffa88572e1c4e9946aae Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 2 Aug 2018 16:38:39 +0200 Subject: Fix assert in UI string trimming code when we have 'protected' right part. --- source/blender/editors/interface/interface_widgets.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index d0cdba49536..019aabdb466 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1494,7 +1494,7 @@ float UI_text_clip_middle_ex( rpart = rpart_buf; } - l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, &rpart_width); + l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL); if (l_end < 10 || min_ff(parts_strwidth, strwidth - okwidth) < minwidth) { /* If we really have no place, or we would clip a very small piece of string in the middle, * only show start of string. @@ -1504,7 +1504,7 @@ float UI_text_clip_middle_ex( else { size_t r_offset, r_len; - r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, &rpart_width); + r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL); r_len = strlen(str + r_offset) + 1; /* +1 for the trailing '\0'. */ if (l_end + sep_len + r_len + rpart_len > max_len) { @@ -1525,6 +1525,7 @@ float UI_text_clip_middle_ex( if (rpart) { /* Add back preserved right part to our shorten str. */ memcpy(str + final_lpart_len, rpart, rpart_len + 1); /* +1 for trailing '\0'. */ + okwidth += rpart_width; } strwidth = BLF_width(fstyle->uifont_id, str, max_len); -- cgit v1.2.3 From 9914c05bd762d495fe3778c417ba1c7c9d7f1332 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 2 Aug 2018 17:15:56 +0200 Subject: Depsgraph: fix some DEG queries crashing with new, empty graph. Calling code is responsible to check on NULL pointers here, or ensure is does have a fully built and evaluated depsgraph, but this should never crash in DEG queries themselves. --- source/blender/depsgraph/intern/depsgraph_query.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index ca9f32d4d8c..a6c930196ef 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -128,10 +128,10 @@ Scene *DEG_get_evaluated_scene(const Depsgraph *graph) reinterpret_cast(graph); Scene *scene_cow = deg_graph->scene_cow; /* TODO(sergey): Shall we expand datablock here? Or is it OK to assume - * that calleer is OK with just a pointer in case scene is not up[dated + * that calleer is OK with just a pointer in case scene is not updated * yet? */ - BLI_assert(DEG::deg_copy_on_write_is_expanded(&scene_cow->id)); + BLI_assert(scene_cow != NULL && DEG::deg_copy_on_write_is_expanded(&scene_cow->id)); return scene_cow; } @@ -140,6 +140,9 @@ ViewLayer *DEG_get_evaluated_view_layer(const Depsgraph *graph) const DEG::Depsgraph *deg_graph = reinterpret_cast(graph); Scene *scene_cow = DEG_get_evaluated_scene(graph); + if (scene_cow == NULL) { + return NULL; /* Happens with new, not-yet-built/evaluated graphes. */ + } /* Do name-based lookup. */ /* TODO(sergey): Can this be optimized? */ ViewLayer *view_layer_orig = deg_graph->view_layer; -- cgit v1.2.3 From 909556aa26845e9afe3e96ccb9d6e8b87eb8eae1 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 2 Aug 2018 17:45:17 +0200 Subject: Fix wrong RNA Api parameter definition --- source/blender/makesrna/intern/rna_main_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 50aa3cb5b81..f6e5a6107c9 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -269,9 +269,11 @@ static Material *rna_Main_materials_new(Main *bmain, const char *name) return (Material *)id; } -static void rna_Main_materials_gpencil_data(Main *UNUSED(bmain), struct PointerRNA *ma) +static void rna_Main_materials_gpencil_data(Main *UNUSED(bmain), PointerRNA *id_ptr) { - BKE_material_init_gpencil_settings((Material *)ma); + ID *id = id_ptr->data; + Material *ma = (Material *)id; + BKE_material_init_gpencil_settings(ma); } static const EnumPropertyItem *rna_Main_nodetree_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) -- cgit v1.2.3 From ce551ada928100e34b13e2ea8a6304d0631ec3e6 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 2 Aug 2018 18:03:01 +0200 Subject: Fix missing type for material arry This function was called by RNA Api and had grease pencil object type missing. --- source/blender/blenkernel/intern/material.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 03ec26c07d0..5edf9b9048f 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -319,6 +319,8 @@ Material ***give_matarar_id(ID *id) return &(((Curve *)id)->mat); case ID_MB: return &(((MetaBall *)id)->mat); + case ID_GD: + return &(((bGPdata *)id)->mat); default: break; } -- cgit v1.2.3 From 3578212e462d2a67f49d64ce5fb64df43200654f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 18:03:47 +0200 Subject: Eevee: Fix missing UBO binds. Some of them are unecessary and should be removed from the shader instead. But for now we need a quick fix for the crashes happening on some platforms. See T55475. --- source/blender/draw/engines/eevee/eevee_lightprobes.c | 14 +++++++++++++- source/blender/draw/engines/eevee/eevee_lookdev.c | 10 +++------- source/blender/draw/engines/eevee/eevee_materials.c | 9 +++++++++ source/blender/draw/engines/eevee/eevee_screen_raytrace.c | 3 +++ .../blender/draw/engines/eevee/eevee_temporal_sampling.c | 2 +- source/blender/draw/engines/eevee/eevee_volumes.c | 6 ++++++ source/blender/draw/engines/eevee/shaders/lamps_lib.glsl | 3 +++ 7 files changed, 38 insertions(+), 9 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 691d6ffe6eb..8b021279411 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -376,7 +376,10 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); - DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRW_shgroup_call_add(grp, geom, NULL); } { @@ -394,6 +397,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, #endif DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); @@ -413,6 +417,7 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1); DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); DRW_shgroup_call_add(grp, geom, NULL); @@ -471,6 +476,13 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat case GPU_MAT_SUCCESS: grp = DRW_shgroup_material_create(gpumat, psl->probe_background); DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1); + /* TODO (fclem): remove thoses (need to clean the GLSL files). */ + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); DRW_shgroup_call_add(grp, geom, NULL); break; default: diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c index 345a28590c6..deb724c9ae6 100644 --- a/source/blender/draw/engines/eevee/eevee_lookdev.c +++ b/source/blender/draw/engines/eevee/eevee_lookdev.c @@ -112,18 +112,14 @@ void EEVEE_lookdev_cache_init( if (!pinfo) { /* Do not fadeout when doing probe rendering, only when drawing the background */ DRW_shgroup_uniform_float(*grp, "studioLightBackground", &v3d->shading.studiolight_background, 1); - if (v3d->shading.studiolight_background > 0.0f) { - BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE); - tex = sl->equirectangular_irradiance_gputexture; - } + BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IRRADIANCE_GPUTEXTURE); + tex = sl->equirectangular_irradiance_gputexture; } else { BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_RADIANCE_GPUTEXTURE); tex = sl->equirectangular_radiance_gputexture; } - if (tex != NULL) { - DRW_shgroup_uniform_texture(*grp, "image", tex); - } + DRW_shgroup_uniform_texture(*grp, "image", tex); /* Do we need to recalc the lightprobes? */ if (pinfo && diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 39f7443145f..fd097aa783c 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -971,6 +971,13 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) case GPU_MAT_SUCCESS: grp = DRW_shgroup_material_create(gpumat, psl->background_pass); DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1); + /* TODO (fclem): remove thoses (need to clean the GLSL files). */ + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); DRW_shgroup_call_add(grp, geom, NULL); break; case GPU_MAT_QUEUED: @@ -998,10 +1005,12 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE; psl->depth_pass = DRW_pass_create("Depth Pass", state); stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass); + DRW_shgroup_uniform_block(stl->g_data->depth_shgrp, "clip_block", sldata->clip_ubo); state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", state); stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass_cull); + DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_cull, "clip_block", sldata->clip_ubo); state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE; psl->depth_pass_clip = DRW_pass_create("Depth Pass Clip", state); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index b882db174b0..46229c2dc9b 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -227,6 +227,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); if (!effects->reflection_trace_full) { @@ -245,6 +247,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output); DRW_shgroup_uniform_texture_ref(grp, "pdfBuffer", &effects->ssr_pdf_output); DRW_shgroup_uniform_texture_ref(grp, "prevColorBuffer", &txl->color_double_buffer); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 76e11e02d26..6cb2d1d3b53 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -299,11 +299,11 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->color_double_buffer); DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->color); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); if (effects->enabled_effects & EFFECT_TAA_REPROJECT) { // DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); DRW_shgroup_uniform_texture_ref(grp, "velocityBuffer", &effects->velocity_tx); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); } else { DRW_shgroup_uniform_float(grp, "alpha", &effects->taa_alpha, 1); diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index d0cea65d05e..4f163af2202 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -397,6 +397,12 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) if (grp) { DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + /* TODO (fclem): remove thoses (need to clean the GLSL files). */ + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); } } diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl index ec5f6f4472f..7281eb4cf2d 100644 --- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl @@ -318,6 +318,8 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector) #define SSS_LUT_SIZE 64.0 #define SSS_LUT_SCALE ((SSS_LUT_SIZE - 1.0) / float(SSS_LUT_SIZE)) #define SSS_LUT_BIAS (0.5 / float(SSS_LUT_SIZE)) + +#ifdef USE_TRANSLUCENCY layout(std140) uniform sssProfile { vec4 kernel[MAX_SSS_SAMPLES]; vec4 radii_max_radius; @@ -330,6 +332,7 @@ vec3 sss_profile(float s) { s /= radii_max_radius.w; return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb; } +#endif vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale) { -- cgit v1.2.3 From 8f6ff3adfae7b7f14e0bab293efd0c8231982c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 18:31:38 +0200 Subject: GPUShader: Add name for debugging & identifying shaders. --- source/blender/draw/intern/draw_manager_shader.c | 16 ++++++++-------- source/blender/gpu/GPU_material.h | 2 +- source/blender/gpu/GPU_shader.h | 6 ++++-- source/blender/gpu/intern/gpu_basic_shader.c | 3 ++- source/blender/gpu/intern/gpu_codegen.c | 5 +++-- source/blender/gpu/intern/gpu_codegen.h | 2 +- source/blender/gpu/intern/gpu_material.c | 19 +++++++++++++++++-- source/blender/gpu/intern/gpu_shader.c | 20 ++++++++++++++++---- source/blender/gpu/intern/gpu_shader_private.h | 3 +++ 9 files changed, 55 insertions(+), 21 deletions(-) diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index b85e6267687..7aa40b0ce04 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -257,7 +257,7 @@ void DRW_deferred_shader_remove(GPUMaterial *mat) GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines) { - return GPU_shader_create(vert, frag, geom, NULL, defines); + return GPU_shader_create(vert, frag, geom, NULL, defines, __func__); } GPUShader *DRW_shader_create_with_lib( @@ -274,7 +274,7 @@ GPUShader *DRW_shader_create_with_lib( geom_with_lib = BLI_string_joinN(lib, geom); } - sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines); + sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__); MEM_freeN(vert_with_lib); MEM_freeN(frag_with_lib); @@ -290,22 +290,22 @@ GPUShader *DRW_shader_create_with_transform_feedback( const GPUShaderTFBType prim_type, const char **varying_names, const int varying_count) { return GPU_shader_create_ex(vert, NULL, geom, NULL, defines, GPU_SHADER_FLAGS_NONE, - prim_type, varying_names, varying_count); + prim_type, varying_names, varying_count, __func__); } GPUShader *DRW_shader_create_2D(const char *frag, const char *defines) { - return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines); + return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines, __func__); } GPUShader *DRW_shader_create_3D(const char *frag, const char *defines) { - return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines); + return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines, __func__); } GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines) { - return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines); + return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__); } GPUShader *DRW_shader_create_3D_depth_only(void) @@ -351,7 +351,7 @@ GPUMaterial *DRW_shader_create_from_world( if (mat == NULL) { mat = GPU_material_from_nodetree( scene, wo->nodetree, &wo->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines); + vert, geom, frag_lib, defines, wo->id.name); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { @@ -373,7 +373,7 @@ GPUMaterial *DRW_shader_create_from_material( if (mat == NULL) { mat = GPU_material_from_nodetree( scene, ma->nodetree, &ma->gpumaterial, engine_type, options, - vert, geom, frag_lib, defines); + vert, geom, frag_lib, defines, ma->id.name); } if (GPU_material_status(mat) == GPU_MAT_QUEUED) { diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 9fea9eaf4e1..5945621cb65 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -247,7 +247,7 @@ GPUMaterial *GPU_material_from_nodetree_find( struct ListBase *gpumaterials, const void *engine_type, int options); GPUMaterial *GPU_material_from_nodetree( struct Scene *scene, struct bNodeTree *ntree, struct ListBase *gpumaterials, const void *engine_type, int options, - const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines); + const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, const char *name); void GPU_material_compile(GPUMaterial *mat); void GPU_material_free(struct ListBase *gpumaterial); diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 704abdb13a1..ec5ffc0f354 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -62,7 +62,8 @@ GPUShader *GPU_shader_create( const char *fragcode, const char *geocode, const char *libcode, - const char *defines); + const char *defines, + const char *shader_name); GPUShader *GPU_shader_create_ex( const char *vertexcode, const char *fragcode, @@ -72,7 +73,8 @@ GPUShader *GPU_shader_create_ex( const int flags, const GPUShaderTFBType tf_type, const char **tf_names, - const int tf_count); + const int tf_count, + const char *shader_name); void GPU_shader_free(GPUShader *shader); void GPU_shader_bind(GPUShader *shader); diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c index 61e8cf87038..1b7b1ecf85a 100644 --- a/source/blender/gpu/intern/gpu_basic_shader.c +++ b/source/blender/gpu/intern/gpu_basic_shader.c @@ -243,7 +243,8 @@ static GPUShader *gpu_basic_shader(int options) datatoc_gpu_shader_basic_frag_glsl, geom_glsl, NULL, - defines); + defines, + __func__); if (shader) { /* set texture map to first texture unit */ diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 3b9d2e08769..c6cf0c55594 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -1993,7 +1993,7 @@ GPUPass *GPU_generate_pass_new( return pass; } -void GPU_pass_compile(GPUPass *pass) +void GPU_pass_compile(GPUPass *pass, const char *shname) { if (!pass->compiled) { pass->shader = GPU_shader_create( @@ -2001,7 +2001,8 @@ void GPU_pass_compile(GPUPass *pass) pass->fragmentcode, pass->geometrycode, NULL, - pass->defines); + pass->defines, + shname); pass->compiled = true; } } diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index 278843fc948..4af87c6a226 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -184,7 +184,7 @@ void GPU_nodes_extract_dynamic_inputs(struct GPUShader *shader, ListBase *inputs void GPU_nodes_get_vertex_attributes(ListBase *nodes, struct GPUVertexAttribs *attribs); void GPU_nodes_prune(ListBase *nodes, struct GPUNodeLink *outlink); -void GPU_pass_compile(GPUPass *pass); +void GPU_pass_compile(GPUPass *pass, const char *shname); void GPU_pass_release(GPUPass *pass); void GPU_pass_free_nodes(ListBase *nodes); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 5e0d9275aa2..9859f56c1db 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -43,6 +43,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_string.h" #include "BKE_main.h" #include "BKE_node.h" @@ -120,6 +121,10 @@ struct GPUMaterial { short int sss_falloff; float sss_sharpness; bool sss_dirty; + +#ifndef NDEBUG + char name[64]; +#endif }; enum { @@ -581,7 +586,7 @@ GPUMaterial *GPU_material_from_nodetree_find( */ GPUMaterial *GPU_material_from_nodetree( Scene *scene, struct bNodeTree *ntree, ListBase *gpumaterials, const void *engine_type, int options, - const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines) + const char *vert_code, const char *geom_code, const char *frag_lib, const char *defines, const char *name) { LinkData *link; bool has_volume_output, has_surface_output; @@ -594,6 +599,11 @@ GPUMaterial *GPU_material_from_nodetree( mat->scene = scene; mat->engine_type = engine_type; mat->options = options; +#ifndef NDEBUG + BLI_snprintf(mat->name, sizeof(mat->name), "%s", name); +#else + UNUSED_VARS(name); +#endif /* localize tree to create links for reroute and mute */ bNodeTree *localtree = ntreeLocalize(ntree); @@ -666,7 +676,12 @@ void GPU_material_compile(GPUMaterial *mat) /* NOTE: The shader may have already been compiled here since we are * sharing GPUShader across GPUMaterials. In this case it's a no-op. */ - GPU_pass_compile(mat->pass); +#ifndef NDEBUG + GPU_pass_compile(mat->pass, mat->name); +#else + GPU_pass_compile(mat->pass, __func__); +#endif + GPUShader *sh = GPU_pass_shader_get(mat->pass); if (sh != NULL) { diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 5346d3f1aee..3a6ad04b69a 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -31,6 +31,7 @@ #include "BLI_math_base.h" #include "BLI_math_vector.h" #include "BLI_path_util.h" +#include "BLI_string.h" #include "BKE_appdir.h" #include "BKE_global.h" @@ -172,6 +173,8 @@ extern char datatoc_gpu_shader_gpencil_fill_frag_glsl[]; /* cache of built-in shaders (each is created on first use) */ static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL }; +static uint g_shaderid = 0; + typedef struct { const char *vert; const char *frag; @@ -272,7 +275,8 @@ GPUShader *GPU_shader_create( const char *fragcode, const char *geocode, const char *libcode, - const char *defines) + const char *defines, + const char *shname) { return GPU_shader_create_ex( vertexcode, @@ -283,7 +287,8 @@ GPUShader *GPU_shader_create( GPU_SHADER_FLAGS_NONE, GPU_SHADER_TFB_NONE, NULL, - 0); + 0, + shname); } #define DEBUG_SHADER_NONE "" @@ -342,7 +347,8 @@ GPUShader *GPU_shader_create_ex( const int flags, const GPUShaderTFBType tf_type, const char **tf_names, - const int tf_count) + const int tf_count, + const char *shname) { #ifdef WITH_OPENSUBDIV bool use_opensubdiv = (flags & GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV) != 0; @@ -360,6 +366,12 @@ GPUShader *GPU_shader_create_ex( shader = MEM_callocN(sizeof(GPUShader), "GPUShader"); gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE); +#ifndef NDEBUG + BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++); +#else + UNUSED_VARS(shname); +#endif + if (vertexcode) shader->vertex = glCreateShader(GL_VERTEX_SHADER); if (fragcode) @@ -969,7 +981,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) } /* common case */ - builtin_shaders[shader] = GPU_shader_create(stages->vert, stages->frag, stages->geom, NULL, defines); + builtin_shaders[shader] = GPU_shader_create(stages->vert, stages->frag, stages->geom, NULL, defines, __func__); } return builtin_shaders[shader]; diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index d16aae79aae..69c0c41cef4 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -38,6 +38,9 @@ struct GPUShader { GPUShaderInterface *interface; /* cached uniform & attrib interface for shader */ int feedback_transform_type; +#ifndef NDEBUG + char name[64]; +#endif }; #endif /* __GPU_SHADER_PRIVATE_H__ */ -- cgit v1.2.3 From bd7ab6b98991889ed691531b4fdb00e4ec58413f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 18:32:10 +0200 Subject: DRW: Cleanup: Fix header naming. --- source/blender/draw/intern/DRW_render.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index abba8d3ce91..0812fe0bbe7 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -252,14 +252,14 @@ struct GPUShader *DRW_shader_create_2D(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_3D(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines); struct GPUShader *DRW_shader_create_3D_depth_only(void); -struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool no_deferred); -struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool no_deferred); +struct GPUMaterial *DRW_shader_find_from_world(struct World *wo, const void *engine_type, int options, bool deferred); +struct GPUMaterial *DRW_shader_find_from_material(struct Material *ma, const void *engine_type, int options, bool deferred); struct GPUMaterial *DRW_shader_create_from_world( struct Scene *scene, struct World *wo, const void *engine_type, int options, - const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred); + const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred); struct GPUMaterial *DRW_shader_create_from_material( struct Scene *scene, struct Material *ma, const void *engine_type, int options, - const char *vert, const char *geom, const char *frag_lib, const char *defines, bool no_deferred); + const char *vert, const char *geom, const char *frag_lib, const char *defines, bool deferred); void DRW_shader_free(struct GPUShader *shader); #define DRW_SHADER_FREE_SAFE(shader) do { \ if (shader != NULL) { \ -- cgit v1.2.3 From e7adf1dfb070be0bf9a99da3b13c09ac72f994bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 18:32:50 +0200 Subject: Cleanup: Fix compilation warnings. --- source/blender/draw/engines/eevee/eevee_lightcache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index b0b66ee50dc..da55cbca2e0 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -755,6 +755,9 @@ static void compute_cell_id( probe->grid_resolution_z))); int visited_cells = 0; + *r_stride = 0; + *r_final_idx = 0; + r_local_cell[0] = r_local_cell[1] = r_local_cell[2] = 0; for (int lvl = max_lvl; lvl >= 0; --lvl) { *r_stride = 1 << lvl; int prev_stride = *r_stride << 1; -- cgit v1.2.3 From acdb136dcec5cbf200e7cf1825d4735e193c5b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 18:33:19 +0200 Subject: DRW: Add UBO binding checking routine. --- source/blender/draw/intern/draw_manager_exec.c | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 1134f421c16..ed01080be87 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -34,6 +34,7 @@ #include "GPU_draw.h" #include "GPU_extensions.h" +#include "intern/gpu_shader_private.h" #ifdef USE_GPU_SELECT # include "ED_view3d.h" @@ -49,6 +50,8 @@ void DRW_select_load_id(uint id) } #endif +#define DEBUG_UBO_BINDING + struct GPUUniformBuffer *view_ubo; /* -------------------------------------------------------------------- */ @@ -911,6 +914,53 @@ static void bind_ubo(GPUUniformBuffer *ubo, char bind_type) slot_flags[bind_num] = bind_type; } +#ifndef NDEBUG +/** + * Opengl specification is strict on buffer binding. + * + * " If any active uniform block is not backed by a + * sufficiently large buffer object, the results of shader + * execution are undefined, and may result in GL interruption or + * termination. " - Opengl 3.3 Core Specification + * + * For now we only check if the binding is correct. Not the size of + * the bound ubo. + * + * See T55475. + * */ +static bool ubo_bindings_validate(DRWShadingGroup *shgroup) +{ + bool valid = true; +# ifdef DEBUG_UBO_BINDING + /* Check that all active uniform blocks have a non-zero buffer bound. */ + GLint program = 0; + GLint active_blocks = 0; + + glGetIntegerv(GL_CURRENT_PROGRAM, &program); + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &active_blocks); + + for (uint i = 0; i < active_blocks; ++i) { + int binding = 0; + int buffer = 0; + + glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_BINDING, &binding); + glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, binding, &buffer); + + if (buffer == 0) { + char blockname[64]; + glGetActiveUniformBlockName(program, i, sizeof(blockname), NULL, blockname); + + printf("Trying to draw with missing UBO binding.\n"); + printf("Shader : %s, Block : %s\n", shgroup->shader->name, blockname); + + valid = false; + } + } +# endif + return valid; +} +#endif + static void release_texture_slots(bool with_persist) { if (with_persist) { @@ -1087,6 +1137,8 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) #endif + BLI_assert(ubo_bindings_validate(shgroup)); + /* Rendering Calls */ if (!ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM)) { /* Replacing multiple calls with only one */ -- cgit v1.2.3 From 45751065c0e13242e08ef0d0b3dbecf9b4a05baa Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 2 Aug 2018 19:21:12 +0200 Subject: Add list of color to Assign color operator It's more clear for user to see the name of the color --- release/scripts/startup/bl_ui/space_view3d.py | 14 ++++++++++++-- source/blender/editors/gpencil/gpencil_data.c | 24 ++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index ab01560351c..a6d66f20494 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3539,6 +3539,15 @@ class VIEW3D_MT_paint_gpencil(Menu): layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME' layout.operator("gpencil.active_frames_delete_all") +class VIEW3D_MT_assign_material(Menu): + bl_label = "Assign Material" + + def draw(self, context): + layout = self.layout + ob = context.active_object; + + for mat in ob.data.materials: + layout.operator("gpencil.stroke_change_color", text=mat.name).material = mat.name class VIEW3D_MT_edit_gpencil(Menu): bl_label = "Strokes" @@ -3583,7 +3592,7 @@ class VIEW3D_MT_edit_gpencil(Menu): layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator("gpencil.stroke_change_color", text="Assign Material") + layout.menu("VIEW3D_MT_assign_material") layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") layout.separator() @@ -3633,7 +3642,7 @@ class VIEW3D_MT_sculpt_gpencil(Menu): layout.separator() layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer") - layout.operator("gpencil.stroke_change_color", text="Assign Material") + layout.menu("VIEW3D_MT_assign_material") layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...") layout.separator() @@ -4997,6 +5006,7 @@ classes = ( VIEW3D_MT_edit_mesh_delete, VIEW3D_MT_edit_mesh_showhide, VIEW3D_MT_paint_gpencil, + VIEW3D_MT_assign_material, VIEW3D_MT_edit_gpencil, VIEW3D_MT_edit_gpencil_delete, VIEW3D_MT_sculpt_gpencil, diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 01cf8aeb7f1..8598d45ff01 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1131,12 +1131,29 @@ void GPENCIL_OT_stroke_arrange(wmOperatorType *ot) /* ******************* Move Stroke to new color ************************** */ -static int gp_stroke_change_color_exec(bContext *C, wmOperator *UNUSED(op)) +static int gp_stroke_change_color_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); + Material *ma = NULL; + char name[MAX_ID_NAME - 2]; + RNA_string_get(op->ptr, "material", name); + bGPdata *gpd = ED_gpencil_data_get_active(C); Object *ob = CTX_data_active_object(C); - Material *ma = give_current_material(ob, ob->actcol); + if (name[0] == '\0') { + ma = give_current_material(ob, ob->actcol); + } + else { + ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, name); + if (ma == NULL) { + return OPERATOR_CANCELLED; + } + } + /* try to find slot */ int idx = BKE_object_material_slot_find_index(ob, ma) - 1; + if (idx == 0) { + return OPERATOR_CANCELLED; + } /* sanity checks */ if (ELEM(NULL, gpd)) { @@ -1200,6 +1217,9 @@ void GPENCIL_OT_stroke_change_color(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_string(ot->srna, "material", NULL, MAX_ID_NAME - 2, "Material", "Name of the material"); + } /* ******************* Lock color of non selected Strokes colors ************************** */ -- cgit v1.2.3 From 836db3aee80008def4edb5c32c1cd7eccddc862f Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 2 Aug 2018 19:35:29 +0200 Subject: Add Assign Material option to Special menu (W key) Also some renames and cleanups. --- .../bl_ui/properties_grease_pencil_common.py | 55 ------------------- release/scripts/startup/bl_ui/space_view3d.py | 62 ++++++++++++++++++++++ source/blender/editors/gpencil/gpencil_ops.c | 4 +- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 9f2edefc3c2..336e4acfd8f 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -582,59 +582,6 @@ class GPENCIL_MT_separate(Menu): layout.operator("gpencil.stroke_separate", text="Active Layer").mode = 'LAYER' -class GPENCIL_MT_gpencil_edit_specials(Menu): - bl_label = "GPencil Specials" - - def draw(self, context): - layout = self.layout - is_3d_view = context.space_data.type == 'VIEW_3D' - - layout.operator_context = 'INVOKE_REGION_WIN' - - layout.operator("gpencil.stroke_subdivide", text="Subdivide") - layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") - layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") - - layout.separator() - layout.menu("GPENCIL_MT_separate", text="Separate") - - layout.separator() - layout.operator("gpencil.stroke_split", text="Split") - - layout.separator() - - layout.operator("gpencil.stroke_join", text="Join").type = 'JOIN' - layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' - layout.operator("gpencil.stroke_flip", text="Flip Direction") - - layout.separator() - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' - - if is_3d_view: - layout.separator() - layout.operator("gpencil.reproject") - - -class GPENCIL_MT_gpencil_sculpt_specials(Menu): - bl_label = "GPencil Specials" - - def draw(self, context): - layout = self.layout - is_3d_view = context.space_data.type == 'VIEW_3D' - - layout.operator_context = 'INVOKE_REGION_WIN' - - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") - layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' - - layout.separator() - - layout.operator("gpencil.stroke_subdivide", text="Subdivide") - layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") - layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") - - class GPENCIL_MT_gpencil_draw_specials(Menu): bl_label = "GPencil Draw Specials" @@ -859,8 +806,6 @@ classes = ( GPENCIL_MT_snap, GPENCIL_MT_separate, - GPENCIL_MT_gpencil_edit_specials, - GPENCIL_MT_gpencil_sculpt_specials, GPENCIL_MT_gpencil_draw_specials, GPENCIL_MT_gpencil_draw_delete, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index a6d66f20494..349832cedf2 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3539,6 +3539,7 @@ class VIEW3D_MT_paint_gpencil(Menu): layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME' layout.operator("gpencil.active_frames_delete_all") + class VIEW3D_MT_assign_material(Menu): bl_label = "Assign Material" @@ -3549,6 +3550,7 @@ class VIEW3D_MT_assign_material(Menu): for mat in ob.data.materials: layout.operator("gpencil.stroke_change_color", text=mat.name).material = mat.name + class VIEW3D_MT_edit_gpencil(Menu): bl_label = "Strokes" @@ -4898,6 +4900,64 @@ class VIEW3D_PT_gpencil_multi_frame(Panel): layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True) +class VIEW3D_MT_gpencil_edit_specials(Menu): + bl_label = "Grease Pencil Specials" + + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' + + layout.operator_context = 'INVOKE_REGION_WIN' + + layout.menu("VIEW3D_MT_assign_material") + layout.separator() + + layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") + layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") + + layout.separator() + layout.menu("GPENCIL_MT_separate", text="Separate") + + layout.separator() + layout.operator("gpencil.stroke_split", text="Split") + + layout.separator() + + layout.operator("gpencil.stroke_join", text="Join").type = 'JOIN' + layout.operator("gpencil.stroke_join", text="Join & Copy").type = 'JOINCOPY' + layout.operator("gpencil.stroke_flip", text="Flip Direction") + + layout.separator() + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' + + if is_3d_view: + layout.separator() + layout.operator("gpencil.reproject") + + +class VIEW3D_MT_gpencil_sculpt_specials(Menu): + bl_label = "Grease Pencil Specials" + + def draw(self, context): + layout = self.layout + is_3d_view = context.space_data.type == 'VIEW_3D' + + layout.operator_context = 'INVOKE_REGION_WIN' + layout.menu("VIEW3D_MT_assign_material") + layout.separator() + + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame") + layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame All Layers").mode = 'ALL' + + layout.separator() + + layout.operator("gpencil.stroke_subdivide", text="Subdivide") + layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") + layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") + + classes = ( VIEW3D_HT_header, VIEW3D_MT_editor_menus, @@ -5041,6 +5101,8 @@ classes = ( VIEW3D_PT_object_type_visibility, VIEW3D_PT_grease_pencil, VIEW3D_PT_gpencil_multi_frame, + VIEW3D_MT_gpencil_edit_specials, + VIEW3D_MT_gpencil_sculpt_specials, VIEW3D_PT_quad_view, VIEW3D_PT_view3d_stereo, VIEW3D_PT_shading, diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 3a86b0c13ef..b2e1758b169 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -299,7 +299,7 @@ static void ed_keymap_gpencil_sculpt(wmKeyMap *keymap) RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.gpencil_sculpt.brush.size"); /* menu sculpt specials */ - WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_sculpt_specials", WKEY, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "VIEW3D_MT_gpencil_sculpt_specials", WKEY, KM_PRESS, 0, 0); } static void ed_keymap_gpencil_weight(wmKeyMap *keymap) @@ -371,7 +371,7 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "GPENCIL_OT_active_frames_delete_all", DELKEY, KM_PRESS, KM_SHIFT, 0); /* menu edit specials */ - WM_keymap_add_menu(keymap, "GPENCIL_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "VIEW3D_MT_gpencil_edit_specials", WKEY, KM_PRESS, 0, 0); /* menu separate */ WM_keymap_add_menu(keymap, "GPENCIL_MT_separate", PKEY, KM_PRESS, 0, 0); -- cgit v1.2.3 From 9887b32e736669a9b4aef64771dd41fbf6629a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 19:32:31 +0200 Subject: Eevee: Fix missing UBO bind. --- source/blender/draw/engines/eevee/eevee_lightprobes.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 8b021279411..93f0e7e9315 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -515,6 +515,9 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); DRW_shgroup_uniform_float_copy(grp, "sphere_size", scene_eval->eevee.gi_cubemap_draw_size * 0.5f); + /* TODO (fclem) get rid of thoses UBO. */ + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); } /* Grid Display */ @@ -531,6 +534,11 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat DRW_shgroup_uniform_vec3(shgrp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex); DRW_shgroup_uniform_float_copy(shgrp, "sphere_size", scene_eval->eevee.gi_irradiance_draw_size * 0.5f); + /* TODO (fclem) get rid of thoses UBO. */ + DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo); int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2; DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, NULL); } -- cgit v1.2.3 From 2a8413a0dddbb8693b9a0c0bb88452472ba92cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Aug 2018 21:12:08 +0200 Subject: Eevee: Don't show probe display when not using scene lighting The display is broken otherwise. --- source/blender/draw/engines/eevee/eevee_lightprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 93f0e7e9315..50f4e694d2a 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -501,7 +501,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat } } - if (DRW_state_draw_support()) { + if (DRW_state_draw_support() && !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; psl->probe_display = DRW_pass_create("LightProbe Display", state); -- cgit v1.2.3 From 3eab49dd365e2785abbc51b6f23ac6e05c8eedc7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Aug 2018 11:43:50 +1000 Subject: Icons: add particle brush icons --- release/datafiles/icons/brush.particle.add.dat | Bin 0 -> 2060 bytes release/datafiles/icons/brush.particle.comb.dat | Bin 0 -> 3590 bytes release/datafiles/icons/brush.particle.cut.dat | Bin 0 -> 6578 bytes release/datafiles/icons/brush.particle.length.dat | Bin 0 -> 3824 bytes release/datafiles/icons/brush.particle.puff.dat | Bin 0 -> 3644 bytes release/datafiles/icons/brush.particle.smooth.dat | Bin 0 -> 2870 bytes release/datafiles/icons/brush.particle.weight.dat | Bin 0 -> 3878 bytes source/blender/editors/datafiles/CMakeLists.txt | 7 +++++++ 8 files changed, 7 insertions(+) create mode 100644 release/datafiles/icons/brush.particle.add.dat create mode 100644 release/datafiles/icons/brush.particle.comb.dat create mode 100644 release/datafiles/icons/brush.particle.cut.dat create mode 100644 release/datafiles/icons/brush.particle.length.dat create mode 100644 release/datafiles/icons/brush.particle.puff.dat create mode 100644 release/datafiles/icons/brush.particle.smooth.dat create mode 100644 release/datafiles/icons/brush.particle.weight.dat diff --git a/release/datafiles/icons/brush.particle.add.dat b/release/datafiles/icons/brush.particle.add.dat new file mode 100644 index 00000000000..e78bf251371 Binary files /dev/null and b/release/datafiles/icons/brush.particle.add.dat differ diff --git a/release/datafiles/icons/brush.particle.comb.dat b/release/datafiles/icons/brush.particle.comb.dat new file mode 100644 index 00000000000..5ece6bf754d Binary files /dev/null and b/release/datafiles/icons/brush.particle.comb.dat differ diff --git a/release/datafiles/icons/brush.particle.cut.dat b/release/datafiles/icons/brush.particle.cut.dat new file mode 100644 index 00000000000..79306d5d7e9 Binary files /dev/null and b/release/datafiles/icons/brush.particle.cut.dat differ diff --git a/release/datafiles/icons/brush.particle.length.dat b/release/datafiles/icons/brush.particle.length.dat new file mode 100644 index 00000000000..4c9da271316 Binary files /dev/null and b/release/datafiles/icons/brush.particle.length.dat differ diff --git a/release/datafiles/icons/brush.particle.puff.dat b/release/datafiles/icons/brush.particle.puff.dat new file mode 100644 index 00000000000..b0e797853c3 Binary files /dev/null and b/release/datafiles/icons/brush.particle.puff.dat differ diff --git a/release/datafiles/icons/brush.particle.smooth.dat b/release/datafiles/icons/brush.particle.smooth.dat new file mode 100644 index 00000000000..a3cbe3cf657 Binary files /dev/null and b/release/datafiles/icons/brush.particle.smooth.dat differ diff --git a/release/datafiles/icons/brush.particle.weight.dat b/release/datafiles/icons/brush.particle.weight.dat new file mode 100644 index 00000000000..309ee157a19 Binary files /dev/null and b/release/datafiles/icons/brush.particle.weight.dat differ diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 0698282c4e5..910b61cbdd8 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -564,6 +564,13 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES brush.paint_weight.lighten brush.paint_weight.mix brush.paint_weight.multiply + brush.particle.add + brush.particle.comb + brush.particle.cut + brush.particle.length + brush.particle.puff + brush.particle.smooth + brush.particle.weight brush.sculpt.blob brush.sculpt.clay brush.sculpt.clay_strips -- cgit v1.2.3 From fa0f938b111ffa281865613f80e425c27f3096b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 3 Aug 2018 09:48:28 +0200 Subject: Eevee: Fix assert with hair drawing This remove unused clip_block when not needed and the useless ubo bind that were put there for the sake of not crashing. --- source/blender/draw/engines/eevee/eevee_materials.c | 2 -- source/blender/draw/engines/eevee/shaders/prepass_vert.glsl | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index fd097aa783c..535dce7730a 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -1005,12 +1005,10 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE; psl->depth_pass = DRW_pass_create("Depth Pass", state); stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass); - DRW_shgroup_uniform_block(stl->g_data->depth_shgrp, "clip_block", sldata->clip_ubo); state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", state); stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass_cull); - DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_cull, "clip_block", sldata->clip_ubo); state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE; psl->depth_pass_clip = DRW_pass_create("Depth Pass Clip", state); diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl index f2e9e7001e8..e110937c5aa 100644 --- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl @@ -2,10 +2,12 @@ uniform mat4 ModelViewProjectionMatrix; uniform mat4 ModelMatrix; +#ifdef CLIP_PLANES /* keep in sync with DRWManager.view_data */ layout(std140) uniform clip_block { vec4 ClipPlanes[1]; }; +#endif #ifndef HAIR_SHADER in vec3 pos; -- cgit v1.2.3 From f55863acd4977a1ec92e1d30f06a7ae6b894660d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 3 Aug 2018 09:49:22 +0200 Subject: DRW: Augment Debug messages --- source/blender/draw/intern/draw_manager.h | 5 +++-- source/blender/draw/intern/draw_manager_data.c | 6 +++--- source/blender/draw/intern/draw_manager_exec.c | 9 +++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 9b01f17649c..902ecb9ee9b 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -262,10 +262,11 @@ struct DRWShadingGroup { #ifndef NDEBUG char attribs_count; #endif - +#if !defined(NDEBUG) || defined(USE_GPU_SELECT) + DRWPass *pass_parent; /* backlink to pass we're in */ +#endif #ifdef USE_GPU_SELECT GPUVertBuf *inst_selectid; - DRWPass *pass_parent; /* backlink to pass we're in */ int override_selectid; /* Override for single object instances. */ #endif }; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 407eea16d91..6b15803723b 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -122,7 +122,7 @@ static void drw_shgroup_uniform(DRWShadingGroup *shgroup, const char *name, if (location == -1) { if (G.debug & G_DEBUG) - fprintf(stderr, "Uniform '%s' not found!\n", name); + fprintf(stderr, "Pass : %s, Uniform '%s' not found!\n", shgroup->pass_parent->name, name); /* Nice to enable eventually, for now eevee uses uniforms that might not exist. */ // BLI_assert(0); return; @@ -730,7 +730,7 @@ static DRWShadingGroup *drw_shgroup_create_ex(struct GPUShader *shader, DRWPass shgroup->instance_vbo = NULL; #endif -#ifdef USE_GPU_SELECT +#if !defined(NDEBUG) || defined(USE_GPU_SELECT) shgroup->pass_parent = pass; #endif @@ -1026,7 +1026,7 @@ DRWPass *DRW_pass_create(const char *name, DRWState state) { DRWPass *pass = BLI_mempool_alloc(DST.vmempool->passes); pass->state = state; - if (G.debug_value > 20) { + if ((G.debug_value > 20) || (G.debug & G_DEBUG)) { BLI_strncpy(pass->name, name, MAX_PASS_NAME); } diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index ed01080be87..004e0137c66 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -950,10 +950,11 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup) char blockname[64]; glGetActiveUniformBlockName(program, i, sizeof(blockname), NULL, blockname); - printf("Trying to draw with missing UBO binding.\n"); - printf("Shader : %s, Block : %s\n", shgroup->shader->name, blockname); - - valid = false; + if (valid) { + printf("Trying to draw with missing UBO binding.\n"); + valid = false; + } + printf("Pass : %s, Shader : %s, Block : %s\n", shgroup->pass_parent->name, shgroup->shader->name, blockname); } } # endif -- cgit v1.2.3 From b5a1e3d471ad0657a10596b7f2f47b6c7e0fb3f4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 3 Aug 2018 10:13:33 +0200 Subject: Depsgraph: add helper to ensure a given scene/view_layer graph is up-to-date. Since that call make the graph active, it should only be used in active editing context aware code (i.e. essentially, operators). --- source/blender/blenkernel/BKE_scene.h | 3 +++ source/blender/blenkernel/intern/scene.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index e2032e10833..e7a26afadf5 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -147,6 +147,9 @@ void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph, struct Main *bmain); +void BKE_scene_view_layer_graph_evaluated_ensure( + struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer); + struct SceneRenderView *BKE_scene_add_render_view(struct Scene *sce, const char *name); bool BKE_scene_remove_render_view(struct Scene *scene, struct SceneRenderView *srv); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index ba25fc14ac9..8522c7f4445 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1477,6 +1477,18 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, DEG_ids_clear_recalc(bmain, depsgraph); } +/** Ensures given scene/view_layer pair has a valid, up-to-date depsgraph. + * + * \warning Sets matching depsgraph as active, so should only be called from the active editing context + * (usually, from operators). + */ +void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + DEG_make_active(depsgraph); + BKE_scene_graph_update_tagged(depsgraph, bmain); +} + /* return default view */ SceneRenderView *BKE_scene_add_render_view(Scene *sce, const char *name) { -- cgit v1.2.3 From cd5ee246565d06240f578e0ffba1310254bbec3e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 3 Aug 2018 10:15:34 +0200 Subject: Operators: add a new flag stating that operator needs access to evaluated data. For now, that flag is only used in redo code, since after undo step depsgraph is totally empty... We *may* want to add at least an assert in op calling code too, though? --- source/blender/editors/undo/ed_undo.c | 10 ++++++++++ source/blender/makesrna/intern/rna_wm.c | 2 ++ source/blender/windowmanager/WM_types.h | 1 + 3 files changed, 13 insertions(+) diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 7c1dc148dde..ffe4008f7d6 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -48,6 +48,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_layer.h" #include "BKE_undo_system.h" @@ -414,6 +415,15 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op) } } + if (op->type->flag & OPTYPE_USE_EVAL_DATA) { + /* We need to force refresh of depsgraph after undo step, + * redoing the operator *may* rely on some valid evaluated data. */ + Main *bmain = CTX_data_main(C); + scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + BKE_scene_view_layer_graph_evaluated_ensure(bmain, scene, view_layer); + } + retval = WM_operator_repeat(C, op); if ((retval & OPERATOR_FINISHED) == 0) { if (G.debug & G_DEBUG) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 3432adc6eb3..a4c8dfbbdef 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -432,6 +432,8 @@ static const EnumPropertyItem operator_flag_items[] = { "is enabled"}, {OPTYPE_PRESET, "PRESET", 0, "Preset", "Display a preset button with the operators settings"}, {OPTYPE_INTERNAL, "INTERNAL", 0, "Internal", "Removes the operator from search results"}, + {OPTYPE_USE_EVAL_DATA, "USE_EVAL_DATA", 0, "Use Evaluated Data", + "Uses evaluated data (i.e. needs a valid depsgraph for current context)"}, {0, NULL, 0, NULL, NULL} }; #endif diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 60dd9ad2e72..6b1bb8f4806 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -145,6 +145,7 @@ enum { OPTYPE_LOCK_BYPASS = (1 << 7), /* Allow operator to run when interface is locked */ OPTYPE_UNDO_GROUPED = (1 << 8), /* Special type of undo which doesn't store itself multiple times */ + OPTYPE_USE_EVAL_DATA = (1 << 9), /* Need evaluated data (i.e. a valid, up-to-date depsgraph for current context) */ }; /* context to call operator in for WM_operator_name_call */ -- cgit v1.2.3 From 56fd63e1ad4f8e8e9ce66220127ecbf80b6e39e1 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 3 Aug 2018 10:17:00 +0200 Subject: Fix T55791: blender 2.8 crash on redoing 'snap to cursor' with Offset option ON. Many snap_to operators need a fully evaluated depsgraph to run properly... --- source/blender/editors/space_view3d/view3d_snap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 6cb0db94099..15be77ff6ab 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -221,7 +221,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) ot->poll = ED_operator_region_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; } /* *************************************************** */ @@ -449,7 +449,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) ot->poll = ED_operator_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* rna */ RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", @@ -483,7 +483,7 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot) ot->poll = ED_operator_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; } @@ -712,7 +712,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) ot->poll = ED_operator_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; } /* ********************************************** */ @@ -794,7 +794,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) ot->poll = ED_operator_view3d_active; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; } /* **************************************************** */ -- cgit v1.2.3 From 6c8cc91f816d67f2f4ef1d41b226bb8d50a8b0b2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 3 Aug 2018 10:25:06 +0200 Subject: Fix T56180: Grease Pencil edit mode select menu crash. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that there are most certainly many other operators that’d need that same flag... Don’t have time to hunt them down currently, will just fix as issues are found, for now. --- source/blender/editors/gpencil/gpencil_edit.c | 2 +- source/blender/editors/gpencil/gpencil_select.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 56d1d53ea40..789917780a0 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -2847,7 +2847,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot) ot->poll = gp_strokes_edit3d_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* properties */ ot->prop = RNA_def_enum(ot->srna, "type", reproject_type, GP_REPROJECT_PLANAR, "Projection Type", ""); diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index 9386bfb3333..3e0caa8d5d8 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -986,7 +986,7 @@ void GPENCIL_OT_select_circle(wmOperatorType *ot) ot->cancel = WM_gesture_circle_cancel; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* properties */ WM_operator_properties_gesture_circle_select(ot); @@ -1107,7 +1107,7 @@ void GPENCIL_OT_select_border(wmOperatorType *ot) ot->poll = gpencil_select_poll; /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* rna */ WM_operator_properties_gesture_border_select(ot); @@ -1225,7 +1225,7 @@ void GPENCIL_OT_select_lasso(wmOperatorType *ot) ot->cancel = WM_gesture_lasso_cancel; /* flags */ - ot->flag = OPTYPE_UNDO; + ot->flag = OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* properties */ WM_operator_properties_gesture_lasso_select(ot); @@ -1401,7 +1401,7 @@ void GPENCIL_OT_select(wmOperatorType *ot) ot->poll = gpencil_select_poll; /* flag */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_USE_EVAL_DATA; /* properties */ WM_operator_properties_mouse_select(ot); -- cgit v1.2.3 From 5fd3d1fda44fdc5da4b279309004996b1deaa3b4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 10:28:27 +0200 Subject: Fix T56217: Segment Fault when using the Fill Brush on Blank GP Object The error was in any GP object without layers. Also added a check to avoid paint in a locked layer. --- source/blender/editors/gpencil/gpencil_fill.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 253f0db865e..ec90c826a27 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -987,7 +987,9 @@ static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op)) /* set GP datablock */ tgpf->gpd = gpd; tgpf->gpl = BKE_gpencil_layer_getactive(gpd); - + if (tgpf->gpl == NULL) { + tgpf->gpl = BKE_gpencil_layer_addnew(tgpf->gpd, DATA_("GP_Layer"), true); + } tgpf->lock_axis = ts->gp_sculpt.lock_axis; tgpf->oldkey = -1; @@ -1087,6 +1089,12 @@ static void gpencil_fill_cancel(bContext *C, wmOperator *op) static int gpencil_fill_init(bContext *C, wmOperator *op) { tGPDfill *tgpf; + /* cannot paint in locked layer */ + bGPdata *gpd = CTX_data_gpencil_data(C); + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + if ((gpl) && (gpl->flag & GP_LAYER_LOCKED)) { + return 0; + } /* check context */ tgpf = op->customdata = gp_session_init_fill(C, op); -- cgit v1.2.3 From e1a68619874bbef7b5ac0593d586d17ce129637f Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Fri, 3 Aug 2018 10:58:42 +0200 Subject: Bugfix: audaspace cmake variables need to be cached. --- extern/audaspace/blender_config.cmake | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/extern/audaspace/blender_config.cmake b/extern/audaspace/blender_config.cmake index fb1ef95fee4..7deb78d27da 100644 --- a/extern/audaspace/blender_config.cmake +++ b/extern/audaspace/blender_config.cmake @@ -1,21 +1,20 @@ set(AUDASPACE_STANDALONE FALSE) -set(BUILD_DEMOS FALSE) -set(SHARED_LIBRARY FALSE) -set(WITH_C TRUE) -set(WITH_DOCS FALSE) -set(WITH_FFMPEG ${WITH_CODEC_FFMPEG}) -set(WITH_FFTW FALSE) -set(WITH_LIBSNDFILE ${WITH_CODEC_SNDFILE}) -set(SEPARATE_C FALSE) -set(PLUGIN_FFMPEG FALSE) -set(PLUGIN_JACK FALSE) -set(PLUGIN_LIBSNDFILE FALSE) -set(PLUGIN_OPENAL FALSE) -set(PLUGIN_SDL FALSE) -set(WITH_PYTHON_MODULE FALSE) -set(DYNLOAD_JACK ${WITH_JACK_DYNLOAD}) -set(WITH_BINDING_DOCS FALSE) -set(BLENDER_AUDASPACE TRUE) +set(BUILD_DEMOS FALSE CACHE BOOL "Build and install demos") +set(SHARED_LIBRARY FALSE CACHE BOOL "Build Shared Library") +set(WITH_C TRUE CACHE BOOL "Build C Module") +set(WITH_DOCS FALSE CACHE BOOL "Build C++ HTML Documentation with Doxygen") +set(WITH_FFMPEG ${WITH_CODEC_FFMPEG} CACHE BOOL "Build With FFMPEG") +set(WITH_FFTW FALSE CACHE BOOL "Build With FFTW") +set(WITH_LIBSNDFILE ${WITH_CODEC_SNDFILE} CACHE BOOL "Build With LibSndFile") +set(SEPARATE_C FALSE CACHE BOOL "Build C Binding as separate library") +set(PLUGIN_FFMPEG FALSE CACHE BOOL "Build FFMPEG Plugin") +set(PLUGIN_JACK FALSE CACHE BOOL "Build JACK Plugin") +set(PLUGIN_LIBSNDFILE FALSE CACHE BOOL "Build LibSndFile Plugin") +set(PLUGIN_OPENAL FALSE CACHE BOOL "Build OpenAL Plugin") +set(PLUGIN_SDL FALSE CACHE BOOL "Build SDL Plugin") +set(WITH_PYTHON_MODULE FALSE CACHE BOOL "Build Python Module") +set(DYNLOAD_JACK ${WITH_JACK_DYNLOAD} CACHE BOOL "Dynamically load JACK") +set(WITH_BINDING_DOCS FALSE CACHE BOOL "Build C/Python HTML Documentation with Sphinx") set(FFMPEG_FOUND ${WITH_CODEC_FFMPEG}) set(JACK_FOUND ${WITH_JACK}) set(LIBSNDFILE_FOUND ${WITH_CODEC_SNDFILE}) @@ -26,5 +25,7 @@ set(NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIRS}) set(SDL_FOUND ${WITH_SDL}) if(WIN32) - set(DEFAULT_PLUGIN_PATH "plugins") + set(DEFAULT_PLUGIN_PATH "plugins" CACHE STRING "Default plugin installation and loading path.") endif() + +mark_as_advanced(BUILD_DEMOS SHARED_LIBRARY WITH_C WITH_DOCS WITH_FFMPEG WITH_FFTW WITH_LIBSNDFILE SEPARATE_C PLUGIN_FFMPEG PLUGIN_JACK PLUGIN_LIBSNDFILE PLUGIN_OPENAL PLUGIN_SDL WITH_PYTHON_MODULE DYNLOAD_JACK WITH_BINDING_DOCS DEFAULT_PLUGIN_PATH) -- cgit v1.2.3 From 5d4b981bc28278d254f247b511bed041d4daf599 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 13:41:40 +0200 Subject: Add missing single user management for grease pencil materials --- source/blender/editors/object/object_relations.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 874b36ef42e..78e44e52299 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1875,6 +1875,7 @@ static void single_mat_users_expand(Main *bmain) Mesh *me; Curve *cu; MetaBall *mb; + bGPdata *gpd; for (ob = bmain->object.first; ob; ob = ob->id.next) if (ob->id.tag & LIB_TAG_NEW) @@ -1891,6 +1892,10 @@ 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); + + for (gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) + if (gpd->id.tag & LIB_TAG_NEW) + new_id_matar(bmain, gpd->mat, gpd->totcol); } /* used for copying scenes */ -- cgit v1.2.3 From fe8dcffd79488451f748a0c9cf33e7ca6579c028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 3 Aug 2018 14:34:05 +0200 Subject: GPUShader: Fix warning in release build. --- source/blender/gpu/intern/gpu_shader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 3a6ad04b69a..67ae1414b66 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -173,7 +173,9 @@ extern char datatoc_gpu_shader_gpencil_fill_frag_glsl[]; /* cache of built-in shaders (each is created on first use) */ static GPUShader *builtin_shaders[GPU_NUM_BUILTIN_SHADERS] = { NULL }; +#ifndef NDEBUG static uint g_shaderid = 0; +#endif typedef struct { const char *vert; -- cgit v1.2.3 From 7288d4d8c4a390fb58509120809360a56c00e3cf Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 16:36:53 +0200 Subject: Replace wrong aasign material flag to BKE_MAT_ASSIGN_USERPREF --- source/blender/blenkernel/intern/gpencil.c | 2 +- source/blender/editors/gpencil/gpencil_add_monkey.c | 2 +- source/blender/editors/gpencil/gpencil_data.c | 2 +- source/blender/editors/gpencil/gpencil_edit.c | 4 ++-- source/blender/editors/gpencil/gpencil_old.c | 2 +- source/blender/editors/gpencil/gpencil_paint.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 18817f20d1c..b619304d39b 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1073,7 +1073,7 @@ Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob) BKE_object_material_slot_add(bmain, ob); } ma = BKE_material_add_gpencil(bmain, DATA_("Material")); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); } else if (ma->gp_style == NULL) { BKE_material_init_gpencil_settings(ma); diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c index 8a7128adde1..b0c3675c123 100644 --- a/source/blender/editors/gpencil/gpencil_add_monkey.c +++ b/source/blender/editors/gpencil/gpencil_add_monkey.c @@ -68,7 +68,7 @@ static int gpencil_monkey_color(Main *bmain, Object *ob, const ColorTemplate *pc /* create a new one */ BKE_object_material_slot_add(bmain, ob); ma = BKE_material_add_gpencil(bmain, pct->name); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); copy_v4_v4(ma->gp_style->stroke_rgba, pct->line); copy_v4_v4(ma->gp_style->fill_rgba, pct->fill); diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 8598d45ff01..43721d73a80 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1903,7 +1903,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) Material *tmp_ma = (*matar)[i]; if (BKE_object_material_slot_find_index(ob_dst, tmp_ma) == 0) { BKE_object_material_slot_add(bmain, ob_dst); - assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF); } } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 789917780a0..969ff326c61 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -734,7 +734,7 @@ GHash *gp_copybuf_validate_colormap(bContext *C) if (BKE_object_material_slot_find_index(ob, ma) == 0) { BKE_object_material_slot_add(bmain, ob); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); } /* Store this mapping (for use later when pasting) */ @@ -3195,7 +3195,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op) BKE_object_material_slot_add(bmain, ob_dst); } - assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF); idx = totadd; } diff --git a/source/blender/editors/gpencil/gpencil_old.c b/source/blender/editors/gpencil/gpencil_old.c index b7af1c80d4c..76d519fe371 100644 --- a/source/blender/editors/gpencil/gpencil_old.c +++ b/source/blender/editors/gpencil/gpencil_old.c @@ -129,7 +129,7 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *UNUSED(op)) /* create material slot */ BKE_object_material_slot_add(bmain, ob); Material *ma = BKE_material_add_gpencil(bmain, palcolor->info); - assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); /* copy color settings */ MaterialGPencilStyle *gp_style = ma->gp_style; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 6a0bf0c4a47..88f90d6c128 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1604,7 +1604,7 @@ static void gp_init_colors(tGPsdata *p) /* check if the material is already on object material slots and add it if missing */ if (BKE_object_material_slot_find_index(p->ob, p->material) == 0) { BKE_object_material_slot_add(p->bmain, p->ob); - assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_USERPREF); } /* assign color information to temp tGPsdata */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 3cd298e9b87..88754f29db3 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -126,7 +126,7 @@ static void bakeModifier( if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); - assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 859e12adfb5..641a75bc353 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -134,7 +134,7 @@ static void bakeModifier( if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); - assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_EXISTING); + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); -- cgit v1.2.3 From f2a8e55fc528b8f73554821453238763d8a0ce94 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 17:37:21 +0200 Subject: New grease pencil primitive STROKE This creates a simple stroke with several colors to have a basic structure to start drawing. --- source/blender/editors/gpencil/CMakeLists.txt | 1 + .../blender/editors/gpencil/gpencil_add_stroke.c | 203 +++++++++++++++++++++ source/blender/editors/include/ED_gpencil.h | 1 + source/blender/editors/object/object_add.c | 14 +- source/blender/makesdna/DNA_object_types.h | 3 +- source/blender/makesrna/intern/rna_object.c | 1 + 6 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 source/blender/editors/gpencil/gpencil_add_stroke.c diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index f9f196f6634..114e55c5704 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -44,6 +44,7 @@ set(SRC drawgpencil.c editaction_gpencil.c gpencil_add_monkey.c + gpencil_add_stroke.c gpencil_brush.c gpencil_convert.c gpencil_data.c diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c new file mode 100644 index 00000000000..a945173fb90 --- /dev/null +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -0,0 +1,203 @@ +/* + * ***** 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) 2017 Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez, Matias Mendiola + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/gpencil/gpencil_add_monkey.c + * \ingroup edgpencil + */ + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_gpencil_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_context.h" +#include "BKE_gpencil.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "ED_gpencil.h" + +/* Definition of the most important info from a color */ +typedef struct ColorTemplate { + const char *name; + float line[4]; + float fill[4]; +} ColorTemplate; + +/* Add color an ensure duplications (matched by name) */ +static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct) +{ + Material *ma = NULL; + Material ***matar = give_matarar(ob); + short *totcol = give_totcolp(ob); + for (short i = 0; i < *totcol; i++) { + ma = (*matar)[i]; + if (STREQ(ma->id.name, pct->name)) { + return i; + } + } + + /* create a new one */ + BKE_object_material_slot_add(bmain, ob); + ma = BKE_material_add_gpencil(bmain, pct->name); + assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); + + copy_v4_v4(ma->gp_style->stroke_rgba, pct->line); + copy_v4_v4(ma->gp_style->fill_rgba, pct->fill); + + return BKE_object_material_slot_find_index(ob, ma) - 1; +} + +/* ***************************************************************** */ +/* Stroke Geometry */ + +static const float data0[175 * GP_PRIM_DATABUF_SIZE] = {-1.281f, 0.0f, -0.315f, 0.038f, 1.0f, -1.269f, 0.0f, -0.302f, 0.069f, 1.0f, -1.261f, 0.0f, -0.293f, 0.089f, 1.0f, -1.251f, 0.0f, -0.282f, 0.112f, 1.0f, +-1.241f, 0.0f, -0.271f, 0.134f, 1.0f, -1.23f, 0.0f, -0.259f, 0.155f, 1.0f, -1.219f, 0.0f, -0.247f, 0.175f, 1.0f, -1.208f, 0.0f, -0.234f, 0.194f, 1.0f, +-1.196f, 0.0f, -0.221f, 0.211f, 1.0f, -1.184f, 0.0f, -0.208f, 0.227f, 1.0f, -1.172f, 0.0f, -0.194f, 0.242f, 1.0f, -1.159f, 0.0f, -0.18f, 0.256f, 1.0f, +-1.147f, 0.0f, -0.165f, 0.268f, 1.0f, -1.134f, 0.0f, -0.151f, 0.28f, 1.0f, -1.121f, 0.0f, -0.136f, 0.29f, 1.0f, -1.108f, 0.0f, -0.121f, 0.299f, 1.0f, +-1.094f, 0.0f, -0.106f, 0.307f, 1.0f, -1.08f, 0.0f, -0.091f, 0.315f, 1.0f, -1.066f, 0.0f, -0.076f, 0.322f, 1.0f, -1.052f, 0.0f, -0.061f, 0.329f, 1.0f, +-1.037f, 0.0f, -0.047f, 0.335f, 1.0f, -1.022f, 0.0f, -0.032f, 0.341f, 1.0f, -1.007f, 0.0f, -0.017f, 0.346f, 1.0f, -0.991f, 0.0f, -0.003f, 0.351f, 1.0f, +-0.975f, 0.0f, 0.012f, 0.355f, 1.0f, -0.959f, 0.0f, 0.027f, 0.36f, 1.0f, -0.942f, 0.0f, 0.041f, 0.364f, 1.0f, -0.926f, 0.0f, 0.056f, 0.368f, 1.0f, +-0.909f, 0.0f, 0.071f, 0.371f, 1.0f, -0.893f, 0.0f, 0.086f, 0.373f, 1.0f, -0.876f, 0.0f, 0.1f, 0.376f, 1.0f, -0.859f, 0.0f, 0.115f, 0.377f, 1.0f, +-0.842f, 0.0f, 0.129f, 0.378f, 1.0f, -0.824f, 0.0f, 0.144f, 0.379f, 1.0f, -0.807f, 0.0f, 0.158f, 0.379f, 1.0f, -0.79f, 0.0f, 0.172f, 0.379f, 1.0f, +-0.773f, 0.0f, 0.186f, 0.38f, 1.0f, -0.755f, 0.0f, 0.199f, 0.38f, 1.0f, -0.738f, 0.0f, 0.212f, 0.381f, 1.0f, -0.721f, 0.0f, 0.224f, 0.382f, 1.0f, +-0.703f, 0.0f, 0.236f, 0.384f, 1.0f, -0.686f, 0.0f, 0.248f, 0.386f, 1.0f, -0.67f, 0.0f, 0.26f, 0.388f, 1.0f, -0.653f, 0.0f, 0.27f, 0.39f, 1.0f, +-0.637f, 0.0f, 0.28f, 0.393f, 1.0f, -0.621f, 0.0f, 0.29f, 0.396f, 1.0f, -0.605f, 0.0f, 0.298f, 0.399f, 1.0f, -0.589f, 0.0f, 0.306f, 0.403f, 1.0f, +-0.574f, 0.0f, 0.313f, 0.407f, 1.0f, -0.559f, 0.0f, 0.319f, 0.411f, 1.0f, -0.544f, 0.0f, 0.325f, 0.415f, 1.0f, -0.53f, 0.0f, 0.331f, 0.42f, 1.0f, +-0.516f, 0.0f, 0.336f, 0.425f, 1.0f, -0.503f, 0.0f, 0.34f, 0.431f, 1.0f, -0.489f, 0.0f, 0.344f, 0.437f, 1.0f, -0.477f, 0.0f, 0.347f, 0.443f, 1.0f, +-0.464f, 0.0f, 0.35f, 0.45f, 1.0f, -0.452f, 0.0f, 0.352f, 0.457f, 1.0f, -0.44f, 0.0f, 0.354f, 0.464f, 1.0f, -0.429f, 0.0f, 0.355f, 0.471f, 1.0f, +-0.418f, 0.0f, 0.355f, 0.479f, 1.0f, -0.407f, 0.0f, 0.355f, 0.487f, 1.0f, -0.397f, 0.0f, 0.354f, 0.495f, 1.0f, -0.387f, 0.0f, 0.353f, 0.503f, 1.0f, +-0.378f, 0.0f, 0.351f, 0.512f, 1.0f, -0.368f, 0.0f, 0.348f, 0.52f, 1.0f, -0.36f, 0.0f, 0.344f, 0.528f, 1.0f, -0.351f, 0.0f, 0.34f, 0.537f, 1.0f, +-0.344f, 0.0f, 0.336f, 0.545f, 1.0f, -0.336f, 0.0f, 0.33f, 0.553f, 1.0f, -0.329f, 0.0f, 0.324f, 0.562f, 1.0f, -0.322f, 0.0f, 0.318f, 0.57f, 1.0f, +-0.316f, 0.0f, 0.31f, 0.579f, 1.0f, -0.311f, 0.0f, 0.303f, 0.588f, 1.0f, -0.306f, 0.0f, 0.294f, 0.597f, 1.0f, -0.301f, 0.0f, 0.285f, 0.606f, 1.0f, +-0.297f, 0.0f, 0.275f, 0.615f, 1.0f, -0.293f, 0.0f, 0.264f, 0.625f, 1.0f, -0.29f, 0.0f, 0.253f, 0.635f, 1.0f, -0.288f, 0.0f, 0.241f, 0.644f, 1.0f, +-0.286f, 0.0f, 0.229f, 0.654f, 1.0f, -0.285f, 0.0f, 0.216f, 0.664f, 1.0f, -0.284f, 0.0f, 0.202f, 0.675f, 1.0f, -0.283f, 0.0f, 0.188f, 0.685f, 1.0f, +-0.283f, 0.0f, 0.173f, 0.696f, 1.0f, -0.284f, 0.0f, 0.158f, 0.707f, 1.0f, -0.285f, 0.0f, 0.142f, 0.718f, 1.0f, -0.286f, 0.0f, 0.125f, 0.729f, 1.0f, +-0.288f, 0.0f, 0.108f, 0.74f, 1.0f, -0.29f, 0.0f, 0.091f, 0.751f, 1.0f, -0.293f, 0.0f, 0.073f, 0.761f, 1.0f, -0.295f, 0.0f, 0.054f, 0.772f, 1.0f, +-0.298f, 0.0f, 0.035f, 0.782f, 1.0f, -0.302f, 0.0f, 0.016f, 0.793f, 1.0f, -0.305f, 0.0f, -0.004f, 0.804f, 1.0f, -0.309f, 0.0f, -0.024f, 0.815f, 1.0f, +-0.313f, 0.0f, -0.044f, 0.828f, 1.0f, -0.317f, 0.0f, -0.065f, 0.843f, 1.0f, -0.321f, 0.0f, -0.085f, 0.86f, 1.0f, -0.326f, 0.0f, -0.106f, 0.879f, 1.0f, +-0.33f, 0.0f, -0.127f, 0.897f, 1.0f, -0.335f, 0.0f, -0.148f, 0.915f, 1.0f, -0.339f, 0.0f, -0.168f, 0.932f, 1.0f, -0.344f, 0.0f, -0.189f, 0.947f, 1.0f, +-0.348f, 0.0f, -0.21f, 0.962f, 1.0f, -0.353f, 0.0f, -0.23f, 0.974f, 1.0f, -0.357f, 0.0f, -0.25f, 0.985f, 1.0f, -0.361f, 0.0f, -0.27f, 0.995f, 1.0f, +-0.365f, 0.0f, -0.29f, 1.004f, 1.0f, -0.369f, 0.0f, -0.309f, 1.011f, 1.0f, -0.372f, 0.0f, -0.328f, 1.018f, 1.0f, -0.375f, 0.0f, -0.347f, 1.024f, 1.0f, +-0.377f, 0.0f, -0.365f, 1.029f, 1.0f, -0.379f, 0.0f, -0.383f, 1.033f, 1.0f, -0.38f, 0.0f, -0.4f, 1.036f, 1.0f, -0.38f, 0.0f, -0.417f, 1.037f, 1.0f, +-0.38f, 0.0f, -0.434f, 1.037f, 1.0f, -0.379f, 0.0f, -0.449f, 1.035f, 1.0f, -0.377f, 0.0f, -0.464f, 1.032f, 1.0f, -0.374f, 0.0f, -0.478f, 1.029f, 1.0f, +-0.371f, 0.0f, -0.491f, 1.026f, 1.0f, -0.366f, 0.0f, -0.503f, 1.023f, 1.0f, -0.361f, 0.0f, -0.513f, 1.021f, 1.0f, -0.354f, 0.0f, -0.523f, 1.019f, 1.0f, +-0.347f, 0.0f, -0.531f, 1.017f, 1.0f, -0.339f, 0.0f, -0.538f, 1.016f, 1.0f, -0.33f, 0.0f, -0.543f, 1.016f, 1.0f, -0.32f, 0.0f, -0.547f, 1.016f, 1.0f, +-0.31f, 0.0f, -0.549f, 1.016f, 1.0f, -0.298f, 0.0f, -0.55f, 1.017f, 1.0f, -0.286f, 0.0f, -0.55f, 1.017f, 1.0f, -0.274f, 0.0f, -0.548f, 1.018f, 1.0f, +-0.261f, 0.0f, -0.544f, 1.017f, 1.0f, -0.247f, 0.0f, -0.539f, 1.017f, 1.0f, -0.232f, 0.0f, -0.533f, 1.016f, 1.0f, -0.218f, 0.0f, -0.525f, 1.015f, 1.0f, +-0.202f, 0.0f, -0.515f, 1.013f, 1.0f, -0.186f, 0.0f, -0.503f, 1.009f, 1.0f, -0.169f, 0.0f, -0.49f, 1.005f, 1.0f, -0.151f, 0.0f, -0.475f, 0.998f, 1.0f, +-0.132f, 0.0f, -0.458f, 0.99f, 1.0f, -0.112f, 0.0f, -0.44f, 0.98f, 1.0f, -0.091f, 0.0f, -0.42f, 0.968f, 1.0f, -0.069f, 0.0f, -0.398f, 0.955f, 1.0f, +-0.045f, 0.0f, -0.375f, 0.939f, 1.0f, -0.021f, 0.0f, -0.35f, 0.923f, 1.0f, 0.005f, 0.0f, -0.324f, 0.908f, 1.0f, 0.031f, 0.0f, -0.297f, 0.895f, 1.0f, +0.06f, 0.0f, -0.268f, 0.882f, 1.0f, 0.089f, 0.0f, -0.238f, 0.87f, 1.0f, 0.12f, 0.0f, -0.207f, 0.858f, 1.0f, 0.153f, 0.0f, -0.175f, 0.844f, 1.0f, +0.187f, 0.0f, -0.14f, 0.828f, 1.0f, 0.224f, 0.0f, -0.104f, 0.81f, 1.0f, 0.262f, 0.0f, -0.067f, 0.79f, 1.0f, 0.302f, 0.0f, -0.027f, 0.769f, 1.0f, +0.344f, 0.0f, 0.014f, 0.747f, 1.0f, 0.388f, 0.0f, 0.056f, 0.724f, 1.0f, 0.434f, 0.0f, 0.1f, 0.7f, 1.0f, 0.483f, 0.0f, 0.145f, 0.676f, 1.0f, +0.533f, 0.0f, 0.191f, 0.651f, 1.0f, 0.585f, 0.0f, 0.238f, 0.625f, 1.0f, 0.637f, 0.0f, 0.284f, 0.599f, 1.0f, 0.69f, 0.0f, 0.33f, 0.573f, 1.0f, +0.746f, 0.0f, 0.376f, 0.546f, 1.0f, 0.802f, 0.0f, 0.421f, 0.516f, 1.0f, 0.859f, 0.0f, 0.464f, 0.483f, 1.0f, 0.915f, 0.0f, 0.506f, 0.446f, 1.0f, +0.97f, 0.0f, 0.545f, 0.407f, 1.0f, 1.023f, 0.0f, 0.581f, 0.365f, 1.0f, 1.075f, 0.0f, 0.614f, 0.322f, 1.0f, 1.122f, 0.0f, 0.643f, 0.28f, 1.0f, +1.169f, 0.0f, 0.671f, 0.236f, 1.0f, 1.207f, 0.0f, 0.693f, 0.202f, 1.0f, 1.264f, 0.0f, 0.725f, 0.155f, 1.0f, }; + +/* ***************************************************************** */ +/* Monkey Color Data */ + +static const ColorTemplate gp_stroke_material_black = { + "Black", + {0.0f, 0.0f, 0.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_stroke_material_white = { + "White", + {1.0f, 1.0f, 1.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_stroke_material_red = { + "Red", + {1.0f, 0.0f, 0.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_stroke_material_green = { + "Green", + {0.0f, 1.0f, 0.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_stroke_material_blue = { + "Blue", + {0.0f, 0.0f, 1.0f, 1.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, +}; + +static const ColorTemplate gp_stroke_material_grey = { + "Grey", + {0.358f, 0.358f, 0.358f, 1.0f}, + {0.5f, 0.5f, 0.5f, 1.0f}, +}; + +/* ***************************************************************** */ +/* Stroke API */ + +/* add a Simple stroke with colors (original design created by Daniel M. Lara and Matias Mendiola) */ +void ED_gpencil_create_stroke(bContext *C, float mat[4][4]) +{ + Main *bmain = CTX_data_main(C); + Object *ob = CTX_data_active_object(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + bGPdata *gpd = (bGPdata *)ob->data; + bGPDstroke *gps; + + /* create colors */ + int color_Black = gp_stroke_material(bmain, ob, &gp_stroke_material_black); + gp_stroke_material(bmain, ob, &gp_stroke_material_white); + gp_stroke_material(bmain, ob, &gp_stroke_material_red); + gp_stroke_material(bmain, ob, &gp_stroke_material_green); + gp_stroke_material(bmain, ob, &gp_stroke_material_blue); + gp_stroke_material(bmain, ob, &gp_stroke_material_grey); + + /* layers */ + bGPDlayer *Colors = BKE_gpencil_layer_addnew(gpd, "Colors", false); + bGPDlayer *Lines = BKE_gpencil_layer_addnew(gpd, "Lines", false); + + /* frames */ + bGPDframe *frameColor = BKE_gpencil_frame_addnew(Colors, cfra_eval); + bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, cfra_eval); + + /* generate stroke */ + gps = BKE_gpencil_add_stroke(frameLines, color_Black, 175, 3); + BKE_gpencil_stroke_add_points(gps, data0, 175, mat); + + /* update depsgraph */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; +} + diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 3013b455de4..13f8233079b 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -208,6 +208,7 @@ void ED_gpencil_brush_draw_eraser(struct Brush *brush, int x, int y); /* ----------- Add Primitive Utilities -------------- */ void ED_gpencil_create_monkey(struct bContext *C, float mat[4][4]); +void ED_gpencil_create_stroke(struct bContext *C, float mat[4][4]); /* ------------ Object Utilities ------------ */ struct Object *ED_add_gpencil_object(struct bContext *C, struct Scene *scene, const float loc[3]); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 1ae441ee2f4..f41c4071634 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1035,6 +1035,19 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) /* create relevant geometry */ switch (type) { + case GP_STROKE: + { + float radius = RNA_float_get(op->ptr, "radius"); + float mat[4][4]; + + ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + mul_v3_fl(mat[0], radius); + mul_v3_fl(mat[1], radius); + mul_v3_fl(mat[2], radius); + + ED_gpencil_create_stroke(C, mat); + break; + } case GP_MONKEY: { float radius = RNA_float_get(op->ptr, "radius"); @@ -1048,7 +1061,6 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op) ED_gpencil_create_monkey(C, mat); break; } - case GP_EMPTY: /* do nothing */ break; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 47fb2feb7f4..1f6f7cd9bf2 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -474,7 +474,8 @@ enum { /* gpencil add types */ enum { GP_EMPTY = 0, - GP_MONKEY = 1 + GP_STROKE = 1, + GP_MONKEY = 2 }; /* boundtype */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 36c249228de..2d1814532a2 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -94,6 +94,7 @@ const EnumPropertyItem rna_enum_object_empty_drawtype_items[] = { const EnumPropertyItem rna_enum_object_gpencil_type_items[] = { { GP_EMPTY, "EMPTY", ICON_OUTLINER_OB_GREASEPENCIL, "Blank", "Create an empty grease pencil object" }, + { GP_STROKE, "STROKE", ICON_OUTLINER_OB_CURVE, "Stroke", "Create a simple stroke with basic colors" }, { GP_MONKEY, "MONKEY", ICON_MONKEY, "Monkey", "Construct a Suzanne grease pencil object" }, { 0, NULL, 0, NULL, NULL } }; -- cgit v1.2.3 From 5470565527072e290afa2fdc29c4ee09c074d048 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 17:41:20 +0200 Subject: Cleanup: Fix comment --- source/blender/editors/gpencil/gpencil_add_stroke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index a945173fb90..0782a68d80f 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -125,7 +125,7 @@ static const float data0[175 * GP_PRIM_DATABUF_SIZE] = {-1.281f, 0.0f, -0.315f, 1.169f, 0.0f, 0.671f, 0.236f, 1.0f, 1.207f, 0.0f, 0.693f, 0.202f, 1.0f, 1.264f, 0.0f, 0.725f, 0.155f, 1.0f, }; /* ***************************************************************** */ -/* Monkey Color Data */ +/* Color Data */ static const ColorTemplate gp_stroke_material_black = { "Black", -- cgit v1.2.3 From 1ae77fe9c1faf230dc1fa653481d4d9a5aca0d24 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 3 Aug 2018 21:06:49 +0200 Subject: Grease Pencil: Set Lock Axis default to Y axis --- source/blender/blenloader/intern/versioning_280.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index ab787a52cfd..aed1fd8b416 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1826,7 +1826,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } - + /* default loc axis */ + if (!DNA_struct_elem_find(fd->filesdna, "GP_BrushEdit_Settings", "int", "lock_axis")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + /* lock axis */ + GP_BrushEdit_Settings *gset = &scene->toolsettings->gp_sculpt; + if (gset) { + gset->lock_axis = GP_LOCKAXIS_Y; + } + } + } } } -- cgit v1.2.3 From 27ffd37c15593d4581b8462de435a08766477a4b Mon Sep 17 00:00:00 2001 From: Charlie Jolly Date: Sat, 4 Aug 2018 09:49:15 +0200 Subject: Fix GP mirror modifier axis --- .../gpencil_modifiers/intern/MOD_gpencilmirror.c | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index afecdd34a5c..d4e8e8d3cff 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -138,17 +138,18 @@ static void generateStrokes( int tot_strokes; int i; - /* count strokes to avoid infinite loop after adding new strokes to tail of listbase */ - tot_strokes = BLI_listbase_count(&gpf->strokes); - - for (i = 0, gps = gpf->strokes.first; i < tot_strokes; i++, gps = gps->next) { - if (is_stroke_affected_by_modifier( - ob, mmd->layername, mmd->pass_index, 1, gpl, gps, - mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) - { - /* check each axis for mirroring */ - for (int xi = 0; xi < 3; ++xi) { - if (mmd->flag & (GP_MIRROR_AXIS_X << xi)) { + /* check each axis for mirroring */ + for (int xi = 0; xi < 3; ++xi) { + if (mmd->flag & (GP_MIRROR_AXIS_X << xi)) { + + /* count strokes to avoid infinite loop after adding new strokes to tail of listbase */ + tot_strokes = BLI_listbase_count(&gpf->strokes); + + for (i = 0, gps = gpf->strokes.first; i < tot_strokes; i++, gps = gps->next) { + if (is_stroke_affected_by_modifier( + ob, mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) + { /* clip before duplicate */ clip_stroke(mmd, gps); -- cgit v1.2.3 From a56ec3dfe3e1486bbf386687b8de5aa936c2498b Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 4 Aug 2018 13:40:38 +0200 Subject: Fix T56222: Bevel Modifier bug (uninitialized value). --- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 33380cee18e..adfcb8dc68f 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -4930,7 +4930,7 @@ static void find_even_superellipse_chords_general(int seg, float r, double *xval double sum; double temp; - bool precision_reached; + bool precision_reached = true; bool seg_odd = seg % 2; bool rbig; -- cgit v1.2.3 From ccf794dfc4c84e9831c48defa4dbb43b9e5bf63f Mon Sep 17 00:00:00 2001 From: Antonioya Date: Sat, 4 Aug 2018 15:59:57 +0200 Subject: GP: Fix stupid mistake in mirror modifier The object can be NULL. This was a line used in debug that it was not removed. Also removed an old function not used. Thanks to Charlie Jolly for catching this error. --- .../gpencil_modifiers/intern/MOD_gpencilmirror.c | 29 ---------------------- 1 file changed, 29 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index d4e8e8d3cff..a01ed4da695 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -73,29 +73,6 @@ static void copyData(const GpencilModifierData *md, GpencilModifierData *target) BKE_gpencil_modifier_copyData_generic(md, target); } -static void clip_stroke(MirrorGpencilModifierData *mmd, bGPDstroke *gps) -{ - int i; - bGPDspoint *pt; - float fpt[3]; - if ((mmd->flag & GP_MIRROR_CLIPPING) == 0) { - return; - } - - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - copy_v3_v3(fpt, &pt->x); - for (int xi = 0; xi < 3; ++xi) { - if (mmd->flag & (GP_MIRROR_AXIS_X << xi)) { - if (fpt[xi] >= 0.0f) { - fpt[xi] = 0.0f; - } - } - } - copy_v3_v3(&pt->x, fpt); - } - -} - static void update_position(Object *ob, MirrorGpencilModifierData *mmd, bGPDstroke *gps, int axis) { int i; @@ -150,9 +127,6 @@ static void generateStrokes( ob, mmd->layername, mmd->pass_index, 1, gpl, gps, mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) { - /* clip before duplicate */ - clip_stroke(mmd, gps); - gps_new = BKE_gpencil_stroke_duplicate(gps); update_position(ob, mmd, gps_new, xi); BLI_addtail(&gpf->strokes, gps_new); @@ -171,9 +145,6 @@ static void bakeModifier( bGPdata *gpd = ob->data; int oldframe = (int)DEG_get_ctime(depsgraph); - if (mmd->object == NULL) - return; - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { /* apply mirror effects on this frame */ -- cgit v1.2.3 From 86f6c15809c672847bd8c62a9f166bf096ccd85c Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 22:11:11 +0530 Subject: Removed redundant comment in BMesh --- release/scripts/addons | 2 +- source/blender/bmesh/bmesh_class.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index 371960484a3..27970761a18 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd +Subproject commit 27970761a18926abe1b0020aa350305e3109a537 diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 5ff1d2c970f..70884454ce5 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -238,7 +238,7 @@ typedef struct BMesh { struct BLI_mempool *looplistpool; #endif - struct MLoopNorSpaceArray *lnor_spacearr; /* Stores MLoopNorSpaceArray for this BMesh */ + struct MLoopNorSpaceArray *lnor_spacearr; char spacearr_dirty; /* should be copy of scene select mode */ -- cgit v1.2.3 From e8748e5ae7955b31c17c6cddb5e092202b39fcfd Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 22:11:57 +0530 Subject: Fixed comment formatting in editmesh.c --- source/blender/blenkernel/intern/editmesh.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 00e508e4d8f..7d66d25c58a 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -251,10 +251,10 @@ void BKE_editmesh_lnorspace_update(BMEditMesh *em) { BMesh *bm = em->bm; - /* We need to create clnors data if none exist yet, otherwise there is no way to edit them. */ - /* Similar code to MESH_OT_customdata_custom_splitnormals_add operator, we want to keep same shading - * in case we were using autosmooth so far... */ - /* Note: there is a problem here, which is that if someone starts a normal editing operation on previously + /* We need to create clnors data if none exist yet, otherwise there is no way to edit them. + * Similar code to MESH_OT_customdata_custom_splitnormals_add operator, we want to keep same shading + * in case we were using autosmooth so far... + * Note: there is a problem here, which is that if someone starts a normal editing operation on previously * autosmooth-ed mesh, and cancel that operation, generated clnors data remain, with related sharp edges * (and hence autosmooth is 'lost'). * Not sure how critical this is, and how to fix that issue? */ -- cgit v1.2.3 From 997b35f57a5454b5a43d47fddd84459bd19936f0 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 22:31:53 +0530 Subject: Added comments on hn_mode, BMOps on bevel --- source/blender/bmesh/intern/bmesh_mesh.c | 2 -- source/blender/bmesh/intern/bmesh_opdefines.c | 10 +++++----- source/blender/bmesh/intern/bmesh_operators.h | 8 ++++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 96707335081..4059cf27f23 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -320,7 +320,6 @@ void BM_mesh_free(BMesh *bm) */ /* We use that existing internal API flag, assuming no other tool using it would run concurrently to clnors editing. */ -/* XXX Should we rather add a new internal flag? */ #define BM_LNORSPACE_UPDATE _FLAG_MF typedef struct BMEdgesCalcVectorsData { @@ -1077,7 +1076,6 @@ void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]) bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL); } -/* will change later */ #define CLEAR_SPACEARRAY_THRESHOLD(x) ((x) / 2) void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 49d160f5d4a..d9093e774e6 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1736,17 +1736,17 @@ static BMOpDefine bmo_bevel_def = { {"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */ {"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */ {"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */ - {"mark_seam", BMO_OP_SLOT_BOOL}, - {"mark_sharp", BMO_OP_SLOT_BOOL}, - {"strength", BMO_OP_SLOT_FLT}, - {"hnmode", BMO_OP_SLOT_INT}, + {"mark_seam", BMO_OP_SLOT_BOOL}, /* extend edge data to allow seams to run across bevels */ + {"mark_sharp", BMO_OP_SLOT_BOOL}, /* extend edge data to allow sharp edges to run across bevels */ + {"strength", BMO_OP_SLOT_FLT}, /* strength of calculated normal in range (0, 1) for custom clnors */ + {"hnmode", BMO_OP_SLOT_INT}, /* harden normals mode used in bevel if enabled */ {{'\0'}}, }, /* slots_out */ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */ - {"normals.out", BMO_OP_SLOT_MAPPING}, + {"normals.out", BMO_OP_SLOT_MAPPING}, /* output normals per vertex for beveled edges */ {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 9f6ac50a3e5..6d518545967 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -128,10 +128,10 @@ enum { }; enum { - BEVEL_HN_NONE, - BEVEL_HN_FACE, - BEVEL_HN_ADJ, - BEVEL_HN_FIX_SHA, + BEVEL_HN_NONE, /* Disable harden normals */ + BEVEL_HN_FACE, /* harden normals according to face area */ + BEVEL_HN_ADJ, /* harden normals according to adjacent 'beveled' faces */ + BEVEL_HN_FIX_SHA, /* Special mode to fix normal shading continuity */ }; extern const BMOpDefine *bmo_opdefines[]; -- cgit v1.2.3 From 7db1db72bbdd178e0c8da4b39bfa166a1f0e2f84 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 22:32:28 +0530 Subject: Fixed hnmode not being passed with bevel tool --- source/blender/bmesh/operators/bmo_bevel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index cd27b486929..9d956c26390 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -66,7 +66,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp, 0/*hnmode*/, op); + BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp, hnmode, op); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); -- cgit v1.2.3 From cc30793a76fa058f53ed43f7515c6417128ffebe Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 22:38:54 +0530 Subject: Added comments to seam and sharp len, removed unused var --- source/blender/bmesh/tools/bmesh_bevel.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index bcf44ad4384..f9555b324c3 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -152,8 +152,8 @@ typedef struct BoundVert { Profile profile; /* edge profile between this and next BoundVert */ bool any_seam; /* are any of the edges attached here seams? */ bool visited; /* used during delta adjust pass */ - int seam_len; - int sharp_len; + int seam_len; /* length of seam starting from current boundvert to next boundvert with ccw ordering */ + int sharp_len; /* Same as seam_len but defines length of sharp edges */ // int _pad; } BoundVert; @@ -185,7 +185,6 @@ typedef struct BevVert { EdgeHalf *edges; /* array of size edgecount; CCW order from vertex normal side */ BMEdge **wire_edges; /* array of size wirecount of wire edges */ VMesh *vmesh; /* mesh structure for replacing vertex */ - bool fix_shading; } BevVert; /* Bevel parameters and state */ @@ -3209,8 +3208,6 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv) return tri_corner_adj_vmesh(bp, bv); } - bv->fix_shading = true; - /* First construct an initial control mesh, with nseg==2 */ ns = bv->vmesh->seg; vm0 = new_adj_vmesh(mem_arena, n, 2, bv->vmesh->boundstart); -- cgit v1.2.3 From e5e9578881c0825e6bc0696818e3a4cdc939c371 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 23:20:53 +0530 Subject: Added comments to functionality in main bevel code --- source/blender/bmesh/tools/bmesh_bevel.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index f9555b324c3..79310deef2a 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1537,15 +1537,19 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) { EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; + /* First first edge with seam or sharp edge data */ while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) { e = e->next; if (e == efirst) break; } + + /* If no such edge found, return */ if ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) return; - efirst = e; + efirst = e; /* Set efirst to this first encountered edge*/ + do { int flag_count = 0; EdgeHalf *ne = e->next; @@ -1559,13 +1563,12 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) { break; } - if (flag == BM_ELEM_SEAM) + if (flag == BM_ELEM_SEAM) /* Set seam_len / sharp_len of starting edge */ e->rightv->seam_len = flag_count; else if (flag == BM_ELEM_SMOOTH) e->rightv->sharp_len = flag_count; e = ne; } while (e != efirst); - } static void bevel_extend_edge_data(BevVert *bv) @@ -1575,10 +1578,14 @@ static void bevel_extend_edge_data(BevVert *bv) BoundVert *bcur = bv->vmesh->boundstart, *start = bcur; do { + /* If current boundvert has a seam length > 0 then it has a seam running along its edges */ if (bcur->seam_len) { if (!bv->vmesh->boundstart->seam_len && start == bv->vmesh->boundstart) - start = bcur; + start = bcur; /* set start to first boundvert with seam_len > 0 */ + /* Now for all the mesh_verts starting at current index and ending at idxlen + * We go through outermost ring and through all its segments and add seams + * for those edges */ int idxlen = bcur->index + bcur->seam_len; for (int i = bcur->index; i < idxlen; i++) { BMVert *v1 = mesh_vert(vm, i % vm->count, 0, 0)->v, *v2; @@ -1586,6 +1593,7 @@ static void bevel_extend_edge_data(BevVert *bv) for (int k = 1; k < vm->seg; k++) { v2 = mesh_vert(vm, i % vm->count, 0, k)->v; + /* Here v1 & v2 are current and next BMverts, we find common edge and set its edge data */ e = v1->e; while (e->v1 != v2 && e->v2 != v2) { if (e->v1 == v1) @@ -1597,7 +1605,7 @@ static void bevel_extend_edge_data(BevVert *bv) v1 = v2; } BMVert *v3 = mesh_vert(vm, (i + 1) % vm->count, 0, 0)->v; - e = v1->e; + e = v1->e; //Do same as above for first and last vert while (e->v1 != v3 && e->v2 != v3) { if (e->v1 == v1) e = e->v1_disk_link.next; @@ -1672,6 +1680,7 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B if (bp->hnmode == BEVEL_HN_FACE) { GHash *tempfaceHash = BLI_ghash_int_new(__func__); + /* Iterate through all faces of current BMVert and add their normal*face_area to n_final */ BM_ITER_ELEM(e, &eiter, bv->v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_TAG)) { @@ -1714,6 +1723,7 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B } do { + /* Set normals.out for vertices as computed earlier */ if (BMO_slot_map_contains(nslot, bcur->nv.v) != true) { float(*vert_normal) = MEM_callocN(sizeof(*vert_normal) * 3, __func__); -- cgit v1.2.3 From 435d731c6fcc5ea106264317bc5c669ebc27ad7f Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 23:36:00 +0530 Subject: Added some comments to bevel_harden_normals for bev tool --- source/blender/editors/mesh/editmesh_bevel.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 51bfaaf61e5..442eef927af 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -147,20 +147,23 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st BMLoop *l, *l_cur, *l_first; BMIter fiter; - BMOpSlot *nslot = BMO_slot_get(bmop->slots_out, "normals.out"); + BMOpSlot *nslot = BMO_slot_get(bmop->slots_out, "normals.out"); /* Per vertex normals depending on hn_mode */ + /* Similar functionality to bm_mesh_loops_calc_normals... Edges that can be smoothed are tagged */ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { if (BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur)))) { + /* Both adjacent loops are sharp, set clnor to face normal */ if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) { const int loop_index = BM_elem_index_get(l_cur); short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset); BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], f->no, clnors); } else { + /* Find next corresponding sharp edge in this smooth fan */ BMVert *v_pivot = l_cur->v; float *calc_n = BLI_ghash_lookup(nslot->data.ghash, v_pivot); @@ -173,6 +176,7 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }, cn_unwght[3] = { 0.0f, 0.0f, 0.0f }; + /* Fan through current vert and accumulate normals and loops */ while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); if (lfan_pivot_next) { -- cgit v1.2.3 From 710d2def6509d2c993cb96f42eb1a97ccc60bfcf Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sat, 4 Aug 2018 23:38:12 +0530 Subject: Initialized normal data in BevMod --- source/blender/modifiers/intern/MOD_bevel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 3db4089138b..152fee9eb77 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -70,7 +70,9 @@ static void initData(ModifierData *md) bmd->profile = 0.5f; bmd->bevel_angle = DEG2RADF(30.0f); bmd->defgrp_name[0] = '\0'; + bmd->hnmode = MOD_BEVEL_HN_NONE; bmd->hn_strength = 0.5f; + bmd->clnordata.faceHash = NULL; } static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) -- cgit v1.2.3 From c41ce58fdeba46dd96dccd7d2b98b1d3f5de726e Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Sun, 5 Aug 2018 08:39:20 +0530 Subject: Fix indentation, spacing and added comments --- source/blender/bmesh/intern/bmesh_mesh.c | 15 ++++--- source/blender/bmesh/operators/bmo_bevel.c | 3 +- source/blender/bmesh/tools/bmesh_bevel.c | 15 ++++--- source/blender/editors/mesh/editmesh_bevel.c | 16 ++++--- source/blender/editors/mesh/editmesh_tools.c | 6 ++- source/blender/modifiers/intern/MOD_bevel.c | 51 ++++++++++++++-------- .../blender/modifiers/intern/MOD_weighted_normal.c | 6 ++- 7 files changed, 72 insertions(+), 40 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 4059cf27f23..292453fac4b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -1114,9 +1114,10 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) /* Note that we only handle unselected neighbor vertices here, main loop will take care of * selected ones. */ - if (!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT) && + if ((!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT)) && !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) { + BMLoop *l_prev; BMIter liter_prev; BM_ITER_ELEM(l_prev, &liter_prev, l->prev->v, BM_LOOPS_OF_VERT) { @@ -1125,9 +1126,10 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_prev->v)); } - if (!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT) && + if ((!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT)) && !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) { + BMLoop *l_next; BMIter liter_next; BM_ITER_ELEM(l_next, &liter_next, l->next->v, BM_LOOPS_OF_VERT) { @@ -1172,7 +1174,8 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); int l_index = BM_elem_index_get(l); - BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], *clnor, oldnors[l_index]); + BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], *clnor, + oldnors[l_index]); } } } @@ -1191,7 +1194,8 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) if (preserve_clnor) { short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); int l_index = BM_elem_index_get(l); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], *clnor); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], + *clnor); } BM_ELEM_API_FLAG_DISABLE(l, BM_LNORSPACE_UPDATE); } @@ -1398,7 +1402,8 @@ BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm) BLI_assert(bm->spacearr_dirty == 0); BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN(sizeof(*lnors_ed_arr), __func__); - lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, __func__); + lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, + __func__); if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 9d956c26390..eb299dbba60 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -66,7 +66,8 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide, mark_seam, mark_sharp, hnmode, op); + BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, + loop_slide, mark_seam, mark_sharp, hnmode, op); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 79310deef2a..b45c9e295ab 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1554,16 +1554,19 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) int flag_count = 0; EdgeHalf *ne = e->next; - while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { + while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && + ne != efirst) + { if (ne->is_bev) flag_count++; ne = ne->next; } if (ne == e || (ne == efirst && (!neg && !BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag) || - (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) { + (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) + { break; } - if (flag == BM_ELEM_SEAM) /* Set seam_len / sharp_len of starting edge */ + if (flag == BM_ELEM_SEAM) /* Set seam_len / sharp_len of starting edge */ e->rightv->seam_len = flag_count; else if (flag == BM_ELEM_SMOOTH) e->rightv->sharp_len = flag_count; @@ -1687,7 +1690,7 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B BMFace *f_a, *f_b; BM_edge_face_pair(e, &f_a, &f_b); - if(f_a && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)))) { + if (f_a && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)))) { int f_area = BM_face_calc_area(f_a); float f_no[3]; copy_v3_v3(f_no, f_a->no); @@ -1695,7 +1698,7 @@ static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, B add_v3_v3(n_final, f_no); BLI_ghash_insert(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_a)), NULL); } - if(f_b && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)))) { + if (f_b && !BLI_ghash_haskey(tempfaceHash, SET_UINT_IN_POINTER(BM_elem_index_get(f_b)))) { int f_area = BM_face_calc_area(f_b); float f_no[3]; copy_v3_v3(f_no, f_b->no); @@ -3794,7 +3797,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv) NULL, bme1, bme2, bme3, mat_nr); } } - if(do_fix_shading_bv) + if (do_fix_shading_bv) BLI_ghash_insert(bp->faceHash, r_f, NULL); } } diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 442eef927af..931e395736f 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -153,7 +153,8 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { - if (BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT) && (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || + if ((BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT)) && + ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur)))) { /* Both adjacent loops are sharp, set clnor to face normal */ @@ -191,7 +192,7 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); - if(BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT)) + if (BM_elem_flag_test(lfan_pivot->f, BM_ELEM_SELECT)) add_v3_v3(cn_unwght, cur); if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) { @@ -215,7 +216,8 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors); } else - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], cn_unwght, clnors); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], cn_unwght, + clnors); } BLI_ghash_remove(nslot->data.ghash, v_pivot, NULL, MEM_freeN); } @@ -347,7 +349,7 @@ static bool edbm_bevel_calc(wmOperator *op) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); } - if(hnmode != BEVEL_HN_NONE) + if (hnmode != BEVEL_HN_NONE) bevel_harden_normals(em, &bmop, hn_strength, hnmode); /* no need to de-select existing geometry */ @@ -794,6 +796,8 @@ void MESH_OT_bevel(wmOperatorType *ot) RNA_def_boolean(ot->srna, "mark_sharp", false, "Mark Sharp", "Mark beveled edges as sharp"); RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100); - RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength", "Strength of calculated normal", 0.0f, 1.0f); - RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_NONE, "Normal Mode", "Weighting mode for Harden Normals"); + RNA_def_float(ot->srna, "strength", 0.5f, 0.0f, 1.0f, "Normal Strength", + "Strength of calculated normal", 0.0f, 1.0f); + RNA_def_enum(ot->srna, "hnmode", harden_normals_items, BEVEL_HN_NONE, "Normal Mode", + "Weighting mode for Harden Normals"); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d327e270a35..d94d3051b50 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7063,7 +7063,8 @@ static void point_normals_update_header(bContext *C, wmOperator *op) WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_RESET), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")), - WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), + WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align"))); #undef WM_MODALKEY @@ -8063,7 +8064,8 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) if (BLI_BITMAP_TEST(loop_set, BM_elem_index_get(l))) { const int loop_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], clnors); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], + clnors); } } } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 152fee9eb77..f1dc73436ee 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -110,7 +110,9 @@ static void bevel_set_weighted_normal_face_strength(BMesh *bm, Scene *scene) } } -static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const float hn_strength, const int hnmode, MDeformVert *dvert, int vgroup) +static void bevel_mod_harden_normals( + BevelModifierData *bmd, BMesh *bm, const float hn_strength, + const int hnmode, MDeformVert *dvert, int vgroup) { if (bmd->res > 20 || bmd->value == 0) return; @@ -128,13 +130,16 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl BMIter fiter; GHash *faceHash = bmd->clnordata.faceHash; + /* Iterate throught all loops of a face */ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { - if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) || (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && - BM_loop_check_cyclic_smooth_fan(l_cur)))) { + if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) || + (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur))) + { + /* previous and next edge is sharp, accumulate face normals into loop */ if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) { const int loop_index = BM_elem_index_get(l_cur); short *clnors = BM_ELEM_CD_GET_VOID_P(l_cur, cd_clnors_offset); @@ -151,8 +156,8 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl e_next = lfan_pivot->e; BLI_SMALLSTACK_DECLARE(loops, BMLoop *); float cn_wght[3] = { 0.0f, 0.0f, 0.0f }; - int recon_face_count = 0; /* Reconstructed face */ - BMFace *recon_face = NULL; + int recon_face_count = 0; /* Counts number of reconstructed faces current vert is connected to */ + BMFace *recon_face = NULL; /* Reconstructed face */ while (true) { lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next); @@ -169,12 +174,12 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl int weight = BM_elem_float_data_get(&bm->edata, lfan_pivot->f, CD_BWEIGHT); if (weight) { if (hnmode == MOD_BEVEL_HN_FACE) { - float cur[3]; + float cur[3]; //Add area weighted face normals mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); add_v3_v3(cn_wght, cur); } else - add_v3_v3(cn_wght, lfan_pivot->f->no); + add_v3_v3(cn_wght, lfan_pivot->f->no); //Else simply add face normals } else add_v3_v3(cn_wght, lfan_pivot->f->no); @@ -182,7 +187,9 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl } else if (bmd->lim_flags & MOD_BEVEL_VGROUP) { const bool has_vgroup = dvert != NULL; - const bool vert_of_group = has_vgroup && defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL; + const bool vert_of_group = has_vgroup && + (defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL); + if (vert_of_group && hnmode == MOD_BEVEL_HN_FACE) { float cur[3]; mul_v3_v3fl(cur, lfan_pivot->f->no, BM_face_calc_area(lfan_pivot->f)); @@ -214,18 +221,22 @@ static void bevel_mod_harden_normals(BevelModifierData *bmd, BMesh *bm, const fl const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); + /* If vertex is edge vert with 1 reconnected face */ if (recon_face_count == 1 || do_normal_to_recon) { - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, clnors); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, + clnors); } else if (vertex_only == false || recon_face_count == 0) { copy_v3_v3(n_final, l->f->no); mul_v3_fl(n_final, 1.0f - hn_strength); add_v3_v3(n_final, cn_wght); normalize_v3(n_final); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, + clnors); } - else if(BLI_ghash_haskey(faceHash, l->f)) - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); + else if (BLI_ghash_haskey(faceHash, l->f)) + BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, + clnors); } } } @@ -261,6 +272,8 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b if (f_b) has_f_b = BLI_ghash_haskey(faceHash, f_b); if (has_f_a ^ has_f_b) { + /* If one of both faces is present in faceHash then we are at a border + * between new vmesh created and reconstructed face */ for (int i = 0; i < 2; i++) { BMVert *v = (i == 0) ? e->v1 : e->v2; @@ -291,12 +304,14 @@ static void bevel_fix_normal_shading_continuity(BevelModifierData *bmd, BMesh *b } } } - else if(has_f_a == true && has_f_b == true) { + else if (has_f_a == true && has_f_b == true) { + /* Else if both faces are present we assign clnor corresponding + * to vert normal and face normal */ for (int i = 0; i < 2; i++) { BMVert *v = (i == 0) ? e->v1 : e->v2; BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) { - if(l->f == f_a || l->f == f_b) { + if (l->f == f_a || l->f == f_b) { const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); float n_final[3], cn_wght[3]; @@ -417,9 +432,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (bmd->hnmode != BEVEL_HN_FIX_SHA && bmd->hnmode != MOD_BEVEL_HN_NONE) { bevel_mod_harden_normals(bmd, bm, bmd->hn_strength, bmd->hnmode, dvert, vgroup); } - if(bmd->hnmode == BEVEL_HN_FIX_SHA) + if (bmd->hnmode == BEVEL_HN_FIX_SHA) bevel_fix_normal_shading_continuity(bmd, bm); - if(set_wn_strength) + if (set_wn_strength) bevel_set_weighted_normal_face_strength(bm, scene); result = BKE_bmesh_to_mesh_nomain(bm, &(struct BMeshToMeshParams){0}); @@ -429,7 +444,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BM_mesh_free(bm); - if(bmd->clnordata.faceHash) + if (bmd->clnordata.faceHash) BLI_ghash_free(bmd->clnordata.faceHash, NULL, NULL); result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; @@ -450,7 +465,7 @@ ModifierTypeInfo modifierType_Bevel = { /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | - eModifierTypeFlag_AcceptsCVs, + eModifierTypeFlag_AcceptsCVs, /* copyData */ modifier_copyData_generic, diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index a2ace1aadc4..3e788db9c00 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -217,7 +217,8 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, Weight num_items = lnors_spacearr.num_spaces; items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__); - /* In this first loop, we assign each WeightedNormalDataAggregateItem to its smooth fan of loops (aka lnor space). */ + /* In this first loop, we assign each WeightedNormalDataAggregateItem + * to its smooth fan of loops (aka lnor space). */ MPoly *mp; int mp_index; int item_index; @@ -572,7 +573,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes .mpoly = mpoly, .polynors = polynors, - .poly_strength = CustomData_get_layer_named(&result->pdata, CD_PROP_INT, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID), + .poly_strength = CustomData_get_layer_named(&result->pdata, CD_PROP_INT, + MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID), .dvert = dvert, .defgrp_index = defgrp_index, -- cgit v1.2.3 From 9a8541d0297beac9763c0afa53d4fc1d6853a1a9 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 5 Aug 2018 09:19:15 +0200 Subject: Minor fix unused var compiler warning. --- source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index a01ed4da695..6c54d4c49be 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -140,7 +140,6 @@ static void bakeModifier( Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob) { - MirrorGpencilModifierData *mmd = (MirrorGpencilModifierData *)md; Scene *scene = DEG_get_evaluated_scene(depsgraph); bGPdata *gpd = ob->data; int oldframe = (int)DEG_get_ctime(depsgraph); -- cgit v1.2.3 From 6d0835eca7e6bdec9f19bbb5fb194146225164c7 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Sun, 5 Aug 2018 11:06:20 +0200 Subject: GP: Fix NULL pointer when preview is not ready The preview cannot be ready when create a material with python --- source/blender/makesrna/intern/rna_material.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 56f5a12516b..b6250a81b3b 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -114,10 +114,11 @@ static void rna_MaterialGpencil_update(Main *bmain, Scene *scene, PointerRNA *pt rna_Material_update(bmain, scene, ptr); /* update previews (icon and thumbnail) */ - preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; - preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; - WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma); - + if (preview != NULL) { + preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; + preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; + WM_main_add_notifier(NC_MATERIAL | ND_SHADING_PREVIEW, ma); + } WM_main_add_notifier(NC_GPENCIL | ND_DATA, ma); } -- cgit v1.2.3 From 5261cd233c0d4de30b792263d0ce6711efd5101a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 5 Aug 2018 11:58:31 +0200 Subject: Fix Cycles crash rendering mix of instanced and non-instanced volumes. --- intern/cycles/kernel/bvh/bvh_volume_all.h | 24 ++++++++++++++---------- intern/cycles/kernel/bvh/qbvh_volume_all.h | 24 ++++++++++++++---------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h index f2379efc656..2ee29ac9c27 100644 --- a/intern/cycles/kernel/bvh/bvh_volume_all.h +++ b/intern/cycles/kernel/bvh/bvh_volume_all.h @@ -212,14 +212,16 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect_array->t = isect_t; if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) + if(object != OBJECT_NONE) { # if BVH_FEATURE(BVH_MOTION) - float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - float t_fac = 1.0f / len(transform_direction(&itfm, dir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); # endif - for(int i = 0; i < num_hits_in_instance; i++) { - (isect_array-i-1)->t *= t_fac; + for(int i = 0; i < num_hits_in_instance; i++) { + (isect_array-i-1)->t *= t_fac; + } } #endif /* BVH_FEATURE(BVH_INSTANCING) */ return num_hits; @@ -257,14 +259,16 @@ uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect_array->t = isect_t; if(num_hits == max_hits) { # if BVH_FEATURE(BVH_INSTANCING) + if(object != OBJECT_NONE) { # if BVH_FEATURE(BVH_MOTION) - float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - float t_fac = 1.0f / len(transform_direction(&itfm, dir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); # endif - for(int i = 0; i < num_hits_in_instance; i++) { - (isect_array-i-1)->t *= t_fac; + for(int i = 0; i < num_hits_in_instance; i++) { + (isect_array-i-1)->t *= t_fac; + } } # endif /* BVH_FEATURE(BVH_INSTANCING) */ return num_hits; diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h index ac5f58a9a51..1e454e4d36b 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume_all.h +++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h @@ -279,14 +279,16 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect_array->t = isect_t; if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) + if(object != OBJECT_NONE) { # if BVH_FEATURE(BVH_MOTION) - float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - float t_fac = 1.0f / len(transform_direction(&itfm, dir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); # endif - for(int i = 0; i < num_hits_in_instance; i++) { - (isect_array-i-1)->t *= t_fac; + for(int i = 0; i < num_hits_in_instance; i++) { + (isect_array-i-1)->t *= t_fac; + } } #endif /* BVH_FEATURE(BVH_INSTANCING) */ return num_hits; @@ -317,14 +319,16 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect_array->t = isect_t; if(num_hits == max_hits) { # if BVH_FEATURE(BVH_INSTANCING) + if(object != OBJECT_NONE) { # if BVH_FEATURE(BVH_MOTION) - float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); - float t_fac = 1.0f / len(transform_direction(&itfm, dir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); # endif - for(int i = 0; i < num_hits_in_instance; i++) { - (isect_array-i-1)->t *= t_fac; + for(int i = 0; i < num_hits_in_instance; i++) { + (isect_array-i-1)->t *= t_fac; + } } # endif /* BVH_FEATURE(BVH_INSTANCING) */ return num_hits; -- cgit v1.2.3 From 75e34b9002f5137695b8b9b685114d4ef866bb5d Mon Sep 17 00:00:00 2001 From: Antonioya Date: Sun, 5 Aug 2018 16:19:24 +0200 Subject: GP: Add python api to create brush settings for grease pencil --- source/blender/blenkernel/BKE_brush.h | 1 + source/blender/blenkernel/intern/brush.c | 34 +++++++++++++++++---------- source/blender/makesrna/intern/rna_main_api.c | 13 ++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index 489746cbfd9..42399835b53 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -49,6 +49,7 @@ void BKE_brush_system_exit(void); void BKE_brush_init(struct Brush *brush); struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode); struct Brush *BKE_brush_add_gpencil(struct Main *bmain, struct ToolSettings *ts, const char *name); +void BKE_brush_init_gpencil_settings(struct Brush *brush); struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode); void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag); struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index c769978f9bb..e1cc3984601 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -167,20 +167,12 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode) return brush; } -/* add a new gp-brush */ -Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name) +/* add grese pencil settings */ +void BKE_brush_init_gpencil_settings(Brush *brush) { - Brush *brush; - Paint *paint = BKE_brush_get_gpencil_paint(ts); - brush = BKE_brush_add(bmain, name, OB_MODE_GPENCIL_PAINT); - - BKE_paint_brush_set(paint, brush); - id_us_min(&brush->id); - - /* grease pencil basic settings */ - brush->size = 3; - - brush->gpencil_settings = MEM_callocN(sizeof(BrushGpencilSettings), "BrushGpencilSettings"); + if (brush->gpencil_settings == NULL) { + brush->gpencil_settings = MEM_callocN(sizeof(BrushGpencilSettings), "BrushGpencilSettings"); + } brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->flag = 0; @@ -195,6 +187,22 @@ Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name) brush->gpencil_settings->curve_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); brush->gpencil_settings->curve_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); brush->gpencil_settings->curve_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); +} + +/* add a new gp-brush */ +Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name) +{ + Brush *brush; + Paint *paint = BKE_brush_get_gpencil_paint(ts); + brush = BKE_brush_add(bmain, name, OB_MODE_GPENCIL_PAINT); + + BKE_paint_brush_set(paint, brush); + id_us_min(&brush->id); + + brush->size = 3; + + /* grease pencil basic settings */ + BKE_brush_init_gpencil_settings(brush); /* return brush */ return brush; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index f6e5a6107c9..9fd9a04ae25 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -443,6 +443,14 @@ static Brush *rna_Main_brushes_new(Main *bmain, const char *name, int mode) return brush; } +static void rna_Main_brush_gpencil_data(Main *UNUSED(bmain), PointerRNA *id_ptr) +{ + ID *id = id_ptr->data; + Brush *brush = (Brush *)id; + BKE_brush_init_gpencil_settings(brush); +} + + static World *rna_Main_worlds_new(Main *bmain, const char *name) { char safe_name[MAX_ID_NAME - 2]; @@ -1272,6 +1280,11 @@ void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "tag", "rna_Main_brushes_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "create_gpencil_data", "rna_Main_brush_gpencil_data"); + RNA_def_function_ui_description(func, "Add grease pencil brush settings"); + parm = RNA_def_pointer(func, "brush", "Brush", "", "Brush"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); } void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop) -- cgit v1.2.3 From 53c56b2b5fdc4fbb53a36e0856edf2c742f0848f Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 5 Aug 2018 18:50:01 +0200 Subject: Fix T54915: Usercount of active action increases when editing things with COW enabled. Just pass along the 'no user refcount' flag to animdata copy function. --- source/blender/blenkernel/intern/library.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 8922cd75618..75444ca3b2f 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1407,13 +1407,13 @@ void *BKE_id_new_nomain(const short type, const char *name) /* by spec, animdata is first item after ID */ /* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */ -static void id_copy_animdata(Main *bmain, ID *id, const bool do_action) +static void id_copy_animdata(Main *bmain, ID *id, const bool do_action, const bool do_id_user) { AnimData *adt = BKE_animdata_from_id(id); if (adt) { IdAdtTemplate *iat = (IdAdtTemplate *)id; - iat->adt = BKE_animdata_copy(bmain, iat->adt, do_action, true); /* could be set to false, need to investigate */ + iat->adt = BKE_animdata_copy(bmain, iat->adt, do_action, do_id_user); } } @@ -1470,7 +1470,9 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int fla /* the duplicate should get a copy of the animdata */ if ((flag & LIB_ID_COPY_NO_ANIMDATA) == 0) { BLI_assert((flag & LIB_ID_COPY_ACTIONS) == 0 || (flag & LIB_ID_CREATE_NO_MAIN) == 0); - id_copy_animdata(bmain, new_id, (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0); + id_copy_animdata(bmain, new_id, + (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0, + (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0); } else if (id_can_have_animdata(new_id)) { IdAdtTemplate *iat = (IdAdtTemplate *)new_id; -- cgit v1.2.3 From 14d9aeacce0ff684b32508122942bec4dbf1fe28 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Aug 2018 12:49:02 +1000 Subject: Cleanup: line length --- .../blender/editors/gpencil/gpencil_add_stroke.c | 135 ++++++++++++++------- 1 file changed, 90 insertions(+), 45 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index 0782a68d80f..5b7c81a3808 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -79,50 +79,96 @@ static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct) /* ***************************************************************** */ /* Stroke Geometry */ -static const float data0[175 * GP_PRIM_DATABUF_SIZE] = {-1.281f, 0.0f, -0.315f, 0.038f, 1.0f, -1.269f, 0.0f, -0.302f, 0.069f, 1.0f, -1.261f, 0.0f, -0.293f, 0.089f, 1.0f, -1.251f, 0.0f, -0.282f, 0.112f, 1.0f, --1.241f, 0.0f, -0.271f, 0.134f, 1.0f, -1.23f, 0.0f, -0.259f, 0.155f, 1.0f, -1.219f, 0.0f, -0.247f, 0.175f, 1.0f, -1.208f, 0.0f, -0.234f, 0.194f, 1.0f, --1.196f, 0.0f, -0.221f, 0.211f, 1.0f, -1.184f, 0.0f, -0.208f, 0.227f, 1.0f, -1.172f, 0.0f, -0.194f, 0.242f, 1.0f, -1.159f, 0.0f, -0.18f, 0.256f, 1.0f, --1.147f, 0.0f, -0.165f, 0.268f, 1.0f, -1.134f, 0.0f, -0.151f, 0.28f, 1.0f, -1.121f, 0.0f, -0.136f, 0.29f, 1.0f, -1.108f, 0.0f, -0.121f, 0.299f, 1.0f, --1.094f, 0.0f, -0.106f, 0.307f, 1.0f, -1.08f, 0.0f, -0.091f, 0.315f, 1.0f, -1.066f, 0.0f, -0.076f, 0.322f, 1.0f, -1.052f, 0.0f, -0.061f, 0.329f, 1.0f, --1.037f, 0.0f, -0.047f, 0.335f, 1.0f, -1.022f, 0.0f, -0.032f, 0.341f, 1.0f, -1.007f, 0.0f, -0.017f, 0.346f, 1.0f, -0.991f, 0.0f, -0.003f, 0.351f, 1.0f, --0.975f, 0.0f, 0.012f, 0.355f, 1.0f, -0.959f, 0.0f, 0.027f, 0.36f, 1.0f, -0.942f, 0.0f, 0.041f, 0.364f, 1.0f, -0.926f, 0.0f, 0.056f, 0.368f, 1.0f, --0.909f, 0.0f, 0.071f, 0.371f, 1.0f, -0.893f, 0.0f, 0.086f, 0.373f, 1.0f, -0.876f, 0.0f, 0.1f, 0.376f, 1.0f, -0.859f, 0.0f, 0.115f, 0.377f, 1.0f, --0.842f, 0.0f, 0.129f, 0.378f, 1.0f, -0.824f, 0.0f, 0.144f, 0.379f, 1.0f, -0.807f, 0.0f, 0.158f, 0.379f, 1.0f, -0.79f, 0.0f, 0.172f, 0.379f, 1.0f, --0.773f, 0.0f, 0.186f, 0.38f, 1.0f, -0.755f, 0.0f, 0.199f, 0.38f, 1.0f, -0.738f, 0.0f, 0.212f, 0.381f, 1.0f, -0.721f, 0.0f, 0.224f, 0.382f, 1.0f, --0.703f, 0.0f, 0.236f, 0.384f, 1.0f, -0.686f, 0.0f, 0.248f, 0.386f, 1.0f, -0.67f, 0.0f, 0.26f, 0.388f, 1.0f, -0.653f, 0.0f, 0.27f, 0.39f, 1.0f, --0.637f, 0.0f, 0.28f, 0.393f, 1.0f, -0.621f, 0.0f, 0.29f, 0.396f, 1.0f, -0.605f, 0.0f, 0.298f, 0.399f, 1.0f, -0.589f, 0.0f, 0.306f, 0.403f, 1.0f, --0.574f, 0.0f, 0.313f, 0.407f, 1.0f, -0.559f, 0.0f, 0.319f, 0.411f, 1.0f, -0.544f, 0.0f, 0.325f, 0.415f, 1.0f, -0.53f, 0.0f, 0.331f, 0.42f, 1.0f, --0.516f, 0.0f, 0.336f, 0.425f, 1.0f, -0.503f, 0.0f, 0.34f, 0.431f, 1.0f, -0.489f, 0.0f, 0.344f, 0.437f, 1.0f, -0.477f, 0.0f, 0.347f, 0.443f, 1.0f, --0.464f, 0.0f, 0.35f, 0.45f, 1.0f, -0.452f, 0.0f, 0.352f, 0.457f, 1.0f, -0.44f, 0.0f, 0.354f, 0.464f, 1.0f, -0.429f, 0.0f, 0.355f, 0.471f, 1.0f, --0.418f, 0.0f, 0.355f, 0.479f, 1.0f, -0.407f, 0.0f, 0.355f, 0.487f, 1.0f, -0.397f, 0.0f, 0.354f, 0.495f, 1.0f, -0.387f, 0.0f, 0.353f, 0.503f, 1.0f, --0.378f, 0.0f, 0.351f, 0.512f, 1.0f, -0.368f, 0.0f, 0.348f, 0.52f, 1.0f, -0.36f, 0.0f, 0.344f, 0.528f, 1.0f, -0.351f, 0.0f, 0.34f, 0.537f, 1.0f, --0.344f, 0.0f, 0.336f, 0.545f, 1.0f, -0.336f, 0.0f, 0.33f, 0.553f, 1.0f, -0.329f, 0.0f, 0.324f, 0.562f, 1.0f, -0.322f, 0.0f, 0.318f, 0.57f, 1.0f, --0.316f, 0.0f, 0.31f, 0.579f, 1.0f, -0.311f, 0.0f, 0.303f, 0.588f, 1.0f, -0.306f, 0.0f, 0.294f, 0.597f, 1.0f, -0.301f, 0.0f, 0.285f, 0.606f, 1.0f, --0.297f, 0.0f, 0.275f, 0.615f, 1.0f, -0.293f, 0.0f, 0.264f, 0.625f, 1.0f, -0.29f, 0.0f, 0.253f, 0.635f, 1.0f, -0.288f, 0.0f, 0.241f, 0.644f, 1.0f, --0.286f, 0.0f, 0.229f, 0.654f, 1.0f, -0.285f, 0.0f, 0.216f, 0.664f, 1.0f, -0.284f, 0.0f, 0.202f, 0.675f, 1.0f, -0.283f, 0.0f, 0.188f, 0.685f, 1.0f, --0.283f, 0.0f, 0.173f, 0.696f, 1.0f, -0.284f, 0.0f, 0.158f, 0.707f, 1.0f, -0.285f, 0.0f, 0.142f, 0.718f, 1.0f, -0.286f, 0.0f, 0.125f, 0.729f, 1.0f, --0.288f, 0.0f, 0.108f, 0.74f, 1.0f, -0.29f, 0.0f, 0.091f, 0.751f, 1.0f, -0.293f, 0.0f, 0.073f, 0.761f, 1.0f, -0.295f, 0.0f, 0.054f, 0.772f, 1.0f, --0.298f, 0.0f, 0.035f, 0.782f, 1.0f, -0.302f, 0.0f, 0.016f, 0.793f, 1.0f, -0.305f, 0.0f, -0.004f, 0.804f, 1.0f, -0.309f, 0.0f, -0.024f, 0.815f, 1.0f, --0.313f, 0.0f, -0.044f, 0.828f, 1.0f, -0.317f, 0.0f, -0.065f, 0.843f, 1.0f, -0.321f, 0.0f, -0.085f, 0.86f, 1.0f, -0.326f, 0.0f, -0.106f, 0.879f, 1.0f, --0.33f, 0.0f, -0.127f, 0.897f, 1.0f, -0.335f, 0.0f, -0.148f, 0.915f, 1.0f, -0.339f, 0.0f, -0.168f, 0.932f, 1.0f, -0.344f, 0.0f, -0.189f, 0.947f, 1.0f, --0.348f, 0.0f, -0.21f, 0.962f, 1.0f, -0.353f, 0.0f, -0.23f, 0.974f, 1.0f, -0.357f, 0.0f, -0.25f, 0.985f, 1.0f, -0.361f, 0.0f, -0.27f, 0.995f, 1.0f, --0.365f, 0.0f, -0.29f, 1.004f, 1.0f, -0.369f, 0.0f, -0.309f, 1.011f, 1.0f, -0.372f, 0.0f, -0.328f, 1.018f, 1.0f, -0.375f, 0.0f, -0.347f, 1.024f, 1.0f, --0.377f, 0.0f, -0.365f, 1.029f, 1.0f, -0.379f, 0.0f, -0.383f, 1.033f, 1.0f, -0.38f, 0.0f, -0.4f, 1.036f, 1.0f, -0.38f, 0.0f, -0.417f, 1.037f, 1.0f, --0.38f, 0.0f, -0.434f, 1.037f, 1.0f, -0.379f, 0.0f, -0.449f, 1.035f, 1.0f, -0.377f, 0.0f, -0.464f, 1.032f, 1.0f, -0.374f, 0.0f, -0.478f, 1.029f, 1.0f, --0.371f, 0.0f, -0.491f, 1.026f, 1.0f, -0.366f, 0.0f, -0.503f, 1.023f, 1.0f, -0.361f, 0.0f, -0.513f, 1.021f, 1.0f, -0.354f, 0.0f, -0.523f, 1.019f, 1.0f, --0.347f, 0.0f, -0.531f, 1.017f, 1.0f, -0.339f, 0.0f, -0.538f, 1.016f, 1.0f, -0.33f, 0.0f, -0.543f, 1.016f, 1.0f, -0.32f, 0.0f, -0.547f, 1.016f, 1.0f, --0.31f, 0.0f, -0.549f, 1.016f, 1.0f, -0.298f, 0.0f, -0.55f, 1.017f, 1.0f, -0.286f, 0.0f, -0.55f, 1.017f, 1.0f, -0.274f, 0.0f, -0.548f, 1.018f, 1.0f, --0.261f, 0.0f, -0.544f, 1.017f, 1.0f, -0.247f, 0.0f, -0.539f, 1.017f, 1.0f, -0.232f, 0.0f, -0.533f, 1.016f, 1.0f, -0.218f, 0.0f, -0.525f, 1.015f, 1.0f, --0.202f, 0.0f, -0.515f, 1.013f, 1.0f, -0.186f, 0.0f, -0.503f, 1.009f, 1.0f, -0.169f, 0.0f, -0.49f, 1.005f, 1.0f, -0.151f, 0.0f, -0.475f, 0.998f, 1.0f, --0.132f, 0.0f, -0.458f, 0.99f, 1.0f, -0.112f, 0.0f, -0.44f, 0.98f, 1.0f, -0.091f, 0.0f, -0.42f, 0.968f, 1.0f, -0.069f, 0.0f, -0.398f, 0.955f, 1.0f, --0.045f, 0.0f, -0.375f, 0.939f, 1.0f, -0.021f, 0.0f, -0.35f, 0.923f, 1.0f, 0.005f, 0.0f, -0.324f, 0.908f, 1.0f, 0.031f, 0.0f, -0.297f, 0.895f, 1.0f, -0.06f, 0.0f, -0.268f, 0.882f, 1.0f, 0.089f, 0.0f, -0.238f, 0.87f, 1.0f, 0.12f, 0.0f, -0.207f, 0.858f, 1.0f, 0.153f, 0.0f, -0.175f, 0.844f, 1.0f, -0.187f, 0.0f, -0.14f, 0.828f, 1.0f, 0.224f, 0.0f, -0.104f, 0.81f, 1.0f, 0.262f, 0.0f, -0.067f, 0.79f, 1.0f, 0.302f, 0.0f, -0.027f, 0.769f, 1.0f, -0.344f, 0.0f, 0.014f, 0.747f, 1.0f, 0.388f, 0.0f, 0.056f, 0.724f, 1.0f, 0.434f, 0.0f, 0.1f, 0.7f, 1.0f, 0.483f, 0.0f, 0.145f, 0.676f, 1.0f, -0.533f, 0.0f, 0.191f, 0.651f, 1.0f, 0.585f, 0.0f, 0.238f, 0.625f, 1.0f, 0.637f, 0.0f, 0.284f, 0.599f, 1.0f, 0.69f, 0.0f, 0.33f, 0.573f, 1.0f, -0.746f, 0.0f, 0.376f, 0.546f, 1.0f, 0.802f, 0.0f, 0.421f, 0.516f, 1.0f, 0.859f, 0.0f, 0.464f, 0.483f, 1.0f, 0.915f, 0.0f, 0.506f, 0.446f, 1.0f, -0.97f, 0.0f, 0.545f, 0.407f, 1.0f, 1.023f, 0.0f, 0.581f, 0.365f, 1.0f, 1.075f, 0.0f, 0.614f, 0.322f, 1.0f, 1.122f, 0.0f, 0.643f, 0.28f, 1.0f, -1.169f, 0.0f, 0.671f, 0.236f, 1.0f, 1.207f, 0.0f, 0.693f, 0.202f, 1.0f, 1.264f, 0.0f, 0.725f, 0.155f, 1.0f, }; +static const float data0[175 * GP_PRIM_DATABUF_SIZE] = { + -1.281f, 0.0f, -0.315f, 0.038f, 1.0f, -1.269f, 0.0f, -0.302f, 0.069f, 1.0f, + -1.261f, 0.0f, -0.293f, 0.089f, 1.0f, -1.251f, 0.0f, -0.282f, 0.112f, 1.0f, + -1.241f, 0.0f, -0.271f, 0.134f, 1.0f, -1.23f, 0.0f, -0.259f, 0.155f, 1.0f, + -1.219f, 0.0f, -0.247f, 0.175f, 1.0f, -1.208f, 0.0f, -0.234f, 0.194f, 1.0f, + -1.196f, 0.0f, -0.221f, 0.211f, 1.0f, -1.184f, 0.0f, -0.208f, 0.227f, 1.0f, + -1.172f, 0.0f, -0.194f, 0.242f, 1.0f, -1.159f, 0.0f, -0.18f, 0.256f, 1.0f, + -1.147f, 0.0f, -0.165f, 0.268f, 1.0f, -1.134f, 0.0f, -0.151f, 0.28f, 1.0f, + -1.121f, 0.0f, -0.136f, 0.29f, 1.0f, -1.108f, 0.0f, -0.121f, 0.299f, 1.0f, + -1.094f, 0.0f, -0.106f, 0.307f, 1.0f, -1.08f, 0.0f, -0.091f, 0.315f, 1.0f, + -1.066f, 0.0f, -0.076f, 0.322f, 1.0f, -1.052f, 0.0f, -0.061f, 0.329f, 1.0f, + -1.037f, 0.0f, -0.047f, 0.335f, 1.0f, -1.022f, 0.0f, -0.032f, 0.341f, 1.0f, + -1.007f, 0.0f, -0.017f, 0.346f, 1.0f, -0.991f, 0.0f, -0.003f, 0.351f, 1.0f, + -0.975f, 0.0f, 0.012f, 0.355f, 1.0f, -0.959f, 0.0f, 0.027f, 0.36f, 1.0f, + -0.942f, 0.0f, 0.041f, 0.364f, 1.0f, -0.926f, 0.0f, 0.056f, 0.368f, 1.0f, + -0.909f, 0.0f, 0.071f, 0.371f, 1.0f, -0.893f, 0.0f, 0.086f, 0.373f, 1.0f, + -0.876f, 0.0f, 0.1f, 0.376f, 1.0f, -0.859f, 0.0f, 0.115f, 0.377f, 1.0f, + -0.842f, 0.0f, 0.129f, 0.378f, 1.0f, -0.824f, 0.0f, 0.144f, 0.379f, 1.0f, + -0.807f, 0.0f, 0.158f, 0.379f, 1.0f, -0.79f, 0.0f, 0.172f, 0.379f, 1.0f, + -0.773f, 0.0f, 0.186f, 0.38f, 1.0f, -0.755f, 0.0f, 0.199f, 0.38f, 1.0f, + -0.738f, 0.0f, 0.212f, 0.381f, 1.0f, -0.721f, 0.0f, 0.224f, 0.382f, 1.0f, + -0.703f, 0.0f, 0.236f, 0.384f, 1.0f, -0.686f, 0.0f, 0.248f, 0.386f, 1.0f, + -0.67f, 0.0f, 0.26f, 0.388f, 1.0f, -0.653f, 0.0f, 0.27f, 0.39f, 1.0f, + -0.637f, 0.0f, 0.28f, 0.393f, 1.0f, -0.621f, 0.0f, 0.29f, 0.396f, 1.0f, + -0.605f, 0.0f, 0.298f, 0.399f, 1.0f, -0.589f, 0.0f, 0.306f, 0.403f, 1.0f, + -0.574f, 0.0f, 0.313f, 0.407f, 1.0f, -0.559f, 0.0f, 0.319f, 0.411f, 1.0f, + -0.544f, 0.0f, 0.325f, 0.415f, 1.0f, -0.53f, 0.0f, 0.331f, 0.42f, 1.0f, + -0.516f, 0.0f, 0.336f, 0.425f, 1.0f, -0.503f, 0.0f, 0.34f, 0.431f, 1.0f, + -0.489f, 0.0f, 0.344f, 0.437f, 1.0f, -0.477f, 0.0f, 0.347f, 0.443f, 1.0f, + -0.464f, 0.0f, 0.35f, 0.45f, 1.0f, -0.452f, 0.0f, 0.352f, 0.457f, 1.0f, + -0.44f, 0.0f, 0.354f, 0.464f, 1.0f, -0.429f, 0.0f, 0.355f, 0.471f, 1.0f, + -0.418f, 0.0f, 0.355f, 0.479f, 1.0f, -0.407f, 0.0f, 0.355f, 0.487f, 1.0f, + -0.397f, 0.0f, 0.354f, 0.495f, 1.0f, -0.387f, 0.0f, 0.353f, 0.503f, 1.0f, + -0.378f, 0.0f, 0.351f, 0.512f, 1.0f, -0.368f, 0.0f, 0.348f, 0.52f, 1.0f, + -0.36f, 0.0f, 0.344f, 0.528f, 1.0f, -0.351f, 0.0f, 0.34f, 0.537f, 1.0f, + -0.344f, 0.0f, 0.336f, 0.545f, 1.0f, -0.336f, 0.0f, 0.33f, 0.553f, 1.0f, + -0.329f, 0.0f, 0.324f, 0.562f, 1.0f, -0.322f, 0.0f, 0.318f, 0.57f, 1.0f, + -0.316f, 0.0f, 0.31f, 0.579f, 1.0f, -0.311f, 0.0f, 0.303f, 0.588f, 1.0f, + -0.306f, 0.0f, 0.294f, 0.597f, 1.0f, -0.301f, 0.0f, 0.285f, 0.606f, 1.0f, + -0.297f, 0.0f, 0.275f, 0.615f, 1.0f, -0.293f, 0.0f, 0.264f, 0.625f, 1.0f, + -0.29f, 0.0f, 0.253f, 0.635f, 1.0f, -0.288f, 0.0f, 0.241f, 0.644f, 1.0f, + -0.286f, 0.0f, 0.229f, 0.654f, 1.0f, -0.285f, 0.0f, 0.216f, 0.664f, 1.0f, + -0.284f, 0.0f, 0.202f, 0.675f, 1.0f, -0.283f, 0.0f, 0.188f, 0.685f, 1.0f, + -0.283f, 0.0f, 0.173f, 0.696f, 1.0f, -0.284f, 0.0f, 0.158f, 0.707f, 1.0f, + -0.285f, 0.0f, 0.142f, 0.718f, 1.0f, -0.286f, 0.0f, 0.125f, 0.729f, 1.0f, + -0.288f, 0.0f, 0.108f, 0.74f, 1.0f, -0.29f, 0.0f, 0.091f, 0.751f, 1.0f, + -0.293f, 0.0f, 0.073f, 0.761f, 1.0f, -0.295f, 0.0f, 0.054f, 0.772f, 1.0f, + -0.298f, 0.0f, 0.035f, 0.782f, 1.0f, -0.302f, 0.0f, 0.016f, 0.793f, 1.0f, + -0.305f, 0.0f, -0.004f, 0.804f, 1.0f, -0.309f, 0.0f, -0.024f, 0.815f, 1.0f, + -0.313f, 0.0f, -0.044f, 0.828f, 1.0f, -0.317f, 0.0f, -0.065f, 0.843f, 1.0f, + -0.321f, 0.0f, -0.085f, 0.86f, 1.0f, -0.326f, 0.0f, -0.106f, 0.879f, 1.0f, + -0.33f, 0.0f, -0.127f, 0.897f, 1.0f, -0.335f, 0.0f, -0.148f, 0.915f, 1.0f, + -0.339f, 0.0f, -0.168f, 0.932f, 1.0f, -0.344f, 0.0f, -0.189f, 0.947f, 1.0f, + -0.348f, 0.0f, -0.21f, 0.962f, 1.0f, -0.353f, 0.0f, -0.23f, 0.974f, 1.0f, + -0.357f, 0.0f, -0.25f, 0.985f, 1.0f, -0.361f, 0.0f, -0.27f, 0.995f, 1.0f, + -0.365f, 0.0f, -0.29f, 1.004f, 1.0f, -0.369f, 0.0f, -0.309f, 1.011f, 1.0f, + -0.372f, 0.0f, -0.328f, 1.018f, 1.0f, -0.375f, 0.0f, -0.347f, 1.024f, 1.0f, + -0.377f, 0.0f, -0.365f, 1.029f, 1.0f, -0.379f, 0.0f, -0.383f, 1.033f, 1.0f, + -0.38f, 0.0f, -0.4f, 1.036f, 1.0f, -0.38f, 0.0f, -0.417f, 1.037f, 1.0f, + -0.38f, 0.0f, -0.434f, 1.037f, 1.0f, -0.379f, 0.0f, -0.449f, 1.035f, 1.0f, + -0.377f, 0.0f, -0.464f, 1.032f, 1.0f, -0.374f, 0.0f, -0.478f, 1.029f, 1.0f, + -0.371f, 0.0f, -0.491f, 1.026f, 1.0f, -0.366f, 0.0f, -0.503f, 1.023f, 1.0f, + -0.361f, 0.0f, -0.513f, 1.021f, 1.0f, -0.354f, 0.0f, -0.523f, 1.019f, 1.0f, + -0.347f, 0.0f, -0.531f, 1.017f, 1.0f, -0.339f, 0.0f, -0.538f, 1.016f, 1.0f, + -0.33f, 0.0f, -0.543f, 1.016f, 1.0f, -0.32f, 0.0f, -0.547f, 1.016f, 1.0f, + -0.31f, 0.0f, -0.549f, 1.016f, 1.0f, -0.298f, 0.0f, -0.55f, 1.017f, 1.0f, + -0.286f, 0.0f, -0.55f, 1.017f, 1.0f, -0.274f, 0.0f, -0.548f, 1.018f, 1.0f, + -0.261f, 0.0f, -0.544f, 1.017f, 1.0f, -0.247f, 0.0f, -0.539f, 1.017f, 1.0f, + -0.232f, 0.0f, -0.533f, 1.016f, 1.0f, -0.218f, 0.0f, -0.525f, 1.015f, 1.0f, + -0.202f, 0.0f, -0.515f, 1.013f, 1.0f, -0.186f, 0.0f, -0.503f, 1.009f, 1.0f, + -0.169f, 0.0f, -0.49f, 1.005f, 1.0f, -0.151f, 0.0f, -0.475f, 0.998f, 1.0f, + -0.132f, 0.0f, -0.458f, 0.99f, 1.0f, -0.112f, 0.0f, -0.44f, 0.98f, 1.0f, + -0.091f, 0.0f, -0.42f, 0.968f, 1.0f, -0.069f, 0.0f, -0.398f, 0.955f, 1.0f, + -0.045f, 0.0f, -0.375f, 0.939f, 1.0f, -0.021f, 0.0f, -0.35f, 0.923f, 1.0f, + 0.005f, 0.0f, -0.324f, 0.908f, 1.0f, 0.031f, 0.0f, -0.297f, 0.895f, 1.0f, + 0.06f, 0.0f, -0.268f, 0.882f, 1.0f, 0.089f, 0.0f, -0.238f, 0.87f, 1.0f, + 0.12f, 0.0f, -0.207f, 0.858f, 1.0f, 0.153f, 0.0f, -0.175f, 0.844f, 1.0f, + 0.187f, 0.0f, -0.14f, 0.828f, 1.0f, 0.224f, 0.0f, -0.104f, 0.81f, 1.0f, + 0.262f, 0.0f, -0.067f, 0.79f, 1.0f, 0.302f, 0.0f, -0.027f, 0.769f, 1.0f, + 0.344f, 0.0f, 0.014f, 0.747f, 1.0f, 0.388f, 0.0f, 0.056f, 0.724f, 1.0f, + 0.434f, 0.0f, 0.1f, 0.7f, 1.0f, 0.483f, 0.0f, 0.145f, 0.676f, 1.0f, + 0.533f, 0.0f, 0.191f, 0.651f, 1.0f, 0.585f, 0.0f, 0.238f, 0.625f, 1.0f, + 0.637f, 0.0f, 0.284f, 0.599f, 1.0f, 0.69f, 0.0f, 0.33f, 0.573f, 1.0f, + 0.746f, 0.0f, 0.376f, 0.546f, 1.0f, 0.802f, 0.0f, 0.421f, 0.516f, 1.0f, + 0.859f, 0.0f, 0.464f, 0.483f, 1.0f, 0.915f, 0.0f, 0.506f, 0.446f, 1.0f, + 0.97f, 0.0f, 0.545f, 0.407f, 1.0f, 1.023f, 0.0f, 0.581f, 0.365f, 1.0f, + 1.075f, 0.0f, 0.614f, 0.322f, 1.0f, 1.122f, 0.0f, 0.643f, 0.28f, 1.0f, + 1.169f, 0.0f, 0.671f, 0.236f, 1.0f, 1.207f, 0.0f, 0.693f, 0.202f, 1.0f, + 1.264f, 0.0f, 0.725f, 0.155f, 1.0f, +}; /* ***************************************************************** */ /* Color Data */ @@ -200,4 +246,3 @@ void ED_gpencil_create_stroke(bContext *C, float mat[4][4]) DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); gpd->flag |= GP_DATA_CACHE_IS_DIRTY; } - -- cgit v1.2.3 From f7b1fec463eaa9dc3a05809b04cebf3a26c86aed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Aug 2018 12:52:48 +1000 Subject: Cleanup: unused vars --- source/blender/editors/gpencil/gpencil_add_stroke.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index 5b7c81a3808..ebe07fe417f 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -223,7 +223,7 @@ void ED_gpencil_create_stroke(bContext *C, float mat[4][4]) bGPDstroke *gps; /* create colors */ - int color_Black = gp_stroke_material(bmain, ob, &gp_stroke_material_black); + int color_black = gp_stroke_material(bmain, ob, &gp_stroke_material_black); gp_stroke_material(bmain, ob, &gp_stroke_material_white); gp_stroke_material(bmain, ob, &gp_stroke_material_red); gp_stroke_material(bmain, ob, &gp_stroke_material_green); @@ -231,15 +231,16 @@ void ED_gpencil_create_stroke(bContext *C, float mat[4][4]) gp_stroke_material(bmain, ob, &gp_stroke_material_grey); /* layers */ - bGPDlayer *Colors = BKE_gpencil_layer_addnew(gpd, "Colors", false); - bGPDlayer *Lines = BKE_gpencil_layer_addnew(gpd, "Lines", false); + bGPDlayer *colors = BKE_gpencil_layer_addnew(gpd, "Colors", false); + bGPDlayer *lines = BKE_gpencil_layer_addnew(gpd, "Lines", false); /* frames */ - bGPDframe *frameColor = BKE_gpencil_frame_addnew(Colors, cfra_eval); - bGPDframe *frameLines = BKE_gpencil_frame_addnew(Lines, cfra_eval); + bGPDframe *frame_color = BKE_gpencil_frame_addnew(colors, cfra_eval); + bGPDframe *frame_lines = BKE_gpencil_frame_addnew(lines, cfra_eval); + UNUSED_VARS(frame_color); /* generate stroke */ - gps = BKE_gpencil_add_stroke(frameLines, color_Black, 175, 3); + gps = BKE_gpencil_add_stroke(frame_lines, color_black, 175, 3); BKE_gpencil_stroke_add_points(gps, data0, 175, mat); /* update depsgraph */ -- cgit v1.2.3 From 907413ca65f46d4d349fb52cfcf42bf6212f62b3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 6 Aug 2018 17:08:39 +1000 Subject: Fix T55012: Corruption editing screen keymap --- source/blender/makesrna/intern/rna_wm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 8930c144f17..d0d01b9e43e 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -380,6 +380,10 @@ const EnumPropertyItem rna_enum_event_type_items[] = { {NDOF_BUTTON_A, "NDOF_BUTTON_A", 0, "NDOF Button A", "NdofBA"}, {NDOF_BUTTON_B, "NDOF_BUTTON_B", 0, "NDOF Button B", "NdofBB"}, {NDOF_BUTTON_C, "NDOF_BUTTON_C", 0, "NDOF Button C", "NdofBC"}, + /* Action Zones. */ + {EVT_ACTIONZONE_AREA, "ACTIONZONE_AREA", 0, "ActionZone Area", "AZone Area"}, + {EVT_ACTIONZONE_REGION, "ACTIONZONE_REGION", 0, "ActionZone Region", "AZone Region"}, + {EVT_ACTIONZONE_FULLSCREEN, "ACTIONZONE_FULLSCREEN", 0, "ActionZone Fullscreen", "AZone FullScr"}, {0, NULL, 0, NULL, NULL} }; -- cgit v1.2.3 From e680a9d80d46a7d76552664a0210ac2750d9ab49 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 6 Aug 2018 11:45:56 +0200 Subject: Cleanup LIB_ID_COPY_ flags a bit, add missing comment. --- source/blender/blenkernel/BKE_library.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index aaf53a2396b..16e05cd136a 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -79,12 +79,14 @@ enum { LIB_ID_COPY_NO_PROXY_CLEAR = 1 << 16, /* Object only, needed by make_local code. */ LIB_ID_COPY_NO_PREVIEW = 1 << 17, /* Do not copy preview data, when supported. */ LIB_ID_COPY_CACHES = 1 << 18, /* Copy runtime data caches. */ - /* XXX TODO Do we want to keep that? would rather try to get rid of it... */ - LIB_ID_COPY_ACTIONS = 1 << 19, /* EXCEPTION! Deep-copy actions used by animdata of copied ID. */ - LIB_ID_COPY_KEEP_LIB = 1 << 20, /* Keep the library pointer when copying datablock outside of bmain. */ - LIB_ID_COPY_NO_ANIMDATA = 1 << 21, /* Don't copy id->adt, used by ID datablock localization routines. */ - LIB_ID_COPY_SHAPEKEY = 1 << 22, /* EXCEPTION! Deep-copy shapekeys used by copied obdata ID. */ - LIB_ID_COPY_CD_REFERENCE = 1 << 23, + LIB_ID_COPY_NO_ANIMDATA = 1 << 19, /* Don't copy id->adt, used by ID datablock localization routines. */ + LIB_ID_COPY_CD_REFERENCE = 1 << 20, /* Mesh: Reference CD data layers instead of doing real copy. */ + + /* XXX Hackish/not-so-nice specific behaviors needed for some corner cases. + * Ideally we should not have those, but we need them for now... */ + LIB_ID_COPY_ACTIONS = 1 << 24, /* EXCEPTION! Deep-copy actions used by animdata of copied ID. */ + LIB_ID_COPY_KEEP_LIB = 1 << 25, /* Keep the library pointer when copying datablock outside of bmain. */ + LIB_ID_COPY_SHAPEKEY = 1 << 26, /* EXCEPTION! Deep-copy shapekeys used by copied obdata ID. */ }; void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag); -- cgit v1.2.3 From d890ad37a8268d31f3f79443b6c3b4a3c6a8b10e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 6 Aug 2018 11:48:05 +0200 Subject: Fix horrible invalid mesh freeing in weightvg modifiers. Comes from rB7661f8a65b. Found while checking on T55818, but not solving that issue of course. --- source/blender/modifiers/intern/MOD_weightvgedit.c | 4 +++- source/blender/modifiers/intern/MOD_weightvgmix.c | 4 +++- source/blender/modifiers/intern/MOD_weightvgproximity.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index a34ed1baaff..356edcd7bec 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -214,7 +214,9 @@ static Mesh *applyModifier( } /* Ultimate security check. */ if (!dvert) { - BKE_id_free(NULL, result); + if (result != mesh) { + BKE_id_free(NULL, result); + } return mesh; } diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index b6a7228b171..3c740530258 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -254,7 +254,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Ultimate security check. */ if (!dvert) { - BKE_id_free(NULL, result); + if (result != mesh) { + BKE_id_free(NULL, result); + } return mesh; } diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 05b1ec19253..c485aa132d7 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -433,7 +433,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } /* Ultimate security check. */ if (!dvert) { - BKE_id_free(NULL, result); + if (result != mesh) { + BKE_id_free(NULL, result); + } return mesh; } -- cgit v1.2.3 From 4c4aa65adbef3b119fbd1e3e5e8bb17bdef67718 Mon Sep 17 00:00:00 2001 From: Andrew Hale Date: Mon, 6 Aug 2018 11:37:49 +0200 Subject: PyAPI: Make skin modifier roots settable This make the root flag writable using the Python API, using the generic skin vertex flag setter function. Reviewed By: Campbell Barton Differential Revision: http://developer.blender.org/D3583 --- source/blender/makesrna/intern/rna_mesh.c | 4 +++- source/blender/python/bmesh/bmesh_py_types_meshdata.c | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 0b8f90e1c68..0e0e869a340 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -3220,7 +3220,9 @@ static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) prop = RNA_def_property(srna, "use_root", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_ROOT); - RNA_def_property_ui_text(prop, "Root", "Vertex is a root for rotation calculations and armature generation"); + RNA_def_property_ui_text(prop, "Root", + "Vertex is a root for rotation calculations and armature generation, " + "setting this flag does not clear other roots in the same mesh island"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "use_loose", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index ea606329b07..fabbfdb94c5 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -282,7 +282,7 @@ static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void } PyDoc_STRVAR(bpy_bmvertskin_flag__use_root_doc, -"Use as root vertex.\n\n:type: boolean" +"Use as root vertex. Setting this flag does not clear other roots in the same mesh island.\n\n:type: boolean" ); PyDoc_STRVAR(bpy_bmvertskin_flag__use_loose_doc, "Use loose vertex.\n\n:type: boolean" @@ -311,17 +311,16 @@ static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void * } } -/* XXX Todo: Make root settable, currently the code to disable all other verts as roots sits within the modifier */ static PyGetSetDef bpy_bmvertskin_getseters[] = { /* attributes match rna_mesh_gen */ {(char *)"radius", (getter)bpy_bmvertskin_radius_get, (setter)bpy_bmvertskin_radius_set, (char *)bpy_bmvertskin_radius_doc, NULL}, - {(char *)"use_root", (getter)bpy_bmvertskin_flag_get, (setter)NULL, (char *)bpy_bmvertskin_flag__use_root_doc, (void *)MVERT_SKIN_ROOT}, + {(char *)"use_root", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_root_doc, (void *)MVERT_SKIN_ROOT}, {(char *)"use_loose", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_loose_doc, (void *)MVERT_SKIN_LOOSE}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; -static PyTypeObject BPy_BMVertSkin_Type; /* bm.loops.layers.uv.active */ +static PyTypeObject BPy_BMVertSkin_Type; /* bm.loops.layers.skin.active */ static void bm_init_types_bmvertskin(void) { -- cgit v1.2.3 From d07a408a400e25e2e60131bf56065901d63e728c Mon Sep 17 00:00:00 2001 From: Antonioya Date: Mon, 6 Aug 2018 16:11:31 +0200 Subject: GP: Fix Front z-depth display precision The zdepth 0 was clipped and need 0.000001 --- .../blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl | 9 ++++++--- .../blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl | 4 ++-- .../draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl index 35f47d6c418..d2cad4e44f7 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl @@ -129,12 +129,15 @@ void main() /* set zdepth */ if (xraymode == GP_XRAY_FRONT) { - gl_FragDepth = 0.0; + gl_FragDepth = 0.000001; } - if (xraymode == GP_XRAY_3DSPACE) { + else if (xraymode == GP_XRAY_3DSPACE) { gl_FragDepth = gl_FragCoord.z; } - if (xraymode == GP_XRAY_BACK) { + else if (xraymode == GP_XRAY_BACK) { gl_FragDepth = 0.999999; } + else { + gl_FragDepth = 0.000001; + } } diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl index f092149430c..63f22e0f812 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl @@ -26,7 +26,7 @@ vec2 toScreenSpace(vec4 vertex) float getZdepth(vec4 point) { if (xraymode == GP_XRAY_FRONT) { - return 0.0; + return 0.000001; } if (xraymode == GP_XRAY_3DSPACE) { return (point.z / point.w); @@ -36,7 +36,7 @@ float getZdepth(vec4 point) } /* in front by default */ - return 0.0; + return 0.000001; } vec2 rotateUV(vec2 uv, float angle) diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl index 0bcfe8cddb7..f9054b44996 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl @@ -33,7 +33,7 @@ vec2 toScreenSpace(vec4 vertex) float getZdepth(vec4 point) { if (xraymode == GP_XRAY_FRONT) { - return 0.0; + return 0.000001; } if (xraymode == GP_XRAY_3DSPACE) { return (point.z / point.w); @@ -43,7 +43,7 @@ float getZdepth(vec4 point) } /* in front by default */ - return 0.0; + return 0.000001; } void main(void) { -- cgit v1.2.3 From 563e17091daf9d8df236dfe50c6522d0f0933571 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Mon, 6 Aug 2018 17:01:47 +0200 Subject: GP: Add Simplify Shader FX option This option was missing when old VFX modifers were backported as Shader FX. --- release/scripts/startup/bl_ui/properties_scene.py | 1 + source/blender/draw/engines/gpencil/gpencil_engine.c | 11 ++++++++--- source/blender/draw/engines/gpencil/gpencil_engine.h | 1 + source/blender/makesdna/DNA_scene_types.h | 4 +++- source/blender/makesrna/intern/rna_scene.c | 5 +++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index e324e7a9882..5d87b858da6 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -589,6 +589,7 @@ class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel): col = layout.column() col.prop(rd, "simplify_gpencil_onplay", text="Playback Only") col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers") + col.prop(rd, "simplify_gpencil_shader_fx", text="ShaderFX") col = layout.column(align=True) col.prop(rd, "simplify_gpencil_view_fill") diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 8b8da3f2065..ae1f853d87c 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -353,6 +353,7 @@ void GPENCIL_cache_init(void *vedata) /* save simplify flags (can change while drawing, so it's better to save) */ stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->playing); stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->playing); + stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->playing); /* save pixsize */ stl->storage->pixsize = DRW_viewport_pixelsize_get(); @@ -465,7 +466,9 @@ void GPENCIL_cache_init(void *vedata) } /* create effects passes */ - GPENCIL_create_fx_passes(psl); + if (!stl->storage->simplify_fx) { + GPENCIL_create_fx_passes(psl); + } } } @@ -559,7 +562,7 @@ void GPENCIL_cache_finish(void *vedata) } /* FX passses */ tGPencilObjectCache *cache = &stl->g_data->gp_object_cache[i]; - if (!is_multiedit) { + if ((!stl->storage->simplify_fx) && (!is_multiedit)) { DRW_gpencil_fx_prepare(&e_data, vedata, cache); } } @@ -720,7 +723,9 @@ void GPENCIL_draw_scene(void *ved) DRW_draw_pass(psl->drawing_pass); } /* fx passes */ - if (BKE_shaderfx_has_gpencil(ob)) { + if ((!stl->storage->simplify_fx) && + (BKE_shaderfx_has_gpencil(ob))) + { stl->storage->tonemapping = 0; DRW_gpencil_fx_draw(&e_data, vedata, cache); } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 5d276490663..96a82e91010 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -53,6 +53,7 @@ struct RenderLayer; #define GP_SIMPLIFY_ONPLAY(playing) (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0)) #define GP_SIMPLIFY_FILL(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL))) #define GP_SIMPLIFY_MODIF(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER))) +#define GP_SIMPLIFY_FX(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX))) #define GP_IS_CAMERAVIEW ((rv3d != NULL) && (rv3d->persp == RV3D_CAMOB && v3d->camera)) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 6629eeae3fa..5a5614b775e 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2067,7 +2067,9 @@ typedef enum eGPencil_SimplifyFlags { /* Simplify modifier on viewport */ SIMPLIFY_GPENCIL_MODIFIER = (1 << 3), /* Remove fill external line */ - SIMPLIFY_GPENCIL_REMOVE_FILL_LINE = (1 << 4) + SIMPLIFY_GPENCIL_REMOVE_FILL_LINE = (1 << 4), + /* Simplify Shader FX */ + SIMPLIFY_GPENCIL_FX = (1 << 5) } eGPencil_SimplifyFlags; /* ToolSettings.gpencil_*_align - Stroke Placement mode flags */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index c8f1d810b00..6e572b084d4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -5211,6 +5211,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Disable Modifiers", "Do not apply modifiers in the viewport"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + prop = RNA_def_property(srna, "simplify_gpencil_shader_fx", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "simplify_gpencil", SIMPLIFY_GPENCIL_FX); + RNA_def_property_ui_text(prop, "Simplify Shaders", "Do not apply shader fx"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + /* persistent data */ prop = RNA_def_property(srna, "use_persistent_data", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", R_PERSISTENT_DATA); -- cgit v1.2.3 From faf43ff9ad8e55fc2d80daf1523454c816e327b4 Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Mon, 6 Aug 2018 22:55:25 +0300 Subject: macOS Deps: use xcode 10.13 sdk --- build_files/build_environment/cmake/options.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 08d43d6a0a2..c4dcf212e68 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -126,7 +126,7 @@ else() ) set(OSX_ARCHITECTURES x86_64) set(OSX_DEPLOYMENT_TARGET 10.9) - set(OSX_SDK_VERSION 10.12) + set(OSX_SDK_VERSION 10.13) set(OSX_SYSROOT ${XCODE_DEV_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk) set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}") -- cgit v1.2.3 From 3d083f376b9c75f868c9687946549acd18d91959 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Aug 2018 12:45:01 +1000 Subject: Fix T56255: Crash w/ collection access from Python --- source/blender/blenloader/intern/readfile.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 293114c4b79..b7aeee491c5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6495,6 +6495,8 @@ static void direct_link_scene(FileData *fd, Scene *sce) if (sce->master_collection) { sce->master_collection = newdataadr(fd, sce->master_collection); direct_link_collection(fd, sce->master_collection); + /* Needed because this is an ID outside of Main. */ + sce->master_collection->id.py_instance = NULL; } /* insert into global old-new map for reading without UI (link_global accesses it again) */ -- cgit v1.2.3 From f70798474357bb64d75aeeb14e2ba7e2d12ac881 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Aug 2018 12:58:08 +1000 Subject: Fix T56258: Solidify assert w/ empty mesh --- source/blender/modifiers/intern/MOD_solidify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 3a1fe1513af..1fac637a9ef 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -774,7 +774,7 @@ static Mesh *applyModifier( /* add faces & edges */ origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); - BLI_assert(origindex_edge != NULL); + BLI_assert((numEdges == 0) || (origindex_edge != NULL)); ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */ orig_ed = &origindex_edge[(numEdges * stride) + newEdges]; for (i = 0; i < rimVerts; i++, ed++, orig_ed++) { -- cgit v1.2.3 From ac2cdb21e69b4dcfc4c273cfcf2b94f7afb789f5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Aug 2018 13:22:07 +1000 Subject: Fix T56252: Selectable Bases includes hidden objects --- source/blender/editors/screen/screen_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index ecfc9f2cca0..5a520540301 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -167,7 +167,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } else if (CTX_data_equals(member, "selectable_bases")) { for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_SELECTABLE) != 0) { + if ((base->flag & BASE_VISIBLE) && (base->flag & BASE_SELECTABLE) != 0) { CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); } } -- cgit v1.2.3 From b274a01e58e19ef4b6e45b96cfe21c0c2597b3fe Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 13:36:30 +0200 Subject: Fix T56261: Grease Pencil simplify options get segment fault The depsgraph was not updated as expected with the function used and the cache was not set as dirty. --- source/blender/makesrna/intern/rna_scene.c | 7 ++++++- source/blender/makesrna/intern/rna_sculpt_paint.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6e572b084d4..bb87dde06c1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -534,7 +534,12 @@ static const EnumPropertyItem transform_orientation_items[] = { /* Grease Pencil update cache */ static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { - DEG_id_type_tag(bmain, ID_GD); + /* mark all grease pencil datablocks */ + for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c500c5f261f..37a5376f5d5 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -35,6 +35,7 @@ #include "rna_internal.h" #include "DNA_ID.h" +#include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" #include "DNA_screen_types.h" @@ -120,7 +121,12 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { - DEG_id_type_tag(bmain, ID_GD); + /* mark all grease pencil datablocks */ + for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } -- cgit v1.2.3 From d04e8f41ae9675a99eb0f7996a12ad64bd03b9cc Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 13:56:30 +0200 Subject: Cleanup GP: Change playing field to boolean --- source/blender/draw/engines/gpencil/gpencil_draw_utils.c | 6 +++--- source/blender/draw/engines/gpencil/gpencil_engine.c | 16 ++++++++-------- source/blender/draw/engines/gpencil/gpencil_engine.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 4d2942e08fd..dba5f7b9c20 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -754,7 +754,7 @@ static void gpencil_draw_strokes( DRWShadingGroup *strokegrp; float viewmatrix[4][4]; const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - const bool playing = (bool)stl->storage->playing; + const bool playing = stl->storage->is_playing; const bool is_render = (bool)stl->storage->is_render; const bool is_mat_preview = (bool)stl->storage->is_mat_preview; const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true; @@ -1141,7 +1141,7 @@ void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene cache->cache_idx = 0; /* check if playing animation */ - bool playing = (bool)stl->storage->playing; + bool playing = stl->storage->is_playing; /* draw strokes */ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { @@ -1187,7 +1187,7 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; /* check if playing animation */ - bool playing = (bool)stl->storage->playing; + bool playing = stl->storage->is_playing; GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); cache->cache_idx = 0; diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index ae1f853d87c..668869a2f89 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -327,9 +327,9 @@ void GPENCIL_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND); /* detect if playing animation */ - stl->storage->playing = 0; + stl->storage->is_playing = false; if (draw_ctx->evil_C) { - stl->storage->playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL ? 1 : 0; + stl->storage->is_playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL ? true : false; } if (obact_gpd) { @@ -337,7 +337,7 @@ void GPENCIL_cache_init(void *vedata) * and this produces errors. To be sure, we set cache as dirty because the frame * is changing. */ - if (stl->storage->playing == 1) { + if (stl->storage->is_playing == true) { obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY; } /* if render, set as dirty to update all data */ @@ -351,9 +351,9 @@ void GPENCIL_cache_init(void *vedata) stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview"); /* save simplify flags (can change while drawing, so it's better to save) */ - stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->playing); - stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->playing); - stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->playing); + stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing); + stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing); + stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing); /* save pixsize */ stl->storage->pixsize = DRW_viewport_pixelsize_get(); @@ -364,7 +364,7 @@ void GPENCIL_cache_init(void *vedata) /* detect if painting session */ if ((obact_gpd) && (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) && - (stl->storage->playing == 0)) + (stl->storage->is_playing == false)) { if (((obact_gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) && (obact_gpd->runtime.sbuffer_size > 1)) @@ -637,7 +637,7 @@ void GPENCIL_draw_scene(void *ved) const DRWContextState *draw_ctx = DRW_context_state_get(); View3D *v3d = draw_ctx->v3d; Object *obact = draw_ctx->obact; - const bool playing = (bool)stl->storage->playing; + const bool playing = stl->storage->is_playing; const bool is_render = stl->storage->is_render; /* paper pass to display a confortable area to draw over complex scenes with geometry */ diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 96a82e91010..738b04337c1 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -105,7 +105,7 @@ typedef struct GPENCIL_Storage { int keep_size; float obj_scale; float pixfactor; - int playing; + bool is_playing; bool is_render; bool is_mat_preview; const float *pixsize; -- cgit v1.2.3 From 4c712fd17eade91d1eac65edae09f39460ae60ea Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 14:15:41 +0200 Subject: Fix T56263: Crash when sculpting a GP object with animation This is a limitation of the current operator design. I have added a test to be sure the operator is not initializated while play animations to avoid segment fault. In the future, we can enable this option again, but it will need a operator redesign. --- source/blender/editors/gpencil/gpencil_brush.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index 0fadef55b9d..aed55c15b19 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -1814,9 +1814,18 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve { tGP_BrushEditData *gso = NULL; const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input"); + const bool is_playing = ED_screen_animation_playing(CTX_wm_manager(C)) != NULL ? true : false; bool needs_timer = false; float brush_rate = 0.0f; + /* the operator cannot work while play animation */ + if (is_playing) { + BKE_report(op->reports, RPT_ERROR, + "Cannot sculpt while play animation"); + + return OPERATOR_CANCELLED; + } + /* init painting data */ if (!gpsculpt_brush_init(C, op)) return OPERATOR_CANCELLED; -- cgit v1.2.3 From 030297209f2508a704b8851fa5d7d9a6696561b5 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Tue, 7 Aug 2018 11:41:55 -0300 Subject: Fix T54799: NDOF events not dispatched on windows. Caused by commit rB785e8a636a29 --- intern/ghost/intern/GHOST_System.cpp | 2 ++ intern/ghost/intern/GHOST_SystemWin32.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index c3fd87c65af..4a8a8c48018 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -219,10 +219,12 @@ bool GHOST_System::getFullScreen(void) void GHOST_System::dispatchEvents() { #ifdef WITH_INPUT_NDOF + #ifndef WIN32 // NDOF Motion event is sent only once per dispatch, so do it now: if (m_ndofManager) { m_ndofManager->sendMotionEvent(); } + #endif #endif if (m_eventManager) { diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 17c41e96be4..924173a6c68 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1110,8 +1110,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, break; #ifdef WITH_INPUT_NDOF case RIM_TYPEHID: - if (system->processNDOF(raw)) + if (system->processNDOF(raw)) { + system->m_ndofManager->sendMotionEvent(); eventHandled = true; + } break; #endif } -- cgit v1.2.3 From 035d827b5b132627d5ea73e3fa237d8fd2185b4f Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 16:41:38 +0200 Subject: Cleanup: Tag only objects of the scene collections In previous commit the bmain loop updated all GP objects, but must tag only scene collection objects. --- source/blender/makesrna/intern/rna_scene.c | 19 ++++++++++++++----- source/blender/makesrna/intern/rna_sculpt_paint.c | 20 +++++++++++++++----- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index bb87dde06c1..bdb905690f3 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -532,13 +532,22 @@ static const EnumPropertyItem transform_orientation_items[] = { #endif /* Grease Pencil update cache */ -static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_GPencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { - /* mark all grease pencil datablocks */ - for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { - gpd->flag |= GP_DATA_CACHE_IS_DIRTY; - DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + /* mark all grease pencil datablocks of the scene */ + FOREACH_SCENE_COLLECTION_BEGIN(scene, collection) + { + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, ob) + { + if (ob->type == OB_GPENCIL) { + bGPdata *gpd = (bGPdata *)ob->data; + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + FOREACH_SCENE_COLLECTION_END; WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 37a5376f5d5..faa879b54b1 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -107,6 +107,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" +#include "BKE_collection.h" #include "BKE_context.h" #include "BKE_particle.h" #include "BKE_pbvh.h" @@ -119,13 +120,22 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #include "ED_particle.h" -static void rna_GPencil_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_GPencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) { - /* mark all grease pencil datablocks */ - for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) { - gpd->flag |= GP_DATA_CACHE_IS_DIRTY; - DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + /* mark all grease pencil datablocks of the scene */ + FOREACH_SCENE_COLLECTION_BEGIN(scene, collection) + { + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, ob) + { + if (ob->type == OB_GPENCIL) { + bGPdata *gpd = (bGPdata *)ob->data; + gpd->flag |= GP_DATA_CACHE_IS_DIRTY; + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); + } + } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; } + FOREACH_SCENE_COLLECTION_END; WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } -- cgit v1.2.3 From 8a035612ee8bd361bf43c8935b03822cf1208435 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 20:10:20 +0200 Subject: Fix T56266: Grease Pencil Tint and Color modifier error when apply The material created was not right when apply the modifiers. These errors were related to the material modification from old palette system before the merge and for any reason this code was not changed in the right way. Also changed the "Create Colors" to "Create Materials" to keep UI names aligned. --- .../scripts/startup/bl_ui/properties_data_modifier.py | 4 ++-- .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 19 +++++++++++++------ .../gpencil_modifiers/intern/MOD_gpenciltint.c | 18 ++++++++++++------ source/blender/makesrna/intern/rna_gpencil_modifier.c | 8 ++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 7eeb45cc52e..3a1801f2a53 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1756,7 +1756,7 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") row = layout.row() - row.prop(md, "create_colors") + row.prop(md, "create_materials") def GP_COLOR(self, layout, ob, md): gpd = ob.data @@ -1778,7 +1778,7 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") row = layout.row() - row.prop(md, "create_colors") + row.prop(md, "create_materials") def GP_OPACITY(self, layout, ob, md): gpd = ob.data diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 88754f29db3..155de7305b7 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -35,6 +35,8 @@ #include "DNA_gpencil_types.h" #include "DNA_gpencil_modifier_types.h" +#include "MEM_guardedalloc.h" + #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math_color.h" @@ -120,18 +122,24 @@ static void bakeModifier( copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + deformStroke(md, depsgraph, ob, gpl, gps); + /* look for color */ - if (mmd->flag & GP_TINT_CREATE_COLORS) { + if (mmd->flag & GP_COLOR_CREATE_COLORS) { Material *newmat = BLI_ghash_lookup(gh_color, mat->id.name); if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); + newmat->gp_style = MEM_dupallocN(mat->gp_style); + newmat->preview = NULL; + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v3_v3(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v3_v3(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); BLI_ghash_insert(gh_color, mat->id.name, newmat); + DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); } /* reasign color index */ int idx = BKE_object_material_slot_find_index(ob, newmat); @@ -139,11 +147,10 @@ static void bakeModifier( } else { /* reuse existing color */ - copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v3_v3(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v3_v3(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); } - deformStroke(md, depsgraph, ob, gpl, gps); } } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 641a75bc353..e937f6454c2 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -35,6 +35,8 @@ #include "DNA_gpencil_types.h" #include "DNA_gpencil_modifier_types.h" +#include "MEM_guardedalloc.h" + #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math_vector.h" @@ -128,18 +130,24 @@ static void bakeModifier( copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + deformStroke(md, depsgraph, ob, gpl, gps); + /* look for color */ if (mmd->flag & GP_TINT_CREATE_COLORS) { Material *newmat = (Material *)BLI_ghash_lookup(gh_color, mat->id.name); if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); + newmat->gp_style = MEM_dupallocN(mat->gp_style); + newmat->preview = NULL; + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v3_v3(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v3_v3(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); BLI_ghash_insert(gh_color, mat->id.name, newmat); + DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); } /* reasign color index */ int idx = BKE_object_material_slot_find_index(ob, newmat); @@ -147,11 +155,9 @@ static void bakeModifier( } else { /* reuse existing color */ - copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v3_v3(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v3_v3(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); } - - deformStroke(md, depsgraph, ob, gpl, gps); } } } diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 8c4edf8030c..1bfcf415a94 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -681,9 +681,9 @@ static void rna_def_modifier_gpenciltint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Factor", "Factor for mixing color"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "create_colors", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "create_materials", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TINT_CREATE_COLORS); - RNA_def_property_ui_text(prop, "Create Colors", "When apply modifier, create new color in the palette"); + RNA_def_property_ui_text(prop, "Create Materials", "When apply modifier, create new material"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); @@ -739,9 +739,9 @@ static void rna_def_modifier_gpencilcolor(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Value", "Color Value"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "create_colors", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "create_materials", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_COLOR_CREATE_COLORS); - RNA_def_property_ui_text(prop, "Create Colors", "When apply modifier, create new color in the palette"); + RNA_def_property_ui_text(prop, "Create Materials", "When apply modifier, create new material"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); -- cgit v1.2.3 From 95e490889dda96768e69ec222b91898f13ef0c1d Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Tue, 7 Aug 2018 21:53:02 +0300 Subject: macOS GHOST: use non-deprecated functions for coordinates --- intern/ghost/intern/GHOST_WindowCocoa.mm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 2b986428fd3..22dc772fff0 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -865,30 +865,30 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - NSPoint screenCoord; - NSPoint baseCoord; + NSRect screenCoord; + NSRect baseCoord; - screenCoord.x = inX; - screenCoord.y = inY; + screenCoord.origin.x = inX; + screenCoord.origin.y = inY; - baseCoord = [m_window convertScreenToBase:screenCoord]; + baseCoord = [m_window convertRectFromScreen:screenCoord]; - outX = baseCoord.x; - outY = baseCoord.y; + outX = baseCoord.origin.x; + outY = baseCoord.origin.y; } void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const { - NSPoint screenCoord; - NSPoint baseCoord; + NSRect screenCoord; + NSRect baseCoord; - baseCoord.x = inX; - baseCoord.y = inY; + baseCoord.origin.x = inX; + baseCoord.origin.y = inY; - screenCoord = [m_window convertBaseToScreen:baseCoord]; + screenCoord = [m_window convertRectToScreen:baseCoord]; - outX = screenCoord.x; - outY = screenCoord.y; + outX = screenCoord.origin.x; + outY = screenCoord.origin.y; } -- cgit v1.2.3 From 3884b86927747a2662d0852d6d57c043c37d8cb4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 22:13:02 +0200 Subject: Fix T56266: Second try to fix material problems --- .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 19 ++++++++++++++----- .../gpencil_modifiers/intern/MOD_gpenciltint.c | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 155de7305b7..b47987ddbc0 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -135,8 +135,8 @@ static void bakeModifier( assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - copy_v3_v3(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v3_v3(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); BLI_ghash_insert(gh_color, mat->id.name, newmat); DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); @@ -146,9 +146,18 @@ static void bakeModifier( gps->mat_nr = idx - 1; } else { - /* reuse existing color */ - copy_v3_v3(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v3_v3(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + /* reuse existing color (but update only first time) */ + if (BLI_ghash_lookup(gh_color, mat->id.name) == NULL) { + copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + BLI_ghash_insert(gh_color, mat->id.name, mat); + } + /* update previews (icon and thumbnail) */ + if (mat->preview != NULL) { + mat->preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; + mat->preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; + } + DEG_id_tag_update(&mat->id, DEG_TAG_COPY_ON_WRITE); } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index e937f6454c2..8e2e97abf84 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -143,8 +143,8 @@ static void bakeModifier( assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - copy_v3_v3(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v3_v3(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); BLI_ghash_insert(gh_color, mat->id.name, newmat); DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); @@ -154,9 +154,18 @@ static void bakeModifier( gps->mat_nr = idx - 1; } else { - /* reuse existing color */ - copy_v3_v3(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v3_v3(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + /* reuse existing color (but update only first time) */ + if (BLI_ghash_lookup(gh_color, mat->id.name) == NULL) { + copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + BLI_ghash_insert(gh_color, mat->id.name, mat); + } + /* update previews (icon and thumbnail) */ + if (mat->preview != NULL) { + mat->preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; + mat->preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; + } + DEG_id_tag_update(&mat->id, DEG_TAG_COPY_ON_WRITE); } } } -- cgit v1.2.3 From d2f709b1792ba017ba29b7228a706a7bb05622a1 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 22:22:03 +0200 Subject: Fix memory leak in previous commit --- source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c | 3 --- source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index b47987ddbc0..b2df49a8d06 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -35,8 +35,6 @@ #include "DNA_gpencil_types.h" #include "DNA_gpencil_modifier_types.h" -#include "MEM_guardedalloc.h" - #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math_color.h" @@ -130,7 +128,6 @@ static void bakeModifier( if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); - newmat->gp_style = MEM_dupallocN(mat->gp_style); newmat->preview = NULL; assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 8e2e97abf84..89d48492e46 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -35,8 +35,6 @@ #include "DNA_gpencil_types.h" #include "DNA_gpencil_modifier_types.h" -#include "MEM_guardedalloc.h" - #include "BLI_blenlib.h" #include "BLI_ghash.h" #include "BLI_math_vector.h" @@ -49,6 +47,7 @@ #include "BKE_material.h" #include "BKE_main.h" +#include "DEG_depsgraph.h" #include "DEG_depsgraph.h" #include "MOD_gpencil_util.h" @@ -138,7 +137,6 @@ static void bakeModifier( if (newmat == NULL) { BKE_object_material_slot_add(bmain, ob); newmat = BKE_material_copy(bmain, mat); - newmat->gp_style = MEM_dupallocN(mat->gp_style); newmat->preview = NULL; assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); -- cgit v1.2.3 From 5f71093bb64c3cf589f432a8768e772dcbc72aed Mon Sep 17 00:00:00 2001 From: Antonioya Date: Tue, 7 Aug 2018 22:26:54 +0200 Subject: Cleanup: Fix stupid duplication --- source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 89d48492e46..08cf1c13692 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -47,7 +47,6 @@ #include "BKE_material.h" #include "BKE_main.h" -#include "DEG_depsgraph.h" #include "DEG_depsgraph.h" #include "MOD_gpencil_util.h" -- cgit v1.2.3 From cb58658f4145239082573aec49f261ce389a03ca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 10:59:50 +1000 Subject: Cleanup: style --- source/blender/blenkernel/intern/subdiv_eval.c | 10 +++++----- source/blender/blenkernel/intern/subdiv_mesh.c | 2 +- .../blender/compositor/operations/COM_CryptomatteOperation.cpp | 2 +- source/blender/depsgraph/intern/builder/deg_builder_nodes.cc | 6 +++--- source/blender/draw/engines/gpencil/gpencil_engine.c | 4 ++-- source/blender/editors/gpencil/gpencil_add_stroke.c | 2 +- source/blender/editors/gpencil/gpencil_brush.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 8621b1f87f9..e23be84ee26 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -122,11 +122,11 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, vertex_index < num_face_vertices; vertex_index++, mluv++) { - evaluator->setFaceVaryingData(evaluator, - layer_index, - mluv->uv, - uv_indicies[vertex_index], - 1); + evaluator->setFaceVaryingData(evaluator, + layer_index, + mluv->uv, + uv_indicies[vertex_index], + 1); } } } diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index a58dbdcff84..bb27cb6a31e 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -2251,7 +2251,7 @@ static void points_for_loose_edges_interpolation_get( SubdivMeshContext *ctx, const MEdge *coarse_edge, const MEdge *neighbors[2], - float points_r[4][3]) + float points_r[4][3]) { const Mesh *coarse_mesh = ctx->coarse_mesh; const MVert *coarse_mvert = coarse_mesh->mvert; diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp index f3fa81075c6..9a1cbdd7a00 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp @@ -22,7 +22,7 @@ CryptomatteOperation::CryptomatteOperation(size_t num_inputs) : NodeOperation() { - for(size_t i = 0; i < num_inputs; i++) { + for (size_t i = 0; i < num_inputs; i++) { this->addInputSocket(COM_DT_COLOR); } inputs.resize(num_inputs); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index e20b589bf22..efd57734b48 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -1233,9 +1233,9 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata) DEG_NODE_TYPE_GEOMETRY, function_bind(BKE_gpencil_eval_geometry, _1, - (bGPdata *)obdata_cow), - DEG_OPCODE_PLACEHOLDER, - "Geometry Eval"); + (bGPdata *)obdata_cow), + DEG_OPCODE_PLACEHOLDER, + "Geometry Eval"); op_node->set_as_entry(); break; } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 668869a2f89..3f64d72d354 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -329,7 +329,7 @@ void GPENCIL_cache_init(void *vedata) /* detect if playing animation */ stl->storage->is_playing = false; if (draw_ctx->evil_C) { - stl->storage->is_playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL ? true : false; + stl->storage->is_playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL; } if (obact_gpd) { @@ -724,7 +724,7 @@ void GPENCIL_draw_scene(void *ved) } /* fx passes */ if ((!stl->storage->simplify_fx) && - (BKE_shaderfx_has_gpencil(ob))) + (BKE_shaderfx_has_gpencil(ob))) { stl->storage->tonemapping = 0; DRW_gpencil_fx_draw(&e_data, vedata, cache); diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index ebe07fe417f..f932f98ac1d 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -23,7 +23,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/gpencil/gpencil_add_monkey.c +/** \file blender/editors/gpencil/gpencil_add_stroke.c * \ingroup edgpencil */ diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index aed55c15b19..ff93e7fc57d 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -1814,7 +1814,7 @@ static int gpsculpt_brush_invoke(bContext *C, wmOperator *op, const wmEvent *eve { tGP_BrushEditData *gso = NULL; const bool is_modal = RNA_boolean_get(op->ptr, "wait_for_input"); - const bool is_playing = ED_screen_animation_playing(CTX_wm_manager(C)) != NULL ? true : false; + const bool is_playing = ED_screen_animation_playing(CTX_wm_manager(C)) != NULL; bool needs_timer = false; float brush_rate = 0.0f; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index 6c54d4c49be..4c359be670f 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -124,8 +124,8 @@ static void generateStrokes( for (i = 0, gps = gpf->strokes.first; i < tot_strokes; i++, gps = gps->next) { if (is_stroke_affected_by_modifier( - ob, mmd->layername, mmd->pass_index, 1, gpl, gps, - mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) + ob, mmd->layername, mmd->pass_index, 1, gpl, gps, + mmd->flag & GP_MIRROR_INVERT_LAYER, mmd->flag & GP_MIRROR_INVERT_PASS)) { gps_new = BKE_gpencil_stroke_duplicate(gps); update_position(ob, mmd, gps_new, xi); -- cgit v1.2.3 From 931a279f441f6f9c3266d4789e9aa5aed1c16aa8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 11:00:57 +1000 Subject: Cleanup: use static variables --- intern/clog/clog.c | 2 +- intern/ghost/intern/GHOST_TaskbarX11.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/clog/clog.c b/intern/clog/clog.c index 9a80d99fe73..f64e7c19a5f 100644 --- a/intern/clog/clog.c +++ b/intern/clog/clog.c @@ -559,7 +559,7 @@ static void CLG_ctx_free(CLogContext *ctx) * \{ */ /* We could support multiple at once, for now this seems not needed. */ -struct CLogContext *g_ctx = NULL; +static struct CLogContext *g_ctx = NULL; void CLG_init(void) { diff --git a/intern/ghost/intern/GHOST_TaskbarX11.cpp b/intern/ghost/intern/GHOST_TaskbarX11.cpp index 2ef82dc6636..9826ccdfa37 100644 --- a/intern/ghost/intern/GHOST_TaskbarX11.cpp +++ b/intern/ghost/intern/GHOST_TaskbarX11.cpp @@ -44,7 +44,7 @@ static unity_event_loop_t unity_event_loop; static bool libunity_initialized = false; static bool libunity_available = false; -void* libunity_handle = NULL; +static void *libunity_handle = NULL; void GHOST_TaskBarX11::free() { -- cgit v1.2.3 From d07d3e0987d5b4caf86ae1dc4749c0062a5b6189 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 11:31:28 +1000 Subject: Cleanup: indentation --- source/blender/makesrna/intern/rna_mesh.c | 6 +++--- source/blender/python/bmesh/bmesh_py_types_meshdata.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 0e0e869a340..c97cf2923f2 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -3220,9 +3220,9 @@ static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) prop = RNA_def_property(srna, "use_root", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MVERT_SKIN_ROOT); - RNA_def_property_ui_text(prop, "Root", - "Vertex is a root for rotation calculations and armature generation, " - "setting this flag does not clear other roots in the same mesh island"); + RNA_def_property_ui_text(prop, "Root", + "Vertex is a root for rotation calculations and armature generation, " + "setting this flag does not clear other roots in the same mesh island"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); prop = RNA_def_property(srna, "use_loose", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index fabbfdb94c5..97e64fd376e 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -314,7 +314,7 @@ static int bpy_bmvertskin_flag_set(BPy_BMVertSkin *self, PyObject *value, void * static PyGetSetDef bpy_bmvertskin_getseters[] = { /* attributes match rna_mesh_gen */ {(char *)"radius", (getter)bpy_bmvertskin_radius_get, (setter)bpy_bmvertskin_radius_set, (char *)bpy_bmvertskin_radius_doc, NULL}, - {(char *)"use_root", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_root_doc, (void *)MVERT_SKIN_ROOT}, + {(char *)"use_root", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_root_doc, (void *)MVERT_SKIN_ROOT}, {(char *)"use_loose", (getter)bpy_bmvertskin_flag_get, (setter)bpy_bmvertskin_flag_set, (char *)bpy_bmvertskin_flag__use_loose_doc, (void *)MVERT_SKIN_LOOSE}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ -- cgit v1.2.3 From f86c965d7f22b1a9b633ac3039e32327030822f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 11:49:51 +1000 Subject: Cleanup: use conforming header guard --- source/blender/compositor/intern/COM_CPUDevice.h | 4 ++-- source/blender/compositor/intern/COM_ChunkOrder.h | 4 ++-- source/blender/compositor/intern/COM_ChunkOrderHotspot.h | 4 ++-- source/blender/compositor/intern/COM_CompositorContext.h | 4 ++-- source/blender/compositor/intern/COM_Converter.h | 4 ++-- source/blender/compositor/intern/COM_Debug.h | 4 ++-- source/blender/compositor/intern/COM_Device.h | 4 ++-- source/blender/compositor/intern/COM_ExecutionGroup.h | 4 ++-- source/blender/compositor/intern/COM_ExecutionSystem.h | 6 +++--- source/blender/compositor/intern/COM_MemoryBuffer.h | 4 ++-- source/blender/compositor/intern/COM_MemoryProxy.h | 4 ++-- source/blender/compositor/intern/COM_NodeConverter.h | 6 +++--- source/blender/compositor/intern/COM_NodeGraph.h | 6 +++--- source/blender/compositor/intern/COM_NodeOperation.h | 4 ++-- source/blender/compositor/intern/COM_NodeOperationBuilder.h | 6 +++--- source/blender/compositor/intern/COM_OpenCLDevice.h | 4 ++-- source/blender/compositor/intern/COM_SingleThreadedOperation.h | 4 ++-- source/blender/compositor/intern/COM_SocketReader.h | 6 +++--- source/blender/compositor/intern/COM_WorkPackage.h | 4 ++-- source/blender/compositor/intern/COM_WorkScheduler.h | 6 +++--- source/blender/compositor/nodes/COM_AlphaOverNode.h | 4 ++-- source/blender/compositor/nodes/COM_BilateralBlurNode.h | 4 ++-- source/blender/compositor/nodes/COM_BlurNode.h | 4 ++-- source/blender/compositor/nodes/COM_BokehBlurNode.h | 4 ++-- source/blender/compositor/nodes/COM_BokehImageNode.h | 4 ++-- source/blender/compositor/nodes/COM_BoxMaskNode.h | 4 ++-- source/blender/compositor/nodes/COM_BrightnessNode.h | 4 ++-- source/blender/compositor/nodes/COM_ChannelMatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_ChromaMatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorBalanceNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorCorrectionNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorCurveNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorMatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorRampNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorSpillNode.h | 4 ++-- source/blender/compositor/nodes/COM_ColorToBWNode.h | 4 ++-- source/blender/compositor/nodes/COM_CombineColorNode.h | 4 ++-- source/blender/compositor/nodes/COM_CompositorNode.h | 4 ++-- source/blender/compositor/nodes/COM_ConvertAlphaNode.h | 4 ++-- source/blender/compositor/nodes/COM_CornerPinNode.h | 6 +++--- source/blender/compositor/nodes/COM_CropNode.h | 4 ++-- source/blender/compositor/nodes/COM_CryptomatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_DefocusNode.h | 4 ++-- source/blender/compositor/nodes/COM_DespeckleNode.h | 4 ++-- source/blender/compositor/nodes/COM_DifferenceMatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_DilateErodeNode.h | 4 ++-- source/blender/compositor/nodes/COM_DirectionalBlurNode.h | 4 ++-- source/blender/compositor/nodes/COM_DisplaceNode.h | 4 ++-- source/blender/compositor/nodes/COM_DistanceMatteNode.h | 4 ++-- source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h | 4 ++-- source/blender/compositor/nodes/COM_EllipseMaskNode.h | 4 ++-- source/blender/compositor/nodes/COM_FlipNode.h | 4 ++-- source/blender/compositor/nodes/COM_GammaNode.h | 4 ++-- source/blender/compositor/nodes/COM_GlareNode.h | 4 ++-- source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h | 4 ++-- source/blender/compositor/nodes/COM_HueSaturationValueNode.h | 4 ++-- source/blender/compositor/nodes/COM_IDMaskNode.h | 4 ++-- source/blender/compositor/nodes/COM_InpaintNode.h | 4 ++-- source/blender/compositor/nodes/COM_InvertNode.h | 4 ++-- source/blender/compositor/nodes/COM_LensDistortionNode.h | 4 ++-- source/blender/compositor/nodes/COM_MapUVNode.h | 4 ++-- source/blender/compositor/nodes/COM_MathNode.h | 4 ++-- source/blender/compositor/nodes/COM_MixNode.h | 4 ++-- source/blender/compositor/nodes/COM_MovieDistortionNode.h | 4 ++-- source/blender/compositor/nodes/COM_NormalNode.h | 4 ++-- source/blender/compositor/nodes/COM_NormalizeNode.h | 4 ++-- source/blender/compositor/nodes/COM_OutputFileNode.h | 4 ++-- source/blender/compositor/nodes/COM_PixelateNode.h | 4 ++-- source/blender/compositor/nodes/COM_RotateNode.h | 4 ++-- source/blender/compositor/nodes/COM_ScaleNode.h | 4 ++-- source/blender/compositor/nodes/COM_SeparateColorNode.h | 4 ++-- source/blender/compositor/nodes/COM_SetAlphaNode.h | 4 ++-- source/blender/compositor/nodes/COM_SocketProxyNode.h | 4 ++-- source/blender/compositor/nodes/COM_SplitViewerNode.h | 4 ++-- source/blender/compositor/nodes/COM_Stabilize2dNode.h | 4 ++-- source/blender/compositor/nodes/COM_SunBeamsNode.h | 4 ++-- source/blender/compositor/nodes/COM_SwitchNode.h | 4 ++-- source/blender/compositor/nodes/COM_SwitchViewNode.h | 4 ++-- source/blender/compositor/nodes/COM_TimeNode.h | 4 ++-- source/blender/compositor/nodes/COM_TonemapNode.h | 4 ++-- source/blender/compositor/nodes/COM_TranslateNode.h | 4 ++-- source/blender/compositor/nodes/COM_ValueNode.h | 4 ++-- source/blender/compositor/nodes/COM_VectorBlurNode.h | 4 ++-- source/blender/compositor/nodes/COM_VectorCurveNode.h | 4 ++-- source/blender/compositor/nodes/COM_ViewLevelsNode.h | 4 ++-- source/blender/compositor/nodes/COM_ViewerNode.h | 4 ++-- source/blender/compositor/nodes/COM_ZCombineNode.h | 4 ++-- source/blender/compositor/operations/COM_AlphaOverKeyOperation.h | 4 ++-- source/blender/compositor/operations/COM_AlphaOverMixedOperation.h | 4 ++-- .../compositor/operations/COM_AlphaOverPremultiplyOperation.h | 4 ++-- source/blender/compositor/operations/COM_AntiAliasOperation.h | 4 ++-- source/blender/compositor/operations/COM_BlurBaseOperation.h | 4 ++-- source/blender/compositor/operations/COM_BokehImageOperation.h | 4 ++-- source/blender/compositor/operations/COM_BoxMaskOperation.h | 4 ++-- source/blender/compositor/operations/COM_BrightnessOperation.h | 4 ++-- source/blender/compositor/operations/COM_CalculateMeanOperation.h | 4 ++-- .../compositor/operations/COM_CalculateStandardDeviationOperation.h | 4 ++-- source/blender/compositor/operations/COM_ChangeHSVOperation.h | 4 ++-- source/blender/compositor/operations/COM_ChannelMatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_ChromaMatteOperation.h | 4 ++-- .../blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorCorrectionOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorCurveOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorMatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorRampOperation.h | 4 ++-- source/blender/compositor/operations/COM_ColorSpillOperation.h | 4 ++-- source/blender/compositor/operations/COM_CompositorOperation.h | 4 ++-- .../compositor/operations/COM_ConvertColorProfileOperation.h | 4 ++-- .../compositor/operations/COM_ConvertDepthToRadiusOperation.h | 4 ++-- source/blender/compositor/operations/COM_ConvertOperation.h | 4 ++-- .../compositor/operations/COM_ConvolutionEdgeFilterOperation.h | 4 ++-- .../blender/compositor/operations/COM_ConvolutionFilterOperation.h | 4 ++-- source/blender/compositor/operations/COM_CropOperation.h | 4 ++-- source/blender/compositor/operations/COM_CryptomatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_CurveBaseOperation.h | 4 ++-- source/blender/compositor/operations/COM_DespeckleOperation.h | 4 ++-- source/blender/compositor/operations/COM_DifferenceMatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_DilateErodeOperation.h | 4 ++-- source/blender/compositor/operations/COM_DisplaceOperation.h | 4 ++-- source/blender/compositor/operations/COM_DisplaceSimpleOperation.h | 4 ++-- .../blender/compositor/operations/COM_DistanceRGBMatteOperation.h | 4 ++-- .../blender/compositor/operations/COM_DistanceYCCMatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_DotproductOperation.h | 4 ++-- source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h | 4 ++-- source/blender/compositor/operations/COM_EllipseMaskOperation.h | 4 ++-- .../blender/compositor/operations/COM_FastGaussianBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_FlipOperation.h | 4 ++-- source/blender/compositor/operations/COM_GammaCorrectOperation.h | 4 ++-- source/blender/compositor/operations/COM_GammaOperation.h | 4 ++-- .../blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h | 4 ++-- .../blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_GaussianXBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_GaussianYBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareBaseOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareFogGlowOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareGhostOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareSimpleStarOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareStreaksOperation.h | 4 ++-- source/blender/compositor/operations/COM_GlareThresholdOperation.h | 4 ++-- .../compositor/operations/COM_HueSaturationValueCorrectOperation.h | 4 ++-- source/blender/compositor/operations/COM_IDMaskOperation.h | 4 ++-- source/blender/compositor/operations/COM_ImageOperation.h | 4 ++-- source/blender/compositor/operations/COM_InpaintOperation.h | 4 ++-- source/blender/compositor/operations/COM_InvertOperation.h | 4 ++-- source/blender/compositor/operations/COM_KeyingBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_KeyingClipOperation.h | 4 ++-- source/blender/compositor/operations/COM_KeyingDespillOperation.h | 4 ++-- source/blender/compositor/operations/COM_KeyingOperation.h | 4 ++-- source/blender/compositor/operations/COM_KeyingScreenOperation.h | 4 ++-- source/blender/compositor/operations/COM_LuminanceMatteOperation.h | 4 ++-- source/blender/compositor/operations/COM_MapRangeOperation.h | 4 ++-- source/blender/compositor/operations/COM_MapUVOperation.h | 4 ++-- source/blender/compositor/operations/COM_MapValueOperation.h | 4 ++-- source/blender/compositor/operations/COM_MaskOperation.h | 4 ++-- source/blender/compositor/operations/COM_MathBaseOperation.h | 4 ++-- source/blender/compositor/operations/COM_MixOperation.h | 4 ++-- .../blender/compositor/operations/COM_MovieClipAttributeOperation.h | 4 ++-- source/blender/compositor/operations/COM_MovieClipOperation.h | 4 ++-- source/blender/compositor/operations/COM_MovieDistortionOperation.h | 4 ++-- source/blender/compositor/operations/COM_MultilayerImageOperation.h | 4 ++-- source/blender/compositor/operations/COM_NormalizeOperation.h | 4 ++-- .../compositor/operations/COM_OutputFileMultiViewOperation.h | 4 ++-- source/blender/compositor/operations/COM_OutputFileOperation.h | 4 ++-- source/blender/compositor/operations/COM_PixelateOperation.h | 4 ++-- source/blender/compositor/operations/COM_PlaneCornerPinOperation.h | 4 ++-- .../blender/compositor/operations/COM_PlaneDistortCommonOperation.h | 4 ++-- source/blender/compositor/operations/COM_PlaneTrackOperation.h | 4 ++-- source/blender/compositor/operations/COM_PreviewOperation.h | 4 ++-- .../compositor/operations/COM_ProjectorLensDistortionOperation.h | 4 ++-- source/blender/compositor/operations/COM_QualityStepHelper.h | 4 ++-- source/blender/compositor/operations/COM_ReadBufferOperation.h | 4 ++-- source/blender/compositor/operations/COM_RenderLayersProg.h | 4 ++-- source/blender/compositor/operations/COM_RotateOperation.h | 4 ++-- source/blender/compositor/operations/COM_ScaleOperation.h | 4 ++-- .../compositor/operations/COM_ScreenLensDistortionOperation.h | 4 ++-- source/blender/compositor/operations/COM_SetAlphaOperation.h | 4 ++-- source/blender/compositor/operations/COM_SetColorOperation.h | 4 ++-- source/blender/compositor/operations/COM_SetSamplerOperation.h | 4 ++-- source/blender/compositor/operations/COM_SetValueOperation.h | 4 ++-- source/blender/compositor/operations/COM_SetVectorOperation.h | 4 ++-- source/blender/compositor/operations/COM_SocketProxyOperation.h | 4 ++-- source/blender/compositor/operations/COM_SplitOperation.h | 4 ++-- source/blender/compositor/operations/COM_SunBeamsOperation.h | 4 ++-- source/blender/compositor/operations/COM_TextureOperation.h | 4 ++-- source/blender/compositor/operations/COM_TonemapOperation.h | 4 ++-- source/blender/compositor/operations/COM_TrackPositionOperation.h | 4 ++-- source/blender/compositor/operations/COM_TranslateOperation.h | 4 ++-- source/blender/compositor/operations/COM_VectorBlurOperation.h | 4 ++-- source/blender/compositor/operations/COM_VectorCurveOperation.h | 4 ++-- source/blender/compositor/operations/COM_ViewerOperation.h | 4 ++-- source/blender/compositor/operations/COM_WrapOperation.h | 4 ++-- source/blender/compositor/operations/COM_WriteBufferOperation.h | 4 ++-- source/blender/compositor/operations/COM_ZCombineOperation.h | 4 ++-- 195 files changed, 397 insertions(+), 397 deletions(-) diff --git a/source/blender/compositor/intern/COM_CPUDevice.h b/source/blender/compositor/intern/COM_CPUDevice.h index f98a75e5978..b938b5fc588 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.h +++ b/source/blender/compositor/intern/COM_CPUDevice.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CPUDevice_h -#define _COM_CPUDevice_h +#ifndef __COM_CPUDEVICE_H__ +#define __COM_CPUDEVICE_H__ #include "COM_Device.h" diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h index 4728b771e3c..f61816c6511 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.h +++ b/source/blender/compositor/intern/COM_ChunkOrder.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ChunkOrder_h_ -#define _COM_ChunkOrder_h_ +#ifndef __COM_CHUNKORDER_H__ +#define __COM_CHUNKORDER_H__ #include "COM_ChunkOrderHotspot.h" class ChunkOrder { diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.h b/source/blender/compositor/intern/COM_ChunkOrderHotspot.h index 09e9fa44c3b..620980518ef 100644 --- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.h +++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ChunkOrderHotSpot_h_ -#define _COM_ChunkOrderHotSpot_h_ +#ifndef __COM_CHUNKORDERHOTSPOT_H__ +#define __COM_CHUNKORDERHOTSPOT_H__ #ifdef WITH_CXX_GUARDEDALLOC #include "MEM_guardedalloc.h" diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index 1c702503915..b43e163870c 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CompositorContext_h -#define _COM_CompositorContext_h +#ifndef __COM_COMPOSITORCONTEXT_H__ +#define __COM_COMPOSITORCONTEXT_H__ #include #include diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h index b57220351e8..d0b888e24a0 100644 --- a/source/blender/compositor/intern/COM_Converter.h +++ b/source/blender/compositor/intern/COM_Converter.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Converter_h -#define _COM_Converter_h +#ifndef __COM_CONVERTER_H__ +#define __COM_CONVERTER_H__ #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h index f5db93e8825..8a5014afb96 100644 --- a/source/blender/compositor/intern/COM_Debug.h +++ b/source/blender/compositor/intern/COM_Debug.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_Debug_h -#define _COM_Debug_h +#ifndef __COM_DEBUG_H__ +#define __COM_DEBUG_H__ #include #include diff --git a/source/blender/compositor/intern/COM_Device.h b/source/blender/compositor/intern/COM_Device.h index 4ab6e1e2f96..202ca1d0b4f 100644 --- a/source/blender/compositor/intern/COM_Device.h +++ b/source/blender/compositor/intern/COM_Device.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Device_h -#define _COM_Device_h +#ifndef __COM_DEVICE_H__ +#define __COM_DEVICE_H__ #include "COM_WorkPackage.h" diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index 20ffbeaa357..88c702b8477 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ExecutionGroup_h -#define _COM_ExecutionGroup_h +#ifndef __COM_EXECUTIONGROUP_H__ +#define __COM_EXECUTIONGROUP_H__ #include "COM_Node.h" #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index acde4a9b772..0990df31c55 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -22,8 +22,8 @@ class ExecutionGroup; -#ifndef _COM_ExecutionSystem_h -#define _COM_ExecutionSystem_h +#ifndef __COM_EXECUTIONSYSTEM_H__ +#define __COM_EXECUTIONSYSTEM_H__ #include "DNA_color_types.h" #include "DNA_node_types.h" @@ -185,4 +185,4 @@ private: #endif }; -#endif /* _COM_ExecutionSystem_h */ +#endif /* __COM_EXECUTIONSYSTEM_H__ */ diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index be948b3e99b..5f6485475d0 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -22,8 +22,8 @@ class MemoryBuffer; -#ifndef _COM_MemoryBuffer_h_ -#define _COM_MemoryBuffer_h_ +#ifndef __COM_MEMORYBUFFER_H__ +#define __COM_MEMORYBUFFER_H__ #include "COM_ExecutionGroup.h" #include "COM_MemoryProxy.h" diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h index b732db37db2..a628c09fa1f 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.h +++ b/source/blender/compositor/intern/COM_MemoryProxy.h @@ -23,8 +23,8 @@ class MemoryProxy; -#ifndef _COM_MemoryProxy_h_ -#define _COM_MemoryProxy_h_ +#ifndef __COM_MEMORYPROXY_H__ +#define __COM_MEMORYPROXY_H__ #include "COM_ExecutionGroup.h" class ExecutionGroup; diff --git a/source/blender/compositor/intern/COM_NodeConverter.h b/source/blender/compositor/intern/COM_NodeConverter.h index 825c26bb7af..4fb6b70ad1b 100644 --- a/source/blender/compositor/intern/COM_NodeConverter.h +++ b/source/blender/compositor/intern/COM_NodeConverter.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_NodeCompiler_h -#define _COM_NodeCompiler_h +#ifndef __COM_NODECONVERTER_H__ +#define __COM_NODECONVERTER_H__ #ifdef WITH_CXX_GUARDEDALLOC # include "MEM_guardedalloc.h" @@ -118,4 +118,4 @@ private: #endif }; -#endif /* _COM_NodeCompiler_h */ +#endif /* __COM_NODECONVERTER_H__ */ diff --git a/source/blender/compositor/intern/COM_NodeGraph.h b/source/blender/compositor/intern/COM_NodeGraph.h index 7c6322d2a42..4513a7721d6 100644 --- a/source/blender/compositor/intern/COM_NodeGraph.h +++ b/source/blender/compositor/intern/COM_NodeGraph.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_NodeGraph_h -#define _COM_NodeGraph_h +#ifndef __COM_NODEGRAPH_H__ +#define __COM_NODEGRAPH_H__ #include #include @@ -113,4 +113,4 @@ protected: #endif }; -#endif /* _COM_NodeGraph_h */ +#endif /* __COM_NODEGRAPH_H__ */ diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 5ee3cc22b53..9ab9156e7e4 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Operation_h -#define _COM_Operation_h +#ifndef __COM_NODEOPERATION_H__ +#define __COM_NODEOPERATION_H__ #include #include diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h index 0eafd27b46a..71622b1e9bb 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_NodeCompilerImpl_h -#define _COM_NodeCompilerImpl_h +#ifndef __COM_NODEOPERATIONBUILDER_H__ +#define __COM_NODEOPERATIONBUILDER_H__ #include #include @@ -167,4 +167,4 @@ private: #endif }; -#endif /* _COM_NodeCompilerImpl_h */ +#endif /* __COM_NODEOPERATIONBUILDER_H__ */ diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h index fa358f65ddf..a3a5cd36902 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.h +++ b/source/blender/compositor/intern/COM_OpenCLDevice.h @@ -22,8 +22,8 @@ class OpenCLDevice; -#ifndef _COM_OpenCLDevice_h -#define _COM_OpenCLDevice_h +#ifndef __COM_OPENCLDEVICE_H__ +#define __COM_OPENCLDEVICE_H__ #include "COM_Device.h" #include "clew.h" diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.h b/source/blender/compositor/intern/COM_SingleThreadedOperation.h index e0dc06ef733..b582e47dba7 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedOperation.h +++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SingleThreadedOperation_h -#define _COM_SingleThreadedOperation_h +#ifndef __COM_SINGLETHREADEDOPERATION_H__ +#define __COM_SINGLETHREADEDOPERATION_H__ #include "COM_NodeOperation.h" class SingleThreadedOperation : public NodeOperation { diff --git a/source/blender/compositor/intern/COM_SocketReader.h b/source/blender/compositor/intern/COM_SocketReader.h index ff72d925184..af6b891e7ab 100644 --- a/source/blender/compositor/intern/COM_SocketReader.h +++ b/source/blender/compositor/intern/COM_SocketReader.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SocketReader_h -#define _COM_SocketReader_h +#ifndef __COM_SOCKETREADER_H__ +#define __COM_SOCKETREADER_H__ #include "BLI_rect.h" #include "COM_defines.h" @@ -121,4 +121,4 @@ public: #endif }; -#endif /* _COM_SocketReader_h */ +#endif /* __COM_SOCKETREADER_H__ */ diff --git a/source/blender/compositor/intern/COM_WorkPackage.h b/source/blender/compositor/intern/COM_WorkPackage.h index 970a69b38d8..b0a74a1b0ee 100644 --- a/source/blender/compositor/intern/COM_WorkPackage.h +++ b/source/blender/compositor/intern/COM_WorkPackage.h @@ -22,8 +22,8 @@ class WorkPackage; -#ifndef _COM_WorkPackage_h_ -#define _COM_WorkPackage_h_ +#ifndef __COM_WORKPACKAGE_H__ +#define __COM_WORKPACKAGE_H__ class ExecutionGroup; #include "COM_ExecutionGroup.h" diff --git a/source/blender/compositor/intern/COM_WorkScheduler.h b/source/blender/compositor/intern/COM_WorkScheduler.h index 14b02e70913..a08b3856a8b 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.h +++ b/source/blender/compositor/intern/COM_WorkScheduler.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_WorkScheduler_h_ -#define _COM_WorkScheduler_h_ +#ifndef __COM_WORKSCHEDULER_H__ +#define __COM_WORKSCHEDULER_H__ #include "COM_ExecutionGroup.h" extern "C" { @@ -120,4 +120,4 @@ public: #endif }; -#endif /* _COM_WorkScheduler_h_ */ +#endif /* __COM_WORKSCHEDULER_H__ */ diff --git a/source/blender/compositor/nodes/COM_AlphaOverNode.h b/source/blender/compositor/nodes/COM_AlphaOverNode.h index b1fe85cf800..0af2ea3310d 100644 --- a/source/blender/compositor/nodes/COM_AlphaOverNode.h +++ b/source/blender/compositor/nodes/COM_AlphaOverNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_AlphaOverNode_h_ -#define _COM_AlphaOverNode_h_ +#ifndef __COM_ALPHAOVERNODE_H__ +#define __COM_ALPHAOVERNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BilateralBlurNode.h b/source/blender/compositor/nodes/COM_BilateralBlurNode.h index 6d13cd5b96a..babb558e0d1 100644 --- a/source/blender/compositor/nodes/COM_BilateralBlurNode.h +++ b/source/blender/compositor/nodes/COM_BilateralBlurNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BilateralBlurNode_h_ -#define _COM_BilateralBlurNode_h_ +#ifndef __COM_BILATERALBLURNODE_H__ +#define __COM_BILATERALBLURNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BlurNode.h b/source/blender/compositor/nodes/COM_BlurNode.h index fecba9c0eef..9a5f5ea1efd 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.h +++ b/source/blender/compositor/nodes/COM_BlurNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BlurNode_h_ -#define _COM_BlurNode_h_ +#ifndef __COM_BLURNODE_H__ +#define __COM_BLURNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.h b/source/blender/compositor/nodes/COM_BokehBlurNode.h index 2c8d52ad277..48cd661a7bf 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.h +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BokehBlurNode_h_ -#define _COM_BokehBlurNode_h_ +#ifndef __COM_BOKEHBLURNODE_H__ +#define __COM_BOKEHBLURNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BokehImageNode.h b/source/blender/compositor/nodes/COM_BokehImageNode.h index 36ee1300661..70f363b8cf6 100644 --- a/source/blender/compositor/nodes/COM_BokehImageNode.h +++ b/source/blender/compositor/nodes/COM_BokehImageNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BokehImageNode_h_ -#define _COM_BokehImageNode_h_ +#ifndef __COM_BOKEHIMAGENODE_H__ +#define __COM_BOKEHIMAGENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BoxMaskNode.h b/source/blender/compositor/nodes/COM_BoxMaskNode.h index 8229aa58ac1..01557229be9 100644 --- a/source/blender/compositor/nodes/COM_BoxMaskNode.h +++ b/source/blender/compositor/nodes/COM_BoxMaskNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BoxMaskNode_h_ -#define _COM_BoxMaskNode_h_ +#ifndef __COM_BOXMASKNODE_H__ +#define __COM_BOXMASKNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.h b/source/blender/compositor/nodes/COM_BrightnessNode.h index bacd3510517..27155e27774 100644 --- a/source/blender/compositor/nodes/COM_BrightnessNode.h +++ b/source/blender/compositor/nodes/COM_BrightnessNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BrightnessNode_h_ -#define _COM_BrightnessNode_h_ +#ifndef __COM_BRIGHTNESSNODE_H__ +#define __COM_BRIGHTNESSNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index f528578e6dd..c5f062cb215 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ChannelMatteNode_h_ -#define _COM_ChannelMatteNode_h_ +#ifndef __COM_CHANNELMATTENODE_H__ +#define __COM_CHANNELMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index d1eb3a907ef..7d0b34ecf5d 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ChromaMatteNode_h_ -#define _COM_ChromaMatteNode_h_ +#ifndef __COM_CHROMAMATTENODE_H__ +#define __COM_CHROMAMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index 1244dbbb7c5..d203fef20f4 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorBalanceNode_h_ -#define _COM_ColorBalanceNode_h_ +#ifndef __COM_COLORBALANCENODE_H__ +#define __COM_COLORBALANCENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h index d943136ceb8..fcbd7631cb4 100644 --- a/source/blender/compositor/nodes/COM_ColorCorrectionNode.h +++ b/source/blender/compositor/nodes/COM_ColorCorrectionNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorCorrectionNode_h_ -#define _COM_ColorCorrectionNode_h_ +#ifndef __COM_COLORCORRECTIONNODE_H__ +#define __COM_COLORCORRECTIONNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.h b/source/blender/compositor/nodes/COM_ColorCurveNode.h index 0f99625e31a..ad51611d1cf 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.h +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorCurveNode_h_ -#define _COM_ColorCurveNode_h_ +#ifndef __COM_COLORCURVENODE_H__ +#define __COM_COLORCURVENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index c17d3eb6c4e..f2c3c08beea 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ColorMatteNode_h_ -#define _COM_ColorMatteNode_h_ +#ifndef __COM_COLORMATTENODE_H__ +#define __COM_COLORMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorNode.h b/source/blender/compositor/nodes/COM_ColorNode.h index d03c910bfd2..205f4d07135 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.h +++ b/source/blender/compositor/nodes/COM_ColorNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorNode_h_ -#define _COM_ColorNode_h_ +#ifndef __COM_COLORNODE_H__ +#define __COM_COLORNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index c5e6b2f6154..4332d831e31 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorRampNode_h_ -#define _COM_ColorRampNode_h_ +#ifndef __COM_COLORRAMPNODE_H__ +#define __COM_COLORRAMPNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index 7442d2b0261..cb2cd8a2ea3 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorSpillNode_h_ -#define _COM_ColorSpillNode_h_ +#ifndef __COM_COLORSPILLNODE_H__ +#define __COM_COLORSPILLNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ColorToBWNode.h b/source/blender/compositor/nodes/COM_ColorToBWNode.h index 350ab88513d..05f937eb555 100644 --- a/source/blender/compositor/nodes/COM_ColorToBWNode.h +++ b/source/blender/compositor/nodes/COM_ColorToBWNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorToBWNode_h_ -#define _COM_ColorToBWNode_h_ +#ifndef __COM_COLORTOBWNODE_H__ +#define __COM_COLORTOBWNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.h b/source/blender/compositor/nodes/COM_CombineColorNode.h index d5439e0056c..030224e16f9 100644 --- a/source/blender/compositor/nodes/COM_CombineColorNode.h +++ b/source/blender/compositor/nodes/COM_CombineColorNode.h @@ -21,8 +21,8 @@ * Lukas Toenne */ -#ifndef _COM_CombineColorNode_h_ -#define _COM_CombineColorNode_h_ +#ifndef __COM_COMBINECOLORNODE_H__ +#define __COM_COMBINECOLORNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_CompositorNode.h b/source/blender/compositor/nodes/COM_CompositorNode.h index 4e96eb63776..a21013f2ce2 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.h +++ b/source/blender/compositor/nodes/COM_CompositorNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CompositorNode_h_ -#define _COM_CompositorNode_h_ +#ifndef __COM_COMPOSITORNODE_H__ +#define __COM_COMPOSITORNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h index 5bc5169b6d9..37482d66269 100644 --- a/source/blender/compositor/nodes/COM_ConvertAlphaNode.h +++ b/source/blender/compositor/nodes/COM_ConvertAlphaNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ConvertAlphaNode_h_ -#define _COM_ConvertAlphaNode_h_ +#ifndef __COM_CONVERTALPHANODE_H__ +#define __COM_CONVERTALPHANODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_CornerPinNode.h b/source/blender/compositor/nodes/COM_CornerPinNode.h index 70e48e41d6b..63428fa653b 100644 --- a/source/blender/compositor/nodes/COM_CornerPinNode.h +++ b/source/blender/compositor/nodes/COM_CornerPinNode.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_CornerPinNode_h -#define _COM_CornerPinNode_h +#ifndef __COM_CORNERPINNODE_H__ +#define __COM_CORNERPINNODE_H__ #include "COM_Node.h" @@ -38,4 +38,4 @@ public: void convertToOperations(NodeConverter &converter, const CompositorContext &context) const; }; -#endif /* _COM_CornerPinNode_h */ +#endif /* __COM_CORNERPINNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_CropNode.h b/source/blender/compositor/nodes/COM_CropNode.h index d33243b915a..a7d529c426f 100644 --- a/source/blender/compositor/nodes/COM_CropNode.h +++ b/source/blender/compositor/nodes/COM_CropNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CropNode_h_ -#define _COM_CropNode_h_ +#ifndef __COM_CROPNODE_H__ +#define __COM_CROPNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.h b/source/blender/compositor/nodes/COM_CryptomatteNode.h index 0ee3c1740b3..2e1784dedb9 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.h +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.h @@ -19,8 +19,8 @@ * Lukas Stockner */ -#ifndef _COM_CryptomatteNode_h_ -#define _COM_CryptomatteNode_h_ +#ifndef __COM_CRYPTOMATTENODE_H__ +#define __COM_CRYPTOMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DefocusNode.h b/source/blender/compositor/nodes/COM_DefocusNode.h index 917499ee93a..99efdd15b37 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.h +++ b/source/blender/compositor/nodes/COM_DefocusNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DefocusNode_h_ -#define _COM_DefocusNode_h_ +#ifndef __COM_DEFOCUSNODE_H__ +#define __COM_DEFOCUSNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DespeckleNode.h b/source/blender/compositor/nodes/COM_DespeckleNode.h index 64d99db7ded..e8097be35dd 100644 --- a/source/blender/compositor/nodes/COM_DespeckleNode.h +++ b/source/blender/compositor/nodes/COM_DespeckleNode.h @@ -18,8 +18,8 @@ * Contributor: Campbell Barton */ -#ifndef _COM_DespeckleNode_h_ -#define _COM_DespeckleNode_h_ +#ifndef __COM_DESPECKLENODE_H__ +#define __COM_DESPECKLENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 98fb917e152..ea3da8d2fca 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DifferenceMatteNode_h_ -#define _COM_DifferenceMatteNode_h_ +#ifndef __COM_DIFFERENCEMATTENODE_H__ +#define __COM_DIFFERENCEMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.h b/source/blender/compositor/nodes/COM_DilateErodeNode.h index 560087da30a..aff3ecbb4b0 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.h +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DilateErodeNode_h_ -#define _COM_DilateErodeNode_h_ +#ifndef __COM_DILATEERODENODE_H__ +#define __COM_DILATEERODENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h index 720ac32005e..eef51e140bc 100644 --- a/source/blender/compositor/nodes/COM_DirectionalBlurNode.h +++ b/source/blender/compositor/nodes/COM_DirectionalBlurNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DirectionalBlurNode_h_ -#define _COM_DirectionalBlurNode_h_ +#ifndef __COM_DIRECTIONALBLURNODE_H__ +#define __COM_DIRECTIONALBLURNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DisplaceNode.h b/source/blender/compositor/nodes/COM_DisplaceNode.h index 6eb894077fc..28105fd5963 100644 --- a/source/blender/compositor/nodes/COM_DisplaceNode.h +++ b/source/blender/compositor/nodes/COM_DisplaceNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DisplaceNode_h_ -#define _COM_DisplaceNode_h_ +#ifndef __COM_DISPLACENODE_H__ +#define __COM_DISPLACENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index e7a514b79c4..e7bd3c57dfa 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DistanceMatteNode_h_ -#define _COM_DistanceMatteNode_h_ +#ifndef __COM_DISTANCEMATTENODE_H__ +#define __COM_DISTANCEMATTENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h index 4ee58e18c9b..91a23005128 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DoubleEdgeMaskNode_h_ -#define _COM_DoubleEdgeMaskNode_h_ +#ifndef __COM_DOUBLEEDGEMASKNODE_H__ +#define __COM_DOUBLEEDGEMASKNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_EllipseMaskNode.h b/source/blender/compositor/nodes/COM_EllipseMaskNode.h index 50c578c2d7b..e5e9861b2d9 100644 --- a/source/blender/compositor/nodes/COM_EllipseMaskNode.h +++ b/source/blender/compositor/nodes/COM_EllipseMaskNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_EllipseMaskNode_h_ -#define _COM_EllipseMaskNode_h_ +#ifndef __COM_ELLIPSEMASKNODE_H__ +#define __COM_ELLIPSEMASKNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_FlipNode.h b/source/blender/compositor/nodes/COM_FlipNode.h index 033f893ab76..8c9a78df85d 100644 --- a/source/blender/compositor/nodes/COM_FlipNode.h +++ b/source/blender/compositor/nodes/COM_FlipNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FlipNode_h_ -#define _COM_FlipNode_h_ +#ifndef __COM_FLIPNODE_H__ +#define __COM_FLIPNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_GammaNode.h b/source/blender/compositor/nodes/COM_GammaNode.h index 3b8a530edd9..8b6434b9c6a 100644 --- a/source/blender/compositor/nodes/COM_GammaNode.h +++ b/source/blender/compositor/nodes/COM_GammaNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GammaNode_h_ -#define _COM_GammaNode_h_ +#ifndef __COM_GAMMANODE_H__ +#define __COM_GAMMANODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_GlareNode.h b/source/blender/compositor/nodes/COM_GlareNode.h index afc9ad3e6f3..93f92313835 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.h +++ b/source/blender/compositor/nodes/COM_GlareNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareNode_h_ -#define _COM_GlareNode_h_ +#ifndef __COM_GLARENODE_H__ +#define __COM_GLARENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h index cc425626608..f940a20e0da 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueCorrectNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_HueSaturationValueCorrectNode_h_ -#define _COM_HueSaturationValueCorrectNode_h_ +#ifndef __COM_HUESATURATIONVALUECORRECTNODE_H__ +#define __COM_HUESATURATIONVALUECORRECTNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h index 669cb6d2cff..f09164de34f 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.h +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_HueSaturationValueNode_h_ -#define _COM_HueSaturationValueNode_h_ +#ifndef __COM_HUESATURATIONVALUENODE_H__ +#define __COM_HUESATURATIONVALUENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_IDMaskNode.h b/source/blender/compositor/nodes/COM_IDMaskNode.h index 120d173e5c3..8a6e55a946e 100644 --- a/source/blender/compositor/nodes/COM_IDMaskNode.h +++ b/source/blender/compositor/nodes/COM_IDMaskNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_IDMaskNode_h_ -#define _COM_IDMaskNode_h_ +#ifndef __COM_IDMASKNODE_H__ +#define __COM_IDMASKNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_InpaintNode.h b/source/blender/compositor/nodes/COM_InpaintNode.h index 6c167ed90ff..dcc563234be 100644 --- a/source/blender/compositor/nodes/COM_InpaintNode.h +++ b/source/blender/compositor/nodes/COM_InpaintNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_InpaintNode_h_ -#define _COM_InpaintNode_h_ +#ifndef __COM_INPAINTNODE_H__ +#define __COM_INPAINTNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_InvertNode.h b/source/blender/compositor/nodes/COM_InvertNode.h index a946799ce67..9ca774e7600 100644 --- a/source/blender/compositor/nodes/COM_InvertNode.h +++ b/source/blender/compositor/nodes/COM_InvertNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_InvertNode_h_ -#define _COM_InvertNode_h_ +#ifndef __COM_INVERTNODE_H__ +#define __COM_INVERTNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.h b/source/blender/compositor/nodes/COM_LensDistortionNode.h index 231de6a5175..ee0f9f1bc06 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.h +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_LensDistortionNode_h_ -#define _COM_LensDistortionNode_h_ +#ifndef __COM_LENSDISTORTIONNODE_H__ +#define __COM_LENSDISTORTIONNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_MapUVNode.h b/source/blender/compositor/nodes/COM_MapUVNode.h index 286ec4205f1..245a31ce83c 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.h +++ b/source/blender/compositor/nodes/COM_MapUVNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_MapUVNode_h_ -#define _COM_MapUVNode_h_ +#ifndef __COM_MAPUVNODE_H__ +#define __COM_MAPUVNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_MathNode.h b/source/blender/compositor/nodes/COM_MathNode.h index 4c84dc2a331..cf92765f6da 100644 --- a/source/blender/compositor/nodes/COM_MathNode.h +++ b/source/blender/compositor/nodes/COM_MathNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MathNode_h_ -#define _COM_MathNode_h_ +#ifndef __COM_MATHNODE_H__ +#define __COM_MATHNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_MixNode.h b/source/blender/compositor/nodes/COM_MixNode.h index e5424c2f4e5..10954080a51 100644 --- a/source/blender/compositor/nodes/COM_MixNode.h +++ b/source/blender/compositor/nodes/COM_MixNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MixNode_h_ -#define _COM_MixNode_h_ +#ifndef __COM_MIXNODE_H__ +#define __COM_MIXNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_MovieDistortionNode.h b/source/blender/compositor/nodes/COM_MovieDistortionNode.h index 5ef0115bbaa..97cfaec57c8 100644 --- a/source/blender/compositor/nodes/COM_MovieDistortionNode.h +++ b/source/blender/compositor/nodes/COM_MovieDistortionNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MovieDistortionNode_h_ -#define _COM_MovieDistortionNode_h_ +#ifndef __COM_MOVIEDISTORTIONNODE_H__ +#define __COM_MOVIEDISTORTIONNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index c9b37580eca..4e1dbe55360 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_NormalNode_h_ -#define _COM_NormalNode_h_ +#ifndef __COM_NORMALNODE_H__ +#define __COM_NORMALNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_NormalizeNode.h b/source/blender/compositor/nodes/COM_NormalizeNode.h index a0eb7c9f5a9..02f413c6ae4 100644 --- a/source/blender/compositor/nodes/COM_NormalizeNode.h +++ b/source/blender/compositor/nodes/COM_NormalizeNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_NormalizeNode_h_ -#define _COM_NormalizeNode_h_ +#ifndef __COM_NORMALIZENODE_H__ +#define __COM_NORMALIZENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.h b/source/blender/compositor/nodes/COM_OutputFileNode.h index b321572d638..b246dd2a541 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.h +++ b/source/blender/compositor/nodes/COM_OutputFileNode.h @@ -21,8 +21,8 @@ * Lukas Tönne */ -#ifndef _COM_OutputFileNode_h_ -#define _COM_OutputFileNode_h_ +#ifndef __COM_OUTPUTFILENODE_H__ +#define __COM_OUTPUTFILENODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_PixelateNode.h b/source/blender/compositor/nodes/COM_PixelateNode.h index 06ac886c843..b43c15b01da 100644 --- a/source/blender/compositor/nodes/COM_PixelateNode.h +++ b/source/blender/compositor/nodes/COM_PixelateNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_PixelateNode_h_ -#define _COM_PixelateNode_h_ +#ifndef __COM_PIXELATENODE_H__ +#define __COM_PIXELATENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_RotateNode.h b/source/blender/compositor/nodes/COM_RotateNode.h index e897c9a49df..e3c9710891b 100644 --- a/source/blender/compositor/nodes/COM_RotateNode.h +++ b/source/blender/compositor/nodes/COM_RotateNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_RotateNode_h_ -#define _COM_RotateNode_h_ +#ifndef __COM_ROTATENODE_H__ +#define __COM_ROTATENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ScaleNode.h b/source/blender/compositor/nodes/COM_ScaleNode.h index 614866d2318..b1695aab966 100644 --- a/source/blender/compositor/nodes/COM_ScaleNode.h +++ b/source/blender/compositor/nodes/COM_ScaleNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ScaleNode_h_ -#define _COM_ScaleNode_h_ +#ifndef __COM_SCALENODE_H__ +#define __COM_SCALENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.h b/source/blender/compositor/nodes/COM_SeparateColorNode.h index 0e47a98a1aa..a1ec23b71c7 100644 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.h +++ b/source/blender/compositor/nodes/COM_SeparateColorNode.h @@ -21,8 +21,8 @@ * Lukas Toenne */ -#ifndef _COM_SeparateColorNode_h_ -#define _COM_SeparateColorNode_h_ +#ifndef __COM_SEPARATECOLORNODE_H__ +#define __COM_SEPARATECOLORNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_SetAlphaNode.h b/source/blender/compositor/nodes/COM_SetAlphaNode.h index efc8ccf1f27..f71d743c1d4 100644 --- a/source/blender/compositor/nodes/COM_SetAlphaNode.h +++ b/source/blender/compositor/nodes/COM_SetAlphaNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetAlphaNode_h_ -#define _COM_SetAlphaNode_h_ +#ifndef __COM_SETALPHANODE_H__ +#define __COM_SETALPHANODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h index faa458492cb..ce19a9abd7d 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SocketProxyNode_h_ -#define _COM_SocketProxyNode_h_ +#ifndef __COM_SOCKETPROXYNODE_H__ +#define __COM_SOCKETPROXYNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.h b/source/blender/compositor/nodes/COM_SplitViewerNode.h index 674067696ea..c073713f21f 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.h +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SplitViewerNode_h_ -#define _COM_SplitViewerNode_h_ +#ifndef __COM_SPLITVIEWERNODE_H__ +#define __COM_SPLITVIEWERNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.h b/source/blender/compositor/nodes/COM_Stabilize2dNode.h index d0b5f6e96f6..2859432fac7 100644 --- a/source/blender/compositor/nodes/COM_Stabilize2dNode.h +++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Stabilize2dNode_h_ -#define _COM_Stabilize2dNode_h_ +#ifndef __COM_STABILIZE2DNODE_H__ +#define __COM_STABILIZE2DNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_SunBeamsNode.h b/source/blender/compositor/nodes/COM_SunBeamsNode.h index 4024eb276bc..425b97061ca 100644 --- a/source/blender/compositor/nodes/COM_SunBeamsNode.h +++ b/source/blender/compositor/nodes/COM_SunBeamsNode.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_SunBeamsNode_h_ -#define _COM_SunBeamsNode_h_ +#ifndef __COM_SUNBEAMSNODE_H__ +#define __COM_SUNBEAMSNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_SwitchNode.h b/source/blender/compositor/nodes/COM_SwitchNode.h index 37ba73528f3..5967bbd5dd0 100644 --- a/source/blender/compositor/nodes/COM_SwitchNode.h +++ b/source/blender/compositor/nodes/COM_SwitchNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SwitchNode_h_ -#define _COM_SwitchNode_h_ +#ifndef __COM_SWITCHNODE_H__ +#define __COM_SWITCHNODE_H__ #include "COM_Node.h" #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.h b/source/blender/compositor/nodes/COM_SwitchViewNode.h index 6ab5145bed5..f4171940880 100644 --- a/source/blender/compositor/nodes/COM_SwitchViewNode.h +++ b/source/blender/compositor/nodes/COM_SwitchViewNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_SwitchViewNode_h_ -#define _COM_SwitchViewNode_h_ +#ifndef __COM_SWITCHVIEWNODE_H__ +#define __COM_SWITCHVIEWNODE_H__ #include "COM_Node.h" #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/nodes/COM_TimeNode.h b/source/blender/compositor/nodes/COM_TimeNode.h index 065c55f2780..7ebc6f2cc67 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.h +++ b/source/blender/compositor/nodes/COM_TimeNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TimeNode_h_ -#define _COM_TimeNode_h_ +#ifndef __COM_TIMENODE_H__ +#define __COM_TIMENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_TonemapNode.h b/source/blender/compositor/nodes/COM_TonemapNode.h index e504db4c014..13e51acf3fe 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.h +++ b/source/blender/compositor/nodes/COM_TonemapNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TonemapNode_h_ -#define _COM_TonemapNode_h_ +#ifndef __COM_TONEMAPNODE_H__ +#define __COM_TONEMAPNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_TranslateNode.h b/source/blender/compositor/nodes/COM_TranslateNode.h index 484f28b1089..51d969dbb04 100644 --- a/source/blender/compositor/nodes/COM_TranslateNode.h +++ b/source/blender/compositor/nodes/COM_TranslateNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TranslateNode_h_ -#define _COM_TranslateNode_h_ +#ifndef __COM_TRANSLATENODE_H__ +#define __COM_TRANSLATENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ValueNode.h b/source/blender/compositor/nodes/COM_ValueNode.h index b88c502be7f..e1b13c2d8aa 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.h +++ b/source/blender/compositor/nodes/COM_ValueNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ValueNode_h_ -#define _COM_ValueNode_h_ +#ifndef __COM_VALUENODE_H__ +#define __COM_VALUENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.h b/source/blender/compositor/nodes/COM_VectorBlurNode.h index 0e7ad015cc5..5f741ff0852 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.h +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_VectorBlurNode_h_ -#define _COM_VectorBlurNode_h_ +#ifndef __COM_VECTORBLURNODE_H__ +#define __COM_VECTORBLURNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_VectorCurveNode.h b/source/blender/compositor/nodes/COM_VectorCurveNode.h index 8cf76cff206..d8a2121a7c6 100644 --- a/source/blender/compositor/nodes/COM_VectorCurveNode.h +++ b/source/blender/compositor/nodes/COM_VectorCurveNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_VectorCurveNode_h_ -#define _COM_VectorCurveNode_h_ +#ifndef __COM_VECTORCURVENODE_H__ +#define __COM_VECTORCURVENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.h b/source/blender/compositor/nodes/COM_ViewLevelsNode.h index c56c6b0cef1..7fca060389a 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.h +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ViewLevelsNode_h_ -#define _COM_ViewLevelsNode_h_ +#ifndef __COM_VIEWLEVELSNODE_H__ +#define __COM_VIEWLEVELSNODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/nodes/COM_ViewerNode.h b/source/blender/compositor/nodes/COM_ViewerNode.h index 1f2cb02dcd6..67d6387a17c 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.h +++ b/source/blender/compositor/nodes/COM_ViewerNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ViewerNode_h_ -#define _COM_ViewerNode_h_ +#ifndef __COM_VIEWERNODE_H__ +#define __COM_VIEWERNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.h b/source/blender/compositor/nodes/COM_ZCombineNode.h index 9a438d6dde3..8e166ddf168 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.h +++ b/source/blender/compositor/nodes/COM_ZCombineNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ZCombineNode_h_ -#define _COM_ZCombineNode_h_ +#ifndef __COM_ZCOMBINENODE_H__ +#define __COM_ZCOMBINENODE_H__ #include "COM_Node.h" diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h index 144c60f2966..569c18888d8 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_AlphaOverKeyOperation_h -#define _COM_AlphaOverKeyOperation_h +#ifndef __COM_ALPHAOVERKEYOPERATION_H__ +#define __COM_ALPHAOVERKEYOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h index a76bf12481d..a5174f0839a 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_AlphaOverMixedOperation_h_ -#define _COM_AlphaOverMixedOperation_h_ +#ifndef __COM_ALPHAOVERMIXEDOPERATION_H__ +#define __COM_ALPHAOVERMIXEDOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h index 8551dba7b7c..e52971222ab 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_AlphaOverPremultiplyOperation_h -#define _COM_AlphaOverPremultiplyOperation_h +#ifndef __COM_ALPHAOVERPREMULTIPLYOPERATION_H__ +#define __COM_ALPHAOVERPREMULTIPLYOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h index a6f74eb214c..34243cd34b6 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.h +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_AntiAliasOperation_h -#define _COM_AntiAliasOperation_h +#ifndef __COM_ANTIALIASOPERATION_H__ +#define __COM_ANTIALIASOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h index 1a57b170c9a..8b3cfcafcef 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.h +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BlurBaseOperation_h -#define _COM_BlurBaseOperation_h +#ifndef __COM_BLURBASEOPERATION_H__ +#define __COM_BLURBASEOPERATION_H__ #include "COM_NodeOperation.h" #include "COM_QualityStepHelper.h" diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h index 6f2001566ea..c6ca7054352 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.h +++ b/source/blender/compositor/operations/COM_BokehImageOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BokehImageOperation_h -#define _COM_BokehImageOperation_h +#ifndef __COM_BOKEHIMAGEOPERATION_H__ +#define __COM_BOKEHIMAGEOPERATION_H__ #include "COM_NodeOperation.h" /** diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.h b/source/blender/compositor/operations/COM_BoxMaskOperation.h index 292e3a9391f..399b7dd393b 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.h +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BoxMaskOperation_h -#define _COM_BoxMaskOperation_h +#ifndef __COM_BOXMASKOPERATION_H__ +#define __COM_BOXMASKOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h index 8bda13ea418..1ebccf761a7 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.h +++ b/source/blender/compositor/operations/COM_BrightnessOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_BrightnessOperation_h -#define _COM_BrightnessOperation_h +#ifndef __COM_BRIGHTNESSOPERATION_H__ +#define __COM_BRIGHTNESSOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.h b/source/blender/compositor/operations/COM_CalculateMeanOperation.h index d7d927791b2..1872cb738b2 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.h +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CalculateMeanOperation_h -#define _COM_CalculateMeanOperation_h +#ifndef __COM_CALCULATEMEANOPERATION_H__ +#define __COM_CALCULATEMEANOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h index dfeaa7297a8..7089e40b210 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CalculateStandardDeviationOperation_h -#define _COM_CalculateStandardDeviationOperation_h +#ifndef __COM_CALCULATESTANDARDDEVIATIONOPERATION_H__ +#define __COM_CALCULATESTANDARDDEVIATIONOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_CalculateMeanOperation.h" diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h index 9685a298607..16c4a0cca07 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ChangeHSVOperation_h -#define _COM_ChangeHSVOperation_h +#ifndef __COM_CHANGEHSVOPERATION_H__ +#define __COM_CHANGEHSVOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h index 58b467e7892..46ef7809492 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ChannelMatteOperation_h -#define _COM_ChannelMatteOperation_h +#ifndef __COM_CHANNELMATTEOPERATION_H__ +#define __COM_CHANNELMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h index a68790838c0..ba7f207b1c6 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ChromaMatteOperation_h -#define _COM_ChromaMatteOperation_h +#ifndef __COM_CHROMAMATTEOPERATION_H__ +#define __COM_CHROMAMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h index 44981a2c957..77a5dd55cd9 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorBalanceASCCDLOperation_h -#define _COM_ColorBalanceASCCDLOperation_h +#ifndef __COM_COLORBALANCEASCCDLOPERATION_H__ +#define __COM_COLORBALANCEASCCDLOPERATION_H__ #include "COM_NodeOperation.h" /** diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h index 97fc8b6f870..3dbe2e11058 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorBalanceLGGOperation_h -#define _COM_ColorBalanceLGGOperation_h +#ifndef __COM_COLORBALANCELGGOPERATION_H__ +#define __COM_COLORBALANCELGGOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h index 7c7ccf2db9b..9b691dcb050 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.h +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorCorrectionOperation_h -#define _COM_ColorCorrectionOperation_h +#ifndef __COM_COLORCORRECTIONOPERATION_H__ +#define __COM_COLORCORRECTIONOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.h b/source/blender/compositor/operations/COM_ColorCurveOperation.h index 17c94feed5f..16e3455ceec 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.h +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorCurveOperation_h -#define _COM_ColorCurveOperation_h +#ifndef __COM_COLORCURVEOPERATION_H__ +#define __COM_COLORCURVEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_color_types.h" #include "COM_CurveBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h index 53bbe8f6466..0ceedd23efd 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.h +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_ColorMatteOperation_h -#define _COM_ColorMatteOperation_h +#ifndef __COM_COLORMATTEOPERATION_H__ +#define __COM_COLORMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.h b/source/blender/compositor/operations/COM_ColorRampOperation.h index 2d1919bb4b5..ff6d32fc4e6 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.h +++ b/source/blender/compositor/operations/COM_ColorRampOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorRampOperation_h -#define _COM_ColorRampOperation_h +#ifndef __COM_COLORRAMPOPERATION_H__ +#define __COM_COLORRAMPOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_texture_types.h" diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.h b/source/blender/compositor/operations/COM_ColorSpillOperation.h index 5971db9fa76..519e9a22335 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.h +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ColorSpillOperation_h -#define _COM_ColorSpillOperation_h +#ifndef __COM_COLORSPILLOPERATION_H__ +#define __COM_COLORSPILLOPERATION_H__ #include "COM_NodeOperation.h" /** diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index e7f2bc7d2c6..19ed3180ace 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CompositorOperation_h -#define _COM_CompositorOperation_h +#ifndef __COM_COMPOSITOROPERATION_H__ +#define __COM_COMPOSITOROPERATION_H__ #include "COM_NodeOperation.h" #include "BLI_rect.h" #include "BLI_string.h" diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h index 47f9f20f393..3dc7b67df8d 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ConvertColorProfileOperation_h -#define _COM_ConvertColorProfileOperation_h +#ifndef __COM_CONVERTCOLORPROFILEOPERATION_H__ +#define __COM_CONVERTCOLORPROFILEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h index 65db1cf45d9..5294d04352e 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ConvertDepthToRadiusOperation_h -#define _COM_ConvertDepthToRadiusOperation_h +#ifndef __COM_CONVERTDEPTHTORADIUSOPERATION_H__ +#define __COM_CONVERTDEPTHTORADIUSOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_object_types.h" #include "COM_FastGaussianBlurOperation.h" diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h index 9c23cc9bda7..2bbe14d6c17 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.h +++ b/source/blender/compositor/operations/COM_ConvertOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ConvertOperation_h -#define _COM_ConvertOperation_h +#ifndef __COM_CONVERTOPERATION_H__ +#define __COM_CONVERTOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h index 650d3ddda58..4689a5b34f1 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ConvolutionEdgeFilterOperation_h_ -#define _COM_ConvolutionEdgeFilterOperation_h_ +#ifndef __COM_CONVOLUTIONEDGEFILTEROPERATION_H__ +#define __COM_CONVOLUTIONEDGEFILTEROPERATION_H__ #include "COM_ConvolutionFilterOperation.h" diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h index 99e6fc52ddc..20b8be3278d 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ConvolutionFilterOperation_h_ -#define _COM_ConvolutionFilterOperation_h_ +#ifndef __COM_CONVOLUTIONFILTEROPERATION_H__ +#define __COM_CONVOLUTIONFILTEROPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_CropOperation.h b/source/blender/compositor/operations/COM_CropOperation.h index f73b4c602f6..0e0f25a2bf6 100644 --- a/source/blender/compositor/operations/COM_CropOperation.h +++ b/source/blender/compositor/operations/COM_CropOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CropOperation_h_ -#define _COM_CropOperation_h_ +#ifndef __COM_CROPOPERATION_H__ +#define __COM_CROPOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.h b/source/blender/compositor/operations/COM_CryptomatteOperation.h index 9ce02c048b3..250c5ab8a49 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.h +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.h @@ -18,8 +18,8 @@ * Contributor: Lukas Stockner, Stefan Werner */ -#ifndef _COM_CryptomatteOperation_h -#define _COM_CryptomatteOperation_h +#ifndef __COM_CRYPTOMATTEOPERATION_H__ +#define __COM_CRYPTOMATTEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.h b/source/blender/compositor/operations/COM_CurveBaseOperation.h index 191cf7f5307..1eb943dcc51 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.h +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_CurveBaseOperation_h -#define _COM_CurveBaseOperation_h +#ifndef __COM_CURVEBASEOPERATION_H__ +#define __COM_CURVEBASEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_color_types.h" diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.h b/source/blender/compositor/operations/COM_DespeckleOperation.h index 00c5463c17a..4ae0e8525d1 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.h +++ b/source/blender/compositor/operations/COM_DespeckleOperation.h @@ -18,8 +18,8 @@ * Contributor: Campbell Barton */ -#ifndef _COM_DespeckleOperation_h -#define _COM_DespeckleOperation_h +#ifndef __COM_DESPECKLEOPERATION_H__ +#define __COM_DESPECKLEOPERATION_H__ #include "COM_NodeOperation.h" class DespeckleOperation : public NodeOperation { diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h index 3766f85444d..3ea27f85eb6 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.h +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DifferenceMatteOperation_h -#define _COM_DifferenceMatteOperation_h +#ifndef __COM_DIFFERENCEMATTEOPERATION_H__ +#define __COM_DIFFERENCEMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.h b/source/blender/compositor/operations/COM_DilateErodeOperation.h index 92c453d9d85..56dcbb9b4a6 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.h +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DilateErodeOperation_h -#define _COM_DilateErodeOperation_h +#ifndef __COM_DILATEERODEOPERATION_H__ +#define __COM_DILATEERODEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h index 680f2606692..5a30f897203 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DisplaceOperation_h -#define _COM_DisplaceOperation_h +#ifndef __COM_DISPLACEOPERATION_H__ +#define __COM_DISPLACEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h index b3da61722ec..c0bd6bacdd4 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DisplaceSimpleOperation_h -#define _COM_DisplaceSimpleOperation_h +#ifndef __COM_DISPLACESIMPLEOPERATION_H__ +#define __COM_DISPLACESIMPLEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h index 22bc10b7bc3..0b45b0b75e9 100644 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DistanceRGBMatteOperation_h -#define _COM_DistanceRGBMatteOperation_h +#ifndef __COM_DISTANCERGBMATTEOPERATION_H__ +#define __COM_DISTANCERGBMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h index 27025188d49..afff1414d7a 100644 --- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h +++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_DistanceYCCMatteOperation_h -#define _COM_DistanceYCCMatteOperation_h +#ifndef __COM_DISTANCEYCCMATTEOPERATION_H__ +#define __COM_DISTANCEYCCMATTEOPERATION_H__ #include "COM_MixOperation.h" #include "COM_DistanceRGBMatteOperation.h" diff --git a/source/blender/compositor/operations/COM_DotproductOperation.h b/source/blender/compositor/operations/COM_DotproductOperation.h index 0fbefd716eb..43e38ee7c78 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.h +++ b/source/blender/compositor/operations/COM_DotproductOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DotproductOperation_h_ -#define _COM_DotproductOperation_h_ +#ifndef __COM_DOTPRODUCTOPERATION_H__ +#define __COM_DOTPRODUCTOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h index 4574454dd02..1e5a3bb52a5 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_DoubleEdgeMaskOperation_h -#define _COM_DoubleEdgeMaskOperation_h +#ifndef __COM_DOUBLEEDGEMASKOPERATION_H__ +#define __COM_DOUBLEEDGEMASKOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h index 9de9fb3e11c..59451d2046a 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_EllipseMaskOperation_h -#define _COM_EllipseMaskOperation_h +#ifndef __COM_ELLIPSEMASKOPERATION_H__ +#define __COM_ELLIPSEMASKOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index ae92b1ee095..840849d6126 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FastGaussianBlurOperation_h -#define _COM_FastGaussianBlurOperation_h +#ifndef __COM_FASTGAUSSIANBLUROPERATION_H__ +#define __COM_FASTGAUSSIANBLUROPERATION_H__ #include "COM_BlurBaseOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_FlipOperation.h b/source/blender/compositor/operations/COM_FlipOperation.h index e577259fea4..039f3af5064 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.h +++ b/source/blender/compositor/operations/COM_FlipOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FlipOperation_h_ -#define _COM_FlipOperation_h_ +#ifndef __COM_FLIPOPERATION_H__ +#define __COM_FLIPOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.h b/source/blender/compositor/operations/COM_GammaCorrectOperation.h index aabfe09fbf2..e9b6691349b 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.h +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GammaCorrectOperation_h -#define _COM_GammaCorrectOperation_h +#ifndef __COM_GAMMACORRECTOPERATION_H__ +#define __COM_GAMMACORRECTOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_GammaOperation.h b/source/blender/compositor/operations/COM_GammaOperation.h index ce221965eb5..b51c86f7fd3 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.h +++ b/source/blender/compositor/operations/COM_GammaOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GammaOperation_h -#define _COM_GammaOperation_h +#ifndef __COM_GAMMAOPERATION_H__ +#define __COM_GAMMAOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h index 651e8d9e658..985f56e3ef6 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h @@ -21,8 +21,8 @@ * Campbell Barton */ -#ifndef _COM_GaussianAlphaXBlurOperation_h -#define _COM_GaussianAlphaXBlurOperation_h +#ifndef __COM_GAUSSIANALPHAXBLUROPERATION_H__ +#define __COM_GAUSSIANALPHAXBLUROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_BlurBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h index dc9e5607ae6..3935dcd6568 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h @@ -21,8 +21,8 @@ * Campbell Barton */ -#ifndef _COM_GaussianAlphaYBlurOperation_h -#define _COM_GaussianAlphaYBlurOperation_h +#ifndef __COM_GAUSSIANALPHAYBLUROPERATION_H__ +#define __COM_GAUSSIANALPHAYBLUROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_BlurBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h index 4ad57bda742..88d8ed44de6 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GaussianXBlurOperation_h -#define _COM_GaussianXBlurOperation_h +#ifndef __COM_GAUSSIANXBLUROPERATION_H__ +#define __COM_GAUSSIANXBLUROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_BlurBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h index da1adbd0ea7..5df77eb28ce 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GaussianYBlurOperation_h -#define _COM_GaussianYBlurOperation_h +#ifndef __COM_GAUSSIANYBLUROPERATION_H__ +#define __COM_GAUSSIANYBLUROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_BlurBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.h b/source/blender/compositor/operations/COM_GlareBaseOperation.h index 3f0893d895f..3fa676f4d31 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.h +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareBaseOperation_h -#define _COM_GlareBaseOperation_h +#ifndef __COM_GLAREBASEOPERATION_H__ +#define __COM_GLAREBASEOPERATION_H__ #include "COM_SingleThreadedOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h index 1231185a21a..5bfe40d3a23 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.h +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareFogGlowOperation_h -#define _COM_GlareFogGlowOperation_h +#ifndef __COM_GLAREFOGGLOWOPERATION_H__ +#define __COM_GLAREFOGGLOWOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_GlareBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.h b/source/blender/compositor/operations/COM_GlareGhostOperation.h index 7ce1048efe9..bff13d1bcce 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.h +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareGhostOperation_h -#define _COM_GlareGhostOperation_h +#ifndef __COM_GLAREGHOSTOPERATION_H__ +#define __COM_GLAREGHOSTOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_GlareBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h index 440f3ba147a..7f0cf7be46a 100644 --- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h +++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareSimpleStarOperation_h -#define _COM_GlareSimpleStarOperation_h +#ifndef __COM_GLARESIMPLESTAROPERATION_H__ +#define __COM_GLARESIMPLESTAROPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_GlareBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.h b/source/blender/compositor/operations/COM_GlareStreaksOperation.h index e629ac11623..0671c0b2557 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.h +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareStreaksOperation_h -#define _COM_GlareStreaksOperation_h +#ifndef __COM_GLARESTREAKSOPERATION_H__ +#define __COM_GLARESTREAKSOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_GlareBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.h b/source/blender/compositor/operations/COM_GlareThresholdOperation.h index 647cf74cdcf..9a922a5889c 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.h +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_GlareScaleOperation_h -#define _COM_GlareScaleOperation_h +#ifndef __COM_GLARETHRESHOLDOPERATION_H__ +#define __COM_GLARETHRESHOLDOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_lamp_types.h" diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h index 97bfc836ae2..2a749fef1f8 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_HueSaturationValueCorrectOperation_h -#define _COM_HueSaturationValueCorrectOperation_h +#ifndef __COM_HUESATURATIONVALUECORRECTOPERATION_H__ +#define __COM_HUESATURATIONVALUECORRECTOPERATION_H__ #include "COM_NodeOperation.h" #include "COM_CurveBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h index 89f9855303c..53c2fd154a0 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_IDMaskOperation_h -#define _COM_IDMaskOperation_h +#ifndef __COM_IDMASKOPERATION_H__ +#define __COM_IDMASKOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index 8ab93c2ba64..60172eb6413 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -21,8 +21,8 @@ */ -#ifndef _COM_ImageOperation_h -#define _COM_ImageOperation_h +#ifndef __COM_IMAGEOPERATION_H__ +#define __COM_IMAGEOPERATION_H__ #include "COM_NodeOperation.h" #include "BLI_listbase.h" diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h index fe8e2dd2a19..bd430a3690c 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.h +++ b/source/blender/compositor/operations/COM_InpaintOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_InpaintOperation_h -#define _COM_InpaintOperation_h +#ifndef __COM_INPAINTOPERATION_H__ +#define __COM_INPAINTOPERATION_H__ #include "COM_NodeOperation.h" class InpaintSimpleOperation : public NodeOperation { diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h index 4528895c282..2aeb33a76f5 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.h +++ b/source/blender/compositor/operations/COM_InvertOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_InvertOperation_h -#define _COM_InvertOperation_h +#ifndef __COM_INVERTOPERATION_H__ +#define __COM_INVERTOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.h b/source/blender/compositor/operations/COM_KeyingBlurOperation.h index a1c56cc9c07..2bea3ca8616 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.h +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_KeyingBlurOperation_h -#define _COM_KeyingBlurOperation_h +#ifndef __COM_KEYINGBLUROPERATION_H__ +#define __COM_KEYINGBLUROPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.h b/source/blender/compositor/operations/COM_KeyingClipOperation.h index d79bd14b900..e0571bf15cd 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.h +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_KeyingClipOperation_h -#define _COM_KeyingClipOperation_h +#ifndef __COM_KEYINGCLIPOPERATION_H__ +#define __COM_KEYINGCLIPOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.h b/source/blender/compositor/operations/COM_KeyingDespillOperation.h index da9924d5b4b..6b7fc82367b 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.h +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_KeyingDespillOperation_h -#define _COM_KeyingDespillOperation_h +#ifndef __COM_KEYINGDESPILLOPERATION_H__ +#define __COM_KEYINGDESPILLOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_KeyingOperation.h b/source/blender/compositor/operations/COM_KeyingOperation.h index e4542e2c6dd..a9f3034f6d1 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.h +++ b/source/blender/compositor/operations/COM_KeyingOperation.h @@ -22,8 +22,8 @@ */ -#ifndef _COM_KeyingOperation_h -#define _COM_KeyingOperation_h +#ifndef __COM_KEYINGOPERATION_H__ +#define __COM_KEYINGOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h index 45195b1e98d..25a3dcb6897 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h @@ -22,8 +22,8 @@ */ -#ifndef _COM_KeyingScreenOperation_h -#define _COM_KeyingScreenOperation_h +#ifndef __COM_KEYINGSCREENOPERATION_H__ +#define __COM_KEYINGSCREENOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h index 951c054d241..64d4638c5cd 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.h +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_LuminanceMatteOperation_h -#define _COM_LuminanceMatteOperation_h +#ifndef __COM_LUMINANCEMATTEOPERATION_H__ +#define __COM_LUMINANCEMATTEOPERATION_H__ #include "COM_MixOperation.h" diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.h b/source/blender/compositor/operations/COM_MapRangeOperation.h index 405faf3fb2c..6598c89a09c 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.h +++ b/source/blender/compositor/operations/COM_MapRangeOperation.h @@ -20,8 +20,8 @@ * Daniel Salazar */ -#ifndef _COM_MapRangeOperation_h -#define _COM_MapRangeOperation_h +#ifndef __COM_MAPRANGEOPERATION_H__ +#define __COM_MAPRANGEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_texture_types.h" diff --git a/source/blender/compositor/operations/COM_MapUVOperation.h b/source/blender/compositor/operations/COM_MapUVOperation.h index 1bb26bf14f0..599a07e1afa 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.h +++ b/source/blender/compositor/operations/COM_MapUVOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_MapUVOperation_h -#define _COM_MapUVOperation_h +#ifndef __COM_MAPUVOPERATION_H__ +#define __COM_MAPUVOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_MapValueOperation.h b/source/blender/compositor/operations/COM_MapValueOperation.h index 97528efca19..33513c6f39c 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.h +++ b/source/blender/compositor/operations/COM_MapValueOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MapValueOperation_h -#define _COM_MapValueOperation_h +#ifndef __COM_MAPVALUEOPERATION_H__ +#define __COM_MAPVALUEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_texture_types.h" diff --git a/source/blender/compositor/operations/COM_MaskOperation.h b/source/blender/compositor/operations/COM_MaskOperation.h index 522b873e167..a586a91682e 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.h +++ b/source/blender/compositor/operations/COM_MaskOperation.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_MaskOperation_h -#define _COM_MaskOperation_h +#ifndef __COM_MASKOPERATION_H__ +#define __COM_MASKOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index 5435cc82ba7..54fd3c5d2b9 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MathBaseOperation_h -#define _COM_MathBaseOperation_h +#ifndef __COM_MATHBASEOPERATION_H__ +#define __COM_MATHBASEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index fa13a486657..9063635fda0 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MixBaseOperation_h -#define _COM_MixBaseOperation_h +#ifndef __COM_MIXOPERATION_H__ +#define __COM_MIXOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h index 436b89a0dfb..9ac38da55d3 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MovieClipAttributeOperation_h -#define _COM_MovieClipAttributeOperation_h +#ifndef __COM_MOVIECLIPATTRIBUTEOPERATION_H__ +#define __COM_MOVIECLIPATTRIBUTEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_movieclip_types.h" diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index 28e6c0d0c3a..fae889ed202 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -21,8 +21,8 @@ */ -#ifndef _COM_ImageOperation_h -#define _COM_ImageOperation_h +#ifndef __COM_IMAGEOPERATION_H__ +#define __COM_IMAGEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_movieclip_types.h" diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index 689fcfe11ad..f09e9c29d01 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_MovieDistortionOperation_h_ -#define _COM_MovieDistortionOperation_h_ +#ifndef __COM_MOVIEDISTORTIONOPERATION_H__ +#define __COM_MOVIEDISTORTIONOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_movieclip_types.h" diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h index 2e68f922dd9..4074b80374f 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h @@ -22,8 +22,8 @@ */ -#ifndef _COM_MultilayerImageOperation_h -#define _COM_MultilayerImageOperation_h +#ifndef __COM_MULTILAYERIMAGEOPERATION_H__ +#define __COM_MULTILAYERIMAGEOPERATION_H__ #include "COM_ImageOperation.h" diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.h b/source/blender/compositor/operations/COM_NormalizeOperation.h index 32f39a4d9ca..de1a23926f4 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.h +++ b/source/blender/compositor/operations/COM_NormalizeOperation.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_NormalizeOperation_h -#define _COM_NormalizeOperation_h +#ifndef __COM_NORMALIZEOPERATION_H__ +#define __COM_NORMALIZEOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h index 25ed8816399..74ba8ff2226 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -22,8 +22,8 @@ * Dalai Felinto */ -#ifndef _COM_OutputFileMultiViewOperation_h -#define _COM_OutputFileMultiViewOperation_h +#ifndef __COM_OUTPUTFILEMULTIVIEWOPERATION_H__ +#define __COM_OUTPUTFILEMULTIVIEWOPERATION_H__ #include "COM_NodeOperation.h" #include "BLI_rect.h" diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index 32c9b5ab5b8..cc800ca222a 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -21,8 +21,8 @@ * Lukas Tönne */ -#ifndef _COM_OutputFileOperation_h -#define _COM_OutputFileOperation_h +#ifndef __COM_OUTPUTFILEOPERATION_H__ +#define __COM_OUTPUTFILEOPERATION_H__ #include "COM_NodeOperation.h" #include "BLI_rect.h" diff --git a/source/blender/compositor/operations/COM_PixelateOperation.h b/source/blender/compositor/operations/COM_PixelateOperation.h index 8e60baf7f05..5b08cb429f4 100644 --- a/source/blender/compositor/operations/COM_PixelateOperation.h +++ b/source/blender/compositor/operations/COM_PixelateOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_PixelateOperation_h_ -#define _COM_PixelateOperation_h_ +#ifndef __COM_PIXELATEOPERATION_H__ +#define __COM_PIXELATEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h index a9bd18299eb..980f57c4cea 100644 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h +++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.h @@ -20,8 +20,8 @@ * Lukas Toenne */ -#ifndef _COM_CornerPinWarpImageOperation_h -#define _COM_CornerPinWarpImageOperation_h +#ifndef __COM_PLANECORNERPINOPERATION_H__ +#define __COM_PLANECORNERPINOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h index fc5dd1ff7d8..adf13685b4a 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h @@ -20,8 +20,8 @@ * Sergey Sharybin */ -#ifndef _COM_PlaneTrackCommonOperation_h -#define _COM_PlaneTrackCommonOperation_h +#ifndef __COM_PLANEDISTORTCOMMONOPERATION_H__ +#define __COM_PLANEDISTORTCOMMONOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h index 41761493e12..493d9cb3be1 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h @@ -20,8 +20,8 @@ * Sergey Sharybin */ -#ifndef _COM_PlaneTrackWarpImageOperation_h -#define _COM_PlaneTrackWarpImageOperation_h +#ifndef __COM_PLANETRACKOPERATION_H__ +#define __COM_PLANETRACKOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 907a6c8997f..75317748897 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_PreviewOperation_h -#define _COM_PreviewOperation_h +#ifndef __COM_PREVIEWOPERATION_H__ +#define __COM_PREVIEWOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_image_types.h" #include "DNA_color_types.h" diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h index 12efff14839..79bd5586d8f 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ProjectorLensDistortionOperation_h -#define _COM_ProjectorLensDistortionOperation_h +#ifndef __COM_PROJECTORLENSDISTORTIONOPERATION_H__ +#define __COM_PROJECTORLENSDISTORTIONOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.h b/source/blender/compositor/operations/COM_QualityStepHelper.h index 9076e5a0776..67419cfbc87 100644 --- a/source/blender/compositor/operations/COM_QualityStepHelper.h +++ b/source/blender/compositor/operations/COM_QualityStepHelper.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_QualityStepHelper_h -#define _COM_QualityStepHelper_h +#ifndef __COM_QUALITYSTEPHELPER_H__ +#define __COM_QUALITYSTEPHELPER_H__ #include "COM_defines.h" typedef enum QualityHelper { diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h index c42de32b9e9..c73acbaf300 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.h +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ReadBufferOperation_h -#define _COM_ReadBufferOperation_h +#ifndef __COM_READBUFFEROPERATION_H__ +#define __COM_READBUFFEROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_MemoryProxy.h" diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index 90d57d422e3..2a0f7efc9f8 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -21,8 +21,8 @@ */ -#ifndef _COM_RenderLayersBaseProg_h -#define _COM_RenderLayersBaseProg_h +#ifndef __COM_RENDERLAYERSPROG_H__ +#define __COM_RENDERLAYERSPROG_H__ #include "COM_NodeOperation.h" #include "DNA_scene_types.h" diff --git a/source/blender/compositor/operations/COM_RotateOperation.h b/source/blender/compositor/operations/COM_RotateOperation.h index d332f7208b5..59fb92054e1 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.h +++ b/source/blender/compositor/operations/COM_RotateOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_RotateOperation_h_ -#define _COM_RotateOperation_h_ +#ifndef __COM_ROTATEOPERATION_H__ +#define __COM_ROTATEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 93f9827aabf..b4aecb1515d 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ScaleOperation_h_ -#define _COM_ScaleOperation_h_ +#ifndef __COM_SCALEOPERATION_H__ +#define __COM_SCALEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h index 963a9210b93..f89af962211 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ScreenLensDistortionOperation_h -#define _COM_ScreenLensDistortionOperation_h +#ifndef __COM_SCREENLENSDISTORTIONOPERATION_H__ +#define __COM_SCREENLENSDISTORTIONOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.h b/source/blender/compositor/operations/COM_SetAlphaOperation.h index c4e12a367a5..90deb69a67d 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.h +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetAlphaOperation_h -#define _COM_SetAlphaOperation_h +#ifndef __COM_SETALPHAOPERATION_H__ +#define __COM_SETALPHAOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h index f9fa06f5132..9a509f6fb0c 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.h +++ b/source/blender/compositor/operations/COM_SetColorOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetColorOperation_h -#define _COM_SetColorOperation_h +#ifndef __COM_SETCOLOROPERATION_H__ +#define __COM_SETCOLOROPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.h b/source/blender/compositor/operations/COM_SetSamplerOperation.h index 6d97b20769d..24b14a3ce48 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.h +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetSamplerOperation_h -#define _COM_SetSamplerOperation_h +#ifndef __COM_SETSAMPLEROPERATION_H__ +#define __COM_SETSAMPLEROPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h index a0867a3bc9c..4e274816f27 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.h +++ b/source/blender/compositor/operations/COM_SetValueOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetValueOperation_h -#define _COM_SetValueOperation_h +#ifndef __COM_SETVALUEOPERATION_H__ +#define __COM_SETVALUEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h index 79b55bb7d91..ca35784ff9a 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.h +++ b/source/blender/compositor/operations/COM_SetVectorOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SetVectorOperation_h -#define _COM_SetVectorOperation_h +#ifndef __COM_SETVECTOROPERATION_H__ +#define __COM_SETVECTOROPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h index 55cf6d376b7..61575ac6b2c 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.h +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SocketProxyOperation_h_ -#define _COM_SocketProxyOperation_h_ +#ifndef __COM_SOCKETPROXYOPERATION_H__ +#define __COM_SOCKETPROXYOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_SplitOperation.h b/source/blender/compositor/operations/COM_SplitOperation.h index 4375c760963..a7c7146ddea 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.h +++ b/source/blender/compositor/operations/COM_SplitOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_SplitOperation_h -#define _COM_SplitOperation_h +#ifndef __COM_SPLITOPERATION_H__ +#define __COM_SPLITOPERATION_H__ #include "COM_NodeOperation.h" class SplitOperation : public NodeOperation { diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h index ef80a31fe40..43846ab24d1 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.h +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.h @@ -19,8 +19,8 @@ * Lukas Toenne */ -#ifndef _COM_SunBeamsOperation_h -#define _COM_SunBeamsOperation_h +#ifndef __COM_SUNBEAMSOPERATION_H__ +#define __COM_SUNBEAMSOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index 26d50ca1753..9f0f539800d 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -21,8 +21,8 @@ */ -#ifndef _COM_TextureOperation_h -#define _COM_TextureOperation_h +#ifndef __COM_TEXTUREOPERATION_H__ +#define __COM_TEXTUREOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_texture_types.h" diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h index 6fcf72c9d14..2b07ded7305 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.h +++ b/source/blender/compositor/operations/COM_TonemapOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TonemapOperation_h -#define _COM_TonemapOperation_h +#ifndef __COM_TONEMAPOPERATION_H__ +#define __COM_TONEMAPOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.h b/source/blender/compositor/operations/COM_TrackPositionOperation.h index 87bb0623ad5..add6ccd3459 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.h +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.h @@ -22,8 +22,8 @@ */ -#ifndef _COM_TrackPositionOperation_h -#define _COM_TrackPositionOperation_h +#ifndef __COM_TRACKPOSITIONOPERATION_H__ +#define __COM_TRACKPOSITIONOPERATION_H__ #include diff --git a/source/blender/compositor/operations/COM_TranslateOperation.h b/source/blender/compositor/operations/COM_TranslateOperation.h index f3708ef3c7c..1c54ec62284 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.h +++ b/source/blender/compositor/operations/COM_TranslateOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TranslateOperation_h_ -#define _COM_TranslateOperation_h_ +#ifndef __COM_TRANSLATEOPERATION_H__ +#define __COM_TRANSLATEOPERATION_H__ #include "COM_NodeOperation.h" diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.h b/source/blender/compositor/operations/COM_VectorBlurOperation.h index 30ca2f644bb..a33761166c6 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.h +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_VectorBlurOperation_h -#define _COM_VectorBlurOperation_h +#ifndef __COM_VECTORBLUROPERATION_H__ +#define __COM_VECTORBLUROPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_node_types.h" #include "COM_QualityStepHelper.h" diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.h b/source/blender/compositor/operations/COM_VectorCurveOperation.h index 518e4713c99..a5c1cb6d446 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.h +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_VectorCurveOperation_h -#define _COM_VectorCurveOperation_h +#ifndef __COM_VECTORCURVEOPERATION_H__ +#define __COM_VECTORCURVEOPERATION_H__ #include "COM_NodeOperation.h" #include "COM_CurveBaseOperation.h" diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index 0e4bff2c4e8..43e305fb291 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ViewerOperation_h -#define _COM_ViewerOperation_h +#ifndef __COM_VIEWEROPERATION_H__ +#define __COM_VIEWEROPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_image_types.h" #include "BLI_rect.h" diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h index 4a17b29ede8..4b8d1d8846b 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.h +++ b/source/blender/compositor/operations/COM_WrapOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_WrapOperation_h_ -#define _COM_WrapOperation_h_ +#ifndef __COM_WRAPOPERATION_H__ +#define __COM_WRAPOPERATION_H__ #include "COM_ReadBufferOperation.h" diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h index 73314c947f5..583d58e7b99 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.h +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_WriteBufferOperation_h_ -#define _COM_WriteBufferOperation_h_ +#ifndef __COM_WRITEBUFFEROPERATION_H__ +#define __COM_WRITEBUFFEROPERATION_H__ #include "COM_NodeOperation.h" #include "COM_MemoryProxy.h" diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h index c9d26adfc46..be6fb0fe576 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_ZCombineOperation_h -#define _COM_ZCombineOperation_h +#ifndef __COM_ZCOMBINEOPERATION_H__ +#define __COM_ZCOMBINEOPERATION_H__ #include "COM_MixOperation.h" -- cgit v1.2.3 From bb8497fd5d4a647c0b7221ed965dc58c9547a820 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 13:10:53 +1000 Subject: Cleanup: correct header guard Header guard was duplicated before renaming. --- source/blender/compositor/operations/COM_MovieClipOperation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index fae889ed202..2b696cd5df6 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -21,8 +21,8 @@ */ -#ifndef __COM_IMAGEOPERATION_H__ -#define __COM_IMAGEOPERATION_H__ +#ifndef __COM_MOVIECLIPOPERATION_H__ +#define __COM_MOVIECLIPOPERATION_H__ #include "COM_NodeOperation.h" #include "DNA_movieclip_types.h" -- cgit v1.2.3 From c252a7c37a3b03799962dd9324fea609648761bc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 13:30:27 +1000 Subject: UI: don't show pie menu w/ no active object Addresses T56272 --- source/blender/editors/space_view3d/view3d_buttons.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 8fa327d8782..38fac7cb37d 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -60,6 +60,7 @@ #include "BKE_deform.h" #include "BKE_object.h" #include "BKE_object_deform.h" +#include "BKE_report.h" #include "DEG_depsgraph.h" @@ -1223,10 +1224,14 @@ void VIEW3D_OT_properties(wmOperatorType *ot) ot->flag = 0; } -static int view3d_object_mode_menu(bContext *C, wmOperator *UNUSED(op)) +static int view3d_object_mode_menu(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); - if (ob && ((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) { + if (ob == NULL) { + BKE_report(op->reports, RPT_WARNING, "No active object found"); + return OPERATOR_CANCELLED; + } + else if (((ob->mode & OB_MODE_EDIT) == 0) && (ELEM(ob->type, OB_ARMATURE))) { ED_object_mode_toggle(C, OB_MODE_POSE); return OPERATOR_CANCELLED; } -- cgit v1.2.3 From 0cd2eb11ee1762aed076e1f45cbb66d25c90ae17 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 13:56:53 +1000 Subject: UV: stitch multi-object support D3561 by @Al --- .../blender/editors/uvedit/uvedit_smart_stitch.c | 990 +++++++++++++-------- 1 file changed, 627 insertions(+), 363 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 18f1bc872c0..a5e18851f12 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -54,6 +54,7 @@ #include "BKE_customdata.h" #include "BKE_mesh_mapping.h" #include "BKE_editmesh.h" +#include "BKE_layer.h" #include "DEG_depsgraph.h" @@ -150,20 +151,11 @@ typedef struct UvEdge { /* stitch state object */ typedef struct StitchState { float aspect; - /* use limit flag */ - bool use_limit; - /* limit to operator, same as original operator */ - float limit_dist; - /* snap uv islands together during stitching */ - bool snap_islands; - /* stitch at midpoints or at islands */ - bool midpoints; /* object for editmesh */ Object *obedit; /* editmesh, cached for use in modal handler */ BMEditMesh *em; - /* clear seams of stitched edges after stitch */ - bool clear_seams; + /* element map for getting info about uv connectivity */ UvElementMap *element_map; /* edge container */ @@ -178,6 +170,8 @@ typedef struct StitchState { UvEdge *edges; /* hash for quick lookup of edges */ GHash *edge_hash; + /* which islands to stop at (to make active) when pressing 'I' */ + bool *island_is_stitchable; /* count of separate uvs and edges */ int total_separate_edges; @@ -185,18 +179,39 @@ typedef struct StitchState { /* hold selection related information */ void **selection_stack; int selection_size; - /* island that stays in place */ - int static_island; + /* store number of primitives per face so that we can allocate the active island buffer later */ unsigned int *tris_per_island; + /* preview data */ + StitchPreviewer *stitch_preview; +} StitchState; +/* Stitch state container. */ +typedef struct StitchStateContainer { + /* clear seams of stitched edges after stitch */ + bool clear_seams; + /* use limit flag */ + bool use_limit; + /* limit to operator, same as original operator */ + float limit_dist; + /* snap uv islands together during stitching */ + bool snap_islands; + /* stitch at midpoints or at islands */ + bool midpoints; /* vert or edge mode used for stitching */ char mode; /* handle for drawing */ void *draw_handle; - /* preview data */ - StitchPreviewer *stitch_preview; -} StitchState; + /* island that stays in place */ + int static_island; + + /* Objects and states are aligned. */ + int objects_len; + Object **objects; + StitchState **states; + + int active_object_index; +} StitchStateContainer; typedef struct PreviewPosition { int data_position; @@ -270,7 +285,7 @@ static void stitch_preview_delete(StitchPreviewer *stitch_preview) } /* This function updates the header of the UV editor when the stitch tool updates its settings */ -static void stitch_update_header(StitchState *state, bContext *C) +static void stitch_update_header(StitchStateContainer *ssc, bContext *C) { const char *str = IFACE_( "Mode(TAB) %s, " @@ -285,12 +300,13 @@ static void stitch_update_header(StitchState *state, bContext *C) ScrArea *sa = CTX_wm_area(C); if (sa) { - BLI_snprintf(msg, sizeof(msg), str, - state->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"), - WM_bool_as_string(state->snap_islands), - WM_bool_as_string(state->midpoints), - state->limit_dist, - WM_bool_as_string(state->use_limit)); + BLI_snprintf( + msg, sizeof(msg), str, + ssc->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"), + WM_bool_as_string(ssc->snap_islands), + WM_bool_as_string(ssc->midpoints), + ssc->limit_dist, + WM_bool_as_string(ssc->use_limit)); ED_workspace_status_text(C, msg); } @@ -320,7 +336,9 @@ static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], } /* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */ -static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) +static bool stitch_check_uvs_stitchable( + UvElement *element, UvElement *element_iter, + StitchStateContainer *ssc, StitchState *state) { BMesh *bm = state->em->bm; float limit; @@ -329,9 +347,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i return 0; } - limit = state->limit_dist; + limit = ssc->limit_dist; - if (state->use_limit) { + if (ssc->use_limit) { MLoopUV *luv, *luv_iter; BMLoop *l; @@ -355,7 +373,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i } } -static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +static bool stitch_check_edges_stitchable( + UvEdge *edge, UvEdge *edge_iter, + StitchStateContainer *ssc, StitchState *state) { BMesh *bm = state->em->bm; float limit; @@ -364,9 +384,9 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc return 0; } - limit = state->limit_dist; + limit = ssc->limit_dist; - if (state->use_limit) { + if (ssc->use_limit) { BMLoop *l; MLoopUV *luv_orig1, *luv_iter1; MLoopUV *luv_orig2, *luv_iter2; @@ -397,27 +417,30 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc } } -static bool stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) +static bool stitch_check_uvs_state_stitchable( + UvElement *element, UvElement *element_iter, + StitchStateContainer *ssc, StitchState *state) { - if ((state->snap_islands && element->island == element_iter->island) || - (!state->midpoints && element->island == element_iter->island)) + if ((ssc->snap_islands && element->island == element_iter->island) || + (!ssc->midpoints && element->island == element_iter->island)) { return 0; } - return stitch_check_uvs_stitchable(element, element_iter, state); + return stitch_check_uvs_stitchable(element, element_iter, ssc, state); } - -static bool stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +static bool stitch_check_edges_state_stitchable( + UvEdge *edge, UvEdge *edge_iter, + StitchStateContainer *ssc, StitchState *state) { - if ((state->snap_islands && edge->element->island == edge_iter->element->island) || - (!state->midpoints && edge->element->island == edge_iter->element->island)) + if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) || + (!ssc->midpoints && edge->element->island == edge_iter->element->island)) { return 0; } - return stitch_check_edges_stitchable(edge, edge_iter, state); + return stitch_check_edges_stitchable(edge, edge_iter, ssc, state); } /* calculate snapping for islands */ @@ -506,8 +529,8 @@ static void stitch_calculate_island_snapping( static void stitch_island_calculate_edge_rotation( - UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, - IslandStitchData *island_stitch_data) + UvEdge *edge, StitchStateContainer *ssc, StitchState *state, UVVertAverage *uv_average, + unsigned int *uvfinal_map, IslandStitchData *island_stitch_data) { BMesh *bm = state->em->bm; UvElement *element1, *element2; @@ -523,7 +546,7 @@ static void stitch_island_calculate_edge_rotation( luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV); luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV); - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { index1 = uvfinal_map[element1 - state->element_map->buf]; index2 = uvfinal_map[element2 - state->element_map->buf]; } @@ -562,7 +585,7 @@ static void stitch_island_calculate_edge_rotation( static void stitch_island_calculate_vert_rotation( - UvElement *element, StitchState *state, + UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data) { float edgecos = 1.0f, edgesin = 0.0f; @@ -572,7 +595,7 @@ static void stitch_island_calculate_vert_rotation( int rot_elem = 0, rot_elem_neg = 0; BMLoop *l; - if (element->island == state->static_island && !state->midpoints) + if (element->island == ssc->static_island && !ssc->midpoints) return; l = element->l; @@ -582,12 +605,12 @@ static void stitch_island_calculate_vert_rotation( element_iter = state->element_map->vert[index]; for (; element_iter; element_iter = element_iter->next) { - if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) { + if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { int index_tmp1, index_tmp2; float normal[2]; /* only calculate rotation against static island uv verts */ - if (!state->midpoints && element_iter->island != state->static_island) + if (!ssc->midpoints && element_iter->island != ssc->static_island) continue; index_tmp1 = element_iter - state->element_map->buf; @@ -609,7 +632,7 @@ static void stitch_island_calculate_vert_rotation( } } - if (state->midpoints) { + if (ssc->midpoints) { rotation /= 2.0f; rotation_neg /= 2.0f; } @@ -623,6 +646,9 @@ static void stitch_island_calculate_vert_rotation( static void state_delete(StitchState *state) { if (state) { + if (state->island_is_stitchable) { + MEM_freeN(state->island_is_stitchable); + } if (state->element_map) { BM_uv_element_map_free(state->element_map); } @@ -654,6 +680,18 @@ static void state_delete(StitchState *state) } } +static void state_delete_all(StitchStateContainer *ssc) +{ + if (ssc) { + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + state_delete(ssc->states[ob_index]); + } + MEM_freeN(ssc->states); + MEM_freeN(ssc->objects); + MEM_freeN(ssc); + } +} + static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state) { UvEdge *edges = state->edges; @@ -736,7 +774,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */ static void determine_uv_stitchability( - UvElement *element, StitchState *state, + UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data) { int vert_index; @@ -750,7 +788,7 @@ static void determine_uv_stitchability( for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { - if (stitch_check_uvs_stitchable(element, element_iter, state)) { + if (stitch_check_uvs_stitchable(element, element_iter, ssc, state)) { island_stitch_data[element_iter->island].stitchableCandidate = 1; island_stitch_data[element->island].stitchableCandidate = 1; element->flag |= STITCH_STITCHABLE_CANDIDATE; @@ -760,13 +798,13 @@ static void determine_uv_stitchability( } static void determine_uv_edge_stitchability( - UvEdge *edge, StitchState *state, + UvEdge *edge, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data) { UvEdge *edge_iter = edge->first; for (; edge_iter; edge_iter = edge_iter->next) { - if (stitch_check_edges_stitchable(edge, edge_iter, state)) { + if (stitch_check_edges_stitchable(edge, edge_iter, ssc, state)) { island_stitch_data[edge_iter->element->island].stitchableCandidate = 1; island_stitch_data[edge->element->island].stitchableCandidate = 1; edge->flag |= STITCH_STITCHABLE_CANDIDATE; @@ -791,16 +829,16 @@ static void stitch_set_face_preview_buffer_position( /* setup face preview for all coincident uvs and their faces */ static void stitch_setup_face_preview_for_uv_group( - UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, - PreviewPosition *preview_position) + UvElement *element, StitchStateContainer *ssc, StitchState *state, + IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { StitchPreviewer *preview = state->stitch_preview; /* static island does not change so returning immediately */ - if (state->snap_islands && !state->midpoints && state->static_island == element->island) + if (ssc->snap_islands && !ssc->midpoints && ssc->static_island == element->island) return; - if (state->snap_islands) { + if (ssc->snap_islands) { island_stitch_data[element->island].addedForPreview = 1; } @@ -813,11 +851,18 @@ static void stitch_setup_face_preview_for_uv_group( /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */ static void stitch_validate_uv_stitchability( - UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, - PreviewPosition *preview_position) + UvElement *element, StitchStateContainer *ssc, StitchState *state, + IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { - UvElement *element_iter; StitchPreviewer *preview = state->stitch_preview; + + /* If not the active object, then it's unstitchable */ + if (ssc->states[ssc->active_object_index] != state) { + preview->num_unstitchable++; + return; + } + + UvElement *element_iter; int vert_index; BMLoop *l; @@ -831,11 +876,11 @@ static void stitch_validate_uv_stitchability( if (element_iter->separate) { if (element_iter == element) continue; - if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { - if ((element_iter->island == state->static_island) || (element->island == state->static_island)) { + if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { + if ((element_iter->island == ssc->static_island) || (element->island == ssc->static_island)) { element->flag |= STITCH_STITCHABLE; preview->num_stitchable++; - stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(element, ssc, state, island_stitch_data, preview_position); return; } } @@ -850,21 +895,28 @@ static void stitch_validate_uv_stitchability( static void stitch_validate_edge_stitchability( - UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data, - PreviewPosition *preview_position) + UvEdge *edge, StitchStateContainer *ssc, StitchState *state, + IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { - UvEdge *edge_iter = edge->first; StitchPreviewer *preview = state->stitch_preview; + /* If not the active object, then it's unstitchable */ + if (ssc->states[ssc->active_object_index] != state) { + preview->num_unstitchable++; + return; + } + + UvEdge *edge_iter = edge->first; + for (; edge_iter; edge_iter = edge_iter->next) { if (edge_iter == edge) continue; - if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) { - if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) { + if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) { + if ((edge_iter->element->island == ssc->static_island) || (edge->element->island == ssc->static_island)) { edge->flag |= STITCH_STITCHABLE; preview->num_stitchable++; - stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position); - stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], ssc, state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], ssc, state, island_stitch_data, preview_position); return; } } @@ -880,7 +932,7 @@ static void stitch_validate_edge_stitchability( static void stitch_propagate_uv_final_position( Scene *scene, UvElement *element, int index, PreviewPosition *preview_position, - UVVertAverage *final_position, StitchState *state, + UVVertAverage *final_position, StitchStateContainer *ssc, StitchState *state, const bool final) { BMesh *bm = state->em->bm; @@ -909,12 +961,12 @@ static void stitch_propagate_uv_final_position( int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position; if (face_preview_pos != STITCH_NO_PREVIEW) { copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->loop_of_poly_index, - final_position[index].uv); + final_position[index].uv); } } /* end of calculations, keep only the selection flag */ - if ((!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) { + if ((!ssc->snap_islands) || ((!ssc->midpoints) && (element_iter->island == ssc->static_island))) { element_iter->flag &= STITCH_SELECTED; } @@ -924,18 +976,20 @@ static void stitch_propagate_uv_final_position( } /* main processing function. It calculates preview and final positions. */ -static int stitch_process_data(StitchState *state, Scene *scene, int final) +static int stitch_process_data( + StitchStateContainer *ssc, StitchState *state, Scene *scene, int final) { int i; StitchPreviewer *preview; IslandStitchData *island_stitch_data = NULL; - int previous_island = state->static_island; + int previous_island = ssc->static_island; BMesh *bm = state->em->bm; BMFace *efa; BMIter iter; UVVertAverage *final_position = NULL; + bool is_active_state = (state == ssc->states[ssc->active_object_index]); - char stitch_midpoints = state->midpoints; + char stitch_midpoints = ssc->midpoints; /* used to map uv indices to uvaverage indices for selection */ unsigned int *uvfinal_map = NULL; /* per face preview position in preview buffer */ @@ -966,32 +1020,41 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) *****************************************/ for (i = 0; i < state->selection_size; i++) { - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { UvElement *element = (UvElement *)state->selection_stack[i]; - determine_uv_stitchability(element, state, island_stitch_data); + determine_uv_stitchability(element, ssc, state, island_stitch_data); } else { UvEdge *edge = (UvEdge *)state->selection_stack[i]; - determine_uv_edge_stitchability(edge, state, island_stitch_data); + determine_uv_edge_stitchability(edge, ssc, state, island_stitch_data); } } - /* set static island to one that is added for preview */ - state->static_island %= state->element_map->totalIslands; - while (!(island_stitch_data[state->static_island].stitchableCandidate)) { - state->static_island++; - state->static_island %= state->element_map->totalIslands; - /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */ - if (state->static_island == previous_island) - break; + /* remember stitchable candidates as places the 'I' button */ + /* will stop at. */ + for (int island_idx = 0; island_idx < state->element_map->totalIslands; island_idx++) { + state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate?true:false; + } + + if (is_active_state) { + /* set static island to one that is added for preview */ + ssc->static_island %= state->element_map->totalIslands; + while (!(island_stitch_data[ssc->static_island].stitchableCandidate)) { + ssc->static_island++; + ssc->static_island %= state->element_map->totalIslands; + /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */ + if (ssc->static_island == previous_island) { + break; + } + } } for (i = 0; i < state->selection_size; i++) { - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { UvElement *element = (UvElement *)state->selection_stack[i]; if (element->flag & STITCH_STITCHABLE_CANDIDATE) { element->flag &= ~STITCH_STITCHABLE_CANDIDATE; - stitch_validate_uv_stitchability(element, state, island_stitch_data, preview_position); + stitch_validate_uv_stitchability(element, ssc, state, island_stitch_data, preview_position); } else { /* add to preview for unstitchable */ @@ -1002,7 +1065,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvEdge *edge = (UvEdge *)state->selection_stack[i]; if (edge->flag & STITCH_STITCHABLE_CANDIDATE) { edge->flag &= ~STITCH_STITCHABLE_CANDIDATE; - stitch_validate_edge_stitchability(edge, state, island_stitch_data, preview_position); + stitch_validate_edge_stitchability(edge, ssc, state, island_stitch_data, preview_position); } else { preview->num_unstitchable++; @@ -1010,10 +1073,90 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } } + /********************************************************************* + * Setup the stitchable & unstitchable preview buffers and fill * + * them with the appropriate data * + *********************************************************************/ + if (!final) { + BMLoop *l; + MLoopUV *luv; + int stitchBufferIndex = 0, unstitchBufferIndex = 0; + int preview_size = (ssc->mode == STITCH_VERT) ? 2 : 4; + /* initialize the preview buffers */ + preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data"); + preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data"); + + /* will cause cancel and freeing of all data structures so OK */ + if (!preview->preview_stitchable || !preview->preview_unstitchable) { + return 0; + } + + /* fill the appropriate preview buffers */ + if (ssc->mode == STITCH_VERT) { + for (i = 0; i < state->total_separate_uvs; i++) { + UvElement *element = (UvElement *)state->uvs[i]; + if (element->flag & STITCH_STITCHABLE) { + l = element->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); + + stitchBufferIndex++; + } + else if (element->flag & STITCH_SELECTED) { + l = element->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); + unstitchBufferIndex++; + } + } + } + else { + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + if (edge->flag & STITCH_STITCHABLE) { + l = element1->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv); + + stitchBufferIndex++; + BLI_assert(stitchBufferIndex <= preview->num_stitchable); + } + else if (edge->flag & STITCH_SELECTED) { + l = element1->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv); + + unstitchBufferIndex++; + BLI_assert(unstitchBufferIndex <= preview->num_unstitchable); + } + } + } + } + + if (ssc->states[ssc->active_object_index] != state) { + /* This is not the active object/state, exit here */ + MEM_freeN(island_stitch_data); + MEM_freeN(preview_position); + return 1; + } + /***************************************** * Setup preview for stitchable islands * *****************************************/ - if (state->snap_islands) { + if (ssc->snap_islands) { for (i = 0; i < state->element_map->totalIslands; i++) { if (island_stitch_data[i].addedForPreview) { int numOfIslandUVs = 0, j; @@ -1028,26 +1171,24 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /********************************************************************* - * Setup the preview buffers and fill them with the appropriate data * + * Setup the remaining preview buffers and fill them with the * + * appropriate data * *********************************************************************/ if (!final) { BMIter liter; BMLoop *l; MLoopUV *luv; unsigned int buffer_index = 0; - int stitchBufferIndex = 0, unstitchBufferIndex = 0; - int preview_size = (state->mode == STITCH_VERT) ? 2 : 4; + /* initialize the preview buffers */ preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev"); preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev"); - preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data"); - preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data"); - preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris"); + preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[ssc->static_island] * sizeof(float) * 6, "static_island_preview_tris"); - preview->num_static_tris = state->tris_per_island[state->static_island]; + preview->num_static_tris = state->tris_per_island[ssc->static_island]; /* will cause cancel and freeing of all data structures so OK */ - if (!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable) { + if (!preview->preview_polys) { return 0; } @@ -1068,7 +1209,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } } - if (element->island == state->static_island) { + /* if this is the static_island on the active object */ + if (element->island == ssc->static_island) { BMLoop *fl = BM_FACE_FIRST_LOOP(efa); MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV); @@ -1091,67 +1233,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } } } - - /* fill the appropriate preview buffers */ - if (state->mode == STITCH_VERT) { - for (i = 0; i < state->total_separate_uvs; i++) { - UvElement *element = (UvElement *)state->uvs[i]; - if (element->flag & STITCH_STITCHABLE) { - l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); - - stitchBufferIndex++; - } - else if (element->flag & STITCH_SELECTED) { - l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); - unstitchBufferIndex++; - } - } - } - else { - for (i = 0; i < state->total_separate_edges; i++) { - UvEdge *edge = state->edges + i; - UvElement *element1 = state->uvs[edge->uv1]; - UvElement *element2 = state->uvs[edge->uv2]; - - if (edge->flag & STITCH_STITCHABLE) { - l = element1->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); - - l = element2->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv); - - stitchBufferIndex++; - BLI_assert(stitchBufferIndex <= preview->num_stitchable); - } - else if (edge->flag & STITCH_SELECTED) { - l = element1->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); - - l = element2->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv); - - unstitchBufferIndex++; - BLI_assert(unstitchBufferIndex <= preview->num_unstitchable); - } - } - } } /****************************************************** * Here we calculate the final coordinates of the uvs * ******************************************************/ - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); } @@ -1161,7 +1249,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) /* first pass, calculate final position for stitchable uvs of the static island */ for (i = 0; i < state->selection_size; i++) { - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { UvElement *element = state->selection_stack[i]; if (element->flag & STITCH_STITCHABLE) { @@ -1177,21 +1265,21 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) copy_v2_v2(final_position[i].uv, luv->uv); final_position[i].count = 1; - if (state->snap_islands && element->island == state->static_island && !stitch_midpoints) + if (ssc->snap_islands && element->island == ssc->static_island && !stitch_midpoints) continue; element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; for ( ; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { - if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { + if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { l = element_iter->l; luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); if (stitch_midpoints) { add_v2_v2(final_position[i].uv, luv->uv); final_position[i].count++; } - else if (element_iter->island == state->static_island) { + else if (element_iter->island == ssc->static_island) { /* if multiple uvs on the static island exist, * last checked remains. to disambiguate we need to limit or use * edge stitch */ @@ -1227,11 +1315,11 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE; state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE; - if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints) + if (ssc->snap_islands && edge->element->island == ssc->static_island && !stitch_midpoints) continue; for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) { - if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) { + if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) { l = state->uvs[edge_iter->uv1]->l; luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); l = state->uvs[edge_iter->uv2]->l; @@ -1243,7 +1331,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) add_v2_v2(final_position[edge->uv2].uv, luv2->uv); final_position[edge->uv2].count++; } - else if (edge_iter->element->island == state->static_island) { + else if (edge_iter->element->island == ssc->static_island) { copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); } @@ -1254,7 +1342,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */ - if (state->mode == STITCH_EDGE && stitch_midpoints) { + if (ssc->mode == STITCH_EDGE && stitch_midpoints) { for (i = 0; i < state->total_separate_uvs; i++) { final_position[i].uv[0] /= final_position[i].count; final_position[i].uv[1] /= final_position[i].count; @@ -1262,8 +1350,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /* second pass, calculate island rotation and translation before modifying any uvs */ - if (state->snap_islands) { - if (state->mode == STITCH_VERT) { + if (ssc->snap_islands) { + if (ssc->mode == STITCH_VERT) { for (i = 0; i < state->selection_size; i++) { UvElement *element = state->selection_stack[i]; @@ -1291,13 +1379,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) { - stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); + stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, uvfinal_map, island_stitch_data); island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true; } } /* clear seams of stitched edges */ - if (final && state->clear_seams) { + if (final && ssc->clear_seams) { for (i = 0; i < state->total_separate_edges; i++) { UvEdge *edge = state->edges + i; if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && @@ -1312,7 +1400,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvElement *element = state->selection_stack[i]; if (!island_stitch_data[element->island].use_edge_rotation) { if (element->flag & STITCH_STITCHABLE) { - stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + stitch_island_calculate_vert_rotation(element, ssc, state, island_stitch_data); } } } @@ -1329,7 +1417,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); /* accumulate each islands' translation from stitchable elements. it is important to do here - * because in final pass MTFaces get modified and result is zero. */ + * because in final pass MTFaces get modified and result is zero. */ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; @@ -1342,13 +1430,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) UvEdge *edge = state->selection_stack[i]; if (edge->flag & STITCH_STITCHABLE) { - stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data); + stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, NULL, island_stitch_data); island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true; } } /* clear seams of stitched edges */ - if (final && state->clear_seams) { + if (final && ssc->clear_seams) { for (i = 0; i < state->selection_size; i++) { UvEdge *edge = state->selection_stack[i]; if (edge->flag & STITCH_STITCHABLE) { @@ -1361,30 +1449,30 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) /* third pass, propagate changes to coincident uvs */ for (i = 0; i < state->selection_size; i++) { - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { UvElement *element = state->selection_stack[i]; - stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, state, final); + stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, ssc, state, final); } else { UvEdge *edge = state->selection_stack[i]; stitch_propagate_uv_final_position( - scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final); + scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, ssc, state, final); stitch_propagate_uv_final_position( - scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final); + scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, ssc, state, final); edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY); } } /* final pass, calculate Island translation/rotation if needed */ - if (state->snap_islands) { + if (ssc->snap_islands) { stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final); } MEM_freeN(final_position); - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { MEM_freeN(uvfinal_map); } MEM_freeN(island_stitch_data); @@ -1393,6 +1481,17 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) return 1; } +static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int final) +{ + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + if (!stitch_process_data(ssc, ssc->states[ob_index], scene, final)) { + return 0; + } + } + + return 1; +} + /* Stitch hash initialization functions */ static unsigned int uv_edge_hash(const void *key) { @@ -1477,13 +1576,13 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_ } } -static void stitch_switch_selection_mode(StitchState *state) +static void stitch_set_selection_mode(StitchState *state, const char from_stitch_mode) { void **old_selection_stack = state->selection_stack; int old_selection_size = state->selection_size; state->selection_size = 0; - if (state->mode == STITCH_VERT) { + if (from_stitch_mode == STITCH_VERT) { int i; state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack), "stitch_new_edge_selection_stack"); @@ -1504,7 +1603,6 @@ static void stitch_switch_selection_mode(StitchState *state) element->flag &= ~STITCH_SELECTED; } - state->mode = STITCH_EDGE; } else { int i; @@ -1521,12 +1619,26 @@ static void stitch_switch_selection_mode(StitchState *state) edge->flag &= ~STITCH_SELECTED; } - state->mode = STITCH_VERT; } MEM_freeN(old_selection_stack); } -static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect) +static void stitch_switch_selection_mode_all(StitchStateContainer *ssc) +{ + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + stitch_set_selection_mode(ssc->states[ob_index], ssc->mode); + } + + if (ssc->mode == STITCH_VERT) { + ssc->mode = STITCH_EDGE; + } + else { + ssc->mode = STITCH_VERT; + } +} + +static void stitch_calculate_edge_normal( + BMEditMesh *em, UvEdge *edge, float *normal, float aspect) { BMLoop *l1 = edge->element->l; MLoopUV *luv1, *luv2; @@ -1535,7 +1647,7 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV); luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV); - sub_v2_v2v2(tangent, luv2->uv, luv1->uv); + sub_v2_v2v2(tangent, luv2->uv, luv1->uv); tangent[1] /= aspect; @@ -1559,111 +1671,120 @@ static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float /* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { - int j, index = 0; - unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0; - StitchState *state = (StitchState *)arg; - StitchPreviewer *stitch_preview = state->stitch_preview; - GPUVertBuf *vbo, *vbo_line; - float col[4]; - - static GPUVertFormat format = { 0 }; - static unsigned int pos_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - } - GPU_blend(true); + StitchStateContainer *ssc = (StitchStateContainer *)arg; - /* Static Tris */ - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col); - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3); - for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) { - GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]); - } - stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + int j, index = 0; + unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0; + StitchState *state = ssc->states[ob_index]; + StitchPreviewer *stitch_preview = state->stitch_preview; + GPUVertBuf *vbo, *vbo_line; + float col[4]; + static GPUVertFormat format = { 0 }; + static unsigned int pos_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + } - /* Preview Polys */ - for (int i = 0; i < stitch_preview->num_polys; i++) - num_line += stitch_preview->uvs_per_polygon[i]; + GPU_blend(true); - num_tri = num_line - 2 * stitch_preview->num_polys; + /* Static Tris */ + if (stitch_preview->static_tris) { + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3); + for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]); + } + stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); + } - /* we need to convert the polys into triangles / lines */ - vbo = GPU_vertbuf_create_with_format(&format); - vbo_line = GPU_vertbuf_create_with_format(&format); + /* Preview Polys */ + if (stitch_preview->preview_polys) { + for (int i = 0; i < stitch_preview->num_polys; i++) + num_line += stitch_preview->uvs_per_polygon[i]; - GPU_vertbuf_data_alloc(vbo, num_tri * 3); - GPU_vertbuf_data_alloc(vbo_line, num_line * 2); + num_tri = num_line - 2 * stitch_preview->num_polys; - for (int i = 0; i < stitch_preview->num_polys; i++) { - BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3); + /* we need to convert the polys into triangles / lines */ + vbo = GPU_vertbuf_create_with_format(&format); + vbo_line = GPU_vertbuf_create_with_format(&format); - /* Start line */ - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]); + GPU_vertbuf_data_alloc(vbo, num_tri * 3); + GPU_vertbuf_data_alloc(vbo_line, num_line * 2); - for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) { - GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]); - GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); - GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); - } + for (int i = 0; i < stitch_preview->num_polys; i++) { + BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3); - /* Closing line */ - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); - /* j = uvs_per_polygon[i] - 1*/ - GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]); + /* Start line */ + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]); - index += stitch_preview->uvs_per_polygon[i] * 2; - } - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col); - stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col); - stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col); + for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) { + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]); + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); + GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); - GPU_blend(false); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]); + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]); + } + /* Closing line */ + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]); + /* j = uvs_per_polygon[i] - 1*/ + GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]); - /* draw stitch vert/lines preview */ - if (state->mode == STITCH_VERT) { - GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f); + index += stitch_preview->uvs_per_polygon[i] * 2; + } - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable); - for (int i = 0; i < stitch_preview->num_stitchable; i++) { - GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col); + stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col); + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col); + stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col); } - stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable); - for (int i = 0; i < stitch_preview->num_unstitchable; i++) { - GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); - } - stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); - } - else { - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2); - for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) { - GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + GPU_blend(false); + + /* draw stitch vert/lines preview */ + if (ssc->mode == STITCH_VERT) { + GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f); + + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable); + for (int i = 0; i < stitch_preview->num_stitchable; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + } + stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); + + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable); + for (int i = 0; i < stitch_preview->num_unstitchable; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); + } + stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col); } - stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); + else { + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2); + for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]); + } + stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); - UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2); - for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) { - GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); + UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col); + vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2); + for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) { + GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]); + } + stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); } - stitch_draw_vbo(vbo, GPU_PRIM_LINES, col); } } @@ -1689,7 +1810,9 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state) return BLI_ghash_lookup(state->edge_hash, &tmp_edge); } -static int stitch_init(bContext *C, wmOperator *op) +static StitchState* stitch_init( + bContext *C, wmOperator *op, + StitchStateContainer *ssc, Object *obedit) { /* for fast edge lookup... */ GHash *edge_hash; @@ -1707,47 +1830,16 @@ static int stitch_init(bContext *C, wmOperator *op) StitchState *state; Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; - ARegion *ar = CTX_wm_region(C); float aspx, aspy; - Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - if (!ar) - return 0; - - state = MEM_callocN(sizeof(StitchState), "stitch state"); - - op->customdata = state; + state = MEM_callocN(sizeof(StitchState), "stitch state obj"); /* initialize state */ - state->use_limit = RNA_boolean_get(op->ptr, "use_limit"); - state->limit_dist = RNA_float_get(op->ptr, "limit"); state->obedit = obedit; state->em = em; - state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands"); - state->static_island = RNA_int_get(op->ptr, "static_island"); - state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); - state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); - if (RNA_struct_property_is_set(op->ptr, "mode")) { - state->mode = RNA_enum_get(op->ptr, "mode"); - } - else { - if (ts->uv_flag & UV_SYNC_SELECTION) { - if (ts->selectmode & SCE_SELECT_VERTEX) - state->mode = STITCH_VERT; - else - state->mode = STITCH_EDGE; - } - else { - if (ts->uv_selectmode & UV_SELECT_VERTEX) { - state->mode = STITCH_VERT; - } - else { - state->mode = STITCH_EDGE; - } - } - } /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -1758,16 +1850,12 @@ static int stitch_init(bContext *C, wmOperator *op) } if (!state->element_map) { state_delete(state); - return 0; + return NULL; } ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy); state->aspect = aspx / aspy; - /* Entirely possible if redoing last operator that static island is bigger than total number of islands. - * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */ - state->static_island %= state->element_map->totalIslands; - /* Count 'unique' uvs */ for (i = 0; i < state->element_map->totalUVs; i++) { if (state->element_map->buf[i].separate) { @@ -1786,11 +1874,11 @@ static int stitch_init(bContext *C, wmOperator *op) state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map"); /* Allocate the edge stack */ edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); - all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges"); + all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "ssc_edges"); if (!state->uvs || !map || !edge_hash || !all_edges) { state_delete(state); - return 0; + return NULL; } /* So that we can use this as index for the UvElements */ @@ -1859,7 +1947,7 @@ static int stitch_init(bContext *C, wmOperator *op) /* I assume any system will be able to at least allocate an iterator :p */ if (!edges) { state_delete(state); - return 0; + return NULL; } state->total_separate_edges = total_edges; @@ -1909,7 +1997,8 @@ static int stitch_init(bContext *C, wmOperator *op) state->selection_size = 0; /* Load old selection if redoing operator with different settings */ - if (RNA_struct_property_is_set(op->ptr, "selection")) { + /* WIP */ + if (false && RNA_struct_property_is_set(op->ptr, "selection")) { int faceIndex, elementIndex; UvElement *element; enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode"); @@ -1962,16 +2051,15 @@ static int stitch_init(bContext *C, wmOperator *op) } /* if user has switched the operator mode after operation, we need to convert * the stored format */ - if (state->mode != stored_mode) { - state->mode = stored_mode; - stitch_switch_selection_mode(state); + if (ssc->mode != stored_mode) { + stitch_set_selection_mode(state, stored_mode); } /* Clear the selection */ RNA_collection_clear(op->ptr, "selection"); } else { - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -2023,22 +2111,155 @@ static int stitch_init(bContext *C, wmOperator *op) } } - if (!stitch_process_data(state, scene, false)) { + state->island_is_stitchable = MEM_callocN(sizeof(bool) * state->element_map->totalIslands, "stitch I stops"); + if (!state->island_is_stitchable) { + state_delete(state); + return NULL; + } + if (!stitch_process_data(ssc, state, scene, false)) { state_delete(state); + return NULL; + } + + return state; +} + +static bool goto_next_island(StitchStateContainer *ssc) +{ + StitchState *active_state = ssc->states[ssc->active_object_index]; + StitchState *original_active_state = active_state; + + int original_island = ssc->static_island; + + do { + ssc->static_island++; + if (ssc->static_island >= active_state->element_map->totalIslands) { + /* go to next object */ + ssc->active_object_index++; + ssc->active_object_index %= ssc->objects_len; + + active_state = ssc->states[ssc->active_object_index]; + ssc->static_island = 0; + } + + if (active_state->island_is_stitchable[ssc->static_island]) { + /* We're at an island to make active */ + return true; + } + } while (!(active_state == original_active_state + && ssc->static_island == original_island)); + + return false; +} + +static int stitch_init_all(bContext *C, wmOperator *op) +{ + ARegion *ar = CTX_wm_region(C); + if (!ar) + return 0; + + Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; + + StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection"); + + op->customdata = ssc; + + ssc->use_limit = RNA_boolean_get(op->ptr, "use_limit"); + ssc->limit_dist = RNA_float_get(op->ptr, "limit"); + ssc->snap_islands = RNA_boolean_get(op->ptr, "snap_islands"); + ssc->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); + ssc->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); + ssc->active_object_index = RNA_int_get(op->ptr, "active_object_index"); + ssc->static_island = 0; + + if (RNA_struct_property_is_set(op->ptr, "mode")) { + ssc->mode = RNA_enum_get(op->ptr, "mode"); + } + else { + if (ts->uv_flag & UV_SYNC_SELECTION) { + if (ts->selectmode & SCE_SELECT_VERTEX) + ssc->mode = STITCH_VERT; + else + ssc->mode = STITCH_EDGE; + } + else { + if (ts->uv_selectmode & UV_SELECT_VERTEX) { + ssc->mode = STITCH_VERT; + } + else { + ssc->mode = STITCH_EDGE; + } + } + } + + ssc->objects_len = 0; + ssc->states = NULL; + + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, &objects_len); + + if (!objects_len) + { + MEM_freeN(objects); + state_delete_all(ssc); return 0; } - state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW); + ssc->objects = MEM_callocN(sizeof(Object*) * objects_len, "Object *ssc->objects"); + ssc->states = MEM_callocN(sizeof(StitchState*) * objects_len, "StitchState"); + ssc->objects_len = 0; + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + + StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit); + + if (stitch_state_ob) { + ssc->objects[ssc->objects_len] = obedit; + ssc->states[ssc->objects_len] = stitch_state_ob; + ssc->objects_len++; + } + } + + MEM_freeN(objects); + + if (ssc->objects_len == 0) { + state_delete_all(ssc); + return 0; + } + + ssc->active_object_index %= ssc->objects_len; + + ssc->static_island = RNA_int_get(op->ptr, "static_island"); + + StitchState *state = ssc->states[ssc->active_object_index]; + ssc->static_island %= state->element_map->totalIslands; + + /* If the initial active object doesn't have any stitchable islands */ + /* then no active island will be seen in the UI. Make sure we're on */ + /* a stitchable object and island. */ + if (!state->island_is_stitchable[ssc->static_island]) { + goto_next_island(ssc); + state = ssc->states[ssc->active_object_index]; + } + + /* process active stitchobj again now that it can detect it's the active stitchobj */ + stitch_process_data(ssc, state, scene, false); + + stitch_update_header(ssc, C); + + ssc->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, ssc, REGION_DRAW_POST_VIEW); - stitch_update_header(state, C); return 1; } static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Object *obedit = CTX_data_edit_object(C); - if (!stitch_init(C, op)) + if (!stitch_init_all(C, op)) return OPERATOR_CANCELLED; WM_event_add_modal_handler(C, op); @@ -2048,34 +2269,37 @@ static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(even static void stitch_exit(bContext *C, wmOperator *op, int finished) { - StitchState *state; Scene *scene; SpaceImage *sima; ScrArea *sa = CTX_wm_area(C); - Object *obedit; scene = CTX_data_scene(C); - obedit = CTX_data_edit_object(C); sima = CTX_wm_space_image(C); - state = (StitchState *)op->customdata; + StitchStateContainer *ssc = (StitchStateContainer *)op->customdata; + StitchState *state = ssc->states[ssc->active_object_index]; + Object *obedit = state->obedit; if (finished) { int i; - RNA_float_set(op->ptr, "limit", state->limit_dist); - RNA_boolean_set(op->ptr, "use_limit", state->use_limit); - RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands); - RNA_int_set(op->ptr, "static_island", state->static_island); - RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints); - RNA_enum_set(op->ptr, "mode", state->mode); - RNA_enum_set(op->ptr, "stored_mode", state->mode); + RNA_float_set(op->ptr, "limit", ssc->limit_dist); + RNA_boolean_set(op->ptr, "use_limit", ssc->use_limit); + RNA_boolean_set(op->ptr, "snap_islands", ssc->snap_islands); + RNA_boolean_set(op->ptr, "midpoint_snap", ssc->midpoints); + RNA_boolean_set(op->ptr, "clear_seams", ssc->clear_seams); + RNA_enum_set(op->ptr, "mode", ssc->mode); + RNA_enum_set(op->ptr, "stored_mode", ssc->mode); + RNA_int_set(op->ptr, "active_object_index", ssc->active_object_index); + + RNA_int_set(op->ptr, "static_island", ssc->static_island); /* Store selection for re-execution of stitch */ + /* WIP */ for (i = 0; i < state->selection_size; i++) { UvElement *element; PointerRNA itemptr; - if (state->mode == STITCH_VERT) { + if (ssc->mode == STITCH_VERT) { element = state->selection_stack[i]; } else { @@ -2093,12 +2317,13 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) if (sa) ED_workspace_status_text(C, NULL); - ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, ssc->draw_handle); DEG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - state_delete(state); + state_delete_all(ssc); + op->customdata = NULL; } @@ -2113,9 +2338,9 @@ static int stitch_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - if (!stitch_init(C, op)) + if (!stitch_init_all(C, op)) return OPERATOR_CANCELLED; - if (stitch_process_data((StitchState *)op->customdata, scene, 1)) { + if (stitch_process_data_all((StitchStateContainer *)op->customdata, scene, 1)) { stitch_exit(C, op, 1); return OPERATOR_FINISHED; } @@ -2125,7 +2350,8 @@ static int stitch_exec(bContext *C, wmOperator *op) } } -static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state) +static StitchState* stitch_select( + bContext *C, Scene *scene, const wmEvent *event, StitchStateContainer *ssc) { /* add uv under mouse to processed uv's */ float co[2]; @@ -2135,36 +2361,60 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); - if (state->mode == STITCH_VERT) { - if (uv_find_nearest_vert( - scene, ima, state->obedit, co, 0.0f, &hit)) + if (ssc->mode == STITCH_VERT) { + if (uv_find_nearest_vert_multi( + scene, ima, ssc->objects, ssc->objects_len, co, 0.0f, &hit)) { /* Add vertex to selection, deselect all common uv's of vert other * than selected and update the preview. This behavior was decided so that * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ + /* find StitchState from hit->ob */ + StitchState *state = NULL; + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + if (hit.ob == ssc->objects[ob_index]) { + state = ssc->states[ob_index]; + break; + } + } + /* This works due to setting of tmp in find nearest uv vert */ UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l); stitch_select_uv(element, state, false); + return state; } } else { - if (uv_find_nearest_edge( - scene, ima, state->obedit, co, &hit)) + if (uv_find_nearest_edge_multi( + scene, ima, ssc->objects, ssc->objects_len, co, &hit)) { + /* find StitchState from hit->ob */ + StitchState *state = NULL; + for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) { + if (hit.ob == ssc->objects[ob_index]) { + state = ssc->states[ob_index]; + break; + } + } + UvEdge *edge = uv_edge_get(hit.l, state); stitch_select_edge(edge, state, false); + + return state; } } + + return NULL; } static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) { - StitchState *state; + StitchStateContainer *ssc; Scene *scene = CTX_data_scene(C); - state = (StitchState *)op->customdata; + ssc = op->customdata; + StitchState *active_state = ssc->states[ssc->active_object_index]; switch (event->type) { case MIDDLEMOUSE: @@ -2178,9 +2428,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case LEFTMOUSE: if (event->shift && (U.flag & USER_LMOUSESELECT)) { if (event->val == KM_PRESS) { - stitch_select(C, scene, event, state); + StitchState *selected_state = stitch_select(C, scene, event, ssc); - if (!stitch_process_data(state, scene, false)) { + if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2191,7 +2441,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case PADENTER: case RETKEY: if (event->val == KM_PRESS) { - if (stitch_process_data(state, scene, true)) { + if (stitch_process_data(ssc, active_state, scene, true)) { stitch_exit(C, op, 1); return OPERATOR_FINISHED; } @@ -2207,8 +2457,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case PADPLUSKEY: case WHEELUPMOUSE: if (event->val == KM_PRESS && event->alt) { - state->limit_dist += 0.01f; - if (!stitch_process_data(state, scene, false)) { + ssc->limit_dist += 0.01f; + if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2221,9 +2471,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case PADMINUS: case WHEELDOWNMOUSE: if (event->val == KM_PRESS && event->alt) { - state->limit_dist -= 0.01f; - state->limit_dist = MAX2(0.01f, state->limit_dist); - if (!stitch_process_data(state, scene, false)) { + ssc->limit_dist -= 0.01f; + ssc->limit_dist = MAX2(0.01f, ssc->limit_dist); + if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2236,8 +2486,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) /* Use Limit (Default off) */ case LKEY: if (event->val == KM_PRESS) { - state->use_limit = !state->use_limit; - if (!stitch_process_data(state, scene, false)) { + ssc->use_limit = !ssc->use_limit; + if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2247,12 +2497,23 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case IKEY: if (event->val == KM_PRESS) { - state->static_island++; - state->static_island %= state->element_map->totalIslands; + /* Move to next island and maybe next object */ - if (!stitch_process_data(state, scene, false)) { - stitch_cancel(C, op); - return OPERATOR_CANCELLED; + if (goto_next_island(ssc)) { + StitchState *new_active_state = ssc->states[ssc->active_object_index]; + + /* active_state is the origional active state */ + if (active_state != new_active_state) { + if (!stitch_process_data(ssc, active_state, scene, false)) { + stitch_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + + if (!stitch_process_data(ssc, new_active_state, scene, false)) { + stitch_cancel(C, op); + return OPERATOR_CANCELLED; + } } break; } @@ -2260,8 +2521,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case MKEY: if (event->val == KM_PRESS) { - state->midpoints = !state->midpoints; - if (!stitch_process_data(state, scene, false)) { + ssc->midpoints = !ssc->midpoints; + if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2275,9 +2536,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) { - stitch_select(C, scene, event, state); + StitchState *selected_state = stitch_select(C, scene, event, ssc); - if (!stitch_process_data(state, scene, false)) { + if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2288,8 +2549,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) /* snap islands on/off */ case SKEY: if (event->val == KM_PRESS) { - state->snap_islands = !state->snap_islands; - if (!stitch_process_data(state, scene, false)) { + ssc->snap_islands = !ssc->snap_islands; + if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2302,9 +2563,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) /* switch between edge/vertex mode */ case TABKEY: if (event->val == KM_PRESS) { - stitch_switch_selection_mode(state); + stitch_switch_selection_mode_all(ssc); - if (!stitch_process_data(state, scene, false)) { + if (!stitch_process_data_all(ssc, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; } @@ -2316,8 +2577,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) } /* if updated settings, renew feedback message */ - stitch_update_header(state, C); + stitch_update_header(ssc, C); ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_RUNNING_MODAL; } @@ -2353,14 +2615,16 @@ void UV_OT_stitch(wmOperatorType *ot) "Limit distance in normalized coordinates", 0.0, FLT_MAX); RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island", "Island that stays in place when stitching islands", 0, INT_MAX); + RNA_def_int(ot->srna, "active_object_index", 0, 0, INT_MAX, "Active Object", + "Index of the active object", 0, INT_MAX); RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint", "UVs are stitched at midpoint instead of at static island"); RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", "Clear seams of stitched edges"); RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode", "Use vertex or edge stitching"); - prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode", - "Use vertex or edge stitching"); + prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode", + "Use vertex or edge stitching"); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", ""); /* Selection should not be editable or viewed in toolbar */ -- cgit v1.2.3 From cb15854bf91e0d5229d73b5859b5e132a55217b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 15:08:50 +1000 Subject: Fix missing uniform for vert/weight/texture paint Entering any of these modes would assert immediately. --- source/blender/draw/modes/paint_texture_mode.c | 2 ++ source/blender/draw/modes/paint_vertex_mode.c | 1 + source/blender/draw/modes/paint_weight_mode.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 8256bb4d0d7..cf8e520323e 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -227,6 +227,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); DRW_shgroup_uniform_texture(grp, "image", tex); DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1); + DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); stl->g_data->shgroup_image_array[i] = grp; } else { @@ -259,6 +260,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index 33af72e8616..bbe17415da1 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -125,6 +125,7 @@ static void PAINT_VERTEX_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index d4fc73e7f88..3bbe8911491 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -154,6 +154,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { @@ -173,6 +174,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay); + DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", globals_ubo); } } -- cgit v1.2.3 From b6dba5caac17522d695ee2d40699178f32e35444 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 15:17:30 +1000 Subject: Vertex Paint: use original mesh data This is already done in weight paint mode, avoids a mesh refresh on selection changes. --- source/blender/draw/modes/paint_vertex_mode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index bbe17415da1..236f76367d4 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -36,6 +36,8 @@ #include "DNA_mesh_types.h" #include "DNA_view3d_types.h" +#include "DEG_depsgraph_query.h" + extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ extern struct GlobalsUboStorage ts; /* draw_common.c */ @@ -147,6 +149,8 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob) const View3D *v3d = draw_ctx->v3d; if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) { + /* We're always painting on original, display original data. */ + ob = DEG_get_original_object(ob); const Mesh *me = ob->data; const bool use_wire = (v3d->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0; const bool use_surface = v3d->overlay.vertex_paint_mode_opacity != 0.0f; -- cgit v1.2.3 From e8e812fb1d2014ac62b9224ce74532c7f8d740d9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 15:33:11 +1000 Subject: UI: only show vertex select w/ weight paint mode Was being used for vertex paint where it's not supported. --- source/blender/editors/space_view3d/view3d_header.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index da449fac183..83cabd2a60e 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -321,7 +321,9 @@ static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C) else { uiLayout *row = uiLayoutRow(layout, true); uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); - uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + if (ob->mode & OB_MODE_WEIGHT_PAINT) { + uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + } } } } -- cgit v1.2.3 From ff7429213899bfa802f3becc4377b4c07192ca64 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 15:52:25 +1000 Subject: 3D View: hide object centers in paint modes Match 2.7x behavior --- source/blender/draw/modes/object_mode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 675a2a02db8..85a56285625 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -2090,11 +2090,15 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob, ViewL if (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_ORIGINS) { return; } + const Object *obact = OBACT(view_layer); + if (obact->mode & OB_MODE_ALL_PAINT) { + return; + } const bool is_library = ob->id.us > 1 || ID_IS_LINKED(ob); DRWShadingGroup *shgroup; - if (ob == OBACT(view_layer)) { + if (ob == obact) { shgroup = stl->g_data->center_active; } else if (ob->base_flag & BASE_SELECTED) { -- cgit v1.2.3 From bbaedad632845b90e00c9ec07f497a02193e0e40 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 16:02:45 +1000 Subject: Minor tweak to last commit --- source/blender/draw/modes/object_mode.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 85a56285625..26e1428cb8b 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -2090,15 +2090,11 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob, ViewL if (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_ORIGINS) { return; } - const Object *obact = OBACT(view_layer); - if (obact->mode & OB_MODE_ALL_PAINT) { - return; - } const bool is_library = ob->id.us > 1 || ID_IS_LINKED(ob); DRWShadingGroup *shgroup; - if (ob == obact) { + if (ob == OBACT(view_layer)) { shgroup = stl->g_data->center_active; } else if (ob->base_flag & BASE_SELECTED) { @@ -2348,8 +2344,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) return; } - bool do_outlines = (draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0); - bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0); + const bool do_outlines = (draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0); + const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0); const bool hide_object_extra = (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0; if (do_outlines) { @@ -2510,7 +2506,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) /* don't show object extras in set's */ if ((ob->base_flag & (BASE_FROM_SET | BASE_FROMDUPLI)) == 0) { - DRW_shgroup_object_center(stl, ob, view_layer, v3d); + if ((draw_ctx->object_mode & OB_MODE_ALL_PAINT) == 0) { + DRW_shgroup_object_center(stl, ob, view_layer, v3d); + } if (show_relations) { DRW_shgroup_relationship_lines(stl, ob); -- cgit v1.2.3 From b496bf022bc48fd759e4848edf93d181985e31ad Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 17:08:53 +1000 Subject: Fix T54584: Crash w/ image undo Using accumulation undo type (eg painting) as the first undo step, broke code which adds an initial memfile undo. --- source/blender/blenkernel/intern/undo_system.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index ba7d432fab3..2231f43c9c3 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -254,6 +254,7 @@ void BKE_undosys_stack_clear_active(UndoStack *ustack) static bool undosys_stack_push_main(UndoStack *ustack, const char *name, struct Main *bmain) { UNDO_NESTED_ASSERT(false); + BLI_assert(ustack->step_init == NULL); CLOG_INFO(&LOG, 1, "'%s'", name); bContext *C_temp = CTX_create(); CTX_data_main_set(C_temp, bmain); @@ -434,7 +435,13 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, bContext *C, const char Main *bmain = G.main; if (bmain->is_memfile_undo_written == false) { const char *name_internal = "MemFile Internal"; - if (undosys_stack_push_main(ustack, name_internal, bmain)) { + /* Don't let 'step_init' cause issues when adding memfile undo step. */ + void *step_init = ustack->step_init; + ustack->step_init = NULL; + const bool ok = undosys_stack_push_main(ustack, name_internal, bmain); + /* Restore 'step_init'. */ + ustack->step_init = step_init; + if (ok) { UndoStep *us = ustack->steps.last; BLI_assert(STREQ(us->name, name_internal)); us->skip = true; -- cgit v1.2.3 From 697d4b227e71a6e90329e2cb4e83dafcddb4af72 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 17:54:41 +1000 Subject: Ghost/X11: correct function signature --- intern/ghost/intern/GHOST_WindowX11.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index dc701062df8..623d57705b2 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -598,13 +598,15 @@ GHOST_WindowX11(GHOST_SystemX11 *system, } #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) -static void destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/) +static Bool destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/) { GHOST_PRINT("XIM input context destroyed\n"); if (ptr) { *(XIC *)ptr = NULL; } + /* Ignored by X11. */ + return True; } bool GHOST_WindowX11::createX11_XIC() -- cgit v1.2.3 From b74612e034020bd5c5e38f8f122555799872ffa2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 8 Aug 2018 10:55:30 +0200 Subject: Fix T56251: Outliner crash on selecting nested. We need a valid tree here, undo step will make it invalid... --- source/blender/editors/space_outliner/outliner_collections.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index e480cac2dcc..946d2b019a9 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -138,8 +138,10 @@ static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void static int collection_new_exec(bContext *C, wmOperator *op) { SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); struct CollectionNewData data = { .error = false, @@ -147,6 +149,8 @@ static int collection_new_exec(bContext *C, wmOperator *op) }; if (RNA_boolean_get(op->ptr, "nested")) { + outliner_build_tree(bmain, scene, view_layer, soops, ar); + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_selected_to_add, &data); if (data.error) { -- cgit v1.2.3 From 65b31a4c9c1e0e4c7e4cd8b4c92e3554908a17c7 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 11:09:12 +0200 Subject: GP: Check render status before use it. --- source/blender/draw/engines/gpencil/gpencil_engine.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 3f64d72d354..7bb6e528678 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -331,6 +331,9 @@ void GPENCIL_cache_init(void *vedata) if (draw_ctx->evil_C) { stl->storage->is_playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL; } + /* save render state */ + stl->storage->is_render = DRW_state_is_image_render(); + stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview"); if (obact_gpd) { /* for some reason, when press play there is a delay in the animation flag check @@ -346,10 +349,6 @@ void GPENCIL_cache_init(void *vedata) } } - /* save render state */ - stl->storage->is_render = DRW_state_is_image_render(); - stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview"); - /* save simplify flags (can change while drawing, so it's better to save) */ stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing); stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing); -- cgit v1.2.3 From 106e73da8298697e8b96d878a279bbc98bdfa6ca Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 11:10:56 +0200 Subject: Fix T56270: Crash when save a grease pencil file with instance modifier. The error was related to duplicate names in the internal hash used to order instances in z-depth. --- source/blender/draw/engines/gpencil/gpencil_draw_utils.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index dba5f7b9c20..93269d4543f 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1263,6 +1263,8 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object { /* reset random */ mmd->rnd[0] = 1; + char buf[8]; + int e = 0; /* Generate instances */ for (int x = 0; x < mmd->count[0]; x++) { @@ -1284,6 +1286,14 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object /* add object to cache */ newob = MEM_dupallocN(ob); + + /* create a unique name or the object hash used in draw will fail. + * the name must be unique in the hash, not in the scene because + * the object never is linked to scene. + */ + sprintf(buf, "___%d", e++); + strncat(newob->id.name, buf, sizeof(newob->id.name)); + mul_m4_m4m4(newob->obmat, ob->obmat, mat); /* apply scale */ -- cgit v1.2.3 From bc63d6f39ade353610669e97bdbcbbb184ef48c8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 19:16:43 +1000 Subject: Fix T55095: Undo crash w/ linked library data --- source/blender/blenkernel/intern/undo_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 2231f43c9c3..0ebfb4065e4 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -864,7 +864,7 @@ ID *BKE_undosys_ID_map_lookup_with_prev(const UndoIDPtrMap *map, ID *id_src, ID return id_prev_match[1]; } else { - ID *id_dst = BKE_undosys_ID_map_lookup(map, id_src); + ID *id_dst = (id_src->lib == NULL) ? BKE_undosys_ID_map_lookup(map, id_src) : id_src; id_prev_match[0] = id_src; id_prev_match[1] = id_dst; return id_dst; -- cgit v1.2.3 From 3e0bf69bfd8360b3a4b90940d59d231832962bf4 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 11:48:18 +0200 Subject: GP: Change to make the temp name unique The previous commit could fail if some corner situations. This new temp name must be unique always. --- source/blender/draw/engines/gpencil/gpencil_draw_utils.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 93269d4543f..499eb14e254 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1263,7 +1263,6 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object { /* reset random */ mmd->rnd[0] = 1; - char buf[8]; int e = 0; /* Generate instances */ @@ -1287,12 +1286,16 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object /* add object to cache */ newob = MEM_dupallocN(ob); - /* create a unique name or the object hash used in draw will fail. + /* Create a unique name or the object hash used in draw will fail. * the name must be unique in the hash, not in the scene because - * the object never is linked to scene. + * the object never is linked to scene and is removed after drawing. + * + * It uses special characters to be sure the name cannot be equal + * to any existing name because UI limits the use of special characters. + * + * Name = OB\t_{pointer}_{index} */ - sprintf(buf, "___%d", e++); - strncat(newob->id.name, buf, sizeof(newob->id.name)); + sprintf(newob->id.name, "OB\t_%p_%d", &ob, e++); mul_m4_m4m4(newob->obmat, ob->obmat, mat); -- cgit v1.2.3 From 7a6d7d056bee4336e891b83b7bba8ab41de36ebf Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 8 Aug 2018 11:54:58 +0200 Subject: Fix T56273: User count assert on re-saving a particular file. new background image/clip of Camera ID was totally wrong, down the old, broken 'way it used to be' instead of using new, more generic system. Those ID pointers were not even added to library_query.c file, shame! xD --- source/blender/blenkernel/intern/camera.c | 18 ------------------ source/blender/blenkernel/intern/library_query.c | 9 +++++++++ 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 1b5995de4f0..07b0e3b782e 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -108,16 +108,6 @@ void *BKE_camera_add(Main *bmain, const char *name) void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *cam_dst, const Camera *cam_src, const int flag) { BLI_duplicatelist(&cam_dst->bg_images, &cam_src->bg_images); - if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { - for (CameraBGImage *bgpic = cam_dst->bg_images.first; bgpic; bgpic = bgpic->next) { - if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { - id_us_plus((ID *)bgpic->ima); - } - else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { - id_us_plus((ID *)bgpic->clip); - } - } - } } Camera *BKE_camera_copy(Main *bmain, const Camera *cam) @@ -135,14 +125,6 @@ void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local) /** Free (or release) any data used by this camera (does not free the camera itself). */ void BKE_camera_free(Camera *ca) { - for (CameraBGImage *bgpic = ca->bg_images.first; bgpic; bgpic = bgpic->next) { - if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { - id_us_min((ID *)bgpic->ima); - } - else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { - id_us_min((ID *)bgpic->clip); - } - } BLI_freelistN(&ca->bg_images); BKE_animdata_free((ID *)ca, false); diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 473dd787a69..0626e051e83 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -682,6 +682,15 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call { Camera *camera = (Camera *) id; CALLBACK_INVOKE(camera->dof_ob, IDWALK_CB_NOP); + for (CameraBGImage *bgpic = camera->bg_images.first; bgpic; bgpic = bgpic->next) { + if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { + CALLBACK_INVOKE(bgpic->ima, IDWALK_CB_USER); + } + else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { + CALLBACK_INVOKE(bgpic->clip, IDWALK_CB_USER); + } + } + break; } -- cgit v1.2.3 From 6a07818e8fb3cdc003d6734f0bf79676f6104385 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 8 Aug 2018 11:57:35 +0200 Subject: Cleanup unused arg warning. --- source/blender/blenkernel/intern/camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 07b0e3b782e..6e50b6e41fa 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -105,7 +105,7 @@ void *BKE_camera_add(Main *bmain, const char *name) * * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). */ -void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *cam_dst, const Camera *cam_src, const int flag) +void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *cam_dst, const Camera *cam_src, const int UNUSED(flag)) { BLI_duplicatelist(&cam_dst->bg_images, &cam_src->bg_images); } -- cgit v1.2.3 From 08e49c034b318fa430f2b783b3a3fac089da5f9b Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 12:17:00 +0200 Subject: GP: Fix unreported segment fault with some old files In some corner situations for old files, the weights array could not be initialized properly. --- source/blender/blenkernel/intern/gpencil_modifier.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index 3c2196afb18..d1c455f64e1 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -257,6 +257,11 @@ void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float factor) /* first create temp data and convert points to 2D */ vec2f *points2d = MEM_mallocN(sizeof(vec2f) * gps->totpoints, "GP Stroke temp 2d points"); + /* for some old files, the weights array could not be initializated */ + if (gps->dvert == NULL) { + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); + } + gpencil_stroke_project_2d(gps->points, gps->totpoints, points2d); gpencil_rdp_stroke(gps, points2d, factor); @@ -271,6 +276,11 @@ void BKE_gpencil_simplify_fixed(bGPDstroke *gps) return; } + /* for some old files, the weights array could not be initializated */ + if (gps->dvert == NULL) { + gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights"); + } + /* save points */ bGPDspoint *old_points = MEM_dupallocN(gps->points); MDeformVert *old_dvert = MEM_dupallocN(gps->dvert); -- cgit v1.2.3 From aa41c866364178fa0057bd93fd17718f59aa101a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Aug 2018 20:45:43 +1000 Subject: Cleanup: trailing space --- release/scripts/startup/bl_ui/properties_data_modifier.py | 4 ++-- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- source/blender/editors/mesh/editmesh_bevel.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index f2ed4b3b88c..1671cf7736d 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -147,7 +147,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col.prop(md, "loop_slide") col.prop(md, "mark_seam") col.prop(md, "mark_sharp") - + layout.label(text="Limit Method:") layout.row().prop(md, "limit_method", expand=True) if md.limit_method == 'ANGLE': @@ -158,7 +158,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): layout.label(text="Width Method:") layout.row().prop(md, "offset_type", expand=True) - + layout.label(text="Normal Mode") layout.row().prop(md, "hnmode", expand=True) layout.prop(md, "hn_strength") diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index b45c9e295ab..58380491a10 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1553,7 +1553,7 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) do { int flag_count = 0; EdgeHalf *ne = e->next; - + while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 931e395736f..8d1832e84a4 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -722,7 +722,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event) handled = true; break; } - + } /* Modal numinput inactive, try to handle numeric inputs last... */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d94d3051b50..45ffd3245a3 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7063,7 +7063,7 @@ static void point_normals_update_header(bContext *C, wmOperator *op) WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_RESET), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")), - WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), + WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align"))); -- cgit v1.2.3 From 78a6fa1a7294d73a4f35b08d569d03f1afdd71ac Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 13:37:56 +0200 Subject: Cleanup: Move some duplicate code to new function --- .../gpencil_modifiers/intern/MOD_gpencil_util.c | 47 ++++++++++++++++++++++ .../gpencil_modifiers/intern/MOD_gpencil_util.h | 7 ++++ .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 37 +---------------- .../gpencil_modifiers/intern/MOD_gpenciltint.c | 36 +---------------- 4 files changed, 58 insertions(+), 69 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 664f4b6976c..21a55e3f970 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -33,6 +33,7 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "BLI_math_vector.h" #include "BLI_math_color.h" @@ -45,6 +46,7 @@ #include "DNA_gpencil_modifier_types.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_object.h" #include "BKE_lattice.h" #include "BKE_material.h" @@ -52,6 +54,8 @@ #include "BKE_gpencil_modifier.h" #include "BKE_colortools.h" +#include "DEG_depsgraph.h" + #include "MOD_gpencil_modifiertypes.h" #include "MOD_gpencil_util.h" @@ -140,3 +144,46 @@ float get_modifier_point_weight(MDeformVert *dvert, int inverse, int vindex) return weight; } + +/* set material when apply modifiers (used in tint and color modifier) */ +void gpencil_apply_modifier_material( + Main *bmain, Object *ob, Material *mat, + GHash *gh_color, bGPDstroke *gps, bool crt_material) +{ + MaterialGPencilStyle *gp_style = mat->gp_style; + + /* look for color */ + if (crt_material) { + Material *newmat = BLI_ghash_lookup(gh_color, mat->id.name); + if (newmat == NULL) { + BKE_object_material_slot_add(bmain, ob); + newmat = BKE_material_copy(bmain, mat); + newmat->preview = NULL; + + assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); + + copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + + BLI_ghash_insert(gh_color, mat->id.name, newmat); + DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); + } + /* reasign color index */ + int idx = BKE_object_material_slot_find_index(ob, newmat); + gps->mat_nr = idx - 1; + } + else { + /* reuse existing color (but update only first time) */ + if (BLI_ghash_lookup(gh_color, mat->id.name) == NULL) { + copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); + copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); + BLI_ghash_insert(gh_color, mat->id.name, mat); + } + /* update previews (icon and thumbnail) */ + if (mat->preview != NULL) { + mat->preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; + mat->preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; + } + DEG_id_tag_update(&mat->id, DEG_TAG_COPY_ON_WRITE); + } +} diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h index 39a4947573e..1ca9febbdca 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.h @@ -33,10 +33,13 @@ #ifndef __MOD_GPENCIL_UTIL_H__ #define __MOD_GPENCIL_UTIL_H__ +struct Main; struct Object; struct bGPDlayer; struct bGPDstroke; struct MDeformVert; +struct Material; +struct GHash; bool is_stroke_affected_by_modifier( struct Object *ob, char *mlayername, int mpassindex, int minpoints, @@ -44,4 +47,8 @@ bool is_stroke_affected_by_modifier( float get_modifier_point_weight(struct MDeformVert *dvert, int inverse, int vindex); +void gpencil_apply_modifier_material( + struct Main *bmain, struct Object *ob, struct Material *mat, + struct GHash *gh_color, struct bGPDstroke *gps, bool crt_material); + #endif /* __MOD_GPENCIL_UTIL_H__ */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index b2df49a8d06..4c087577699 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -122,41 +122,8 @@ static void bakeModifier( deformStroke(md, depsgraph, ob, gpl, gps); - /* look for color */ - if (mmd->flag & GP_COLOR_CREATE_COLORS) { - Material *newmat = BLI_ghash_lookup(gh_color, mat->id.name); - if (newmat == NULL) { - BKE_object_material_slot_add(bmain, ob); - newmat = BKE_material_copy(bmain, mat); - newmat->preview = NULL; - - assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - - copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - - BLI_ghash_insert(gh_color, mat->id.name, newmat); - DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); - } - /* reasign color index */ - int idx = BKE_object_material_slot_find_index(ob, newmat); - gps->mat_nr = idx - 1; - } - else { - /* reuse existing color (but update only first time) */ - if (BLI_ghash_lookup(gh_color, mat->id.name) == NULL) { - copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - BLI_ghash_insert(gh_color, mat->id.name, mat); - } - /* update previews (icon and thumbnail) */ - if (mat->preview != NULL) { - mat->preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; - mat->preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; - } - DEG_id_tag_update(&mat->id, DEG_TAG_COPY_ON_WRITE); - } - + gpencil_apply_modifier_material(bmain, ob, mat, gh_color, gps, + (bool)(mmd->flag & GP_COLOR_CREATE_COLORS)); } } } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 08cf1c13692..06212451d48 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -130,40 +130,8 @@ static void bakeModifier( deformStroke(md, depsgraph, ob, gpl, gps); - /* look for color */ - if (mmd->flag & GP_TINT_CREATE_COLORS) { - Material *newmat = (Material *)BLI_ghash_lookup(gh_color, mat->id.name); - if (newmat == NULL) { - BKE_object_material_slot_add(bmain, ob); - newmat = BKE_material_copy(bmain, mat); - newmat->preview = NULL; - - assign_material(bmain, ob, newmat, ob->totcol, BKE_MAT_ASSIGN_USERPREF); - - copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - - BLI_ghash_insert(gh_color, mat->id.name, newmat); - DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); - } - /* reasign color index */ - int idx = BKE_object_material_slot_find_index(ob, newmat); - gps->mat_nr = idx - 1; - } - else { - /* reuse existing color (but update only first time) */ - if (BLI_ghash_lookup(gh_color, mat->id.name) == NULL) { - copy_v4_v4(gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); - copy_v4_v4(gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - BLI_ghash_insert(gh_color, mat->id.name, mat); - } - /* update previews (icon and thumbnail) */ - if (mat->preview != NULL) { - mat->preview->flag[ICON_SIZE_ICON] |= PRV_CHANGED; - mat->preview->flag[ICON_SIZE_PREVIEW] |= PRV_CHANGED; - } - DEG_id_tag_update(&mat->id, DEG_TAG_COPY_ON_WRITE); - } + gpencil_apply_modifier_material(bmain, ob, mat, gh_color, gps, + (bool)(mmd->flag & GP_TINT_CREATE_COLORS)); } } } -- cgit v1.2.3 From 5c4fd526124c348c8f324a2d0a384958c6e793b8 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 16:56:56 +0200 Subject: Fix T56220: Adding Grease Object crashes if link Material is set to Object --- release/scripts/startup/bl_ui/space_view3d.py | 5 ++- source/blender/blenkernel/BKE_gpencil.h | 1 + source/blender/blenkernel/intern/gpencil.c | 15 +++++++ .../blender/editors/gpencil/gpencil_add_monkey.c | 7 ++- .../blender/editors/gpencil/gpencil_add_stroke.c | 7 ++- source/blender/editors/gpencil/gpencil_brush.c | 4 +- source/blender/editors/gpencil/gpencil_data.c | 50 +++++++++------------- source/blender/editors/gpencil/gpencil_edit.c | 8 ++-- source/blender/editors/gpencil/gpencil_fill.c | 2 +- source/blender/editors/gpencil/gpencil_paint.c | 4 +- source/blender/editors/gpencil/gpencil_primitive.c | 2 +- .../gpencil_modifiers/intern/MOD_gpencil_util.c | 2 +- 12 files changed, 57 insertions(+), 50 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 349832cedf2..72296861ad9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3545,9 +3545,10 @@ class VIEW3D_MT_assign_material(Menu): def draw(self, context): layout = self.layout - ob = context.active_object; + ob = context.active_object - for mat in ob.data.materials: + for slot in ob.material_slots: + mat = slot.material layout.operator("gpencil.stroke_change_color", text=mat.name).material = mat.name diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 887a7f4f67b..532eaf9a0e7 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -94,6 +94,7 @@ void BKE_gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe /* materials */ void BKE_gpencil_material_index_remove(struct bGPdata *gpd, int index); void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len); +int BKE_gpencil_get_material_index(struct Object *ob, struct Material *ma); /* statistics functions */ void BKE_gpencil_stats_update(struct bGPdata *gpd); diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index b619304d39b..140e4a25882 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1630,3 +1630,18 @@ void BKE_gpencil_stats_update(bGPdata *gpd) } } + +/* get material index */ +int BKE_gpencil_get_material_index(Object *ob, Material *ma) +{ + short *totcol = give_totcolp(ob); + Material *read_ma = NULL; + for (short i = 0; i < *totcol; i++) { + read_ma = give_current_material(ob, i + 1); + if (ma == read_ma) { + return i + 1; + } + } + + return 0; +} diff --git a/source/blender/editors/gpencil/gpencil_add_monkey.c b/source/blender/editors/gpencil/gpencil_add_monkey.c index b0c3675c123..78286e3f672 100644 --- a/source/blender/editors/gpencil/gpencil_add_monkey.c +++ b/source/blender/editors/gpencil/gpencil_add_monkey.c @@ -55,11 +55,10 @@ typedef struct ColorTemplate { /* Add color an ensure duplications (matched by name) */ static int gpencil_monkey_color(Main *bmain, Object *ob, const ColorTemplate *pct) { - Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); + Material *ma = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); if (STREQ(ma->id.name, pct->name)) { return i; } @@ -73,7 +72,7 @@ static int gpencil_monkey_color(Main *bmain, Object *ob, const ColorTemplate *pc copy_v4_v4(ma->gp_style->stroke_rgba, pct->line); copy_v4_v4(ma->gp_style->fill_rgba, pct->fill); - return BKE_object_material_slot_find_index(ob, ma) - 1; + return BKE_gpencil_get_material_index(ob, ma) - 1; } /* ***************************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_add_stroke.c b/source/blender/editors/gpencil/gpencil_add_stroke.c index f932f98ac1d..c5020593bcb 100644 --- a/source/blender/editors/gpencil/gpencil_add_stroke.c +++ b/source/blender/editors/gpencil/gpencil_add_stroke.c @@ -55,11 +55,10 @@ typedef struct ColorTemplate { /* Add color an ensure duplications (matched by name) */ static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct) { - Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); + Material *ma = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); if (STREQ(ma->id.name, pct->name)) { return i; } @@ -73,7 +72,7 @@ static int gp_stroke_material(Main *bmain, Object *ob, const ColorTemplate *pct) copy_v4_v4(ma->gp_style->stroke_rgba, pct->line); copy_v4_v4(ma->gp_style->fill_rgba, pct->fill); - return BKE_object_material_slot_find_index(ob, ma) - 1; + return BKE_gpencil_get_material_index(ob, ma) - 1; } /* ***************************************************************** */ diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index ff93e7fc57d..d8be0dd665a 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -1053,8 +1053,8 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso) /* Fix color references */ Material *ma = BLI_ghash_lookup(data->new_colors, &new_stroke->mat_nr); - if ((ma) && (BKE_object_material_slot_find_index(ob, ma) > 0)) { - gps->mat_nr = BKE_object_material_slot_find_index(ob, ma) - 1; + if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) { + gps->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1; CLAMP_MIN(gps->mat_nr, 0); } else { diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 43721d73a80..faeee4db169 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1150,8 +1150,8 @@ static int gp_stroke_change_color_exec(bContext *C, wmOperator *op) } } /* try to find slot */ - int idx = BKE_object_material_slot_find_index(ob, ma) - 1; - if (idx == 0) { + int idx = BKE_gpencil_get_material_index(ob, ma) - 1; + if (idx <= 0) { return OPERATOR_CANCELLED; } @@ -1230,7 +1230,6 @@ static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = CTX_data_active_object(C); - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); /* sanity checks */ @@ -1239,9 +1238,8 @@ static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op)) /* first lock all colors */ for (short i = 0; i < *totcol; i++) { - Material *tmp_ma = (*matar)[i]; + Material *tmp_ma = give_current_material(ob, i + 1); tmp_ma->gp_style->flag |= GP_STYLE_COLOR_LOCKED; - } /* loop all selected strokes and unlock any color */ @@ -1256,7 +1254,8 @@ static int gp_stroke_lock_color_exec(bContext *C, wmOperator *UNUSED(op)) continue; } /* unlock color */ - Material *tmp_ma = (*matar)[gps->mat_nr]; + Material *tmp_ma = give_current_material(ob, gps->mat_nr + 1); + tmp_ma->gp_style->flag &= ~GP_STYLE_COLOR_LOCKED; } } @@ -1896,12 +1895,11 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) obact->actdef = 1; /* add missing materials reading source materials and checking in destination object */ - Material ***matar = give_matarar(ob_src); short *totcol = give_totcolp(ob_src); for (short i = 0; i < *totcol; i++) { - Material *tmp_ma = (*matar)[i]; - if (BKE_object_material_slot_find_index(ob_dst, tmp_ma) == 0) { + Material *tmp_ma = give_current_material(ob_src, i + 1); + if (BKE_gpencil_get_material_index(ob_dst, tmp_ma) == 0) { BKE_object_material_slot_add(bmain, ob_dst); assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF); } @@ -1941,7 +1939,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) /* reasign material. Look old material and try to find in dst */ ma_src = give_current_material(ob_src, gps->mat_nr + 1); if (ma_src != NULL) { - idx = BKE_object_material_slot_find_index(ob_dst, ma_src); + idx = BKE_gpencil_get_material_index(ob_dst, ma_src); if (idx > 0) { gps->mat_nr = idx - 1; } @@ -2041,13 +2039,12 @@ static int gpencil_lock_layer_exec(bContext *C, wmOperator *UNUSED(op)) /* first lock and hide all colors */ Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); - if ((totcol == 0) || (matar == NULL)) + if (totcol == 0) return OPERATOR_CANCELLED; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; gp_style->flag |= GP_STYLE_COLOR_LOCKED; gp_style->flag |= GP_STYLE_COLOR_HIDE; @@ -2113,10 +2110,9 @@ static int gpencil_color_isolate_exec(bContext *C, wmOperator *op) /* Test whether to isolate or clear all flags */ Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); /* Skip if this is the active one */ if (ma == active_ma) continue; @@ -2135,7 +2131,7 @@ static int gpencil_color_isolate_exec(bContext *C, wmOperator *op) if (isolate) { /* Set flags on all "other" colors */ for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; if (gp_style == active_color) continue; @@ -2146,7 +2142,7 @@ static int gpencil_color_isolate_exec(bContext *C, wmOperator *op) else { /* Clear flags - Restore everything else */ for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; gp_style->flag &= ~flags; } @@ -2188,16 +2184,15 @@ static int gpencil_color_hide_exec(bContext *C, wmOperator *op) bool unselected = RNA_boolean_get(op->ptr, "unselected"); Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); - if ((totcol == 0) || (matar == NULL)) + if (totcol == 0) return OPERATOR_CANCELLED; if (unselected) { /* hide unselected */ MaterialGPencilStyle *color = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); color = ma->gp_style; if (active_color != color) { color->flag |= GP_STYLE_COLOR_HIDE; @@ -2239,17 +2234,16 @@ static int gpencil_color_reveal_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_active_object(C); Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); - if ((totcol == 0) || (matar == NULL)) + if (totcol == 0) return OPERATOR_CANCELLED; /* make all colors visible */ MaterialGPencilStyle *gp_style = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; gp_style->flag &= ~GP_STYLE_COLOR_HIDE; } @@ -2282,17 +2276,16 @@ static int gpencil_color_lock_all_exec(bContext *C, wmOperator *UNUSED(op)) Object *ob = CTX_data_active_object(C); Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); - if ((totcol == 0) || (matar == NULL)) + if (totcol == 0) return OPERATOR_CANCELLED; /* make all layers non-editable */ MaterialGPencilStyle *gp_style = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; gp_style->flag |= GP_STYLE_COLOR_LOCKED; } @@ -2324,17 +2317,16 @@ static int gpencil_color_unlock_all_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = CTX_data_active_object(C); Material *ma = NULL; - Material ***matar = give_matarar(ob); short *totcol = give_totcolp(ob); - if ((totcol == 0) || (matar == NULL)) + if (totcol == 0) return OPERATOR_CANCELLED; /* make all layers editable again*/ MaterialGPencilStyle *gp_style = NULL; for (short i = 0; i < *totcol; i++) { - ma = (*matar)[i]; + ma = give_current_material(ob, i + 1); gp_style = ma->gp_style; gp_style->flag &= ~GP_STYLE_COLOR_LOCKED; } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 969ff326c61..f7c08239647 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -732,7 +732,7 @@ GHash *gp_copybuf_validate_colormap(bContext *C) int *key = BLI_ghashIterator_getKey(&gh_iter); Material *ma = BLI_ghashIterator_getValue(&gh_iter); - if (BKE_object_material_slot_find_index(ob, ma) == 0) { + if (BKE_gpencil_get_material_index(ob, ma) == 0) { BKE_object_material_slot_add(bmain, ob); assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF); } @@ -980,8 +980,8 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op) /* Remap material */ Material *ma = BLI_ghash_lookup(new_colors, &new_stroke->mat_nr); - if ((ma) && (BKE_object_material_slot_find_index(ob, ma) > 0)) { - gps->mat_nr = BKE_object_material_slot_find_index(ob, ma) - 1; + if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) { + gps->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1; CLAMP_MIN(gps->mat_nr, 0); } else { @@ -3184,7 +3184,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op) /* add duplicate materials */ ma = give_current_material(ob, gps->mat_nr + 1); - idx = BKE_object_material_slot_find_index(ob_dst, ma); + idx = BKE_gpencil_get_material_index(ob_dst, ma); if (idx == 0) { totadd++; diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index ec90c826a27..c6df07ae83e 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -841,7 +841,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf) gps->flag |= GP_STROKE_CYCLIC; gps->flag |= GP_STROKE_3DSPACE; - gps->mat_nr = BKE_object_material_slot_find_index(tgpf->ob, tgpf->mat) - 1; + gps->mat_nr = BKE_gpencil_get_material_index(tgpf->ob, tgpf->mat) - 1; /* allocate memory for storage points */ gps->totpoints = tgpf->sbuffer_size; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 88f90d6c128..d4371926eb4 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1150,7 +1150,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } /* Save material index */ - gps->mat_nr = BKE_object_material_slot_find_index(p->ob, p->material) - 1; + gps->mat_nr = BKE_gpencil_get_material_index(p->ob, p->material) - 1; /* calculate UVs along the stroke */ ED_gpencil_calc_stroke_uv(obact, gps); @@ -1602,7 +1602,7 @@ static void gp_init_colors(tGPsdata *p) } /* check if the material is already on object material slots and add it if missing */ - if (BKE_object_material_slot_find_index(p->ob, p->material) == 0) { + if (BKE_gpencil_get_material_index(p->ob, p->material) == 0) { BKE_object_material_slot_add(p->bmain, p->ob); assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_USERPREF); } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 9dbec666cc4..2dfdeeba0b6 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -177,7 +177,7 @@ static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi) gps->flag |= GP_STROKE_CYCLIC; gps->flag |= GP_STROKE_3DSPACE; - gps->mat_nr = BKE_object_material_slot_find_index(tgpi->ob, tgpi->mat) - 1; + gps->mat_nr = BKE_gpencil_get_material_index(tgpi->ob, tgpi->mat) - 1; /* allocate memory for storage points, but keep empty */ gps->totpoints = 0; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 21a55e3f970..151218c06e4 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -169,7 +169,7 @@ void gpencil_apply_modifier_material( DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); } /* reasign color index */ - int idx = BKE_object_material_slot_find_index(ob, newmat); + int idx = BKE_gpencil_get_material_index(ob, newmat); gps->mat_nr = idx - 1; } else { -- cgit v1.2.3 From 211ad6bf9a8cabe3cd52e58a728c779e272cd832 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 19:48:57 +0200 Subject: GP: Fix memory leak in draw engine for buffer strokes This memory leak was undetected during a long time, but with new memory checking is visible. The problem was the stroke buffer batch was realocating new batches without free the memory. --- .../draw/engines/gpencil/gpencil_draw_utils.c | 27 ++++++++++++++++++---- .../blender/draw/engines/gpencil/gpencil_engine.c | 6 +++++ .../blender/draw/engines/gpencil/gpencil_engine.h | 11 +++++---- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 499eb14e254..0a805fa9b29 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -932,19 +932,26 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false); } + /* clean previous version of the batch */ + if (stl->storage->buffer_stroke) { + GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke); + MEM_SAFE_FREE(e_data->batch_buffer_stroke); + stl->storage->buffer_stroke = false; + } + /* use unit matrix because the buffer is in screen space and does not need conversion */ if (gpd->runtime.mode == GP_STYLE_MODE_LINE) { - stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom( + e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom( gpd, stl->storage->unit_matrix, lthick); } else { - stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom( + e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom( gpd, stl->storage->unit_matrix, lthick); } DRW_shgroup_call_add( stl->g_data->shgrps_drawing_stroke, - stl->g_data->batch_buffer_stroke, + e_data->batch_buffer_stroke, stl->storage->unit_matrix); if ((gpd->runtime.sbuffer_size >= 3) && (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) && @@ -956,12 +963,22 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T } stl->g_data->shgrps_drawing_fill = DRW_shgroup_create( e_data->gpencil_drawing_fill_sh, psl->drawing_pass); - stl->g_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd); + + /* clean previous version of the batch */ + if (stl->storage->buffer_fill) { + GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill); + MEM_SAFE_FREE(e_data->batch_buffer_fill); + stl->storage->buffer_fill = false; + } + + e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd); DRW_shgroup_call_add( stl->g_data->shgrps_drawing_fill, - stl->g_data->batch_buffer_fill, + e_data->batch_buffer_fill, stl->storage->unit_matrix); + stl->storage->buffer_fill = true; } + stl->storage->buffer_stroke = true; } } } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 7bb6e528678..2a4f2f999bc 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -267,6 +267,12 @@ static void GPENCIL_engine_free(void) DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture); + GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke); + MEM_SAFE_FREE(e_data.batch_buffer_stroke); + + GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill); + MEM_SAFE_FREE(e_data.batch_buffer_fill); + /* effects */ GPENCIL_delete_fx_shaders(&e_data); } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 738b04337c1..21ac6045792 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -108,6 +108,8 @@ typedef struct GPENCIL_Storage { bool is_playing; bool is_render; bool is_mat_preview; + bool buffer_stroke; + bool buffer_fill; const float *pixsize; float render_pixsize; int tonemapping; @@ -189,10 +191,6 @@ typedef struct g_data { struct DRWShadingGroup *shgrps_drawing_fill; struct DRWShadingGroup *shgrps_grid; - /* for buffer only one batch is nedeed because the drawing is only of one stroke */ - GPUBatch *batch_buffer_stroke; - GPUBatch *batch_buffer_fill; - /* grid geometry */ GPUBatch *batch_grid; @@ -256,6 +254,11 @@ typedef struct GPENCIL_e_data { struct GPUTexture *temp_color_tx_rim; struct GPUTexture *temp_depth_tx_rim; + + /* for buffer only one batch is nedeed because the drawing is only of one stroke */ + GPUBatch *batch_buffer_stroke; + GPUBatch *batch_buffer_fill; + } GPENCIL_e_data; /* Engine data */ /* GPUBatch Cache */ -- cgit v1.2.3 From c2d363b11804ea2a0ce9e31a120a8a2b73af7a4a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 8 Aug 2018 20:07:12 +0200 Subject: Fix T55818: Dynamically modified influence vertex group not working in modifier stack. Now that we are using meshes, we need to assign back potential new vgroup cdlayer to mesh->dvert pointer... --- source/blender/modifiers/intern/MOD_weightvgedit.c | 1 + source/blender/modifiers/intern/MOD_weightvgmix.c | 1 + source/blender/modifiers/intern/MOD_weightvgproximity.c | 1 + 3 files changed, 3 insertions(+) diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 356edcd7bec..74b1f600242 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -219,6 +219,7 @@ static Mesh *applyModifier( } return mesh; } + result->dvert = dvert; /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w"); diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 3c740530258..379fbe7adaa 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -259,6 +259,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } return mesh; } + result->dvert = dvert; /* Find out which vertices to work on. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index c485aa132d7..6aadd9f7bc2 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -438,6 +438,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } return mesh; } + result->dvert = dvert; /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx"); -- cgit v1.2.3 From e2e854d7511c66c269eb46309fc33ba9e8b3d8f4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 8 Aug 2018 20:13:17 +0200 Subject: WeightVG modifiers: cleanup. --- source/blender/modifiers/intern/MOD_weightvgedit.c | 15 +++++--------- source/blender/modifiers/intern/MOD_weightvgmix.c | 16 +++++---------- .../modifiers/intern/MOD_weightvgproximity.c | 24 ++++++---------------- 3 files changed, 16 insertions(+), 39 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 74b1f600242..47379dec99a 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -203,23 +203,18 @@ static Mesh *applyModifier( } } - Mesh *result = mesh; - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, numVerts); + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); } else { /* Add a valid data layer! */ - dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); } /* Ultimate security check. */ if (!dvert) { - if (result != mesh) { - BKE_id_free(NULL, result); - } return mesh; } - result->dvert = dvert; + mesh->dvert = dvert; /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w"); @@ -252,7 +247,7 @@ static Mesh *applyModifier( /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - weightvg_do_mask(ctx, numVerts, NULL, org_w, new_w, ctx->object, result, wmd->mask_constant, + weightvg_do_mask(ctx, numVerts, NULL, org_w, new_w, ctx->object, mesh, wmd->mask_constant, wmd->mask_defgrp_name, scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -273,7 +268,7 @@ static Mesh *applyModifier( MEM_freeN(dw); /* Return the vgroup-modified mesh. */ - return result; + return mesh; } diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 379fbe7adaa..ea401d01f66 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -243,23 +243,18 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } } - Mesh *result = mesh; - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, numVerts); + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); } else { /* Add a valid data layer! */ - dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); } /* Ultimate security check. */ if (!dvert) { - if (result != mesh) { - BKE_id_free(NULL, result); - } return mesh; } - result->dvert = dvert; + mesh->dvert = dvert; /* Find out which vertices to work on. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); @@ -327,7 +322,6 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MEM_freeN(tdw1); MEM_freeN(tdw2); MEM_freeN(tidx); - BKE_id_free(NULL, result); return mesh; } if (numIdx != -1) { @@ -363,7 +357,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ctx->object, result, wmd->mask_constant, + weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ctx->object, mesh, wmd->mask_constant, wmd->mask_defgrp_name, scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -387,7 +381,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MEM_SAFE_FREE(indices); /* Return the vgroup-modified mesh. */ - return result; + return mesh; } diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 6aadd9f7bc2..4a5a54642ef 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -422,23 +422,12 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes return mesh; } - Mesh *result = mesh; - - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, numVerts); - } - else { - /* Add a valid data layer! */ - dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); - } + dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts); /* Ultimate security check. */ if (!dvert) { - if (result != mesh) { - BKE_id_free(NULL, result); - } return mesh; } - result->dvert = dvert; + mesh->dvert = dvert; /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx"); @@ -457,7 +446,6 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MEM_freeN(tidx); MEM_freeN(tw); MEM_freeN(tdw); - BKE_id_free(NULL, result); return mesh; } if (numIdx != numVerts) { @@ -479,7 +467,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* Get our vertex coordinates. */ if (numIdx != numVerts) { - float (*tv_cos)[3] = BKE_mesh_vertexCos_get(result, NULL); + float (*tv_cos)[3] = BKE_mesh_vertexCos_get(mesh, NULL); v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos"); for (i = 0; i < numIdx; i++) { copy_v3_v3(v_cos[i], tv_cos[indices[i]]); @@ -487,7 +475,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MEM_freeN(tv_cos); } else { - v_cos = BKE_mesh_vertexCos_get(result, NULL); + v_cos = BKE_mesh_vertexCos_get(mesh, NULL); } /* Compute wanted distances. */ @@ -547,7 +535,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes /* Do masking. */ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ob, result, wmd->mask_constant, + weightvg_do_mask(ctx, numIdx, indices, org_w, new_w, ob, mesh, wmd->mask_constant, wmd->mask_defgrp_name, scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -573,7 +561,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes #endif /* Return the vgroup-modified mesh. */ - return result; + return mesh; } -- cgit v1.2.3 From 74f4eb419c2d22287e39139fcc4142ed0e9b95a3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 3 Aug 2018 11:32:36 +0200 Subject: Cleanup: remove leftover game player code. --- source/blender/blenloader/BLO_readfile.h | 2 - source/blender/blenloader/BLO_runtime.h | 53 -------- source/blender/blenloader/BLO_writefile.h | 2 + source/blender/blenloader/CMakeLists.txt | 2 - source/blender/blenloader/intern/blend_validate.c | 2 +- source/blender/blenloader/intern/readfile.c | 44 +------ source/blender/blenloader/intern/runtime.c | 141 ---------------------- source/blender/blenloader/intern/writefile.c | 1 - 8 files changed, 9 insertions(+), 238 deletions(-) delete mode 100644 source/blender/blenloader/BLO_runtime.h delete mode 100644 source/blender/blenloader/intern/runtime.c diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 1251424719a..9040405e537 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -143,8 +143,6 @@ void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh); void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); -BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports); - /* internal function but we need to expose it */ void blo_lib_link_restore( struct Main *newmain, struct wmWindowManager *curwm, diff --git a/source/blender/blenloader/BLO_runtime.h b/source/blender/blenloader/BLO_runtime.h deleted file mode 100644 index 09f25bdca53..00000000000 --- a/source/blender/blenloader/BLO_runtime.h +++ /dev/null @@ -1,53 +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. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -#ifndef __BLO_RUNTIME_H__ -#define __BLO_RUNTIME_H__ - -/** \file BLO_runtime.h - * \ingroup blenloader - */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct BlendFileData; -struct Main; -struct ReportList; - -int BLO_is_a_runtime(const char *file); -struct BlendFileData *BLO_read_runtime(const char *file, struct ReportList *reports); - -bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports); - -#ifdef __cplusplus -} -#endif - -#endif /* __BLO_RUNTIME_H__ */ diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h index f6d0be6f5f0..d615514f081 100644 --- a/source/blender/blenloader/BLO_writefile.h +++ b/source/blender/blenloader/BLO_writefile.h @@ -44,4 +44,6 @@ extern bool BLO_write_file( extern bool BLO_write_file_mem( struct Main *mainvar, struct MemFile *compare, struct MemFile *current, int write_flags); +bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports); + #endif diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 72fa155553d..f2b7f35d353 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -52,7 +52,6 @@ set(SRC intern/blend_validate.c intern/readblenentry.c intern/readfile.c - intern/runtime.c intern/undofile.c intern/versioning_250.c intern/versioning_260.c @@ -64,7 +63,6 @@ set(SRC BLO_blend_defs.h BLO_readfile.h - BLO_runtime.h BLO_undofile.h BLO_writefile.h intern/readfile.h diff --git a/source/blender/blenloader/intern/blend_validate.c b/source/blender/blenloader/intern/blend_validate.c index 4fb5d0e1286..1bc503719b4 100644 --- a/source/blender/blenloader/intern/blend_validate.c +++ b/source/blender/blenloader/intern/blend_validate.c @@ -47,7 +47,7 @@ #include "BKE_report.h" #include "BLO_readfile.h" -#include "BLO_runtime.h" +#include "BLO_writefile.h" #include "readfile.h" diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b7aeee491c5..a990e9213c3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -340,6 +340,12 @@ static void oldnewmap_insert(OldNewMap *onm, const void *oldaddr, void *newaddr, if (oldaddr==NULL || newaddr==NULL) return; + for (int i = 0; i < onm->nentries; i++) { + if (onm->entries[i].old == oldaddr && onm->entries[i].newp != newaddr) { + abort(); + } + } + if (UNLIKELY(onm->nentries == onm->entriessize)) { onm->entriessize *= 2; onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * onm->entriessize); @@ -1034,20 +1040,6 @@ static int *read_file_thumbnail(FileData *fd) return blend_thumb; } -static int fd_read_from_file(FileData *filedata, void *buffer, unsigned int size) -{ - int readsize = read(filedata->filedes, buffer, size); - - if (readsize < 0) { - readsize = EOF; - } - else { - filedata->seek += readsize; - } - - return readsize; -} - static int fd_read_gzip_from_file(FileData *filedata, void *buffer, unsigned int size) { int readsize = gzread(filedata->gzfiledes, buffer, size); @@ -10982,27 +10974,3 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) BKE_main_free(main_newid); } - -/* reading runtime */ - -BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, ReportList *reports) -{ - BlendFileData *bfd = NULL; - FileData *fd = filedata_new(); - fd->filedes = file; - fd->buffersize = actualsize; - fd->read = fd_read_from_file; - - /* needed for library_append and read_libraries */ - BLI_strncpy(fd->relabase, name, sizeof(fd->relabase)); - - fd = blo_decode_and_check(fd, reports); - if (!fd) - return NULL; - - fd->reports = reports; - bfd = blo_read_file_internal(fd, ""); - blo_freefiledata(fd); - - return bfd; -} diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c deleted file mode 100644 index 985e8169819..00000000000 --- a/source/blender/blenloader/intern/runtime.c +++ /dev/null @@ -1,141 +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. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * - */ - -/** - * \file runtime.c - * \brief This file handles the loading of .blend files embedded in runtimes - * \ingroup blenloader - */ - -#include -#include -#include -#include -#include - -#ifdef WIN32 -# include // read, open -# include "BLI_winstuff.h" -#else // ! WIN32 -# include // read -#endif - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "BLO_readfile.h" -#include "BLO_runtime.h" - -#include "BKE_report.h" - -/* Runtime reading */ - -static int handle_read_msb_int(int handle) -{ - unsigned char buf[4]; - - if (read(handle, buf, 4) != 4) - return -1; - - return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0); -} - -int BLO_is_a_runtime(const char *path) -{ - int res = 0, fd = BLI_open(path, O_BINARY | O_RDONLY, 0); - int datastart; - char buf[8]; - - if (fd == -1) - goto cleanup; - - lseek(fd, -12, SEEK_END); - - datastart = handle_read_msb_int(fd); - - if (datastart == -1) - goto cleanup; - else if (read(fd, buf, 8) != 8) - goto cleanup; - else if (memcmp(buf, "BRUNTIME", 8) != 0) - goto cleanup; - else - res = 1; - -cleanup: - if (fd != -1) - close(fd); - - return res; -} - -BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) -{ - BlendFileData *bfd = NULL; - size_t actualsize; - int fd, datastart; - char buf[8]; - - fd = BLI_open(path, O_BINARY | O_RDONLY, 0); - - if (fd == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno)); - goto cleanup; - } - - actualsize = BLI_file_descriptor_size(fd); - - lseek(fd, -12, SEEK_END); - - datastart = handle_read_msb_int(fd); - - if (datastart == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (problem seeking)", path); - goto cleanup; - } - else if (read(fd, buf, 8) != 8) { - BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (truncated header)", path); - goto cleanup; - } - else if (memcmp(buf, "BRUNTIME", 8) != 0) { - BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (not a blend file)", path); - goto cleanup; - } - else { - //printf("starting to read runtime from %s at datastart %d\n", path, datastart); - lseek(fd, datastart, SEEK_SET); - bfd = blo_read_blendafterruntime(fd, path, actualsize - datastart, reports); - fd = -1; // file was closed in blo_read_blendafterruntime() - } - -cleanup: - if (fd != -1) - close(fd); - - return bfd; -} diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 3883e024ab7..2d7b5f13b07 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -191,7 +191,6 @@ #include "BLO_writefile.h" #include "BLO_readfile.h" -#include "BLO_runtime.h" #include "BLO_undofile.h" #include "BLO_blend_defs.h" -- cgit v1.2.3 From aaac963dfa74cda9b46f440e1d73c52636ad6b4a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 8 Aug 2018 20:22:40 +0200 Subject: UI: move grease pencil entry in add menu. The first group of object types is renderable geometry which this belongs to more than the second group, which are unrenderable utility objects. --- release/scripts/startup/bl_ui/space_view3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 72296861ad9..1c345fd3f00 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1481,12 +1481,12 @@ class INFO_MT_add(Menu): layout.menu("INFO_MT_surface_add", icon='OUTLINER_OB_SURFACE') layout.menu("INFO_MT_metaball_add", text="Metaball", icon='OUTLINER_OB_META') layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT') + layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') layout.separator() layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE') layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE' layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY') - layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL') layout.separator() layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER') -- cgit v1.2.3 From 0bfb215bbcb5eb69123c1de896329d94f70aa4ea Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 8 Aug 2018 20:26:14 +0200 Subject: Build: fix ffmpeg using system crystalhd library. --- build_files/build_environment/cmake/ffmpeg.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake index bd49621bf26..3ea1b282d9a 100644 --- a/build_files/build_environment/cmake/ffmpeg.cmake +++ b/build_files/build_environment/cmake/ffmpeg.cmake @@ -103,6 +103,7 @@ ExternalProject_Add(external_ffmpeg --disable-indev=jack --disable-indev=alsa --disable-outdev=alsa + --disable-crystalhd PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/ffmpeg/src/external_ffmpeg < ${PATCH_DIR}/ffmpeg.diff BUILD_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/ffmpeg/src/external_ffmpeg/ && make -j${MAKE_THREADS} INSTALL_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/ffmpeg/src/external_ffmpeg/ && make install -- cgit v1.2.3 From 440ef4235ff0b7a67de978d790bf923c04badabe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 8 Aug 2018 19:48:12 +0200 Subject: OpenJPEG: support building against both 1.5 and 2.3. Patch porting to OpenJPEG 2.3 is by Campbell. Once all platforms are upgraded we can remove the code for 1.5, and upgrade or remove the openjpeg version from extern/. This intermediate step makes it possible for platform maintainers to upgrade to 2.3 without breaking other platforms. --- source/blender/imbuf/intern/IMB_filetype.h | 5 +- source/blender/imbuf/intern/filetype.c | 2 +- source/blender/imbuf/intern/jp2.c | 1253 +++++++++++++++++++++++++++- 3 files changed, 1254 insertions(+), 6 deletions(-) diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h index 31ebc3e54de..5351b00d301 100644 --- a/source/blender/imbuf/intern/IMB_filetype.h +++ b/source/blender/imbuf/intern/IMB_filetype.h @@ -82,8 +82,9 @@ int imb_saveiris(struct ImBuf *ibuf, const char *name, int flags); /* jp2 */ int imb_is_a_jp2(const unsigned char *buf); -struct ImBuf *imb_jp2_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); -int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags); +struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]); +struct ImBuf *imb_load_jp2_filepath(const char *name, int flags, char colorspace[IM_MAX_SPACE]); +int imb_save_jp2(struct ImBuf *ibuf, const char *name, int flags); /* jpeg */ int imb_is_a_jpeg(const unsigned char *mem); diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c index 5dcd9c1c68a..25bbd132a49 100644 --- a/source/blender/imbuf/intern/filetype.c +++ b/source/blender/imbuf/intern/filetype.c @@ -77,7 +77,7 @@ const ImFileType IMB_FILE_TYPES[] = { {imb_initopenexr, NULL, imb_is_a_openexr, NULL, imb_ftype_default, imb_load_openexr, NULL, imb_save_openexr, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_OPENEXR, COLOR_ROLE_DEFAULT_FLOAT}, #endif #ifdef WITH_OPENJPEG - {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_jp2_decode, NULL, imb_savejp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE}, + {NULL, NULL, imb_is_a_jp2, NULL, imb_ftype_default, imb_load_jp2, NULL, imb_save_jp2, NULL, IM_FTYPE_FLOAT, IMB_FTYPE_JP2, COLOR_ROLE_DEFAULT_BYTE}, #endif #ifdef WITH_DDS {NULL, NULL, imb_is_a_dds, NULL, imb_ftype_default, imb_load_dds, NULL, NULL, NULL, 0, IMB_FTYPE_DDS, COLOR_ROLE_DEFAULT_BYTE}, diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index 753b5276222..e4923e94635 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -38,7 +38,1251 @@ #include "openjpeg.h" -// #define JP2_FILEHEADER_SIZE 14 /* UNUSED */ +/* Temporary duplicated implementations for version 1.5 and 2.3, until we + * upgrade all platforms to 2.3. When removing the old code, + * imb_load_jp2_filepath can be added in filetype.c. */ + +#if defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 + +#define JP2_FILEHEADER_SIZE 12 + +static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; +static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00}; + +/* We only need this because of how the presets are set */ +/* this typedef is copied from 'openjpeg-1.5.0/applications/codec/image_to_j2k.c' */ +typedef struct img_folder { + /** The directory path of the folder containing input images*/ + char *imgdirpath; + /** Output format*/ + char *out_format; + /** Enable option*/ + char set_imgdir; + /** Enable Cod Format for output*/ + char set_out_format; + /** User specified rate stored in case of cinema option*/ + float *rates; +} img_fol_t; + +enum { + DCP_CINEMA2K = 3, + DCP_CINEMA4K = 4, +}; + +static bool check_jp2(const unsigned char *mem) /* J2K_CFMT */ +{ + return memcmp(JP2_HEAD, mem, sizeof(JP2_HEAD)) ? 0 : 1; +} + +static bool check_j2k(const unsigned char *mem) /* J2K_CFMT */ +{ + return memcmp(J2K_HEAD, mem, sizeof(J2K_HEAD)) ? 0 : 1; +} + +static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADER_SIZE]) +{ + if (check_jp2(mem)) { + return OPJ_CODEC_JP2; + } + else if (check_j2k(mem)) { + return OPJ_CODEC_J2K; + } + else { + return OPJ_CODEC_UNKNOWN; + } +} + +int imb_is_a_jp2(const unsigned char *buf) +{ + return check_jp2(buf); +} + +/** + * sample error callback expecting a FILE* client object + */ +static void error_callback(const char *msg, void *client_data) +{ + FILE *stream = (FILE *)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** + * sample warning callback expecting a FILE* client object + */ +static void warning_callback(const char *msg, void *client_data) +{ + FILE *stream = (FILE *)client_data; + fprintf(stream, "[WARNING] %s", msg); +} + +#ifdef DEBUG +/** + * sample debug callback expecting no client object + */ +static void info_callback(const char *msg, void *client_data) +{ + FILE *stream = (FILE *)client_data; + fprintf(stream, "[INFO] %s", msg); +} +#endif + +# define PIXEL_LOOPER_BEGIN(_rect) \ + for (y = h - 1; y != (unsigned int)(-1); y--) { \ + for (i = y * w, i_next = (y + 1) * w; \ + i < i_next; \ + i++, _rect += 4) \ + { \ + +# define PIXEL_LOOPER_BEGIN_CHANNELS(_rect, _channels) \ + for (y = h - 1; y != (unsigned int)(-1); y--) { \ + for (i = y * w, i_next = (y + 1) * w; \ + i < i_next; \ + i++, _rect += _channels) \ + { \ + +# define PIXEL_LOOPER_END \ + } \ +} (void)0 \ + + +/** \name Buffer Stream + * \{ */ + +struct BufInfo { + const unsigned char *buf; + const unsigned char *cur; + off_t len; +}; + +static void opj_read_from_buffer_free(void *UNUSED(p_user_data)) +{ + /* nop */ +} + +static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) +{ + struct BufInfo *p_file = p_user_data; + OPJ_UINT32 l_nb_read; + + if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len ) { + l_nb_read = p_nb_bytes; + } + else { + l_nb_read = (OPJ_UINT32)(p_file->buf + p_file->len - p_file->cur); + } + memcpy(p_buffer, p_file->cur, l_nb_read); + p_file->cur += l_nb_read; + + return l_nb_read ? l_nb_read : ((OPJ_SIZE_T)-1); +} + +#if 0 +static OPJ_SIZE_T opj_write_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) +{ + struct BufInfo *p_file = p_user_data; + memcpy(p_file->cur, p_buffer, p_nb_bytes); + p_file->cur += p_nb_bytes; + p_file->len += p_nb_bytes; + return p_nb_bytes; +} +#endif + +static OPJ_OFF_T opj_skip_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data) +{ + struct BufInfo *p_file = p_user_data; + if (p_file->cur + p_nb_bytes < p_file->buf + p_file->len) { + p_file->cur += p_nb_bytes; + return p_nb_bytes; + } + p_file->cur = p_file->buf + p_file->len; + return (OPJ_OFF_T)-1; +} + +static OPJ_BOOL opj_seek_from_buffer(OPJ_OFF_T p_nb_bytes, void *p_user_data) +{ + struct BufInfo *p_file = p_user_data; + if (p_nb_bytes < p_file->len) { + p_file->cur = p_file->buf + p_nb_bytes; + return OPJ_TRUE; + } + p_file->cur = p_file->buf + p_file->len; + return OPJ_FALSE; +} + +/** + * Stream wrapper for memory buffer + * (would be nice if this was supported by the API). + */ + +static opj_stream_t *opj_stream_create_from_buffer( + struct BufInfo *p_file, OPJ_UINT32 p_size, + OPJ_BOOL p_is_read_stream) +{ + opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream); + if (l_stream == NULL) { + return NULL; + } + opj_stream_set_user_data(l_stream, p_file , opj_read_from_buffer_free); + opj_stream_set_user_data_length(l_stream, p_file->len); + opj_stream_set_read_function(l_stream, opj_read_from_buffer); +#if 0 /* UNUSED */ + opj_stream_set_write_function(l_stream, opj_write_from_buffer); +#endif + opj_stream_set_skip_function(l_stream, opj_skip_from_buffer); + opj_stream_set_seek_function(l_stream, opj_seek_from_buffer); + + return l_stream; +} + +/** \} */ + + +/** \name File Stream + * \{ */ + +static void opj_free_from_file(void *p_user_data) +{ + FILE *f = p_user_data; + fclose(f); +} + +static OPJ_UINT64 opj_get_data_length_from_file (void *p_user_data) +{ + FILE *p_file = p_user_data; + OPJ_OFF_T file_length = 0; + + fseek(p_file, 0, SEEK_END); + file_length = ftell(p_file); + fseek(p_file, 0, SEEK_SET); + + return (OPJ_UINT64)file_length; +} + +static OPJ_SIZE_T opj_read_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) +{ + FILE *p_file = p_user_data; + OPJ_SIZE_T l_nb_read = fread(p_buffer, 1, p_nb_bytes, p_file); + return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1; +} + +static OPJ_SIZE_T opj_write_from_file(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) +{ + FILE *p_file = p_user_data; + return fwrite(p_buffer, 1, p_nb_bytes, p_file); +} + +static OPJ_OFF_T opj_skip_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data) +{ + FILE *p_file = p_user_data; + if (fseek(p_file, p_nb_bytes, SEEK_CUR)) { + return -1; + } + return p_nb_bytes; +} + +static OPJ_BOOL opj_seek_from_file(OPJ_OFF_T p_nb_bytes, void *p_user_data) +{ + FILE *p_file = p_user_data; + if (fseek(p_file, p_nb_bytes, SEEK_SET)) { + return OPJ_FALSE; + } + return OPJ_TRUE; +} + +/** + * Stream wrapper for memory file + * (would be nice if this was supported by the API). + */ + +static opj_stream_t *opj_stream_create_from_file( + const char *filepath, OPJ_UINT32 p_size, OPJ_BOOL p_is_read_stream, + FILE **r_file) +{ + FILE *p_file = BLI_fopen(filepath, p_is_read_stream ? "rb" : "wb"); + if (p_file == NULL) { + return NULL; + } + + opj_stream_t *l_stream = opj_stream_create(p_size, p_is_read_stream); + if (l_stream == NULL) { + fclose(p_file); + return NULL; + } + + opj_stream_set_user_data(l_stream, p_file, opj_free_from_file); + opj_stream_set_user_data_length(l_stream, opj_get_data_length_from_file(p_file)); + opj_stream_set_write_function(l_stream, opj_write_from_file); + opj_stream_set_read_function(l_stream, opj_read_from_file); + opj_stream_set_skip_function(l_stream, opj_skip_from_file); + opj_stream_set_seek_function(l_stream, opj_seek_from_file); + + if (r_file) { + *r_file = p_file; + } + return l_stream; +} + +/** \} */ + +static ImBuf *imb_load_jp2_stream( + opj_stream_t *stream, OPJ_CODEC_FORMAT p_format, + int flags, char colorspace[IM_MAX_SPACE]); + +ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +{ + const OPJ_CODEC_FORMAT format = (size > JP2_FILEHEADER_SIZE) ? format_from_header(mem) : OPJ_CODEC_UNKNOWN; + struct BufInfo buf_wrapper = { .buf = mem, .cur = mem, .len = size, }; + opj_stream_t *stream = opj_stream_create_from_buffer(&buf_wrapper, OPJ_J2K_STREAM_CHUNK_SIZE, true); + ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); + opj_stream_destroy(stream); + return ibuf; +} + +ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM_MAX_SPACE]) +{ + FILE *p_file = NULL; + unsigned char mem[JP2_FILEHEADER_SIZE]; + opj_stream_t *stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, true, &p_file); + if (stream) { + return NULL; + } + else { + if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) { + opj_stream_destroy(stream); + return NULL; + } + else { + fseek(p_file, 0, SEEK_SET); + } + } + + const OPJ_CODEC_FORMAT format = format_from_header(mem); + ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace); + opj_stream_destroy(stream); + return ibuf; +} + + +static ImBuf *imb_load_jp2_stream( + opj_stream_t *stream, const OPJ_CODEC_FORMAT format, + int flags, char colorspace[IM_MAX_SPACE]) +{ + if (format == OPJ_CODEC_UNKNOWN) { + return NULL; + } + + struct ImBuf *ibuf = NULL; + bool use_float = false; /* for precision higher then 8 use float */ + bool use_alpha = false; + + long signed_offsets[4] = {0, 0, 0, 0}; + int float_divs[4] = {1, 1, 1, 1}; + + unsigned int i, i_next, w, h, planes; + unsigned int y; + int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ + + opj_dparameters_t parameters; /* decompression parameters */ + + opj_image_t *image = NULL; + opj_codec_t *codec = NULL; /* handle to a decompressor */ + + /* both 8, 12 and 16 bit JP2Ks are default to standard byte colorspace */ + colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); + + /* set decoding parameters to default values */ + opj_set_default_decoder_parameters(¶meters); + + /* JPEG 2000 compressed image data */ + + /* get a decoder handle */ + codec = opj_create_decompress(format); + + /* configure the event callbacks (not required) */ + opj_set_error_handler(codec, error_callback, stderr); + opj_set_warning_handler(codec, warning_callback, stderr); +#ifdef DEBUG /* too noisy */ + opj_set_info_handler(codec, info_callback, stderr); +#endif + + /* setup the decoder decoding parameters using the current image and user parameters */ + if (opj_setup_decoder(codec, ¶meters) == false) { + goto finally; + } + + if (opj_read_header(stream, codec, &image) == false) { + printf("OpenJPEG error: failed to read the header\n"); + goto finally; + } + + /* decode the stream and fill the image structure */ + if (opj_decode(codec, stream, image) == false) { + fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); + goto finally; + } + + if ((image->numcomps * image->x1 * image->y1) == 0) { + fprintf(stderr, "\nError: invalid raw image parameters\n"); + goto finally; + } + + w = image->comps[0].w; + h = image->comps[0].h; + + switch (image->numcomps) { + case 1: /* Grayscale */ + case 3: /* Color */ + planes = 24; + use_alpha = false; + break; + default: /* 2 or 4 - Grayscale or Color + alpha */ + planes = 32; /* grayscale + alpha */ + use_alpha = true; + break; + } + + + i = image->numcomps; + if (i > 4) i = 4; + + while (i) { + i--; + + if (image->comps[i].prec > 8) + use_float = true; + + if (image->comps[i].sgnd) + signed_offsets[i] = 1 << (image->comps[i].prec - 1); + + /* only needed for float images but dosnt hurt to calc this */ + float_divs[i] = (1 << image->comps[i].prec) - 1; + } + + ibuf = IMB_allocImBuf(w, h, planes, use_float ? IB_rectfloat : IB_rect); + + if (ibuf == NULL) { + goto finally; + } + + ibuf->ftype = IMB_FTYPE_JP2; + if (1 /* is_jp2 */ ) { + ibuf->foptions.flag |= JP2_JP2; + } + else { + ibuf->foptions.flag |= JP2_J2K; + } + + if (use_float) { + float *rect_float = ibuf->rect_float; + + if (image->numcomps < 3) { + r = image->comps[0].data; + a = (use_alpha) ? image->comps[1].data : NULL; + + /* grayscale 12bits+ */ + if (use_alpha) { + a = image->comps[1].data; + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[3] = (a[i] + signed_offsets[1]) / float_divs[1]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = rect_float[1] = rect_float[2] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[3] = 1.0f; + } + PIXEL_LOOPER_END; + } + } + else { + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + /* rgb or rgba 12bits+ */ + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; + rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; + rect_float[3] = (float)(a[i] + signed_offsets[3]) / float_divs[3]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_float) { + rect_float[0] = (float)(r[i] + signed_offsets[0]) / float_divs[0]; + rect_float[1] = (float)(g[i] + signed_offsets[1]) / float_divs[1]; + rect_float[2] = (float)(b[i] + signed_offsets[2]) / float_divs[2]; + rect_float[3] = 1.0f; + } + PIXEL_LOOPER_END; + } + } + + } + else { + unsigned char *rect_uchar = (unsigned char *)ibuf->rect; + + if (image->numcomps < 3) { + r = image->comps[0].data; + a = (use_alpha) ? image->comps[1].data : NULL; + + /* grayscale */ + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); + rect_uchar[3] = a[i] + signed_offsets[1]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = rect_uchar[1] = rect_uchar[2] = (r[i] + signed_offsets[0]); + rect_uchar[3] = 255; + } + PIXEL_LOOPER_END; + } + } + else { + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + /* 8bit rgb or rgba */ + if (use_alpha) { + a = image->comps[3].data; + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = r[i] + signed_offsets[0]; + rect_uchar[1] = g[i] + signed_offsets[1]; + rect_uchar[2] = b[i] + signed_offsets[2]; + rect_uchar[3] = a[i] + signed_offsets[3]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) { + rect_uchar[0] = r[i] + signed_offsets[0]; + rect_uchar[1] = g[i] + signed_offsets[1]; + rect_uchar[2] = b[i] + signed_offsets[2]; + rect_uchar[3] = 255; + } + PIXEL_LOOPER_END; + } + } + } + + if (flags & IB_rect) { + IMB_rect_from_float(ibuf); + } + +finally: + + /* free remaining structures */ + if (codec) { + opj_destroy_codec(codec); + } + + if (image) { + opj_image_destroy(image); + } + + return ibuf; +} + +//static opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) +/* prec can be 8, 12, 16 */ + +/* use inline because the float passed can be a function call that would end up being called many times */ +#if 0 +#define UPSAMPLE_8_TO_12(_val) ((_val << 4) | (_val & ((1 << 4) - 1))) +#define UPSAMPLE_8_TO_16(_val) ((_val << 8) + _val) + +#define DOWNSAMPLE_FLOAT_TO_8BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))) +#define DOWNSAMPLE_FLOAT_TO_12BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))) +#define DOWNSAMPLE_FLOAT_TO_16BIT(_val) (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))) +#else + +BLI_INLINE int UPSAMPLE_8_TO_12(const unsigned char _val) +{ + return (_val << 4) | (_val & ((1 << 4) - 1)); +} +BLI_INLINE int UPSAMPLE_8_TO_16(const unsigned char _val) +{ + return (_val << 8) + _val; +} + +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_8BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 255 : (int)(255.0f * (_val))); +} +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_12BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 4095 : (int)(4095.0f * (_val))); +} +BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val) +{ + return (_val) <= 0.0f ? 0 : ((_val) >= 1.0f ? 65535 : (int)(65535.0f * (_val))); +} +#endif + +/* + * 2048x1080 (2K) at 24 fps or 48 fps, or 4096x2160 (4K) at 24 fps; 3x12 bits per pixel, XYZ color space + * + * - In 2K, for Scope (2.39:1) presentation 2048x858 pixels of the image is used + * - In 2K, for Flat (1.85:1) presentation 1998x1080 pixels of the image is used + */ + +/* ****************************** COPIED FROM image_to_j2k.c */ + +/* ----------------------------------------------------------------------- */ +#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/ +#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/ +#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/ +#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ + + +static int initialise_4K_poc(opj_poc_t *POC, int numres) +{ + POC[0].tile = 1; + POC[0].resno0 = 0; + POC[0].compno0 = 0; + POC[0].layno1 = 1; + POC[0].resno1 = numres - 1; + POC[0].compno1 = 3; + POC[0].prg1 = OPJ_CPRL; + POC[1].tile = 1; + POC[1].resno0 = numres - 1; + POC[1].compno0 = 0; + POC[1].layno1 = 1; + POC[1].resno1 = numres; + POC[1].compno1 = 3; + POC[1].prg1 = OPJ_CPRL; + return 2; +} + +static void cinema_parameters(opj_cparameters_t *parameters) +{ + parameters->tile_size_on = 0; /* false */ + parameters->cp_tdx = 1; + parameters->cp_tdy = 1; + + /*Tile part*/ + parameters->tp_flag = 'C'; + parameters->tp_on = 1; + + /*Tile and Image shall be at (0, 0)*/ + parameters->cp_tx0 = 0; + parameters->cp_ty0 = 0; + parameters->image_offset_x0 = 0; + parameters->image_offset_y0 = 0; + + /*Codeblock size = 32 * 32*/ + parameters->cblockw_init = 32; + parameters->cblockh_init = 32; + parameters->csty |= 0x01; + + /*The progression order shall be CPRL*/ + parameters->prog_order = OPJ_CPRL; + + /* No ROI */ + parameters->roi_compno = -1; + + parameters->subsampling_dx = 1; parameters->subsampling_dy = 1; + + /* 9-7 transform */ + parameters->irreversible = 1; +} + +static void cinema_setup_encoder(opj_cparameters_t *parameters, opj_image_t *image, img_fol_t *img_fol) +{ + int i; + float temp_rate; + + switch (parameters->cp_cinema) { + case OPJ_CINEMA2K_24: + case OPJ_CINEMA2K_48: + if (parameters->numresolution > 6) { + parameters->numresolution = 6; + } + if (!((image->comps[0].w == 2048) || (image->comps[0].h == 1080))) { + fprintf(stdout, "Image coordinates %u x %u is not 2K compliant.\nJPEG Digital Cinema Profile-3 " + "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n", + image->comps[0].w, image->comps[0].h); + parameters->cp_rsiz = OPJ_STD_RSIZ; + } + else { + parameters->cp_rsiz = DCP_CINEMA2K; + } + break; + + case OPJ_CINEMA4K_24: + if (parameters->numresolution < 1) { + parameters->numresolution = 1; + } + else if (parameters->numresolution > 7) { + parameters->numresolution = 7; + } + if (!((image->comps[0].w == 4096) || (image->comps[0].h == 2160))) { + fprintf(stdout, "Image coordinates %u x %u is not 4K compliant.\nJPEG Digital Cinema Profile-4" + "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n", + image->comps[0].w, image->comps[0].h); + parameters->cp_rsiz = OPJ_STD_RSIZ; + } + else { + parameters->cp_rsiz = DCP_CINEMA2K; + } + parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution); + break; + case OPJ_OFF: + /* do nothing */ + break; + } + + switch (parameters->cp_cinema) { + case OPJ_CINEMA2K_24: + case OPJ_CINEMA4K_24: + for (i = 0; i < parameters->tcp_numlayers; i++) { + temp_rate = 0; + if (img_fol->rates[i] == 0) { + parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); + } + else { + temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); + if (temp_rate > CINEMA_24_CS) { + parameters->tcp_rates[i] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); + } + else { + parameters->tcp_rates[i] = img_fol->rates[i]; + } + } + } + parameters->max_comp_size = COMP_24_CS; + break; + + case OPJ_CINEMA2K_48: + for (i = 0; i < parameters->tcp_numlayers; i++) { + temp_rate = 0; + if (img_fol->rates[i] == 0) { + parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); + } + else { + temp_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); + if (temp_rate > CINEMA_48_CS) { + parameters->tcp_rates[0] = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)) / + (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); + } + else { + parameters->tcp_rates[i] = img_fol->rates[i]; + } + } + } + parameters->max_comp_size = COMP_48_CS; + break; + case OPJ_OFF: + /* do nothing */ + break; + } + parameters->cp_disto_alloc = 1; +} + +static float channel_colormanage_noop(float value) +{ + return value; +} + +static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) +{ + unsigned char *rect_uchar; + float *rect_float, from_straight[4]; + + unsigned int subsampling_dx = parameters->subsampling_dx; + unsigned int subsampling_dy = parameters->subsampling_dy; + + unsigned int i, i_next, numcomps, w, h, prec; + unsigned int y; + int *r, *g, *b, *a; /* matching 'opj_image_comp.data' type */ + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[4]; /* maximum of 4 components */ + opj_image_t *image = NULL; + + float (*chanel_colormanage_cb)(float); + + img_fol_t img_fol; /* only needed for cinema presets */ + memset(&img_fol, 0, sizeof(img_fol_t)); + + if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { + /* float buffer was managed already, no need in color space conversion */ + chanel_colormanage_cb = channel_colormanage_noop; + } + else { + /* standard linear-to-srgb conversion if float buffer wasn't managed */ + chanel_colormanage_cb = linearrgb_to_srgb; + } + + if (ibuf->foptions.flag & JP2_CINE) { + + if (ibuf->x == 4096 || ibuf->y == 2160) + parameters->cp_cinema = OPJ_CINEMA4K_24; + else { + if (ibuf->foptions.flag & JP2_CINE_48FPS) { + parameters->cp_cinema = OPJ_CINEMA2K_48; + } + else { + parameters->cp_cinema = OPJ_CINEMA2K_24; + } + } + if (parameters->cp_cinema) { + img_fol.rates = (float *)MEM_mallocN(parameters->tcp_numlayers * sizeof(float), "jp2_rates"); + for (i = 0; i < parameters->tcp_numlayers; i++) { + img_fol.rates[i] = parameters->tcp_rates[i]; + } + cinema_parameters(parameters); + } + + color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB; + prec = 12; + numcomps = 3; + } + else { + /* Get settings from the imbuf */ + color_space = (ibuf->foptions.flag & JP2_YCC) ? OPJ_CLRSPC_SYCC : OPJ_CLRSPC_SRGB; + + if (ibuf->foptions.flag & JP2_16BIT) prec = 16; + else if (ibuf->foptions.flag & JP2_12BIT) prec = 12; + else prec = 8; + + /* 32bit images == alpha channel */ + /* grayscale not supported yet */ + numcomps = (ibuf->planes == 32) ? 4 : 3; + } + + w = ibuf->x; + h = ibuf->y; + + + /* initialize image components */ + memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t)); + for (i = 0; i < numcomps; i++) { + cmptparm[i].prec = prec; + cmptparm[i].bpp = prec; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = subsampling_dx; + cmptparm[i].dy = subsampling_dy; + cmptparm[i].w = w; + cmptparm[i].h = h; + } + /* create the image */ + image = opj_image_create(numcomps, &cmptparm[0], color_space); + if (!image) { + printf("Error: opj_image_create() failed\n"); + return NULL; + } + + /* set image offset and reference grid */ + image->x0 = parameters->image_offset_x0; + image->y0 = parameters->image_offset_y0; + image->x1 = image->x0 + (w - 1) * subsampling_dx + 1 + image->x0; + image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0; + + /* set image data */ + rect_uchar = (unsigned char *) ibuf->rect; + rect_float = ibuf->rect_float; + + /* set the destination channels */ + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + a = (numcomps == 4) ? image->comps[3].data : NULL; + + if (rect_float && rect_uchar && prec == 8) { + /* No need to use the floating point buffer, just write the 8 bits from the char buffer */ + rect_float = NULL; + } + + if (rect_float) { + int channels_in_float = ibuf->channels ? ibuf->channels : 4; + + switch (prec) { + case 8: /* Convert blenders float color channels to 8, 12 or 16bit ints */ + if (numcomps == 4) { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_8BIT(from_straight[3]); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2])); + a[i] = 255; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + a[i] = 255; + } + PIXEL_LOOPER_END; + } + } + else { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(from_straight[2])); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_8BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + } + PIXEL_LOOPER_END; + } + } + break; + + case 12: + if (numcomps == 4) { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_12BIT(from_straight[3]); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2])); + a[i] = 4095; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + a[i] = 4095; + } + PIXEL_LOOPER_END; + } + } + else { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(from_straight[2])); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_12BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + } + PIXEL_LOOPER_END; + } + } + break; + + case 16: + if (numcomps == 4) { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2])); + a[i] = DOWNSAMPLE_FLOAT_TO_16BIT(from_straight[3]); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2])); + a[i] = 65535; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + a[i] = 65535; + } + PIXEL_LOOPER_END; + } + } + else { + if (channels_in_float == 4) { + PIXEL_LOOPER_BEGIN(rect_float) + { + premul_to_straight_v4_v4(from_straight, rect_float); + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(from_straight[2])); + } + PIXEL_LOOPER_END; + } + else if (channels_in_float == 3) { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 3) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[1])); + b[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[2])); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN_CHANNELS(rect_float, 1) + { + r[i] = DOWNSAMPLE_FLOAT_TO_16BIT(chanel_colormanage_cb(rect_float[0])); + g[i] = b[i] = r[i]; + } + PIXEL_LOOPER_END; + } + } + break; + } + } + else { + /* just use rect*/ + switch (prec) { + case 8: + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = rect_uchar[0]; + g[i] = rect_uchar[1]; + b[i] = rect_uchar[2]; + a[i] = rect_uchar[3]; + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = rect_uchar[0]; + g[i] = rect_uchar[1]; + b[i] = rect_uchar[2]; + } + PIXEL_LOOPER_END; + } + break; + + case 12: /* Up Sampling, a bit pointless but best write the bit depth requested */ + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); + a[i] = UPSAMPLE_8_TO_12(rect_uchar[3]); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = UPSAMPLE_8_TO_12(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_12(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_12(rect_uchar[2]); + } + PIXEL_LOOPER_END; + } + break; + + case 16: + if (numcomps == 4) { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); + a[i] = UPSAMPLE_8_TO_16(rect_uchar[3]); + } + PIXEL_LOOPER_END; + } + else { + PIXEL_LOOPER_BEGIN(rect_uchar) + { + r[i] = UPSAMPLE_8_TO_16(rect_uchar[0]); + g[i] = UPSAMPLE_8_TO_16(rect_uchar[1]); + b[i] = UPSAMPLE_8_TO_16(rect_uchar[2]); + } + PIXEL_LOOPER_END; + } + break; + } + } + + /* Decide if MCT should be used */ + parameters->tcp_mct = image->numcomps == 3 ? 1 : 0; + + if (parameters->cp_cinema) { + cinema_setup_encoder(parameters, image, &img_fol); + } + + if (img_fol.rates) + MEM_freeN(img_fol.rates); + + return image; +} + +int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int flags); + +int imb_save_jp2(struct ImBuf *ibuf, const char *filepath, int flags) +{ + opj_stream_t *stream = opj_stream_create_from_file(filepath, OPJ_J2K_STREAM_CHUNK_SIZE, false, NULL); + if (stream == NULL) { + return 0; + } + int ret = imb_save_jp2_stream(ibuf, stream, flags); + opj_stream_destroy(stream); + return ret; +} + +/* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ +int imb_save_jp2_stream(struct ImBuf *ibuf, opj_stream_t *stream, int UNUSED(flags)) +{ + int quality = ibuf->foptions.quality; + + opj_cparameters_t parameters; /* compression parameters */ + opj_image_t *image = NULL; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + + /* compression ratio */ + /* invert range, from 10-100, 100-1 + * where jpeg see's 1 and highest quality (lossless) and 100 is very low quality*/ + parameters.tcp_rates[0] = ((100 - quality) / 90.0f * 99.0f) + 1; + + + parameters.tcp_numlayers = 1; /* only one resolution */ + parameters.cp_disto_alloc = 1; + + image = ibuftoimage(ibuf, ¶meters); + + opj_codec_t *codec = NULL; + int ok = false; + /* JP2 format output */ + { + /* get a JP2 compressor handle */ + OPJ_CODEC_FORMAT format = OPJ_CODEC_JP2; + if (ibuf->foptions.flag & JP2_J2K) { + format = OPJ_CODEC_J2K; + } + else if (ibuf->foptions.flag & JP2_JP2) { + format = OPJ_CODEC_JP2; + } + + codec = opj_create_compress(format); + + /* configure the event callbacks (not required) */ + opj_set_error_handler(codec, error_callback, stderr); + opj_set_warning_handler(codec, warning_callback, stderr); +#ifdef DEBUG /* too noisy */ + opj_set_info_handler(codec, info_callback, stderr); +#endif + + /* setup the encoder parameters using the current image and using user parameters */ + if (opj_setup_encoder(codec, ¶meters, image) == false) { + goto finally; + } + + if (opj_start_compress(codec, image, stream) == false) { + goto finally; + } + if (opj_encode(codec, stream) == false) { + goto finally; + } + if (opj_end_compress(codec, stream) == false) { + goto finally; + } + } + + ok = true; + +finally: + /* free remaining compression structures */ + if (codec) { + opj_destroy_codec(codec); + } + + /* free image data */ + if (image) { + opj_image_destroy(image); + } + + if (ok == false) { + fprintf(stderr, "failed to encode image\n"); + } + + return ok; +} + +#else /* defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 */ static const char JP2_HEAD[] = {0x0, 0x0, 0x0, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A}; static const char J2K_HEAD[] = {0xFF, 0x4F, 0xFF, 0x51, 0x00}; @@ -94,6 +1338,7 @@ static void warning_callback(const char *msg, void *client_data) FILE *stream = (FILE *)client_data; fprintf(stream, "[WARNING] %s", msg); } + /** * sample debug callback expecting no client object */ @@ -121,7 +1366,7 @@ static void info_callback(const char *msg, void *client_data) } \ } (void)0 \ -struct ImBuf *imb_jp2_decode(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +struct ImBuf *imb_load_jp2(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { struct ImBuf *ibuf = NULL; bool use_float = false; /* for precision higher then 8 use float */ @@ -960,7 +2205,7 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) /* Found write info at http://users.ece.gatech.edu/~slabaugh/personal/c/bitmapUnix.c */ -int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) +int imb_save_jp2(struct ImBuf *ibuf, const char *name, int flags) { int quality = ibuf->foptions.quality; @@ -1051,3 +2296,5 @@ int imb_savejp2(struct ImBuf *ibuf, const char *name, int flags) return 1; } + +#endif /* defined(OPJ_VERSION_MAJOR) && OPJ_VERSION_MAJOR >= 2 */ -- cgit v1.2.3 From 05c0992c9b8fd852855b908fcd6333678360c307 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Wed, 8 Aug 2018 20:35:08 +0200 Subject: GP: Fix modifiers Tint, Opacity and Hue and create materials to Opacity Thanks to Charlie Jolly (mistajolly@gmail.com) for his patch D3586 that added create materials to opacity modifier. I had to do some more changes to get all running. --- .../startup/bl_ui/properties_data_modifier.py | 3 + .../gpencil_modifiers/intern/MOD_gpencil_util.c | 2 +- .../gpencil_modifiers/intern/MOD_gpencilopacity.c | 64 ++++++++++++---------- .../blender/makesdna/DNA_gpencil_modifier_types.h | 1 + .../blender/makesrna/intern/rna_gpencil_modifier.c | 5 ++ 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 3a1801f2a53..5b3d89c30a5 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1802,6 +1802,9 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row = col.row(align=True) row.prop(md, "pass_index", text="Pass") row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT") + + row = layout.row() + row.prop(md, "create_materials") def GP_INSTANCE(self, layout, ob, md): gpd = ob.data diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 151218c06e4..3914d960a79 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -165,7 +165,7 @@ void gpencil_apply_modifier_material( copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - BLI_ghash_insert(gh_color, mat->id.name, newmat); + BLI_ghash_insert(gh_color, newmat->id.name, newmat); DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); } /* reasign color index */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 74b24acdfb6..541b37523b2 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -31,6 +31,8 @@ #include #include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "DNA_meshdata_types.h" @@ -44,6 +46,7 @@ #include "BKE_material.h" #include "BKE_gpencil.h" #include "BKE_gpencil_modifier.h" +#include "BKE_main.h" #include "DEG_depsgraph.h" @@ -57,6 +60,7 @@ static void initData(GpencilModifierData *md) gpmd->factor = 1.0f; gpmd->layername[0] = '\0'; gpmd->vgname[0] = '\0'; + gpmd->flag |= GP_OPACITY_CREATE_COLORS; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) @@ -70,29 +74,28 @@ static void deformStroke( Object *ob, bGPDlayer *gpl, bGPDstroke *gps) { OpacityGpencilModifierData *mmd = (OpacityGpencilModifierData *)md; - MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); int vindex = defgroup_name_index(ob, mmd->vgname); if (!is_stroke_affected_by_modifier( ob, - mmd->layername, mmd->pass_index, 3, gpl, gps, + mmd->layername, mmd->pass_index, 1, gpl, gps, mmd->flag & GP_OPACITY_INVERT_LAYER, mmd->flag & GP_OPACITY_INVERT_PASS)) { return; } - gp_style->fill_rgba[3] *= mmd->factor; + gps->runtime.tmp_fill_rgba[3] *= mmd->factor; /* if factor is > 1, then force opacity */ if (mmd->factor > 1.0f) { - gp_style->stroke_rgba[3] += mmd->factor - 1.0f; - if (gp_style->fill_rgba[3] > 1e-5) { - gp_style->fill_rgba[3] += mmd->factor - 1.0f; + gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; + if (gps->runtime.tmp_fill_rgba[3] > 1e-5) { + gps->runtime.tmp_fill_rgba[3] += mmd->factor - 1.0f; } } - CLAMP(gp_style->stroke_rgba[3], 0.0f, 1.0f); - CLAMP(gp_style->fill_rgba[3], 0.0f, 1.0f); + CLAMP(gps->runtime.tmp_stroke_rgba[3], 0.0f, 1.0f); + CLAMP(gps->runtime.tmp_fill_rgba[3], 0.0f, 1.0f); /* if opacity > 1.0, affect the strength of the stroke */ if (mmd->factor > 1.0f) { @@ -111,40 +114,43 @@ static void deformStroke( CLAMP(pt->strength, 0.0f, 1.0f); } } - else { - for (int i = 0; i < gps->totpoints; i++) { - bGPDspoint *pt = &gps->points[i]; - MDeformVert *dvert = &gps->dvert[i]; - - /* verify vertex group */ - if (mmd->vgname == NULL) { - pt->strength *= mmd->factor; - } - else { - float weight = get_modifier_point_weight(dvert, ((mmd->flag & GP_OPACITY_INVERT_VGROUP) != 0), vindex); - if (weight >= 0) { - pt->strength *= mmd->factor * weight; - } - } - CLAMP(pt->strength, 0.0f, 1.0f); - } - } - } static void bakeModifier( - struct Main *UNUSED(bmain), Depsgraph *depsgraph, - GpencilModifierData *md, Object *ob) + Main *bmain, Depsgraph *depsgraph, + GpencilModifierData *md, Object *ob) { + OpacityGpencilModifierData *mmd = (OpacityGpencilModifierData *)md; bGPdata *gpd = ob->data; + GHash *gh_color = BLI_ghash_str_new("GP_Opacity modifier"); for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { + + Material *mat = give_current_material(ob, gps->mat_nr + 1); + if (mat == NULL) + continue; + MaterialGPencilStyle *gp_style = mat->gp_style; + /* skip stroke if it doesn't have color info */ + if (ELEM(NULL, gp_style)) + continue; + + copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); + copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); + deformStroke(md, depsgraph, ob, gpl, gps); + + gpencil_apply_modifier_material(bmain, ob, mat, gh_color, gps, + (bool)(mmd->flag & GP_OPACITY_CREATE_COLORS)); } } } + /* free hash buffers */ + if (gh_color) { + BLI_ghash_free(gh_color, NULL, NULL); + gh_color = NULL; + } } GpencilModifierTypeInfo modifierType_Gpencil_Opacity = { diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 1e3a4bf09f0..c1e2244427e 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -182,6 +182,7 @@ typedef enum eOpacityGpencil_Flag { GP_OPACITY_INVERT_LAYER = (1 << 0), GP_OPACITY_INVERT_PASS = (1 << 1), GP_OPACITY_INVERT_VGROUP = (1 << 2), + GP_OPACITY_CREATE_COLORS = (1 << 3), } eOpacityGpencil_Flag; typedef struct InstanceGpencilModifierData { diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 1bfcf415a94..4f29ed58ba7 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -788,6 +788,11 @@ static void rna_def_modifier_gpencilopacity(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Factor", "Factor of Opacity"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "create_materials", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OPACITY_CREATE_COLORS); + RNA_def_property_ui_text(prop, "Create Materials", "When apply modifier, create new material"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "pass_index"); RNA_def_property_range(prop, 0, 100); -- cgit v1.2.3 From 82352565b79d1abb3b6f513bf186c1b3d80e8f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 3 Aug 2018 18:53:36 +0200 Subject: Eevee: Remove some of the non-necessary uniforms The remaining ones are from the attributes linear/srgb switches and from nodes that should be pruned before running their _gpu function. --- .../blender/draw/engines/eevee/eevee_materials.c | 81 ++++++++++++++-------- source/blender/gpu/GPU_material.h | 8 +++ source/blender/gpu/intern/gpu_material.c | 13 ++++ .../blender/gpu/shaders/gpu_shader_material.glsl | 2 +- .../shader/nodes/node_shader_bsdf_anisotropic.c | 2 + .../nodes/shader/nodes/node_shader_bsdf_diffuse.c | 2 + .../nodes/shader/nodes/node_shader_bsdf_glass.c | 2 + .../nodes/shader/nodes/node_shader_bsdf_glossy.c | 2 + .../shader/nodes/node_shader_bsdf_principled.c | 2 + .../shader/nodes/node_shader_bsdf_refraction.c | 2 + .../shader/nodes/node_shader_bsdf_translucent.c | 2 + .../nodes/shader/nodes/node_shader_bsdf_velvet.c | 2 + .../nodes/node_shader_subsurface_scattering.c | 2 + 13 files changed, 92 insertions(+), 30 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 535dce7730a..769ac11736d 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -360,7 +360,9 @@ static char *eevee_get_volume_defines(int options) **/ static void add_standard_uniforms( DRWShadingGroup *shgrp, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - int *ssr_id, float *refract_depth, bool use_ssrefraction, bool use_alpha_blend) + int *ssr_id, float *refract_depth, + bool use_diffuse, bool use_glossy, bool use_refract, + bool use_ssrefraction, bool use_alpha_blend) { LightCache *lcache = vedata->stl->g_data->light_cache; @@ -377,13 +379,13 @@ static void add_standard_uniforms( DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo); - /* TODO if glossy or diffuse bsdf */ - if (true) { + if (use_diffuse || use_glossy || use_refract) { DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex); DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool); DRW_shgroup_uniform_texture_ref(shgrp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); - + } + if ((use_diffuse || use_glossy) && !use_refract) { if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) != 0) { DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->stl->effects->gtao_horizons); } @@ -392,15 +394,13 @@ static void add_standard_uniforms( DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &vedata->txl->maxzbuffer); } } - - /* TODO if diffuse bsdf */ - if (true) { + if (use_diffuse) { DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex); } - - /* TODO if glossy bsdf */ - if (true) { + if (use_glossy || use_refract) { DRW_shgroup_uniform_texture_ref(shgrp, "probeCubes", &lcache->cube_tx.tex); + } + if (use_glossy) { DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); } @@ -851,7 +851,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create( } DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, use_blend); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, use_blend); return shgrp; } @@ -888,7 +888,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( * EDIT: THIS IS NOT THE CASE FOR HAIRS !!! DUMMY!!! */ if (!is_hair) { DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); } } @@ -896,7 +896,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get( DRWShadingGroup *shgrp = DRW_shgroup_hair_create(ob, psys, md, vedata->psl->default_pass[options], e_data.default_lit[options]); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); return shgrp; } else { @@ -928,7 +928,7 @@ static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get( DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass); /* XXX / WATCH: This creates non persistent binds for the ubos and textures. * But it's currently OK because the following shgroups does not add any bind. */ - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false); } return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass); @@ -1116,6 +1116,7 @@ static void material_opaque( EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; EEVEE_LampsInfo *linfo = sldata->lamps; + bool use_diffuse, use_glossy, use_refract; float *color_p = &ma->r; float *metal_p = &ma->metallic; @@ -1123,7 +1124,7 @@ static void material_opaque( float *rough_p = &ma->roughness; const bool use_gpumat = (ma->use_nodes && ma->nodetree); - const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && + const bool use_ssrefract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((effects->enabled_effects & EFFECT_REFRACT) != 0); const bool use_sss = ((ma->blend_flag & MA_BL_SS_SUBSURFACE) != 0) && ((effects->enabled_effects & EFFECT_SSS) != 0); @@ -1138,7 +1139,7 @@ static void material_opaque( /* This will have been created already, just perform a lookup. */ *gpumat = (use_gpumat) ? EEVEE_material_mesh_get( - scene, ma, vedata, false, false, use_refract, use_sss, use_translucency, linfo->shadow_method) : NULL; + scene, ma, vedata, false, false, use_ssrefract, use_sss, use_translucency, linfo->shadow_method) : NULL; *gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get( scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL; return; @@ -1151,7 +1152,7 @@ static void material_opaque( /* Shading */ *gpumat = EEVEE_material_mesh_get( - scene, ma, vedata, false, false, use_refract, + scene, ma, vedata, false, false, use_ssrefract, use_sss, use_translucency, linfo->shadow_method); GPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat); @@ -1167,7 +1168,7 @@ static void material_opaque( * the surface shader. */ status_mat_surface = status_mat_depth; } - else if (use_refract) { + else if (use_ssrefract) { *shgrp_depth = DRW_shgroup_material_create( *gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass); *shgrp_depth_clip = DRW_shgroup_material_create( @@ -1181,8 +1182,14 @@ static void material_opaque( } if (*shgrp_depth != NULL) { - add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, false, false); - add_standard_uniforms(*shgrp_depth_clip, sldata, vedata, NULL, NULL, false, false); + use_diffuse = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_DIFFUSE); + use_glossy = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_GLOSSY); + use_refract = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_REFRACT); + + add_standard_uniforms(*shgrp_depth, sldata, vedata, NULL, NULL, + use_diffuse, use_glossy, use_refract, false, false); + add_standard_uniforms(*shgrp_depth_clip, sldata, vedata, NULL, NULL, + use_diffuse, use_glossy, use_refract, false, false); if (ma->blend_method == MA_BM_CLIP) { DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1); @@ -1200,13 +1207,18 @@ static void material_opaque( { static int no_ssr = -1; static int first_ssr = 1; - int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr; + int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_ssrefract) ? &first_ssr : &no_ssr; + use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE); + use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY); + use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT); *shgrp = DRW_shgroup_material_create( *gpumat, - (use_refract) ? psl->refract_pass : + (use_ssrefract) ? psl->refract_pass : (use_sss) ? psl->sss_pass : psl->material_pass); - add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false); + + add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, + use_diffuse, use_glossy, use_refract, use_ssrefract, false); if (use_sss) { struct GPUTexture *sss_tex_profile = NULL; @@ -1237,7 +1249,6 @@ static void material_opaque( } case GPU_MAT_QUEUED: { - /* TODO Bypass probe compilation. */ color_p = compile_col; metal_p = spec_p = rough_p = ½ break; @@ -1264,7 +1275,7 @@ static void material_opaque( /* Fallback default depth prepass */ if (*shgrp_depth == NULL) { - if (use_refract) { + if (use_ssrefract) { *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp; *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip; } @@ -1292,7 +1303,7 @@ static void material_transparent( EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; EEVEE_LampsInfo *linfo = sldata->lamps; - const bool use_refract = ( + const bool use_ssrefract = ( ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0) ); @@ -1308,7 +1319,7 @@ static void material_transparent( /* Shading */ *gpumat = EEVEE_material_mesh_get( - scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract, + scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_ssrefract, false, false, linfo->shadow_method); switch (GPU_material_status(*gpumat)) { @@ -1318,7 +1329,13 @@ static void material_transparent( bool use_blend = (ma->blend_method & MA_BM_BLEND) != 0; *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass); - add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract, use_blend); + + bool use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE); + bool use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY); + bool use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT); + + add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, + use_diffuse, use_glossy, use_refract, use_ssrefract, use_blend); break; } case GPU_MAT_QUEUED: @@ -1643,11 +1660,17 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, switch (GPU_material_status(gpumat)) { case GPU_MAT_SUCCESS: { + bool use_diffuse = GPU_material_flag_get(gpumat, GPU_MATFLAG_DIFFUSE); + bool use_glossy = GPU_material_flag_get(gpumat, GPU_MATFLAG_GLOSSY); + bool use_refract = GPU_material_flag_get(gpumat, GPU_MATFLAG_REFRACT); + shgrp = DRW_shgroup_material_hair_create( ob, psys, md, psl->material_pass, gpumat); - add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false); + + add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, + use_diffuse, use_glossy, use_refract, false, false); break; } case GPU_MAT_QUEUED: diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 5945621cb65..cc1150b6d77 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -124,6 +124,11 @@ typedef enum GPUMatType { GPU_MATERIAL_TYPE_WORLD = 2, } GPUMatType; +typedef enum GPUMatFlag { + GPU_MATFLAG_DIFFUSE = (1 << 0), + GPU_MATFLAG_GLOSSY = (1 << 1), + GPU_MATFLAG_REFRACT = (1 << 2), +} GPUMatFlag; typedef enum GPUBlendMode { GPU_BLEND_SOLID = 0, @@ -270,6 +275,9 @@ bool GPU_material_do_color_management(GPUMaterial *mat); bool GPU_material_use_domain_surface(GPUMaterial *mat); bool GPU_material_use_domain_volume(GPUMaterial *mat); +void GPU_material_flag_set(GPUMaterial *mat, GPUMatFlag flag); +bool GPU_material_flag_get(GPUMaterial *mat, GPUMatFlag flag); + void GPU_pass_cache_init(void); void GPU_pass_cache_garbage_collect(void); void GPU_pass_cache_free(void); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9859f56c1db..69c3a3a73ba 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -109,6 +109,9 @@ struct GPUMaterial { */ int domain; + /* Only used by Eevee to know which bsdf are used. */ + int flag; + /* Used by 2.8 pipeline */ GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */ @@ -564,6 +567,16 @@ bool GPU_material_use_domain_volume(GPUMaterial *mat) return (mat->domain & GPU_DOMAIN_VOLUME); } +void GPU_material_flag_set(GPUMaterial *mat, GPUMatFlag flag) +{ + mat->flag |= flag; +} + +bool GPU_material_flag_get(GPUMaterial *mat, GPUMatFlag flag) +{ + return (mat->flag & flag); +} + GPUMaterial *GPU_material_from_nodetree_find( ListBase *gpumaterials, const void *engine_type, int options) { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 064ee42907e..808d2f73659 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1102,7 +1102,7 @@ void node_bsdf_anisotropic( vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T, out Closure result) { - node_bsdf_diffuse(color, 0.0, N, result); + node_bsdf_glossy(color, roughness, N, -1, result); } void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index c1423867d96..6551b20a375 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -54,6 +54,8 @@ static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *node, bNode if (!in[4].link) GPU_link(mat, "world_normals_get", &in[4].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_anisotropic", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index 58a37b0e81d..c1b8c748657 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *node, bNodeExec if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_diffuse", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 7b060bc68aa..ada6e21356f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index c3fb43c0ce8..f56837de261 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -51,6 +51,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_uniform(&node->ssr_id)); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 7f02295d45f..831ac1c98da 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -117,6 +117,8 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE GPU_link(mat, "set_rgb", GPU_uniform((float *)one), &sss_scale); } + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id), GPU_uniform(&node->sss_id), sss_scale); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c index 41dd3f8af3c..b59f1c80342 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.c @@ -52,6 +52,8 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, bNode *node, bNodeE if (!in[3].link) GPU_link(mat, "world_normals_get", &in[3].link); + GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT); + return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index 2c0949f275c..349db30af14 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -45,6 +45,8 @@ static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *node, bNode if (!in[1].link) GPU_link(mat, "world_normals_get", &in[1].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_translucent", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index ce331f03d4e..59b831c0dab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -46,6 +46,8 @@ static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *node, bNodeExecD if (!in[2].link) GPU_link(mat, "world_normals_get", &in[2].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + return GPU_stack_link(mat, node, "node_bsdf_velvet", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c index 57fb9026595..3f0ba3c1c60 100644 --- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c +++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c @@ -54,6 +54,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node, if (!in[5].link) GPU_link(mat, "world_normals_get", &in[5].link); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + if (node->sss_id == 1) { bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2); bNodeSocketValueRGBA *socket_data = socket->default_value; -- cgit v1.2.3 From 26d46d00cfa73efe8e434796634dd23e76abbf19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 8 Aug 2018 12:18:02 +0200 Subject: GPUMaterial: Fix Material appear broken when using sliders to tweak props This was likely caused by some sort of race condition where the drawing thread would request the state of the shader before the shader has been compiled. --- source/blender/gpu/intern/gpu_codegen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index c6cf0c55594..cc4b7cc8ebc 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -1894,9 +1894,8 @@ void GPU_nodes_prune(ListBase *nodes, GPUNodeLink *outlink) static bool gpu_pass_is_valid(GPUPass *pass) { - /* Shader is not null if compilation is successful, - * refcount is positive if compilation as not yet been done. */ - return (pass->shader != NULL || pass->refcount > 0); + /* Shader is not null if compilation is successful. */ + return (pass->compiled == false || pass->shader != NULL); } GPUPass *GPU_generate_pass_new( -- cgit v1.2.3 From cac43e1765ab128880bd410d3b8387dc7143f740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 8 Aug 2018 18:34:25 +0200 Subject: Eevee: Use "constant folding" for the principle shader This is more like a static optimisation when some parameters are set to 1.0 or 0.0. In theses case we use a more optimized version of the node. This also revisit the transmission parameter behaviour to make it closer to cycles. --- .../blender/draw/engines/eevee/eevee_materials.c | 4 +- .../engines/eevee/shaders/bsdf_common_lib.glsl | 8 + .../engines/eevee/shaders/lit_surface_frag.glsl | 15 ++ source/blender/gpu/GPU_material.h | 1 + .../blender/gpu/shaders/gpu_shader_material.glsl | 183 +++++++++++++++++---- .../shader/nodes/node_shader_bsdf_principled.c | 59 +++++-- .../shader/nodes/node_shader_eevee_specular.c | 2 + 7 files changed, 225 insertions(+), 47 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 769ac11736d..cd6b5db5b56 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -405,7 +405,7 @@ static void add_standard_uniforms( DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); } - if (use_ssrefraction) { + if (use_refract || use_ssrefraction) { BLI_assert(refract_depth != NULL); DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1); DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->refract_color); @@ -563,6 +563,8 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E datatoc_lit_surface_frag_glsl, datatoc_lit_surface_frag_glsl, datatoc_lit_surface_frag_glsl, + datatoc_lit_surface_frag_glsl, + datatoc_lit_surface_frag_glsl, datatoc_volumetric_lib_glsl); e_data.volume_shader_lib = BLI_string_joinN( diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 8b232bf14a4..286f00783d9 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -548,6 +548,14 @@ float F_eta(float eta, float cos_theta) return result; } +/* Fresnel color blend base on fresnel factor */ +vec3 F_color_blend(float eta, float fresnel, vec3 f0_color) +{ + float f0 = F_eta(eta, 1.0); + float fac = saturate((fresnel - f0) / max(1e-8, 1.0 - f0)); + return mix(f0_color, vec3(1.0), fac); +} + /* Fresnel */ vec3 F_schlick(vec3 f0, float cos_theta) { diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index 22194c22f39..c2e45ebb879 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -54,6 +54,13 @@ uniform int hairThicknessRes = 1; #define CLOSURE_SUBSURFACE #endif /* SURFACE_PRINCIPLED */ +#if !defined(SURFACE_CLEARCOAT) && !defined(CLOSURE_NAME) + #define SURFACE_CLEARCOAT + #define CLOSURE_NAME eevee_closure_clearcoat + #define CLOSURE_GLOSSY + #define CLOSURE_CLEARCOAT +#endif /* SURFACE_CLEARCOAT */ + #if !defined(SURFACE_DIFFUSE) && !defined(CLOSURE_NAME) #define SURFACE_DIFFUSE #define CLOSURE_NAME eevee_closure_diffuse @@ -67,6 +74,14 @@ uniform int hairThicknessRes = 1; #define CLOSURE_SUBSURFACE #endif /* SURFACE_SUBSURFACE */ +#if !defined(SURFACE_SKIN) && !defined(CLOSURE_NAME) + #define SURFACE_SKIN + #define CLOSURE_NAME eevee_closure_skin + #define CLOSURE_DIFFUSE + #define CLOSURE_SUBSURFACE + #define CLOSURE_GLOSSY +#endif /* SURFACE_SKIN */ + #if !defined(SURFACE_GLOSSY) && !defined(CLOSURE_NAME) #define SURFACE_GLOSSY #define CLOSURE_NAME eevee_closure_glossy diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index cc1150b6d77..9dcf308a414 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -128,6 +128,7 @@ typedef enum GPUMatFlag { GPU_MATFLAG_DIFFUSE = (1 << 0), GPU_MATFLAG_GLOSSY = (1 << 1), GPU_MATFLAG_REFRACT = (1 << 2), + GPU_MATFLAG_SSS = (1 << 3), } GPUMatFlag; typedef enum GPUBlendMode { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 808d2f73659..c9564a21d15 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1069,11 +1069,11 @@ void convert_metallic_to_specular_tinted( vec3 basecol, float metallic, float specular_fac, float specular_tint, out vec3 diffuse, out vec3 f0) { - vec3 dielectric = vec3(0.034) * specular_fac * 2.0; float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ - f0 = mix(dielectric * mix(vec3(1.0), tint, specular_tint), basecol, metallic); - diffuse = mix(basecol, vec3(0.0), metallic); + vec3 tmp_col = mix(vec3(1.0), tint, specular_tint); + f0 = mix((0.08 * specular_fac) * tmp_col, basecol, metallic); + diffuse = basecol * (1.0 - metallic); } #ifndef VOLUMETRICS @@ -1126,52 +1126,142 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure r node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, - float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, - float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, - float sss_id, vec3 sss_scale, out Closure result) +void node_bsdf_principled( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) { + ior = max(ior, 1e-5); metallic = saturate(metallic); transmission = saturate(transmission); + float dielectric = 1.0 - metallic; + transmission *= dielectric; + subsurface_color *= dielectric; vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec; convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); - transmission *= 1.0 - metallic; - subsurface *= 1.0 - metallic; - - clearcoat *= 0.25; - clearcoat *= 1.0 - transmission; + /* Far from being accurate, but 2 glossy evaluation is too expensive. + * Most noticeable difference is at grazing angles since the bsdf lut + * f0 color interpolation is done on top of this interpolation. */ + vec3 f0_glass = mix(vec3(1.0), base_color.rgb, specular_tint); + float fresnel = F_eta(ior, dot(N, cameraVec)); + vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel; + f0 = mix(f0, spec_col, transmission); vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); -#ifdef USE_SSS - diffuse = vec3(0.0); -#else - diffuse = mixed_ss_base_color; -#endif - - f0 = mix(f0, vec3(1.0), transmission); - float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; eevee_closure_principled(N, mixed_ss_base_color, f0, int(ssr_id), roughness, - CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior, + CN, clearcoat * 0.25, clearcoat_roughness, 1.0, sss_scalef, ior, out_diff, out_trans, out_spec, out_refr, ssr_spec); vec3 refr_color = base_color.rgb; refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */ + out_refr *= refr_color * (1.0 - fresnel) * transmission; - float fresnel = F_eta(ior, dot(N, cameraVec)); - vec3 refr_spec_color = base_color.rgb * fresnel; - /* This bit maybe innacurate. */ - out_refr = out_refr * refr_color * (1.0 - fresnel) + out_spec * refr_spec_color; + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = out_spec + out_refr; +#ifndef USE_SSS + result.radiance += (out_diff + out_trans) * mixed_ss_base_color * (1.0 - transmission); +#endif + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +#ifdef USE_SSS + result.sss_data.a = sss_scalef; + result.sss_data.rgb = out_diff + out_trans; +# ifdef USE_SSS_ALBEDO + result.sss_albedo.rgb = mixed_ss_base_color; +# else + result.sss_data.rgb *= mixed_ss_base_color; +# endif + result.sss_data.rgb *= (1.0 - transmission); +#endif +} + +void node_bsdf_principled_dielectric( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + metallic = saturate(metallic); + float dielectric = 1.0 - metallic; + + vec3 diffuse, f0, out_diff, out_spec, ssr_spec; + convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); - ssr_spec = mix(ssr_spec, refr_spec_color, transmission); + eevee_closure_default(N, diffuse, f0, int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec); vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; result.radiance = out_spec + out_diff * diffuse; - result.radiance = mix(result.radiance, out_refr, transmission); + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +} + +void node_bsdf_principled_metallic( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + vec3 out_spec, ssr_spec; + + eevee_closure_glossy(N, base_color.rgb, int(ssr_id), roughness, 1.0, out_spec, ssr_spec); + + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = out_spec; + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +} + +void node_bsdf_principled_clearcoat( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + vec3 out_spec, ssr_spec; + + eevee_closure_clearcoat(N, base_color.rgb, int(ssr_id), roughness, CN, clearcoat * 0.25, clearcoat_roughness, + 1.0, out_spec, ssr_spec); + + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = out_spec; + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +} + +void node_bsdf_principled_subsurface( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + metallic = saturate(metallic); + + vec3 diffuse, f0, out_diff, out_spec, out_trans, ssr_spec; + convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); + + subsurface_color = subsurface_color * (1.0 - metallic); + vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); + float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + + eevee_closure_skin(N, mixed_ss_base_color, f0, int(ssr_id), roughness, 1.0, sss_scalef, + out_diff, out_trans, out_spec, ssr_spec); + + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = out_spec; result.ssr_data = vec4(ssr_spec, roughness); result.ssr_normal = normal_encode(vN, viewCameraVec); result.ssr_id = int(ssr_id); @@ -1183,10 +1273,41 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs # else result.sss_data.rgb *= mixed_ss_base_color; # endif - result.sss_data.rgb *= (1.0 - transmission); +#else + result.radiance += (out_diff + out_trans) * mixed_ss_base_color; #endif } +void node_bsdf_principled_glass( + vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular, + float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat, + float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, float ssr_id, + float sss_id, vec3 sss_scale, out Closure result) +{ + ior = max(ior, 1e-5); + + vec3 f0, out_spec, out_refr, ssr_spec; + f0 = mix(vec3(1.0), base_color.rgb, specular_tint); + + eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec); + + vec3 refr_color = base_color.rgb; + refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission events */ + out_refr *= refr_color; + + float fresnel = F_eta(ior, dot(N, cameraVec)); + vec3 spec_col = F_color_blend(ior, fresnel, f0); + out_spec *= spec_col; + ssr_spec *= spec_col * fresnel; + + vec3 vN = normalize(mat3(ViewMatrix) * N); + result = CLOSURE_DEFAULT; + result.radiance = mix(out_refr, out_spec, fresnel); + result.ssr_data = vec4(ssr_spec, roughness); + result.ssr_normal = normal_encode(vN, viewCameraVec); + result.ssr_id = int(ssr_id); +} + void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) { node_bsdf_diffuse(color, 0.0, -N, result); @@ -1220,13 +1341,13 @@ void node_subsurface_scattering( result.sss_data.a = scale; eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans); result.sss_data.rgb = out_diff + out_trans; -#ifdef USE_SSS_ALBEDO +# ifdef USE_SSS_ALBEDO /* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */ result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur); result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur); -#else +# else result.sss_data.rgb *= color.rgb; -#endif +# endif #else node_bsdf_diffuse(color, 0.0, N, result); #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index 831ac1c98da..370dcdcc2ea 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -64,22 +64,12 @@ static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node) node->custom2 = SHD_SUBSURFACE_BURLEY; } +#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f)) +#define socket_not_one(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f)) + static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { GPUNodeLink *sss_scale; -#if 0 /* Old 2.7 glsl viewport */ - // normal - if (!in[17].link) - in[17].link = GPU_builtin(GPU_VIEW_NORMAL); - else - GPU_link(mat, "direction_transform_m4v3", in[17].link, GPU_builtin(GPU_VIEW_MATRIX), &in[17].link); - - // clearcoat normal - if (!in[18].link) - in[18].link = GPU_builtin(GPU_VIEW_NORMAL); - else - GPU_link(mat, "direction_transform_m4v3", in[18].link, GPU_builtin(GPU_VIEW_MATRIX), &in[18].link); -#endif /* Normals */ if (!in[17].link) { @@ -117,9 +107,48 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeE GPU_link(mat, "set_rgb", GPU_uniform((float *)one), &sss_scale); } - GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); + bool use_diffuse = socket_not_one(4) && socket_not_one(15); + bool use_subsurf = socket_not_zero(1) && use_diffuse; + bool use_refract = socket_not_one(4) && socket_not_zero(15); + bool use_clear = socket_not_zero(12); + + /* Due to the manual effort done per config, we only optimize the most common permutations. */ + char *node_name; + uint flag = 0; + if (!use_subsurf && use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_dielectric"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_metallic"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && !use_refract && use_clear) { + static char name[] = "node_bsdf_principled_clearcoat"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY; + } + else if (use_subsurf && use_diffuse && !use_refract && !use_clear) { + static char name[] = "node_bsdf_principled_subsurface"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS | GPU_MATFLAG_GLOSSY; + } + else if (!use_subsurf && !use_diffuse && use_refract && !use_clear && !socket_not_zero(4)) { + static char name[] = "node_bsdf_principled_glass"; + node_name = name; + flag = GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT; + } + else { + static char name[] = "node_bsdf_principled"; + node_name = name; + flag = GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY | GPU_MATFLAG_SSS | GPU_MATFLAG_REFRACT; + } + + GPU_material_flag_set(mat, flag); - return GPU_stack_link(mat, node, "node_bsdf_principled_clearcoat", in, out, GPU_builtin(GPU_VIEW_POSITION), + return GPU_stack_link(mat, node, node_name, in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&node->ssr_id), GPU_uniform(&node->sss_id), sss_scale); } diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c index e05b0be1e62..6583dd0cec3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c +++ b/source/blender/nodes/shader/nodes/node_shader_eevee_specular.c @@ -67,6 +67,8 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat, bNode *node, bNodeEx GPU_link(mat, "set_value", GPU_uniform(&one), &in[9].link); } + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_GLOSSY); + return GPU_stack_link(mat, node, "node_eevee_specular", in, out, GPU_uniform(&node->ssr_id)); } -- cgit v1.2.3 From b8fc6317c765ef28a5cd359b3192280c8a69c301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 8 Aug 2018 20:14:42 +0200 Subject: Eevee: Remove per material SSS toggle This is because we can now optimize the use of SSS on shaders based on socket input values. --- release/scripts/startup/bl_ui/properties_material.py | 6 +----- source/blender/draw/engines/eevee/eevee_materials.c | 5 ++--- source/blender/makesdna/DNA_material_types.h | 2 +- source/blender/makesrna/intern/rna_material.c | 5 ----- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 5d12f762073..706ce497dee 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -212,11 +212,7 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel): layout.prop(mat, "use_screen_refraction") layout.prop(mat, "refraction_depth") - - layout.prop(mat, "use_screen_subsurface") - row = layout.row() - row.active = mat.use_screen_subsurface - row.prop(mat, "use_sss_translucency") + layout.prop(mat, "use_sss_translucency") class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel): diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index cd6b5db5b56..9ef64477aca 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -404,7 +404,6 @@ static void add_standard_uniforms( DRW_shgroup_uniform_texture_ref(shgrp, "probePlanars", &vedata->txl->planar_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); } - if (use_refract || use_ssrefraction) { BLI_assert(refract_depth != NULL); DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1); @@ -1128,8 +1127,7 @@ static void material_opaque( const bool use_gpumat = (ma->use_nodes && ma->nodetree); const bool use_ssrefract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((effects->enabled_effects & EFFECT_REFRACT) != 0); - const bool use_sss = ((ma->blend_flag & MA_BL_SS_SUBSURFACE) != 0) && - ((effects->enabled_effects & EFFECT_SSS) != 0); + bool use_sss = ((effects->enabled_effects & EFFECT_SSS) != 0); const bool use_translucency = use_sss && ((ma->blend_flag & MA_BL_TRANSLUCENCY) != 0); EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma); @@ -1213,6 +1211,7 @@ static void material_opaque( use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE); use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY); use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT); + use_sss = use_sss && GPU_material_flag_get(*gpumat, GPU_MATFLAG_SSS); *shgrp = DRW_shgroup_material_create( *gpumat, diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 50d9b890724..9d4da91aaed 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -273,7 +273,7 @@ enum { enum { MA_BL_HIDE_BACKSIDE = (1 << 0), MA_BL_SS_REFRACTION = (1 << 1), - MA_BL_SS_SUBSURFACE = (1 << 2), + MA_BL_SS_SUBSURFACE = (1 << 2), /* DEPRECATED */ MA_BL_TRANSLUCENCY = (1 << 3), }; diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index b6250a81b3b..44d14975ab0 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -688,11 +688,6 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Screen Space Refraction", "Use raytraced screen space refractions"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - prop = RNA_def_property(srna, "use_screen_subsurface", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_SS_SUBSURFACE); - RNA_def_property_ui_text(prop, "Screen Space Subsurface Scattering", "Use post process subsurface scattering"); - RNA_def_property_update(prop, 0, "rna_Material_draw_update"); - prop = RNA_def_property(srna, "use_sss_translucency", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_TRANSLUCENCY); RNA_def_property_ui_text(prop, "Subsurface Translucency", "Add translucency effect to subsurface"); -- cgit v1.2.3 From c009b09f125853c66da3d6c0cdb53b8d2334b556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 8 Aug 2018 20:15:00 +0200 Subject: Eevee: Fix Clearcoat intensity --- source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index c2e45ebb879..c31fa166634 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -230,7 +230,7 @@ void CLOSURE_NAME( #endif #ifdef CLOSURE_CLEARCOAT - out_spec_clear += l_color_vis * light_specular(ld, ltc_mat_clear, C_N, V, l_vector) * C_intensity * ld.l_spec; + out_spec_clear += l_color_vis * light_specular(ld, ltc_mat_clear, C_N, V, l_vector) * ld.l_spec; #endif } @@ -241,8 +241,8 @@ void CLOSURE_NAME( #ifdef CLOSURE_CLEARCOAT vec3 brdf_lut_lamps_clear = texture(utilTex, vec3(lut_uv_clear, 1.0)).rgb; - out_spec_clear *= F_area(f0, brdf_lut_lamps_clear.xy) * brdf_lut_lamps_clear.z; - out_spec += out_spec_clear; + out_spec_clear *= F_area(vec3(0.04), brdf_lut_lamps_clear.xy) * brdf_lut_lamps_clear.z; + out_spec += out_spec_clear * C_intensity; #endif /* ---------------------------------------------------------------- */ @@ -432,7 +432,7 @@ void CLOSURE_NAME( NV = dot(C_N, V); vec2 C_uv = lut_coords(NV, C_roughness); vec2 C_brdf_lut = texture(utilTex, vec3(C_uv, 1.0)).rg; - vec3 C_fresnel = F_ibl(vec3(0.04), brdf_lut) * specular_occlusion(NV, final_ao, C_roughness); + vec3 C_fresnel = F_ibl(vec3(0.04), C_brdf_lut) * specular_occlusion(NV, final_ao, C_roughness); out_spec += C_spec_accum.rgb * C_fresnel * C_intensity; #endif -- cgit v1.2.3 From 3aee3bbac7317d205b611b9aa713791f17104556 Mon Sep 17 00:00:00 2001 From: Andrew Hale Date: Thu, 9 Aug 2018 08:10:27 +1000 Subject: Math Lib: varied size vector multiply Needed for Python mathutils elementwise multiply. --- source/blender/blenlib/BLI_math_vector.h | 2 ++ source/blender/blenlib/intern/math_vector.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 39625346756..59c9341f75c 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -354,6 +354,8 @@ void range_vn_u(unsigned int *array_tar, const int size, const unsigned int star void range_vn_fl(float *array_tar, const int size, const float start, const float step); void negate_vn(float *array_tar, const int size); void negate_vn_vn(float *array_tar, const float *array_src, const int size); +void mul_vn_vn(float *array_tar, const float *array_src, const int size); +void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size); void mul_vn_fl(float *array_tar, const int size, const float f); void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f); void add_vn_vn(float *array_tar, const float *array_src, const int size); diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index d6e48fa59e7..acb4ee87f69 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -1096,6 +1096,27 @@ void negate_vn_vn(float *array_tar, const float *array_src, const int size) } } +void mul_vn_vn(float *array_tar, const float *array_src, const int size) +{ + float *tar = array_tar + (size - 1); + const float *src = array_src + (size - 1); + int i = size; + while (i--) { + *(tar--) *= *(src--); + } +} + +void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size) +{ + float *tar = array_tar + (size - 1); + const float *src_a = array_src_a + (size - 1); + const float *src_b = array_src_b + (size - 1); + int i = size; + while (i--) { + *(tar--) = *(src_a--) * *(src_b--); + } +} + void mul_vn_fl(float *array_tar, const int size, const float f) { float *array_pt = array_tar + (size - 1); -- cgit v1.2.3 From 0de50a98e384012628ea38dfceebd99f64bcea47 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 9 Aug 2018 12:04:00 +0200 Subject: Fix T56239: creating material crashes with OpenGL render engine selected. --- source/blender/editors/render/render_preview.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 069611be35d..8bb60b19dcf 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -237,7 +237,13 @@ void ED_preview_ensure_dbase(void) static bool check_engine_supports_textures(Scene *scene) { RenderEngineType *type = RE_engines_find(scene->r.engine); - return type->flag & RE_USE_TEXTURE_PREVIEW; + return (type->flag & RE_USE_TEXTURE_PREVIEW) != 0; +} + +static bool check_engine_supports_preview(Scene *scene) +{ + RenderEngineType *type = RE_engines_find(scene->r.engine); + return (type->flag & RE_USE_PREVIEW) != 0; } void ED_preview_free_dbase(void) @@ -753,6 +759,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs sce->r.size = 100; } + /* get the stuff from the builtin preview dbase */ sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp); if (sce == NULL) return; @@ -1092,6 +1099,10 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short continue; } + if (!check_engine_supports_preview(ip->scene)) { + continue; + } + ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); const bool is_render = !(prv->tag & PRV_TAG_DEFFERED); @@ -1268,6 +1279,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ + if (!check_engine_supports_preview(scene)) { + return; + } + /* Only texture node preview is supported with Cycles. */ if (method == PR_NODE_RENDER && id_type != ID_TE) { return; -- cgit v1.2.3 From f284821bf714cca98d86ede1e2a9713094d1d686 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 9 Aug 2018 13:39:35 +0200 Subject: GP: Undo incorrect modification in previous commit --- source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 3914d960a79..151218c06e4 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -165,7 +165,7 @@ void gpencil_apply_modifier_material( copy_v4_v4(newmat->gp_style->stroke_rgba, gps->runtime.tmp_stroke_rgba); copy_v4_v4(newmat->gp_style->fill_rgba, gps->runtime.tmp_fill_rgba); - BLI_ghash_insert(gh_color, newmat->id.name, newmat); + BLI_ghash_insert(gh_color, mat->id.name, newmat); DEG_id_tag_update(&newmat->id, DEG_TAG_COPY_ON_WRITE); } /* reasign color index */ -- cgit v1.2.3 From 2e10c658f42a842404f16a1b03ff4844e41d538c Mon Sep 17 00:00:00 2001 From: Charlie Jolly Date: Thu, 9 Aug 2018 13:42:02 +0200 Subject: GP: Add option to select color affected in modifiers Now it's possible to define if the Tint, Hue and OPacity modifier affect the stroke color, fill color or both. --- .../startup/bl_ui/properties_data_modifier.py | 4 ++++ .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 21 ++++++++++++-------- .../gpencil_modifiers/intern/MOD_gpencilopacity.c | 22 +++++++++++++-------- .../gpencil_modifiers/intern/MOD_gpenciltint.c | 23 +++++++++++++--------- .../blender/makesdna/DNA_gpencil_modifier_types.h | 14 +++++++++++-- .../blender/makesrna/intern/rna_gpencil_modifier.c | 22 +++++++++++++++++++++ 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 5b3d89c30a5..9acc7996bb9 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -1757,6 +1757,8 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row = layout.row() row.prop(md, "create_materials") + row.prop(md, "modify_color") + def GP_COLOR(self, layout, ob, md): gpd = ob.data @@ -1779,6 +1781,7 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row = layout.row() row.prop(md, "create_materials") + row.prop(md, "modify_color") def GP_OPACITY(self, layout, ob, md): gpd = ob.data @@ -1805,6 +1808,7 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel): row = layout.row() row.prop(md, "create_materials") + row.prop(md, "modify_color") def GP_INSTANCE(self, layout, ob, md): gpd = ob.data diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 4c087577699..40ffe293d41 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -60,6 +60,7 @@ static void initData(GpencilModifierData *md) ARRAY_SET_ITEMS(gpmd->hsv, 1.0f, 1.0f, 1.0f); gpmd->layername[0] = '\0'; gpmd->flag |= GP_COLOR_CREATE_COLORS; + gpmd->modify_color = GP_MODIFY_COLOR_BOTH; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) @@ -86,15 +87,19 @@ static void deformStroke( copy_v3_v3(factor, mmd->hsv); add_v3_fl(factor, -1.0f); - rgb_to_hsv_v(gps->runtime.tmp_stroke_rgba, hsv); - add_v3_v3(hsv, factor); - CLAMP3(hsv, 0.0f, 1.0f); - hsv_to_rgb_v(hsv, gps->runtime.tmp_stroke_rgba); + if (mmd->modify_color != GP_MODIFY_COLOR_FILL) { + rgb_to_hsv_v(gps->runtime.tmp_stroke_rgba, hsv); + add_v3_v3(hsv, factor); + CLAMP3(hsv, 0.0f, 1.0f); + hsv_to_rgb_v(hsv, gps->runtime.tmp_stroke_rgba); + } - rgb_to_hsv_v(gps->runtime.tmp_fill_rgba, hsv); - add_v3_v3(hsv, factor); - CLAMP3(hsv, 0.0f, 1.0f); - hsv_to_rgb_v(hsv, gps->runtime.tmp_fill_rgba); + if (mmd->modify_color != GP_MODIFY_COLOR_STROKE) { + rgb_to_hsv_v(gps->runtime.tmp_fill_rgba, hsv); + add_v3_v3(hsv, factor); + CLAMP3(hsv, 0.0f, 1.0f); + hsv_to_rgb_v(hsv, gps->runtime.tmp_fill_rgba); + } } static void bakeModifier( diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 541b37523b2..e0484e19959 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -61,6 +61,7 @@ static void initData(GpencilModifierData *md) gpmd->layername[0] = '\0'; gpmd->vgname[0] = '\0'; gpmd->flag |= GP_OPACITY_CREATE_COLORS; + gpmd->modify_color = GP_MODIFY_COLOR_BOTH; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) @@ -84,19 +85,24 @@ static void deformStroke( return; } - gps->runtime.tmp_fill_rgba[3] *= mmd->factor; + if (mmd->modify_color != GP_MODIFY_COLOR_FILL) { + gps->runtime.tmp_stroke_rgba[3] *= mmd->factor; + /* if factor is > 1, then force opacity */ + if (mmd->factor > 1.0f) { + gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; + } + CLAMP(gps->runtime.tmp_stroke_rgba[3], 0.0f, 1.0f); + } - /* if factor is > 1, then force opacity */ - if (mmd->factor > 1.0f) { - gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; - if (gps->runtime.tmp_fill_rgba[3] > 1e-5) { + if (mmd->modify_color != GP_MODIFY_COLOR_STROKE) { + gps->runtime.tmp_fill_rgba[3] *= mmd->factor; + /* if factor is > 1, then force opacity */ + if (mmd->factor > 1.0f && gps->runtime.tmp_fill_rgba[3] > 1e-5) { gps->runtime.tmp_fill_rgba[3] += mmd->factor - 1.0f; } + CLAMP(gps->runtime.tmp_fill_rgba[3], 0.0f, 1.0f); } - CLAMP(gps->runtime.tmp_stroke_rgba[3], 0.0f, 1.0f); - CLAMP(gps->runtime.tmp_fill_rgba[3], 0.0f, 1.0f); - /* if opacity > 1.0, affect the strength of the stroke */ if (mmd->factor > 1.0f) { for (int i = 0; i < gps->totpoints; i++) { diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 06212451d48..8af9ff6eec8 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -60,6 +60,7 @@ static void initData(GpencilModifierData *md) gpmd->layername[0] = '\0'; ARRAY_SET_ITEMS(gpmd->rgb, 1.0f, 1.0f, 1.0f); gpmd->flag |= GP_TINT_CREATE_COLORS; + gpmd->modify_color = GP_MODIFY_COLOR_BOTH; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) @@ -81,20 +82,24 @@ static void deformStroke( return; } - interp_v3_v3v3(gps->runtime.tmp_stroke_rgba, gps->runtime.tmp_stroke_rgba, mmd->rgb, mmd->factor); - interp_v3_v3v3(gps->runtime.tmp_fill_rgba, gps->runtime.tmp_fill_rgba, mmd->rgb, mmd->factor); + if (mmd->modify_color != GP_MODIFY_COLOR_FILL) { + interp_v3_v3v3(gps->runtime.tmp_stroke_rgba, gps->runtime.tmp_stroke_rgba, mmd->rgb, mmd->factor); + /* if factor is > 1, the alpha must be changed to get full tint */ + if (mmd->factor > 1.0f) { + gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; + } + CLAMP4(gps->runtime.tmp_stroke_rgba, 0.0f, 1.0f); + } - /* if factor is > 1, the alpha must be changed to get full tint */ - if (mmd->factor > 1.0f) { - gps->runtime.tmp_stroke_rgba[3] += mmd->factor - 1.0f; - if (gps->runtime.tmp_fill_rgba[3] > 1e-5) { + if (mmd->modify_color != GP_MODIFY_COLOR_STROKE) { + interp_v3_v3v3(gps->runtime.tmp_fill_rgba, gps->runtime.tmp_fill_rgba, mmd->rgb, mmd->factor); + /* if factor is > 1, the alpha must be changed to get full tint */ + if (mmd->factor > 1.0f && gps->runtime.tmp_fill_rgba[3] > 1e-5) { gps->runtime.tmp_fill_rgba[3] += mmd->factor - 1.0f; } + CLAMP4(gps->runtime.tmp_fill_rgba, 0.0f, 1.0f); } - CLAMP4(gps->runtime.tmp_stroke_rgba, 0.0f, 1.0f); - CLAMP4(gps->runtime.tmp_fill_rgba, 0.0f, 1.0f); - /* if factor > 1.0, affect the strength of the stroke */ if (mmd->factor > 1.0f) { for (int i = 0; i < gps->totpoints; i++) { diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index c1e2244427e..ae3621576f2 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -138,6 +138,12 @@ typedef enum eThickGpencil_Flag { GP_THICK_NORMALIZE = (1 << 4), } eThickGpencil_Flag; +typedef enum eModifyColorGpencil_Flag { + GP_MODIFY_COLOR_BOTH = 0, + GP_MODIFY_COLOR_STROKE = 1, + GP_MODIFY_COLOR_FILL = 2 +} eModifyColorGpencil_Flag; + typedef struct TintGpencilModifierData { GpencilModifierData modifier; char layername[64]; /* layer name */ @@ -145,6 +151,8 @@ typedef struct TintGpencilModifierData { int flag; /* flags */ float rgb[3]; /* Tint color */ float factor; /* Mix factor */ + char modify_color; /* modify stroke, fill or both */ + char pad[7]; } TintGpencilModifierData; typedef enum eTintGpencil_Flag { @@ -159,7 +167,8 @@ typedef struct ColorGpencilModifierData { int pass_index; /* custom index for passes */ int flag; /* flags */ float hsv[3]; /* hsv factors */ - char pad[4]; + char modify_color; /* modify stroke, fill or both */ + char pad[3]; } ColorGpencilModifierData; typedef enum eColorGpencil_Flag { @@ -175,7 +184,8 @@ typedef struct OpacityGpencilModifierData { int pass_index; /* custom index for passes */ int flag; /* flags */ float factor; /* Main Opacity factor */ - char pad[4]; + char modify_color; /* modify stroke, fill or both */ + char pad[3]; } OpacityGpencilModifierData; typedef enum eOpacityGpencil_Flag { diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 4f29ed58ba7..c137eec7568 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -82,6 +82,13 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = { }; #ifndef RNA_RUNTIME +static const EnumPropertyItem modifier_modify_color_items[] = { + { GP_MODIFY_COLOR_BOTH, "BOTH", 0, "Both", "Modify fill and stroke colors" }, + { GP_MODIFY_COLOR_STROKE, "STROKE", 0, "Stroke", "Modify stroke color only" }, + { GP_MODIFY_COLOR_FILL, "FILL", 0, "Fill", "Modify fill color only" }, + { 0, NULL, 0, NULL, NULL } +}; + static const EnumPropertyItem modifier_gphook_falloff_items[] = { { eGPHook_Falloff_None, "NONE", 0, "No Falloff", "" }, { eGPHook_Falloff_Curve, "CURVE", 0, "Curve", "" }, @@ -663,6 +670,11 @@ static void rna_def_modifier_gpenciltint(BlenderRNA *brna) RNA_def_struct_sdna(srna, "TintGpencilModifierData"); RNA_def_struct_ui_icon(srna, ICON_COLOR); + prop = RNA_def_property(srna, "modify_color", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, modifier_modify_color_items); /* share the enum */ + RNA_def_property_ui_text(prop, "Mode", "Set what colors of the stroke are affected"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "layername"); RNA_def_property_ui_text(prop, "Layer", "Layer name"); @@ -713,6 +725,11 @@ static void rna_def_modifier_gpencilcolor(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ColorGpencilModifierData"); RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL); + prop = RNA_def_property(srna, "modify_color", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, modifier_modify_color_items); /* share the enum */ + RNA_def_property_ui_text(prop, "Mode", "Set what colors of the stroke are affected"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "layername"); RNA_def_property_ui_text(prop, "Layer", "Layer name"); @@ -771,6 +788,11 @@ static void rna_def_modifier_gpencilopacity(BlenderRNA *brna) RNA_def_struct_sdna(srna, "OpacityGpencilModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_MASK); + prop = RNA_def_property(srna, "modify_color", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, modifier_modify_color_items); /* share the enum */ + RNA_def_property_ui_text(prop, "Mode", "Set what colors of the stroke are affected"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "layername"); RNA_def_property_ui_text(prop, "Layer", "Layer name"); -- cgit v1.2.3 From 42c2066d08216bb57492fef441ee20217444d395 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Thu, 9 Aug 2018 18:36:38 +0530 Subject: Fixed custom shading not updating in Edit Mode --- source/blender/draw/intern/draw_cache_impl_mesh.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 87737fae820..ba16dab0623 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -427,7 +427,9 @@ static MeshRenderData *mesh_render_data_create_ex( int totloop = bm->totloop; if (is_auto_smooth) { rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__); - BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1, false); + int cd_loop_clnors_offset = CustomData_get_clone_layer_index(&bm->ldata, CD_CUSTOMLOOPNORMAL); + BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, + cd_loop_clnors_offset, false); } rdata->loop_len = totloop; bm_ensure_types |= BM_LOOP; -- cgit v1.2.3 From fea5f26ea56acd73d043e97a96d06067b24ef811 Mon Sep 17 00:00:00 2001 From: Rohan Rathi Date: Thu, 9 Aug 2018 18:56:46 +0530 Subject: Fix trivial error in call --- source/blender/draw/intern/draw_cache_impl_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index ba16dab0623..dcfb9229cc1 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -427,7 +427,7 @@ static MeshRenderData *mesh_render_data_create_ex( int totloop = bm->totloop; if (is_auto_smooth) { rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__); - int cd_loop_clnors_offset = CustomData_get_clone_layer_index(&bm->ldata, CD_CUSTOMLOOPNORMAL); + int cd_loop_clnors_offset = CustomData_get_layer_index(&bm->ldata, CD_CUSTOMLOOPNORMAL); BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, cd_loop_clnors_offset, false); } -- cgit v1.2.3 From a241286859114c6091a86186aa680d638917a05a Mon Sep 17 00:00:00 2001 From: fclem Date: Thu, 9 Aug 2018 15:27:19 +0200 Subject: Cycles: Util, add to_string() with some helper Currently unused, but will allow to convert unknown argument type to a string for reporting and such. --- intern/cycles/util/util_string.cpp | 5 +++++ intern/cycles/util/util_string.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index 995f5d3df27..47119e90a45 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -168,6 +168,11 @@ string string_from_bool(bool var) return "False"; } +string to_string(const char *str) +{ + return string(str); +} + /* Wide char strings helpers for Windows. */ #ifdef _WIN32 diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h index 7dfa97335a9..3a4f4398158 100644 --- a/intern/cycles/util/util_string.h +++ b/intern/cycles/util/util_string.h @@ -29,6 +29,7 @@ using std::string; using std::stringstream; using std::ostringstream; using std::istringstream; +using std::to_string; #ifdef __GNUC__ #define PRINTF_ATTRIBUTE __attribute__((format(printf, 1, 2))) @@ -49,6 +50,7 @@ bool string_endswith(const string& s, const char *end); string string_strip(const string& s); string string_remove_trademark(const string& s); string string_from_bool(const bool var); +string to_string(const char *str); /* Wide char strings are only used on Windows to deal with non-ascii * characters in file names and such. No reason to use such strings -- cgit v1.2.3 From 01feb5d6cc3ffac99778ef2ef7b66b6b24e0980d Mon Sep 17 00:00:00 2001 From: fclem Date: Thu, 9 Aug 2018 15:31:44 +0200 Subject: Cycles: Report more details about OpenCL devices --- intern/cycles/device/device_opencl.cpp | 43 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 95eef8263d4..be0f8f45399 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -23,6 +23,7 @@ #include "util/util_foreach.h" #include "util/util_logging.h" #include "util/util_set.h" +#include "util/util_string.h" CCL_NAMESPACE_BEGIN @@ -166,11 +167,14 @@ string device_opencl_capabilities(void) platform_ids.resize(num_platforms); opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL)); -#define APPEND_STRING_INFO(func, id, name, what) \ + typedef char cl_string[1024]; + +#define APPEND_INFO(func, id, name, what, type) \ do { \ - char data[1024] = "\0"; \ + type data; \ + memset(&data, 0, sizeof(data)); \ opencl_assert(func(id, what, sizeof(data), &data, NULL)); \ - result += string_printf("%s: %s\n", name, data); \ + result += string_printf("%s: %s\n", name, to_string(data).c_str()); \ } while(false) #define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \ do { \ @@ -182,10 +186,10 @@ string device_opencl_capabilities(void) } \ } \ } while(false) -#define APPEND_PLATFORM_STRING_INFO(id, name, what) \ - APPEND_STRING_INFO(clGetPlatformInfo, id, "\tPlatform " name, what) -#define APPEND_DEVICE_STRING_INFO(id, name, what) \ - APPEND_STRING_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) +#define APPEND_PLATFORM_INFO(id, name, what, type) \ + APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type) +#define APPEND_DEVICE_INFO(id, name, what, type) \ + APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type) #define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \ APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) @@ -195,11 +199,11 @@ string device_opencl_capabilities(void) result += string_printf("Platform #%u\n", platform); - APPEND_PLATFORM_STRING_INFO(platform_id, "Name", CL_PLATFORM_NAME); - APPEND_PLATFORM_STRING_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR); - APPEND_PLATFORM_STRING_INFO(platform_id, "Version", CL_PLATFORM_VERSION); - APPEND_PLATFORM_STRING_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE); - APPEND_PLATFORM_STRING_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS); + APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string); + APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string); + APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string); + APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string); + APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string); cl_uint num_devices = 0; opencl_assert(clGetDeviceIDs(platform_ids[platform], @@ -220,13 +224,16 @@ string device_opencl_capabilities(void) result += string_printf("\t\tDevice: #%u\n", device); - APPEND_DEVICE_STRING_INFO(device_id, "Name", CL_DEVICE_NAME); + APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string); APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD); - APPEND_DEVICE_STRING_INFO(device_id, "Vendor", CL_DEVICE_VENDOR); - APPEND_DEVICE_STRING_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION); - APPEND_DEVICE_STRING_INFO(device_id, "Profile", CL_DEVICE_PROFILE); - APPEND_DEVICE_STRING_INFO(device_id, "Version", CL_DEVICE_VERSION); - APPEND_DEVICE_STRING_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS); + APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string); + APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string); + APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string); + APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string); + APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string); + APPEND_DEVICE_INFO(device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint); + APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint); + APPEND_DEVICE_INFO(device_id, "Max work group size", CL_DEVICE_MAX_WORK_GROUP_SIZE, size_t); } } -- cgit v1.2.3 From e20a0798dc6ca38eb4a06dda7948bd1c306d0693 Mon Sep 17 00:00:00 2001 From: fclem Date: Thu, 9 Aug 2018 15:41:24 +0200 Subject: Cycles: Append compute units for RX Vega card names Makes it more clear whether compute device is Vega 56 or Vega 64. --- intern/cycles/device/opencl/opencl_util.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp index 9104f64bedd..d6304ba688a 100644 --- a/intern/cycles/device/opencl/opencl_util.cpp +++ b/intern/cycles/device/opencl/opencl_util.cpp @@ -1136,6 +1136,21 @@ string OpenCLInfo::get_readable_device_name(cl_device_id device_id) name = get_device_name(device_id); } + /* Special exception for AMD Vega, need to be able to tell + * Vega 56 from 64 apart. + */ + if (name == "Radeon RX Vega") { + cl_int max_compute_units = 0; + if (clGetDeviceInfo(device_id, + CL_DEVICE_MAX_COMPUTE_UNITS, + sizeof(max_compute_units), + &max_compute_units, + NULL) == CL_SUCCESS) + { + name += " " + to_string(max_compute_units); + } + } + /* Distinguish from our native CPU device. */ if(get_device_type(device_id) & CL_DEVICE_TYPE_CPU) { name += " (OpenCL)"; -- cgit v1.2.3 From 85cac2221c543e67a9070c94d89d61bf27c7190f Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 9 Aug 2018 16:14:14 +0200 Subject: Fix T56279: Grease Pencil transformations show a help line with wrong origin As grease pencil use multiedit frames instead of multiobject edit, this fix solves the issue. In the future maybe will need modifications if we add multiobject support, but we need a solution now. --- source/blender/editors/transform/transform.c | 34 +++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 85229ddd041..5249b27fb70 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1790,7 +1790,7 @@ static bool helpline_poll(bContext *C) return 0; } -static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) +static void drawHelpline(bContext *C, int x, int y, void *customdata) { TransInfo *t = (TransInfo *)customdata; @@ -1806,23 +1806,31 @@ static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) (float)t->mval[1], }; - -#if 0 /* XXX: Fix from 1c9690e7607bc990cc4a3e6ba839949bb83a78af cannot be used anymore */ - if ((t->flag & T_POINTS) && (t->options & CTX_GPENCIL_STROKES)) { - FOREACH_TRANS_DATA_CONTAINER (t, tc) { - Object *ob = tc->obedit; - float vecrot[3]; - copy_v3_v3(vecrot, t->center); - mul_m4_v3(ob->obmat, vecrot); - projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO); + /* grease pencil only can edit one object at time because GP has + * multiframe edition that replaces multiobject edition. + * If multiobject edition is added, maybe this code will need + * an update + */ + if ((t->flag & T_POINTS) && (t->options & CTX_GPENCIL_STROKES) && + (t->around != V3D_AROUND_ACTIVE)) + { + Object *ob = CTX_data_active_object(C); + if ((ob) && (ob->type == OB_GPENCIL)) { + FOREACH_TRANS_DATA_CONTAINER(t, tc) { + float vecrot[3]; + copy_v3_v3(vecrot, t->center_global); + mul_m4_v3(ob->obmat, vecrot); + projectFloatViewEx(t, vecrot, cent, V3D_PROJ_TEST_CLIP_ZERO); + } + } + else { + /* normally, never must be used */ + projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); } } else { projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); } -#else - projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); -#endif /* Offset the values for the area region. */ const float offset[2] = { -- cgit v1.2.3 From ddc2796e4d872fe3c063570ae735421f52bb56b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 9 Aug 2018 15:03:15 +0200 Subject: Eevee: Principled BSDF: Add support for the sheen parameter This is a rough (but fast) approximation that still match cycles reference in common case. In practice, it's just adding more of the diffuse light computed for the diffuse contribution. --- .../blender/gpu/shaders/gpu_shader_material.glsl | 45 +++++++++++++++++----- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index c9564a21d15..56fa6291c65 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1065,17 +1065,29 @@ float floorfrac(float x, out int i) /* bsdfs */ +vec3 tint_from_color(vec3 color) +{ + float lum = dot(color, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ + return (lum > 0) ? color / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ +} + void convert_metallic_to_specular_tinted( - vec3 basecol, float metallic, float specular_fac, float specular_tint, + vec3 basecol, vec3 basecol_tint, float metallic, float specular_fac, float specular_tint, out vec3 diffuse, out vec3 f0) { - float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */ - vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */ - vec3 tmp_col = mix(vec3(1.0), tint, specular_tint); + vec3 tmp_col = mix(vec3(1.0), basecol_tint, specular_tint); f0 = mix((0.08 * specular_fac) * tmp_col, basecol, metallic); diffuse = basecol * (1.0 - metallic); } +vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint) +{ + float f = 1.0 - NV; + /* Empirical approximation (manual curve fitting). Can be refined. */ + float sheen = f*f*f*0.077 + f*0.01 + 0.00026; + return sheen * mix(vec3(1.0), basecol_tint, sheen_tint); +} + #ifndef VOLUMETRICS void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) { @@ -1137,16 +1149,21 @@ void node_bsdf_principled( transmission = saturate(transmission); float dielectric = 1.0 - metallic; transmission *= dielectric; + sheen *= dielectric; subsurface_color *= dielectric; vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec; - convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); + vec3 ctint = tint_from_color(base_color.rgb); + convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); + + float NV = dot(N, cameraVec); + vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); /* Far from being accurate, but 2 glossy evaluation is too expensive. * Most noticeable difference is at grazing angles since the bsdf lut * f0 color interpolation is done on top of this interpolation. */ vec3 f0_glass = mix(vec3(1.0), base_color.rgb, specular_tint); - float fresnel = F_eta(ior, dot(N, cameraVec)); + float fresnel = F_eta(ior, NV); vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel; f0 = mix(f0, spec_col, transmission); @@ -1164,6 +1181,7 @@ void node_bsdf_principled( vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; result.radiance = out_spec + out_refr; + result.radiance += out_diff * out_sheen; /* Coarse approx. */ #ifndef USE_SSS result.radiance += (out_diff + out_trans) * mixed_ss_base_color * (1.0 - transmission); #endif @@ -1192,13 +1210,17 @@ void node_bsdf_principled_dielectric( float dielectric = 1.0 - metallic; vec3 diffuse, f0, out_diff, out_spec, ssr_spec; - convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); + vec3 ctint = tint_from_color(base_color.rgb); + convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); + + float NV = dot(N, cameraVec); + vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); eevee_closure_default(N, diffuse, f0, int(ssr_id), roughness, 1.0, out_diff, out_spec, ssr_spec); vec3 vN = normalize(mat3(ViewMatrix) * N); result = CLOSURE_DEFAULT; - result.radiance = out_spec + out_diff * diffuse; + result.radiance = out_spec + out_diff * (diffuse + out_sheen); result.ssr_data = vec4(ssr_spec, roughness); result.ssr_normal = normal_encode(vN, viewCameraVec); result.ssr_id = int(ssr_id); @@ -1250,12 +1272,16 @@ void node_bsdf_principled_subsurface( metallic = saturate(metallic); vec3 diffuse, f0, out_diff, out_spec, out_trans, ssr_spec; - convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0); + vec3 ctint = tint_from_color(base_color.rgb); + convert_metallic_to_specular_tinted(base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0); subsurface_color = subsurface_color * (1.0 - metallic); vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface); float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0)) * subsurface; + float NV = dot(N, cameraVec); + vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint); + eevee_closure_skin(N, mixed_ss_base_color, f0, int(ssr_id), roughness, 1.0, sss_scalef, out_diff, out_trans, out_spec, ssr_spec); @@ -1276,6 +1302,7 @@ void node_bsdf_principled_subsurface( #else result.radiance += (out_diff + out_trans) * mixed_ss_base_color; #endif + result.radiance += out_diff * out_sheen; } void node_bsdf_principled_glass( -- cgit v1.2.3 From 5b6dde22935adec109a77a0676c1c2c9cec77e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 9 Aug 2018 16:45:56 +0200 Subject: Eevee: Fix assert with subsurface bsdf --- source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c index 3f0ba3c1c60..f8af125eb9e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c +++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c @@ -54,7 +54,7 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *node, if (!in[5].link) GPU_link(mat, "world_normals_get", &in[5].link); - GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE); + GPU_material_flag_set(mat, GPU_MATFLAG_DIFFUSE | GPU_MATFLAG_SSS); if (node->sss_id == 1) { bNodeSocket *socket = BLI_findlink(&node->original->inputs, 2); -- cgit v1.2.3 From 1282be0f8278d24809d1781713c5adcf0ef5e936 Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Thu, 9 Aug 2018 17:57:12 +0300 Subject: update llvm + clang to 6.0.1 and add openmp for macOS --- build_files/build_environment/CMakeLists.txt | 4 + build_files/build_environment/cmake/clang.cmake | 2 +- build_files/build_environment/cmake/llvm.cmake | 1 - build_files/build_environment/cmake/openmp.cmake | 32 ++++++ build_files/build_environment/cmake/versions.cmake | 13 ++- build_files/build_environment/patches/clang.diff | 127 --------------------- .../build_environment/patches/llvm-alloca-fix.diff | 111 ------------------ release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/tools | 2 +- 10 files changed, 48 insertions(+), 248 deletions(-) create mode 100644 build_files/build_environment/cmake/openmp.cmake delete mode 100644 build_files/build_environment/patches/clang.diff delete mode 100644 build_files/build_environment/patches/llvm-alloca-fix.diff diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index f177560c5f6..4643c48fa72 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -68,6 +68,9 @@ include(cmake/opencollada.cmake) include(cmake/opencolorio.cmake) include(cmake/llvm.cmake) include(cmake/clang.cmake) +if(APPLE) + include(cmake/openmp.cmake) +endif() include(cmake/openimageio.cmake) include(cmake/tiff.cmake) include(cmake/flexbison.cmake) @@ -77,6 +80,7 @@ include(cmake/openvdb.cmake) include(cmake/python.cmake) include(cmake/python_site_packages.cmake) include(cmake/numpy.cmake) + if(WITH_WEBP) include(cmake/webp.cmake) endif() diff --git a/build_files/build_environment/cmake/clang.cmake b/build_files/build_environment/cmake/clang.cmake index 9a2705bc8be..b2e6da73793 100644 --- a/build_files/build_environment/cmake/clang.cmake +++ b/build_files/build_environment/cmake/clang.cmake @@ -21,12 +21,12 @@ set(CLANG_EXTRA_ARGS -DCLANG_PATH_TO_LLVM_BUILD=${LIBDIR}/llvm -DLLVM_USE_CRT_RELEASE=MT -DLLVM_USE_CRT_DEBUG=MTd + -DLLVM_CONFIG=${LIBDIR}/llvm/bin/llvm-config ) ExternalProject_Add(external_clang URL ${CLANG_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH MD5=${CLANG_HASH} - PATCH_COMMAND ${PATCH_CMD} -p 2 -N -R -d ${BUILD_DIR}/clang/src/external_clang < ${PATCH_DIR}/clang.diff PREFIX ${BUILD_DIR}/clang CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/clang ${DEFAULT_CMAKE_FLAGS} ${CLANG_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/clang diff --git a/build_files/build_environment/cmake/llvm.cmake b/build_files/build_environment/cmake/llvm.cmake index 6c59101f543..d6f1920a114 100644 --- a/build_files/build_environment/cmake/llvm.cmake +++ b/build_files/build_environment/cmake/llvm.cmake @@ -38,7 +38,6 @@ ExternalProject_Add(ll URL_HASH MD5=${LLVM_HASH} CMAKE_GENERATOR ${LLVM_GENERATOR} PREFIX ${BUILD_DIR}/ll - PATCH_COMMAND ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/ll/src/ll < ${PATCH_DIR}/llvm-alloca-fix.diff CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/llvm ${DEFAULT_CMAKE_FLAGS} ${LLVM_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/llvm ) diff --git a/build_files/build_environment/cmake/openmp.cmake b/build_files/build_environment/cmake/openmp.cmake new file mode 100644 index 00000000000..ba8e6248126 --- /dev/null +++ b/build_files/build_environment/cmake/openmp.cmake @@ -0,0 +1,32 @@ +# ***** 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. +# +# ***** END GPL LICENSE BLOCK ***** + + +ExternalProject_Add(external_openmp + URL ${OPENMP_URI} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH MD5=${OPENMP_HASH} + PREFIX ${BUILD_DIR}/openmp + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openmp ${DEFAULT_CMAKE_FLAGS} + INSTALL_DIR ${LIBDIR}/clang +) + +add_dependencies( + external_openmp + external_clang +) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 361787fa956..fc58a0a8cc8 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -103,12 +103,15 @@ set(OPENCOLLADA_HASH 23db5087faed4bc4cc1dfe456c0d4701) set(OPENCOLORIO_URI https://github.com/imageworks/OpenColorIO/archive/6de971097c7f552300f669ed69ca0b6cf5a70843.zip) set(OPENCOLORIO_HASH c9de0fd98f26ce6f2e08d617ca68b8e4) -set(LLVM_VERSION 3.4.2) -set(LLVM_URI http://releases.llvm.org/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.gz) -set(LLVM_HASH a20669f75967440de949ac3b1bad439c) +set(LLVM_VERSION 6.0.1) +set(LLVM_URI http://releases.llvm.org/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz) +set(LLVM_HASH c88c98709300ce2c285391f387fecce0) -set(CLANG_URI http://releases.llvm.org/${LLVM_VERSION}/cfe-${LLVM_VERSION}.src.tar.gz) -set(CLANG_HASH 87945973b7c73038871c5f849a818588) +set(CLANG_URI http://releases.llvm.org/${LLVM_VERSION}/cfe-${LLVM_VERSION}.src.tar.xz) +set(CLANG_HASH 4e419bd4e3b55aa06d872320f754bd85) + +set(OPENMP_URI http://releases.llvm.org/${LLVM_VERSION}/openmp-${LLVM_VERSION}.src.tar.xz) +set(OPENMP_HASH 4826402ae3633c36c51ba4d0e5527d30) set(OPENIMAGEIO_VERSION 1.7.15) set(OPENIMAGEIO_URI https://github.com/OpenImageIO/oiio/archive/Release-${OPENIMAGEIO_VERSION}.zip) diff --git a/build_files/build_environment/patches/clang.diff b/build_files/build_environment/patches/clang.diff deleted file mode 100644 index 724e92f8163..00000000000 --- a/build_files/build_environment/patches/clang.diff +++ /dev/null @@ -1,127 +0,0 @@ ---- cfe/trunk/lib/Serialization/ASTWriter.cpp -+++ cfe/trunk/lib/Serialization/ASTWriter.cpp -@@ -56,14 +56,14 @@ - using namespace clang::serialization; - - template --static StringRef bytes(const std::vector &v) { -+static StringRef data(const std::vector &v) { - if (v.empty()) return StringRef(); - return StringRef(reinterpret_cast(&v[0]), - sizeof(T) * v.size()); - } - - template --static StringRef bytes(const SmallVectorImpl &v) { -+static StringRef data(const SmallVectorImpl &v) { - return StringRef(reinterpret_cast(v.data()), - sizeof(T) * v.size()); - } -@@ -1385,7 +1385,7 @@ - Record.push_back(INPUT_FILE_OFFSETS); - Record.push_back(InputFileOffsets.size()); - Record.push_back(UserFilesNum); -- Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, bytes(InputFileOffsets)); -+ Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, data(InputFileOffsets)); - } - - //===----------------------------------------------------------------------===// -@@ -1771,7 +1771,7 @@ - Record.push_back(SOURCE_LOCATION_OFFSETS); - Record.push_back(SLocEntryOffsets.size()); - Record.push_back(SourceMgr.getNextLocalOffset() - 1); // skip dummy -- Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, bytes(SLocEntryOffsets)); -+ Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets)); - - // Write the source location entry preloads array, telling the AST - // reader which source locations entries it should load eagerly. -@@ -2087,7 +2087,7 @@ - Record.push_back(MacroOffsets.size()); - Record.push_back(FirstMacroID - NUM_PREDEF_MACRO_IDS); - Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, -- bytes(MacroOffsets)); -+ data(MacroOffsets)); - } - - void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { -@@ -2185,7 +2185,7 @@ - Record.push_back(PPD_ENTITIES_OFFSETS); - Record.push_back(FirstPreprocessorEntityID - NUM_PREDEF_PP_ENTITY_IDS); - Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record, -- bytes(PreprocessedEntityOffsets)); -+ data(PreprocessedEntityOffsets)); - } - } - -@@ -2548,7 +2548,7 @@ - Record.push_back(CXX_BASE_SPECIFIER_OFFSETS); - Record.push_back(CXXBaseSpecifiersOffsets.size()); - Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record, -- bytes(CXXBaseSpecifiersOffsets)); -+ data(CXXBaseSpecifiersOffsets)); - } - - //===----------------------------------------------------------------------===// -@@ -2623,7 +2623,7 @@ - Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D))); - - ++NumLexicalDeclContexts; -- Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, bytes(Decls)); -+ Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls)); - return Offset; - } - -@@ -2642,7 +2642,7 @@ - Record.push_back(TYPE_OFFSET); - Record.push_back(TypeOffsets.size()); - Record.push_back(FirstTypeID - NUM_PREDEF_TYPE_IDS); -- Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets)); -+ Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets)); - - // Write the declaration offsets array - Abbrev = new BitCodeAbbrev(); -@@ -2655,7 +2655,7 @@ - Record.push_back(DECL_OFFSET); - Record.push_back(DeclOffsets.size()); - Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS); -- Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); -+ Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets)); - } - - void ASTWriter::WriteFileDeclIDsMap() { -@@ -2680,7 +2680,7 @@ - unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); - Record.push_back(FILE_SORTED_DECLS); - Record.push_back(FileSortedIDs.size()); -- Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileSortedIDs)); -+ Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs)); - } - - void ASTWriter::WriteComments() { -@@ -2893,7 +2893,7 @@ - Record.push_back(SelectorOffsets.size()); - Record.push_back(FirstSelectorID - NUM_PREDEF_SELECTOR_IDS); - Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record, -- bytes(SelectorOffsets)); -+ data(SelectorOffsets)); - } - } - -@@ -3253,7 +3253,7 @@ - Record.push_back(IdentifierOffsets.size()); - Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS); - Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, -- bytes(IdentifierOffsets)); -+ data(IdentifierOffsets)); - } - - //===----------------------------------------------------------------------===// -@@ -4046,7 +4046,7 @@ - Record.clear(); - Record.push_back(TU_UPDATE_LEXICAL); - Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, -- bytes(NewGlobalDecls)); -+ data(NewGlobalDecls)); - - // And a visible updates block for the translation unit. - Abv = new llvm::BitCodeAbbrev(); diff --git a/build_files/build_environment/patches/llvm-alloca-fix.diff b/build_files/build_environment/patches/llvm-alloca-fix.diff deleted file mode 100644 index 5394a472167..00000000000 --- a/build_files/build_environment/patches/llvm-alloca-fix.diff +++ /dev/null @@ -1,111 +0,0 @@ -Index: lib/Target/X86/X86ISelLowering.cpp -=================================================================== ---- lib/Target/X86/X86ISelLowering.cpp 2014-04-11 23:04:44.000000000 +0200 -+++ lib/Target/X86/X86ISelLowering.cpp (working copy) -@@ -15493,12 +15493,36 @@ - // non-trivial part is impdef of ESP. - - if (Subtarget->isTargetWin64()) { -+ const char *StackProbeSymbol = -+ Subtarget->isTargetCygMing() ? "___chkstk" : "__chkstk"; -+ -+ MachineInstrBuilder MIB; -+ -+ if (getTargetMachine().getCodeModel() == CodeModel::Large) { -+ // For large code model we need to do indirect call to __chkstk. -+ -+ // R11 will be used to contain the address of __chkstk. -+ // R11 is a volotiale register and assumed to be destoyed by the callee, -+ // so there is no need to save and restore it. -+ BuildMI(*BB, MI, DL, TII->get(X86::MOV64ri), X86::R11) -+ .addExternalSymbol(StackProbeSymbol); -+ // Create a call to __chkstk function which address contained in R11. -+ MIB = BuildMI(*BB, MI, DL, TII->get(X86::CALL64r)) -+ .addReg(X86::R11, RegState::Kill); -+ -+ } else { -+ -+ // For non-large code model we can do direct call to __chkstk. -+ -+ MIB = BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA)) -+ .addExternalSymbol(StackProbeSymbol); -+ } -+ - if (Subtarget->isTargetCygMing()) { - // ___chkstk(Mingw64): - // Clobbers R10, R11, RAX and EFLAGS. - // Updates RSP. -- BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA)) -- .addExternalSymbol("___chkstk") -+ MIB - .addReg(X86::RAX, RegState::Implicit) - .addReg(X86::RSP, RegState::Implicit) - .addReg(X86::RAX, RegState::Define | RegState::Implicit) -@@ -15507,8 +15531,7 @@ - } else { - // __chkstk(MSVCRT): does not update stack pointer. - // Clobbers R10, R11 and EFLAGS. -- BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA)) -- .addExternalSymbol("__chkstk") -+ MIB - .addReg(X86::RAX, RegState::Implicit) - .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit); - // RAX has the offset to be subtracted from RSP. -Index: lib/Target/X86/X86FrameLowering.cpp -=================================================================== ---- lib/Target/X86/X86FrameLowering.cpp 2013-10-24 01:37:01.000000000 +0200 -+++ lib/Target/X86/X86FrameLowering.cpp (working copy) -@@ -635,25 +635,49 @@ - .addReg(X86::EAX, RegState::Kill) - .setMIFlag(MachineInstr::FrameSetup); - } -+ -+ MachineInstrBuilder MIB; - - if (Is64Bit) { -+ - // Handle the 64-bit Windows ABI case where we need to call __chkstk. - // Function prologue is responsible for adjusting the stack pointer. - BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX) - .addImm(NumBytes) - .setMIFlag(MachineInstr::FrameSetup); -+ -+ if (TM.getCodeModel() == CodeModel::Large) { -+ // For large code model we need to do indirect call to __chkstk. -+ -+ -+ // R11 will be used to contain the address of __chkstk. -+ // R11 is a volotiale register and assumed to be destoyed by the callee, -+ // so there is no need to save and restore it. -+ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::R11) -+ .addExternalSymbol(StackProbeSymbol); -+ // Create a call to __chkstk function which address contained in R11. -+ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::CALL64r)) -+ .addReg(X86::R11, RegState::Kill); -+ } else { -+ -+ // For non-large code model we can do direct call to __chkstk. -+ -+ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::W64ALLOCA)) -+ .addExternalSymbol(StackProbeSymbol); -+ } - } else { - // Allocate NumBytes-4 bytes on stack in case of isEAXAlive. - // We'll also use 4 already allocated bytes for EAX. - BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) - .addImm(isEAXAlive ? NumBytes - 4 : NumBytes) - .setMIFlag(MachineInstr::FrameSetup); -+ -+ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32)) -+ .addExternalSymbol(StackProbeSymbol); - } - -- BuildMI(MBB, MBBI, DL, -- TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32)) -- .addExternalSymbol(StackProbeSymbol) -- .addReg(StackPtr, RegState::Define | RegState::Implicit) -+ -+ MIB.addReg(StackPtr, RegState::Define | RegState::Implicit) - .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit) - .setMIFlag(MachineInstr::FrameSetup); - diff --git a/release/scripts/addons b/release/scripts/addons index 9ae033c49c1..6c3a46dc113 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 9ae033c49c1b16718eac6306bdc271a5e6e6bf38 +Subproject commit 6c3a46dc113de870a03191e4c0685238b0823acd diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index f178e6c933a..15b25a42783 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit f178e6c933a25c621a5cc7d92935b66cd2ec2f5d +Subproject commit 15b25a42783d1e516b5298d70b582fae2559ae17 diff --git a/source/tools b/source/tools index 87f7038ee8c..11656ebaf7f 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 87f7038ee8c4b46a5e73a1a9065e2a9b7367f594 +Subproject commit 11656ebaf7f912cdb1b5eb39c5d0a3b5d492c1aa -- cgit v1.2.3 From 1ee93dc670556593ed9913ef97f839e423120613 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Thu, 9 Aug 2018 14:42:26 -0400 Subject: Quiet warnings in bmesh_bevel.c. --- source/blender/bmesh/tools/bmesh_bevel.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index cc9651066a0..071b82afeb9 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -776,6 +776,11 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, bool e sub_v3_v3v3(dir1n, BM_edge_other_vert(e1next->e, v)->co, v->co); sub_v3_v3v3(dir2p, v->co, BM_edge_other_vert(e2prev->e, v)->co); } + else { + /* shup up 'maybe unused' warnings */ + zero_v3(dir1n); + zero_v3(dir2p); + } ang = angle_v3v3(dir1, dir2); if (ang < BEVEL_EPSILON_ANG) { @@ -1538,14 +1543,14 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) EdgeHalf *e = &bv->edges[0], *efirst = &bv->edges[0]; /* First first edge with seam or sharp edge data */ - while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) { + while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag))) { e = e->next; if (e == efirst) break; } /* If no such edge found, return */ - if ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag)))) + if ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag))) return; efirst = e; /* Set efirst to this first encountered edge*/ @@ -1554,14 +1559,14 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) int flag_count = 0; EdgeHalf *ne = e->next; - while ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && + while (((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && ne != efirst) { if (ne->is_bev) flag_count++; ne = ne->next; } - if (ne == e || (ne == efirst && (!neg && !BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag) || + if (ne == e || (ne == efirst && ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) { break; @@ -1665,14 +1670,13 @@ static void bevel_extend_edge_data(BevVert *bv) } while (bcur != start); } -static void bevel_harden_normals_mode(BMesh *bm, BevelParams *bp, BevVert *bv, BMOperator *op) +static void bevel_harden_normals_mode(BevelParams *bp, BevVert *bv, BMOperator *op) { if (bp->hnmode == BEVEL_HN_NONE) return; VMesh *vm = bv->vmesh; BoundVert *bcur = vm->boundstart, *bstart = bcur; - int ns = vm->seg, ns2 = ns / 2; BMEdge *e; BMIter eiter; @@ -5640,7 +5644,7 @@ void BM_mesh_bevel( BevelParams bp = {NULL}; GHashIterator giter; - BMOperator *op; + BMOperator *op = NULL; BevelModNorEditData *clnordata; bp.offset = offset; @@ -5729,7 +5733,7 @@ void BM_mesh_bevel( bv = BLI_ghashIterator_getValue(&giter); bevel_extend_edge_data(bv); if (bm->use_toolflags) { - bevel_harden_normals_mode(bm, &bp, bv, op); + bevel_harden_normals_mode(&bp, bv, op); } } -- cgit v1.2.3 From 569e3640ef1fe6dd701cb8aad27516c029c57f40 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Thu, 9 Aug 2018 12:53:39 -0600 Subject: build_environment: move llvm/clang to ninja on windows. --- build_files/build_environment/cmake/clang.cmake | 9 +++++++++ build_files/build_environment/cmake/llvm.cmake | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/clang.cmake b/build_files/build_environment/cmake/clang.cmake index b2e6da73793..699c38a293a 100644 --- a/build_files/build_environment/cmake/clang.cmake +++ b/build_files/build_environment/cmake/clang.cmake @@ -23,11 +23,20 @@ set(CLANG_EXTRA_ARGS -DLLVM_USE_CRT_DEBUG=MTd -DLLVM_CONFIG=${LIBDIR}/llvm/bin/llvm-config ) + +if(WIN32) + set(CLANG_GENERATOR "Ninja") +else() + set(CLANG_GENERATOR "Unix Makefiles") +endif() + + ExternalProject_Add(external_clang URL ${CLANG_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH MD5=${CLANG_HASH} PREFIX ${BUILD_DIR}/clang + CMAKE_GENERATOR ${CLANG_GENERATOR} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/clang ${DEFAULT_CMAKE_FLAGS} ${CLANG_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/clang ) diff --git a/build_files/build_environment/cmake/llvm.cmake b/build_files/build_environment/cmake/llvm.cmake index d6f1920a114..7390b1bf011 100644 --- a/build_files/build_environment/cmake/llvm.cmake +++ b/build_files/build_environment/cmake/llvm.cmake @@ -26,7 +26,7 @@ set(LLVM_EXTRA_ARGS ) if(WIN32) - set(LLVM_GENERATOR "NMake Makefiles") + set(LLVM_GENERATOR "Ninja") else() set(LLVM_GENERATOR "Unix Makefiles") endif() -- cgit v1.2.3 From eb7b450c0c65388758fcec5764a759d3d347c314 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 10 Aug 2018 08:10:07 +1000 Subject: Cleanup: style --- source/blender/bmesh/intern/bmesh_mesh.c | 21 ++++++++------ source/blender/bmesh/intern/bmesh_mesh.h | 8 +++--- source/blender/bmesh/operators/bmo_bevel.c | 5 ++-- source/blender/bmesh/tools/bmesh_bevel.c | 16 +++++++---- source/blender/bmesh/tools/bmesh_bevel.h | 2 +- source/blender/draw/intern/draw_cache_impl_mesh.c | 5 ++-- source/blender/editors/mesh/editmesh_bevel.c | 32 ++++++++++++---------- source/blender/editors/mesh/editmesh_tools.c | 6 ++-- source/blender/editors/transform/transform.c | 5 ++-- .../blender/editors/uvedit/uvedit_smart_stitch.c | 19 ++++++------- .../gpencil_modifiers/intern/MOD_gpencilcolor.c | 5 ++-- source/blender/imbuf/intern/jp2.c | 2 +- source/blender/modifiers/intern/MOD_bevel.c | 28 ++++++++++--------- .../blender/modifiers/intern/MOD_weighted_normal.c | 9 +++--- 14 files changed, 88 insertions(+), 75 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 292453fac4b..a454fb7e948 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -1115,7 +1115,7 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) /* Note that we only handle unselected neighbor vertices here, main loop will take care of * selected ones. */ if ((!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT)) && - !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) + !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) { BMLoop *l_prev; @@ -1127,7 +1127,7 @@ void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all) } if ((!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT)) && - !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) + !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) { BMLoop *l_next; @@ -1174,8 +1174,9 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); int l_index = BM_elem_index_get(l); - BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], *clnor, - oldnors[l_index]); + BKE_lnor_space_custom_data_to_normal( + bm->lnor_spacearr->lspacearr[l_index], *clnor, + oldnors[l_index]); } } } @@ -1194,8 +1195,9 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor) if (preserve_clnor) { short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset); int l_index = BM_elem_index_get(l); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], - *clnor); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], + *clnor); } BM_ELEM_API_FLAG_DISABLE(l, BM_LNORSPACE_UPDATE); } @@ -1401,9 +1403,10 @@ BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm) BLI_assert(bm->spacearr_dirty == 0); - BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN(sizeof(*lnors_ed_arr), __func__); - lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, - __func__); + BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN( + sizeof(*lnors_ed_arr), __func__); + lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN( + sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, __func__); if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) { BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL); diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index 89077d84447..c7192590b79 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -49,10 +49,10 @@ void BM_mesh_clear(BMesh *bm); void BM_mesh_normals_update(BMesh *bm); void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]); void BM_loops_calc_normal_vcos( - BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*pnos)[3], - const bool use_split_normals, const float split_angle, float(*r_lnos)[3], - struct MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], - const int cd_loop_clnors_offset, const bool do_rebuild); + BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*pnos)[3], + const bool use_split_normals, const float split_angle, float(*r_lnos)[3], + struct MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], + const int cd_loop_clnors_offset, const bool do_rebuild); bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr); void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index eb299dbba60..8bc219d8421 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -66,8 +66,9 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, - loop_slide, mark_seam, mark_sharp, hnmode, op); + BM_mesh_bevel( + bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, + loop_slide, mark_seam, mark_sharp, hnmode, op); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 071b82afeb9..0415526574d 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1553,28 +1553,32 @@ static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg) if ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(e, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(e, flag))) return; - efirst = e; /* Set efirst to this first encountered edge*/ + /* Set efirst to this first encountered edge. */ + efirst = e; do { int flag_count = 0; EdgeHalf *ne = e->next; while (((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(ne, flag)) || (neg && BEV_EXTEND_EDGE_DATA_CHECK(ne, flag))) && - ne != efirst) + ne != efirst) { if (ne->is_bev) flag_count++; ne = ne->next; } if (ne == e || (ne == efirst && ((!neg && !BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag)) || - (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) + (neg && BEV_EXTEND_EDGE_DATA_CHECK(efirst, flag))))) { break; } - if (flag == BM_ELEM_SEAM) /* Set seam_len / sharp_len of starting edge */ + /* Set seam_len / sharp_len of starting edge */ + if (flag == BM_ELEM_SEAM) { e->rightv->seam_len = flag_count; - else if (flag == BM_ELEM_SMOOTH) + } + else if (flag == BM_ELEM_SMOOTH) { e->rightv->sharp_len = flag_count; + } e = ne; } while (e != efirst); } @@ -5635,7 +5639,7 @@ void BM_mesh_bevel( const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, void *mod_bmop_customdata) + const int hnmode, void *mod_bmop_customdata) { BMIter iter; BMVert *v, *v_next; diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index 5cf8b1e78bb..f8a77d431cc 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -34,6 +34,6 @@ void BM_mesh_bevel( const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const int hnmode, void *mod_bmop_customdata); + const int hnmode, void *mod_bmop_customdata); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index dcfb9229cc1..1cf270048e1 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -428,8 +428,9 @@ static MeshRenderData *mesh_render_data_create_ex( if (is_auto_smooth) { rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__); int cd_loop_clnors_offset = CustomData_get_layer_index(&bm->ldata, CD_CUSTOMLOOPNORMAL); - BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, - cd_loop_clnors_offset, false); + BM_loops_calc_normal_vcos( + bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, + cd_loop_clnors_offset, false); } rdata->loop_len = totloop; bm_ensure_types |= BM_LOOP; diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index 8d1832e84a4..e87abc6adf7 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -136,7 +136,7 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op) } } -static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_strength, int hnmode) +static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_strength) { BKE_editmesh_lnorspace_update(em); BM_normals_loops_edges_tag(em->bm, true); @@ -154,8 +154,8 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { if ((BM_elem_flag_test(l_cur->v, BM_ELEM_SELECT)) && - ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) || - (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur)))) + ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) || + (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur)))) { /* Both adjacent loops are sharp, set clnor to face normal */ if (!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG) && !BM_elem_flag_test(l_cur->prev->e, BM_ELEM_TAG)) { @@ -213,11 +213,13 @@ static void bevel_harden_normals(BMEditMesh *em, BMOperator *bmop, float face_st const int l_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); if (calc_n) { - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], calc_n, clnors); + } + else { + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], cn_unwght, clnors); } - else - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], cn_unwght, - clnors); } BLI_ghash_remove(nslot->data.ghash, v_pivot, NULL, MEM_freeN); } @@ -334,11 +336,12 @@ static bool edbm_bevel_calc(wmOperator *op) material = CLAMPIS(material, -1, em->ob->totcol - 1); } - EDBM_op_init(em, &bmop, op, - "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " - "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b strength=%f hnmode=%i", - BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide, mark_seam, mark_sharp, hn_strength, hnmode); + EDBM_op_init( + em, &bmop, op, + "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " + "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b strength=%f hnmode=%i", + BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, + clamp_overlap, material, loop_slide, mark_seam, mark_sharp, hn_strength, hnmode); BMO_op_exec(em->bm, &bmop); @@ -349,8 +352,9 @@ static bool edbm_bevel_calc(wmOperator *op) BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); } - if (hnmode != BEVEL_HN_NONE) - bevel_harden_normals(em, &bmop, hn_strength, hnmode); + if (hnmode != BEVEL_HN_NONE) { + bevel_harden_normals(em, &bmop, hn_strength); + } /* no need to de-select existing geometry */ if (!EDBM_op_finish(em, &bmop, op, true)) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 45ffd3245a3..76ba2e5c67e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7064,7 +7064,7 @@ static void point_normals_update_header(bContext *C, wmOperator *op) WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), - WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), + WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align"))); #undef WM_MODALKEY @@ -8064,8 +8064,8 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) if (BLI_BITMAP_TEST(loop_set, BM_elem_index_get(l))) { const int loop_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], - clnors); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], clnors); } } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c7cbf0e6a46..142460bb7fa 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1831,7 +1831,7 @@ static void drawHelpline(bContext *C, int x, int y, void *customdata) * an update */ if ((t->flag & T_POINTS) && (t->options & CTX_GPENCIL_STROKES) && - (t->around != V3D_AROUND_ACTIVE)) + (t->around != V3D_AROUND_ACTIVE)) { Object *ob = CTX_data_active_object(C); if ((ob) && (ob->type == OB_GPENCIL)) { @@ -4298,7 +4298,6 @@ static void applyRotationValue(TransInfo *t, float angle, float axis[3]) static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) { char str[UI_MAX_DRAW_STR]; - size_t ofs = 0; float final; @@ -4458,7 +4457,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2])) static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm) { BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); - BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; + // BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; tc->custom.mode.data = lnors_ed_arr; tc->custom.mode.free_cb = freeCustomNormalArray; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index a5e18851f12..422c3489e01 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1033,7 +1033,7 @@ static int stitch_process_data( /* remember stitchable candidates as places the 'I' button */ /* will stop at. */ for (int island_idx = 0; island_idx < state->element_map->totalIslands; island_idx++) { - state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate?true:false; + state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate ? true : false; } if (is_active_state) { @@ -1810,7 +1810,7 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state) return BLI_ghash_lookup(state->edge_hash, &tmp_edge); } -static StitchState* stitch_init( +static StitchState *stitch_init( bContext *C, wmOperator *op, StitchStateContainer *ssc, Object *obedit) { @@ -2132,7 +2132,7 @@ static bool goto_next_island(StitchStateContainer *ssc) int original_island = ssc->static_island; - do { + do { ssc->static_island++; if (ssc->static_island >= active_state->element_map->totalIslands) { /* go to next object */ @@ -2147,8 +2147,8 @@ static bool goto_next_island(StitchStateContainer *ssc) /* We're at an island to make active */ return true; } - } while (!(active_state == original_active_state - && ssc->static_island == original_island)); + } while (!(active_state == original_active_state && + ssc->static_island == original_island)); return false; } @@ -2201,15 +2201,14 @@ static int stitch_init_all(bContext *C, wmOperator *op) uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, &objects_len); - if (!objects_len) - { + if (objects_len == 0) { MEM_freeN(objects); state_delete_all(ssc); return 0; } - ssc->objects = MEM_callocN(sizeof(Object*) * objects_len, "Object *ssc->objects"); - ssc->states = MEM_callocN(sizeof(StitchState*) * objects_len, "StitchState"); + ssc->objects = MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects"); + ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState"); ssc->objects_len = 0; for (uint ob_index = 0; ob_index < objects_len; ob_index++) { @@ -2350,7 +2349,7 @@ static int stitch_exec(bContext *C, wmOperator *op) } } -static StitchState* stitch_select( +static StitchState *stitch_select( bContext *C, Scene *scene, const wmEvent *event, StitchStateContainer *ssc) { /* add uv under mouse to processed uv's */ diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 40ffe293d41..0bbd26da670 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -127,8 +127,9 @@ static void bakeModifier( deformStroke(md, depsgraph, ob, gpl, gps); - gpencil_apply_modifier_material(bmain, ob, mat, gh_color, gps, - (bool)(mmd->flag & GP_COLOR_CREATE_COLORS)); + gpencil_apply_modifier_material( + bmain, ob, mat, gh_color, gps, + (bool)(mmd->flag & GP_COLOR_CREATE_COLORS)); } } } diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index e4923e94635..cd6bdd643d5 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -221,7 +221,7 @@ static opj_stream_t *opj_stream_create_from_buffer( if (l_stream == NULL) { return NULL; } - opj_stream_set_user_data(l_stream, p_file , opj_read_from_buffer_free); + opj_stream_set_user_data(l_stream, p_file, opj_read_from_buffer_free); opj_stream_set_user_data_length(l_stream, p_file->len); opj_stream_set_read_function(l_stream, opj_read_from_buffer); #if 0 /* UNUSED */ diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index f1dc73436ee..ba07a3a56cc 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -111,8 +111,8 @@ static void bevel_set_weighted_normal_face_strength(BMesh *bm, Scene *scene) } static void bevel_mod_harden_normals( - BevelModifierData *bmd, BMesh *bm, const float hn_strength, - const int hnmode, MDeformVert *dvert, int vgroup) + BevelModifierData *bmd, BMesh *bm, const float hn_strength, + const int hnmode, MDeformVert *dvert, int vgroup) { if (bmd->res > 20 || bmd->value == 0) return; @@ -136,7 +136,7 @@ static void bevel_mod_harden_normals( l_cur = l_first = BM_FACE_FIRST_LOOP(f); do { if ((!BM_elem_flag_test(l_cur->e, BM_ELEM_TAG)) || - (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur))) + (!BM_elem_flag_test(l_cur, BM_ELEM_TAG) && BM_loop_check_cyclic_smooth_fan(l_cur))) { /* previous and next edge is sharp, accumulate face normals into loop */ @@ -187,8 +187,9 @@ static void bevel_mod_harden_normals( } else if (bmd->lim_flags & MOD_BEVEL_VGROUP) { const bool has_vgroup = dvert != NULL; - const bool vert_of_group = has_vgroup && - (defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL); + const bool vert_of_group = ( + has_vgroup && + (defvert_find_index(&dvert[BM_elem_index_get(l->v)], vgroup) != NULL)); if (vert_of_group && hnmode == MOD_BEVEL_HN_FACE) { float cur[3]; @@ -223,20 +224,21 @@ static void bevel_mod_harden_normals( /* If vertex is edge vert with 1 reconnected face */ if (recon_face_count == 1 || do_normal_to_recon) { - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], recon_face->no, - clnors); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], recon_face->no, clnors); } else if (vertex_only == false || recon_face_count == 0) { copy_v3_v3(n_final, l->f->no); mul_v3_fl(n_final, 1.0f - hn_strength); add_v3_v3(n_final, cn_wght); normalize_v3(n_final); - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], n_final, - clnors); + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], n_final, clnors); + } + else if (BLI_ghash_haskey(faceHash, l->f)) { + BKE_lnor_space_custom_normal_to_data( + bm->lnor_spacearr->lspacearr[l_index], l->v->no, clnors); } - else if (BLI_ghash_haskey(faceHash, l->f)) - BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], l->v->no, - clnors); } } } @@ -466,7 +468,7 @@ ModifierTypeInfo modifierType_Bevel = { eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - + /* copyData */ modifier_copyData_generic, /* deformVerts_DM */ NULL, diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index 3e788db9c00..69c71d34dbc 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -514,8 +514,6 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes MVert *mvert = result->mvert; MLoop *mloop = result->mloop; - bool free_polynors = false; - /* Right now: * If weight = 50 then all faces are given equal weight. * If weight > 50 then more weight given to faces with larger vals (face area / corner angle). @@ -538,7 +536,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (!polynors) { polynors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys); } - BKE_mesh_calc_normals_poly(mvert, NULL, numVerts, mloop, mpoly, numLoops, numPolys, polynors, false); + BKE_mesh_calc_normals_poly(mvert, NULL, numVerts, mloop, mpoly, numLoops, numPolys, polynors, false); const float split_angle = mesh->smoothresh; @@ -573,8 +571,9 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes .mpoly = mpoly, .polynors = polynors, - .poly_strength = CustomData_get_layer_named(&result->pdata, CD_PROP_INT, - MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID), + .poly_strength = CustomData_get_layer_named( + &result->pdata, CD_PROP_INT, + MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID), .dvert = dvert, .defgrp_index = defgrp_index, -- cgit v1.2.3 From 3daf5cc1ceb4854ba7ca481b9e2f1a5ed19bd2cb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 9 Aug 2018 23:10:54 +1000 Subject: Gizmo: 2d select now takes region coords Was taking an event, when only the region coords are needed. --- source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c | 6 +++--- source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c | 6 +++--- source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c | 4 ++-- source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c | 4 ++-- source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c | 4 ++-- source/blender/editors/space_view3d/view3d_gizmo_ruler.c | 4 ++-- source/blender/makesrna/intern/rna_wm_gizmo.c | 6 +++--- source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c | 2 +- source/blender/windowmanager/gizmo/wm_gizmo_fn.h | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c index cb8e2a90b07..953e763a33c 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow2d_gizmo.c @@ -140,15 +140,15 @@ static int gizmo_arrow2d_invoke( } static int gizmo_arrow2d_test_select( - bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) { - const float mval[2] = {event->mval[0], event->mval[1]}; + const float mval_fl[2] = {UNPACK2(mval)}; const float arrow_length = RNA_float_get(gz->ptr, "length"); const float arrow_angle = RNA_float_get(gz->ptr, "angle"); const float line_len = arrow_length * gz->scale_final; float mval_local[2]; - copy_v2_v2(mval_local, mval); + copy_v2_v2(mval_local, mval_fl); sub_v2_v2(mval_local, gz->matrix_basis[3]); float line[2][2]; diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index d976adc06bf..dfc0dcd791c 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -232,20 +232,20 @@ static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz) } static int gizmo_button2d_test_select( - bContext *C, wmGizmo *gz, const wmEvent *event) + bContext *C, wmGizmo *gz, const int mval[2]) { float point_local[2]; if (0) { /* correct, but unnecessarily slow. */ if (gizmo_window_project_2d( - C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false) { return -1; } } else { - copy_v2_v2(point_local, (float[2]){UNPACK2(event->mval)}); + copy_v2_v2(point_local, (float[2]){UNPACK2(mval)}); sub_v2_v2(point_local, gz->matrix_basis[3]); mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC)); } diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 2869b93a790..bb9cac595be 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -718,7 +718,7 @@ static int gizmo_cage2d_get_cursor(wmGizmo *gz) } static int gizmo_cage2d_test_select( - bContext *C, wmGizmo *gz, const wmEvent *event) + bContext *C, wmGizmo *gz, const int mval[2]) { float point_local[2]; float dims[2]; @@ -726,7 +726,7 @@ static int gizmo_cage2d_test_select( const float size_real[2] = {dims[0] / 2.0f, dims[1] / 2.0f}; if (gizmo_window_project_2d( - C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false) { return -1; } diff --git a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c index 8d4db81c11f..fcbd333078d 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/grab3d_gizmo.c @@ -293,12 +293,12 @@ static int gizmo_grab_invoke( static int gizmo_grab_test_select( - bContext *C, wmGizmo *gz, const wmEvent *event) + bContext *C, wmGizmo *gz, const int mval[2]) { float point_local[2]; if (gizmo_window_project_2d( - C, gz, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + C, gz, (const float[2]){UNPACK2(mval)}, 2, true, point_local) == false) { return -1; } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 93617f22490..5a4f910955e 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -343,9 +343,9 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) } static int gizmo_axis_test_select( - bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) { - float point_local[2] = {UNPACK2(event->mval)}; + float point_local[2] = {UNPACK2(mval)}; sub_v2_v2(point_local, gz->matrix_basis[3]); mul_v2_fl(point_local, 1.0f / (gz->scale_basis * UI_DPI_FAC)); diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index fb335d5f922..5853fa6e3b3 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -799,10 +799,10 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) } static int gizmo_ruler_test_select( - bContext *UNUSED(C), wmGizmo *gz, const wmEvent *event) + bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) { RulerItem *ruler_item_pick = (RulerItem *)gz; - float mval_fl[2] = {UNPACK2(event->mval)}; + float mval_fl[2] = {UNPACK2(mval)}; int co_index; /* select and drag */ diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c index 7a2460a7694..1eee5e5522f 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo.c @@ -111,7 +111,7 @@ static void rna_gizmo_draw_select_cb( } static int rna_gizmo_test_select_cb( - struct bContext *C, struct wmGizmo *gz, const struct wmEvent *event) + struct bContext *C, struct wmGizmo *gz, const int location[2]) { extern FunctionRNA rna_Gizmo_test_select_func; wmGizmoGroup *gzgroup = gz->parent_gzgroup; @@ -123,7 +123,7 @@ static int rna_gizmo_test_select_cb( func = &rna_Gizmo_test_select_func; RNA_parameter_list_create(&list, &gz_ptr, func); RNA_parameter_set_lookup(&list, "context", &C); - RNA_parameter_set_lookup(&list, "event", &event); + RNA_parameter_set_lookup(&list, "location", location); gzgroup->type->ext.call((bContext *)C, &gz_ptr, func, &list); void *ret; @@ -966,7 +966,7 @@ static void rna_def_gizmo(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - parm = RNA_def_pointer(func, "event", "Event", "", ""); + parm = RNA_def_int_array(func, "location", 2, NULL, INT_MIN, INT_MAX, "Location", "Region coordinates", INT_MIN, INT_MAX); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); parm = RNA_def_int(func, "intersect_id", 0, 0, INT_MAX, "", "", 0, INT_MAX); RNA_def_function_return(func, parm); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 204662b5713..5efc74b5bb8 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -153,7 +153,7 @@ wmGizmo *wm_gizmogroup_find_intersected_gizmo( { for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { if (gz->type->test_select && (gz->flag & WM_GIZMO_HIDDEN) == 0) { - if ((*r_part = gz->type->test_select(C, gz, event)) != -1) { + if ((*r_part = gz->type->test_select(C, gz, event->mval)) != -1) { return gz; } } diff --git a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h index a94f1e994e9..88065a0fcd5 100644 --- a/source/blender/windowmanager/gizmo/wm_gizmo_fn.h +++ b/source/blender/windowmanager/gizmo/wm_gizmo_fn.h @@ -51,7 +51,7 @@ typedef void (*wmGizmoGroupFnMsgBusSubscribe)( typedef void (*wmGizmoFnSetup)(struct wmGizmo *); typedef void (*wmGizmoFnDraw)(const struct bContext *, struct wmGizmo *); typedef void (*wmGizmoFnDrawSelect)(const struct bContext *, struct wmGizmo *, int); -typedef int (*wmGizmoFnTestSelect)(struct bContext *, struct wmGizmo *, const struct wmEvent *); +typedef int (*wmGizmoFnTestSelect)(struct bContext *, struct wmGizmo *, const int mval[2]); typedef int (*wmGizmoFnModal)(struct bContext *, struct wmGizmo *, const struct wmEvent *, eWM_GizmoFlagTweak); typedef void (*wmGizmoFnPropertyUpdate)(struct wmGizmo *, struct wmGizmoProperty *); typedef void (*wmGizmoFnMatrixBasisGet)(const struct wmGizmo *, float[4][4]); -- cgit v1.2.3 From c19ddcc975f9a19c0a024337fac677907c3ec977 Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Fri, 10 Aug 2018 03:08:18 +0300 Subject: libs: boost 1.68 --- build_files/build_environment/cmake/boost.cmake | 15 ++++++--------- build_files/build_environment/cmake/options.cmake | 2 +- build_files/build_environment/cmake/versions.cmake | 10 +++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/build_files/build_environment/cmake/boost.cmake b/build_files/build_environment/cmake/boost.cmake index 46840b7ead4..f5e4d08289a 100644 --- a/build_files/build_environment/cmake/boost.cmake +++ b/build_files/build_environment/cmake/boost.cmake @@ -57,14 +57,14 @@ if(WIN32) elseif(APPLE) set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh) - set(BOOST_BUILD_COMMAND ./bjam) - set(BOOST_BUILD_OPTIONS toolset=clang cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} --disable-icu boost.locale.icu=off) + set(BOOST_BUILD_COMMAND ./b2) + set(BOOST_BUILD_OPTIONS toolset=darwin cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} --disable-icu boost.locale.icu=off) set(BOOST_HARVEST_CMD echo .) set(BOOST_PATCH_COMMAND echo .) else() set(BOOST_HARVEST_CMD echo .) set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh) - set(BOOST_BUILD_COMMAND ./bjam) + set(BOOST_BUILD_COMMAND ./b2) set(BOOST_BUILD_OPTIONS cxxflags=${PLATFORM_CXXFLAGS} --disable-icu boost.locale.icu=off) set(BOOST_PATCH_COMMAND echo .) endif() @@ -85,23 +85,20 @@ set(BOOST_OPTIONS ${BOOST_TOOLSET} ) -if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") set(BOOST_ADDRESS_MODEL 64) -else() - set(BOOST_ADDRESS_MODEL 32) -endif() + string(TOLOWER ${BUILD_MODE} BOOST_BUILD_TYPE) ExternalProject_Add(external_boost URL ${BOOST_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH MD5=${BOOST_MD5} + URL_HASH MD5=${BOOST_HASH} PREFIX ${BUILD_DIR}/boost UPDATE_COMMAND "" PATCH_COMMAND ${BOOST_PATCH_COMMAND} CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND} - BUILD_COMMAND ${BOOST_BUILD_COMMAND} ${BOOST_BUILD_OPTIONS} -j${MAKE_THREADS} architecture=x86 address-model=${BOOST_ADDRESS_MODEL} variant=${BOOST_BUILD_TYPE} link=static threading=multi ${BOOST_OPTIONS} --prefix=${LIBDIR}/boost install + BUILD_COMMAND ${BOOST_BUILD_COMMAND} ${BOOST_BUILD_OPTIONS} -j${MAKE_THREADS} architecture=x86 address-model=${BOOST_ADDRESS_MODEL} link=static threading=multi ${BOOST_OPTIONS} --prefix=${LIBDIR}/boost install BUILD_IN_SOURCE 1 INSTALL_COMMAND "${BOOST_HARVEST_CMD}" ) diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 08d43d6a0a2..c4dcf212e68 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -126,7 +126,7 @@ else() ) set(OSX_ARCHITECTURES x86_64) set(OSX_DEPLOYMENT_TARGET 10.9) - set(OSX_SDK_VERSION 10.12) + set(OSX_SDK_VERSION 10.13) set(OSX_SYSROOT ${XCODE_DEV_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk) set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}") diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index fc58a0a8cc8..9a0c7c02d5a 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -32,11 +32,11 @@ set(JPEG_VERSION 1.4.2) set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz) set(JPEG_HASH f9804884c1c41eb7f4febb9353a2cb27) -set(BOOST_VERSION 1.60.0) -set(BOOST_VERSION_NODOTS 1_60_0) -set(BOOST_URI http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION_NODOTS}.tar.bz2/download) -set(BOOST_MD5 65a840e1a0b13a558ff19eeb2c4f0cbe) - +set(BOOST_VERSION 1.68.0) +set(BOOST_VERSION_NODOTS 1_68_0) +set(BOOST_URI https://dl.bintray.com/boostorg/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz) +set(BOOST_HASH 5d8b4503582fffa9eefdb9045359c239) + set(BLOSC_VERSION 1.7.1) set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.zip) set(BLOSC_HASH ff5cc729a5a25934ef714217218eed26) -- cgit v1.2.3 From e18a2c4ed7b311fef620ac8faa09c9ce1490abc7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 10 Aug 2018 17:32:40 +1000 Subject: Gizmo: support for 2D selection checks for 3D gizmos This means 3D manipulators can use their own logic for checking if the cursor intersects. --- .../windowmanager/gizmo/intern/wm_gizmo_group.c | 2 +- .../windowmanager/gizmo/intern/wm_gizmo_map.c | 83 ++++++++++++++-------- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 5efc74b5bb8..3ba9fa71601 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -169,7 +169,7 @@ void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, Lis { for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) { if ((gz->flag & WM_GIZMO_HIDDEN) == 0) { - if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && gz->type->draw_select) || + if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && (gz->type->draw_select || gz->type->test_select)) || ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select)) { BLI_addhead(listbase, BLI_genericNodeN(gz)); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 9321ec674a9..0b54f0cbec1 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -453,7 +453,9 @@ void WM_gizmomap_draw( BLI_assert(BLI_listbase_is_empty(&draw_gizmos)); } -static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmos) +static void gizmo_draw_select_3D_loop( + const bContext *C, ListBase *visible_gizmos, + const wmGizmo *gz_stop) { int select_id = 0; wmGizmo *gz; @@ -462,8 +464,14 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo bool is_depth_prev = false; bool is_depth_skip_prev = false; - for (LinkData *link = visible_gizmos->first; link; link = link->next) { + for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) { gz = link->data; + if (gz == gz_stop) { + break; + } + if (gz->type->draw_select == NULL) { + continue; + } bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0; if (is_depth == is_depth_prev) { @@ -490,9 +498,6 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo /* pass the selection id shifted by 8 bits. Last 8 bits are used for selected gizmo part id */ gz->type->draw_select(C, gz, select_id << 8); - - - select_id++; } if (is_depth_prev) { @@ -505,7 +510,7 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo static int gizmo_find_intersected_3d_intern( ListBase *visible_gizmos, const bContext *C, const int co[2], - const int hotspot) + const int hotspot, const wmGizmo *gz_stop) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -525,13 +530,13 @@ static int gizmo_find_intersected_3d_intern( else GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_ALL, 0); /* do the drawing */ - gizmo_draw_select_3D_loop(C, visible_gizmos); + gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop); hits = GPU_select_end(); if (do_passes && (hits > 0)) { GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); - gizmo_draw_select_3D_loop(C, visible_gizmos); + gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop); GPU_select_end(); } @@ -552,36 +557,56 @@ static wmGizmo *gizmo_find_intersected_3d( wmGizmo *result = NULL; int hit = -1; - int hotspot_radii[] = { - 3 * U.pixelsize, - /* This runs on mouse move, careful doing too many tests! */ - 10 * U.pixelsize, - }; - *r_part = 0; /* set up view matrices */ view3d_operator_needs_opengl(C); - hit = -1; - - for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) { - hit = gizmo_find_intersected_3d_intern(visible_gizmos, C, co, hotspot_radii[i]); - if (hit != -1) { - break; + /* Search for 3D gizmo's that use the 2D callback for checking intersections. */ + bool has_3d = false; + { + int select_id = 0; + for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) { + wmGizmo *gz = link->data; + if (gz->type->test_select) { + if ((*r_part = gz->type->test_select(C, gz, co)) != -1) { + hit = select_id; + result = gz; + break; + } + } + else { + has_3d = true; + } } } - if (hit != -1) { - LinkData *link = BLI_findlink(visible_gizmos, hit >> 8); - if (link != NULL) { - *r_part = hit & 255; - result = link->data; + /* Search for 3D intersections if they're before 2D that have been found (if any). + * This way we always use the first hit. */ + if (has_3d) { + const int hotspot_radii[] = { + 3 * U.pixelsize, + /* This runs on mouse move, careful doing too many tests! */ + 10 * U.pixelsize, + }; + for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) { + hit = gizmo_find_intersected_3d_intern(visible_gizmos, C, co, hotspot_radii[i], result); + if (hit != -1) { + break; + } } - else { - /* All gizmos should use selection ID they're given as part of the callback, - * if they don't it will attempt tp lookup non-existing index. */ - BLI_assert(0); + + if (hit != -1) { + LinkData *link = BLI_findlink(visible_gizmos, hit >> 8); + if (link != NULL) { + *r_part = hit & 255; + result = link->data; + } + else { + /* All gizmos should use selection ID they're given as part of the callback, + * if they don't it will attempt tp lookup non-existing index. */ + BLI_assert(0); + } } } -- cgit v1.2.3 From 98c304e865f87a658778781f4280107ed449091c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 10 Aug 2018 21:04:06 +1000 Subject: Gizmo: add option to catch all mouse clicks This was previously default behavior, now it's default. --- .../startup/bl_ui/space_toolsystem_toolbar.py | 16 +++++++ .../blender/editors/gizmo_library/CMakeLists.txt | 1 + source/blender/editors/include/ED_gizmo_library.h | 1 + source/blender/editors/space_api/spacetypes.c | 1 + .../blender/editors/transform/transform_gizmo_3d.c | 51 +++++++++++++++++++--- source/blender/makesdna/DNA_scene_types.h | 10 +++-- source/blender/makesrna/intern/rna_scene.c | 5 +++ 7 files changed, 76 insertions(+), 9 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 629fd2a7557..e1ecba1550a 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -289,6 +289,10 @@ class _defs_transform: @ToolDef.from_fn def translate(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Grab", # cursor='SCROLL_XY', @@ -299,10 +303,15 @@ class _defs_transform: # keymap=( # ("transform.translate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn def rotate(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Rotate", # cursor='SCROLL_XY', @@ -313,10 +322,15 @@ class _defs_transform: # keymap=( # ("transform.rotate", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn def scale(): + def draw_settings(context, layout, tool): + tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") + return dict( text="Scale", # cursor='SCROLL_XY', @@ -327,6 +341,7 @@ class _defs_transform: # keymap=( # ("transform.resize", dict(release_confirm=True), dict(type='EVT_TWEAK_A', value='ANY')), # ), + draw_settings=draw_settings, ) @ToolDef.from_fn @@ -342,6 +357,7 @@ class _defs_transform: def transform(): def draw_settings(context, layout, tool): tool_settings = context.tool_settings + layout.prop(tool_settings, "use_gizmo_apron") layout.prop(tool_settings, "use_gizmo_mode") return dict( diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt index 389820240e2..e1ea5c22ce5 100644 --- a/source/blender/editors/gizmo_library/CMakeLists.txt +++ b/source/blender/editors/gizmo_library/CMakeLists.txt @@ -47,6 +47,7 @@ set(SRC geometry/geom_dial_gizmo.c gizmo_types/arrow2d_gizmo.c gizmo_types/arrow3d_gizmo.c + gizmo_types/blank3d_gizmo.c gizmo_types/button2d_gizmo.c gizmo_types/cage2d_gizmo.c gizmo_types/cage3d_gizmo.c diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 2bf3488a8d3..6471c90194b 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -40,6 +40,7 @@ void ED_gizmotypes_dial_3d(void); void ED_gizmotypes_grab_3d(void); void ED_gizmotypes_facemap_3d(void); void ED_gizmotypes_primitive_3d(void); +void ED_gizmotypes_blank_3d(void); struct wmGizmo; struct wmGizmoGroup; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 7246812dc82..84de55a172d 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -136,6 +136,7 @@ void ED_spacetypes_init(void) ED_gizmotypes_arrow_2d(); ED_gizmotypes_arrow_3d(); ED_gizmotypes_primitive_3d(); + ED_gizmotypes_blank_3d(); ED_gizmotypes_cage_2d(); ED_gizmotypes_cage_3d(); diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 83dfa06f37d..5fe7bbbf45e 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -148,7 +148,9 @@ enum { #define MAN_AXIS_RANGE_SCALE_START MAN_AXIS_SCALE_X #define MAN_AXIS_RANGE_SCALE_END (MAN_AXIS_SCALE_ZX + 1) - MAN_AXIS_LAST = MAN_AXIS_RANGE_SCALE_END, + MAN_AXIS_APRON_C, + + MAN_AXIS_LAST = MAN_AXIS_APRON_C + 1, }; /* axis types */ @@ -162,6 +164,7 @@ enum { typedef struct GizmoGroup { bool all_hidden; int twtype; + int axis_type_default; /* Users may change the twtype, detect changes to re-setup gizmo options. */ int twtype_init; @@ -193,7 +196,7 @@ static wmGizmo *gizmo_get_axis_from_index(const GizmoGroup *man, const short axi return man->gizmos[axis_idx]; } -static short gizmo_get_axis_type(const int axis_idx) +static short gizmo_get_axis_type(const int axis_idx, const int axis_type_default) { if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) { return MAN_AXES_TRANSLATE; @@ -204,6 +207,9 @@ static short gizmo_get_axis_type(const int axis_idx) if (axis_idx >= MAN_AXIS_RANGE_SCALE_START && axis_idx < MAN_AXIS_RANGE_SCALE_END) { return MAN_AXES_SCALE; } + if (axis_idx == MAN_AXIS_APRON_C) { + return axis_type_default; + } BLI_assert(0); return -1; } @@ -326,6 +332,8 @@ static bool gizmo_is_axis_visible( rv3d->twdrawflag & MAN_SCALE_X && (twtype & SCE_MANIP_TRANSLATE) == 0 && (twtype & SCE_MANIP_ROTATE) == 0); + case MAN_AXIS_APRON_C: + return true; } return false; } @@ -1169,9 +1177,11 @@ static void gizmo_xform_message_subscribe( if (type_fn == TRANSFORM_GGT_gizmo) { extern PropertyRNA rna_ToolSettings_transform_pivot_point; extern PropertyRNA rna_ToolSettings_use_gizmo_mode; + extern PropertyRNA rna_ToolSettings_use_gizmo_apron; const PropertyRNA *props[] = { &rna_ToolSettings_transform_pivot_point, &rna_ToolSettings_use_gizmo_mode, + &rna_ToolSettings_use_gizmo_apron, }; for (int i = 0; i < ARRAY_SIZE(props); i++) { WM_msg_subscribe_rna(mbus, &toolsettings_ptr, props[i], &msg_sub_value_gz_tag_refresh, __func__); @@ -1204,6 +1214,12 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup) const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true); const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true); + /* Fallback action. */ + { + const wmGizmoType *gzt_mask = WM_gizmotype_find("GIZMO_GT_blank_3d", true); + man->gizmos[MAN_AXIS_APRON_C] = WM_gizmo_new_ptr(gzt_mask, gzgroup, NULL); + } + #define GIZMO_NEW_ARROW(v, draw_style) { \ man->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \ RNA_enum_set(man->gizmos[v]->ptr, "draw_style", draw_style); \ @@ -1291,9 +1307,23 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup) wmOperatorType *translate, *rotate, *trackball, *resize; } ot_store = {NULL}; GizmoGroup *man = gzgroup->customdata; + + if (man->twtype & SCE_MANIP_TRANSLATE) { + man->axis_type_default = MAN_AXES_TRANSLATE; + } + else if (man->twtype & SCE_MANIP_ROTATE) { + man->axis_type_default = MAN_AXES_ROTATE; + } + else if (man->twtype & SCE_MANIP_SCALE) { + man->axis_type_default = MAN_AXES_SCALE; + } + else { + man->axis_type_default = 0; + } + MAN_ITER_AXES_BEGIN(axis, axis_idx) { - const short axis_type = gizmo_get_axis_type(axis_idx); + const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default); bool constraint_axis[3] = {1, 0, 0}; PointerRNA *ptr; @@ -1356,6 +1386,9 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup) WM_gizmo_set_scale(axis, 0.2f); } break; + case MAN_AXIS_APRON_C: + WM_gizmo_set_scale(axis, 1.2f); + break; } switch (axis_type) { @@ -1472,7 +1505,7 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup) MAN_ITER_AXES_BEGIN(axis, axis_idx) { - const short axis_type = gizmo_get_axis_type(axis_idx); + const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default); const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL); WM_gizmo_set_matrix_location(axis, rv3d->twmat[3]); @@ -1537,6 +1570,7 @@ static void WIDGETGROUP_gizmo_message_subscribe( static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { + const Scene *scene = CTX_data_scene(C); GizmoGroup *man = gzgroup->customdata; // ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -1560,9 +1594,13 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr MAN_ITER_AXES_BEGIN(axis, axis_idx) { - const short axis_type = gizmo_get_axis_type(axis_idx); + const short axis_type = gizmo_get_axis_type(axis_idx, man->axis_type_default); /* XXX maybe unset _HIDDEN flag on redraw? */ - if (gizmo_is_axis_visible(rv3d, man->twtype, idot, axis_type, axis_idx)) { + + if (axis_idx == MAN_AXIS_APRON_C) { + WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, (scene->toolsettings->gizmo_flag & SCE_MANIP_DISABLE_APRON) != 0); + } + else if (gizmo_is_axis_visible(rv3d, man->twtype, idot, axis_type, axis_idx)) { WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false); } else { @@ -1580,6 +1618,7 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr case MAN_AXIS_ROT_C: case MAN_AXIS_SCALE_C: case MAN_AXIS_ROT_T: + case MAN_AXIS_APRON_C: WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]); break; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 13de7f9829e..262c24164df 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2053,9 +2053,13 @@ typedef enum eImagePaintMode { #define EDGE_MODE_TAG_FREESTYLE 5 /* ToolSettings.gizmo_flag */ -#define SCE_MANIP_TRANSLATE 1 -#define SCE_MANIP_ROTATE 2 -#define SCE_MANIP_SCALE 4 +enum { + SCE_MANIP_TRANSLATE = (1 << 0), + SCE_MANIP_ROTATE = (1 << 1), + SCE_MANIP_SCALE = (1 << 2), + + SCE_MANIP_DISABLE_APRON = (1 << 3), +}; /* ToolSettings.gpencil_flags */ typedef enum eGPencil_Flags { diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 0cd261f28bd..21731a54aa1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2426,6 +2426,11 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Gizmo Mode", ""); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ToolSettings_gizmo_flag_update"); + prop = RNA_def_property(srna, "use_gizmo_apron", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "gizmo_flag", SCE_MANIP_DISABLE_APRON); + RNA_def_property_ui_text(prop, "Apron", "Handle input not directly over the gizmo"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + /* Grease Pencil */ prop = RNA_def_property(srna, "use_gpencil_additive_drawing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gpencil_flags", GP_TOOL_FLAG_RETAIN_LAST); -- cgit v1.2.3 From 69d710187d5ae5e5e8b54761187ef8770f3fbb00 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Thu, 9 Aug 2018 20:48:05 +0200 Subject: Fix unreported assert error when change instance modifier Doing very fast change in the number of instances soemtimes get an error of duplicate ghash entry. --- .../draw/engines/gpencil/gpencil_draw_utils.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 0a805fa9b29..f8a04a06d80 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1230,19 +1230,33 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); } - derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); + } + else { + derived_gpf = NULL; + } + if (derived_gpf == NULL) { cache->is_dirty = true; } if (cache->is_dirty) { if (derived_gpf != NULL) { /* first clear temp data */ + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); + } + BKE_gpencil_free_frame_runtime_data(derived_gpf); - BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); } /* create new data */ derived_gpf = BKE_gpencil_frame_duplicate(gpf); - BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); + if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); + } + else { + BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL); + } } /* draw onion skins */ -- cgit v1.2.3 From 693ecdf7d3adcef00b26e7f7d52856440ec980e1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 10 Aug 2018 14:30:27 +0200 Subject: Fix build error due to missing file from commit 98c304e865f8. Proper contents still needs to be added, this just makes things build. --- .../gizmo_library/gizmo_types/blank3d_gizmo.c | 42 ++++++++++++++++++++++ source/blender/editors/include/ED_gizmo_library.h | 3 ++ 2 files changed, 45 insertions(+) create mode 100644 source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c diff --git a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c new file mode 100644 index 00000000000..4dcdb7b7b3f --- /dev/null +++ b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c @@ -0,0 +1,42 @@ +/* + * ***** 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 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "BLI_math.h" + +#include "BKE_context.h" + +#include "ED_view3d.h" +#include "ED_gizmo_library.h" + +#include "WM_types.h" +#include "WM_api.h" + +/* own includes */ +#include "../gizmo_geometry.h" +#include "../gizmo_library_intern.h" + +void ED_gizmotypes_blank_3d(void) +{ +} diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 6471c90194b..41488baa964 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -42,6 +42,9 @@ void ED_gizmotypes_facemap_3d(void); void ED_gizmotypes_primitive_3d(void); void ED_gizmotypes_blank_3d(void); +struct bContext; +struct Object; +struct Scene; struct wmGizmo; struct wmGizmoGroup; -- cgit v1.2.3 From aa5a96430ea0741fac39b87fe17fb0faddadd3cf Mon Sep 17 00:00:00 2001 From: Andrew Hale Date: Fri, 10 Aug 2018 14:53:38 +0200 Subject: Python: Add support for @ infix operator matrix multiplication This differential revision implements the code for T56276 Reviewers: campbellbarton Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D3587 --- source/blender/python/mathutils/mathutils_Matrix.c | 195 ++++++++++++++++++--- .../python/mathutils/mathutils_Quaternion.c | 147 ++++++++++++++-- source/blender/python/mathutils/mathutils_Vector.c | 166 ++++++++++++++---- tests/python/bl_pyapi_mathutils.py | 102 +++++++++-- 4 files changed, 522 insertions(+), 88 deletions(-) diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 70c400f99b8..3bd40cca5c6 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -2321,7 +2321,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1)); } /*------------------------obj * obj------------------------------ - * multiplication */ + * element-wise multiplication */ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) { float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; @@ -2332,7 +2332,6 @@ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar) static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) { float scalar; - int vec_size; MatrixObject *mat1 = NULL, *mat2 = NULL; @@ -2348,15 +2347,124 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) } if (mat1 && mat2) { +#ifdef USE_MATHUTILS_ELEM_MUL /* MATRIX * MATRIX */ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; + if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { + PyErr_SetString(PyExc_ValueError, + "matrix1 * matrix2: matrix1 number of rows/columns " + "and the matrix2 number of rows/columns must be the same"); + return NULL; + } + + mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); + + return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); +#endif + } + else if (mat2) { + /*FLOAT/INT * MATRIX */ + if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) { + return matrix_mul_float(mat2, scalar); + } + } + else if (mat1) { + /* MATRIX * FLOAT/INT */ + if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) { + return matrix_mul_float(mat1, scalar); + } + } + + PyErr_Format(PyExc_TypeError, + "Element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); + return NULL; +} +/*------------------------obj *= obj------------------------------ + * Inplace element-wise multiplication */ +static PyObject *Matrix_imul(PyObject *m1, PyObject *m2) +{ + float scalar; + + MatrixObject *mat1 = NULL, *mat2 = NULL; + + if (MatrixObject_Check(m1)) { + mat1 = (MatrixObject *)m1; + if (BaseMath_ReadCallback(mat1) == -1) + return NULL; + } + if (MatrixObject_Check(m2)) { + mat2 = (MatrixObject *)m2; + if (BaseMath_ReadCallback(mat2) == -1) + return NULL; + } + + if (mat1 && mat2) { +#ifdef USE_MATHUTILS_ELEM_MUL + /* MATRIX *= MATRIX */ + if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) { + PyErr_SetString(PyExc_ValueError, + "matrix1 *= matrix2: matrix1 number of rows/columns " + "and the matrix2 number of rows/columns must be the same"); + return NULL; + } + + mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row); +#else + PyErr_Format(PyExc_TypeError, + "Inplace element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); + return NULL; +#endif + } + else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) { + /* MATRIX *= FLOAT/INT */ + mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar); + } + else { + PyErr_Format(PyExc_TypeError, + "Inplace element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); + return NULL; + } + + (void)BaseMath_WriteCallback(mat1); + Py_INCREF(m1); + return m1; +} +/*------------------------obj @ obj------------------------------ + * matrix multiplication */ +static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2) +{ + int vec_size; + + MatrixObject *mat1 = NULL, *mat2 = NULL; + + if (MatrixObject_Check(m1)) { + mat1 = (MatrixObject *)m1; + if (BaseMath_ReadCallback(mat1) == -1) + return NULL; + } + if (MatrixObject_Check(m2)) { + mat2 = (MatrixObject *)m2; + if (BaseMath_ReadCallback(mat2) == -1) + return NULL; + } + + if (mat1 && mat2) { + /* MATRIX @ MATRIX */ + float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; + int col, row, item; if (mat1->num_col != mat2->num_row) { PyErr_SetString(PyExc_ValueError, - "matrix1 * matrix2: matrix1 number of columns " - "and the matrix2 number of rows must be the same"); + "matrix1 * matrix2: matrix1 number of columns " + "and the matrix2 number of rows must be the same"); return NULL; } @@ -2372,14 +2480,8 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1)); } - else if (mat2) { - /*FLOAT/INT * MATRIX */ - if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) { - return matrix_mul_float(mat2, scalar); - } - } else if (mat1) { - /* MATRIX * VECTOR */ + /* MATRIX @ VECTOR */ if (VectorObject_Check(m2)) { VectorObject *vec2 = (VectorObject *)m2; float tvec[MATRIX_MAX_DIM]; @@ -2398,20 +2500,69 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2) return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2)); } - /*FLOAT/INT * MATRIX */ - else if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) { - return matrix_mul_float(mat1, scalar); + } + + PyErr_Format(PyExc_TypeError, + "Matrix multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); + return NULL; +} +/*------------------------obj @= obj------------------------------ + * inplace matrix multiplication */ +static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2) +{ + MatrixObject *mat1 = NULL, *mat2 = NULL; + + if (MatrixObject_Check(m1)) { + mat1 = (MatrixObject *)m1; + if (BaseMath_ReadCallback(mat1) == -1) + return NULL; + } + if (MatrixObject_Check(m2)) { + mat2 = (MatrixObject *)m2; + if (BaseMath_ReadCallback(mat2) == -1) + return NULL; + } + + if (mat1 && mat2) { + /* MATRIX @= MATRIX */ + float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM]; + int col, row, item; + + if (mat1->num_col != mat2->num_row) { + PyErr_SetString(PyExc_ValueError, + "matrix1 * matrix2: matrix1 number of columns " + "and the matrix2 number of rows must be the same"); + return NULL; } + + for (col = 0; col < mat2->num_col; col++) { + for (row = 0; row < mat1->num_row; row++) { + double dot = 0.0f; + for (item = 0; item < mat1->num_col; item++) { + dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col)); + } + /* store in new matrix as overwriting original at this point will cause + * subsequent iterations to use incorrect values */ + mat[(col * mat1->num_row) + row] = (float)dot; + } + } + + /* copy matrix back */ + memcpy(mat1->matrix, mat, mat1->num_row * mat1->num_col); } else { - BLI_assert(!"internal error"); + PyErr_Format(PyExc_TypeError, + "Inplace matrix multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); + return NULL; } - PyErr_Format(PyExc_TypeError, - "Matrix multiplication: " - "not supported between '%.200s' and '%.200s' types", - Py_TYPE(m1)->tp_name, Py_TYPE(m2)->tp_name); - return NULL; + (void)BaseMath_WriteCallback(mat1); + Py_INCREF(m1); + return m1; } /*-----------------PROTOCOL DECLARATIONS--------------------------*/ @@ -2527,7 +2678,7 @@ static PyNumberMethods Matrix_NumMethods = { NULL, /*nb_float*/ NULL, /* nb_inplace_add */ NULL, /* nb_inplace_subtract */ - NULL, /* nb_inplace_multiply */ + (binaryfunc) Matrix_imul, /* nb_inplace_multiply */ NULL, /* nb_inplace_remainder */ NULL, /* nb_inplace_power */ NULL, /* nb_inplace_lshift */ @@ -2540,6 +2691,8 @@ static PyNumberMethods Matrix_NumMethods = { NULL, /* nb_inplace_floor_divide */ NULL, /* nb_inplace_true_divide */ NULL, /* nb_index */ + (binaryfunc) Matrix_matmul, /* nb_matrix_multiply */ + (binaryfunc) Matrix_imatmul, /* nb_inplace_matrix_multiply */ }; PyDoc_STRVAR(Matrix_translation_doc, diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 48c18dd20c1..bb5983af535 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -834,7 +834,7 @@ static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar) * multiplication */ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) { - float quat[QUAT_SIZE], scalar; + float scalar; QuaternionObject *quat1 = NULL, *quat2 = NULL; if (QuaternionObject_Check(q1)) { @@ -848,9 +848,12 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) return NULL; } - if (quat1 && quat2) { /* QUAT * QUAT (cross product) */ - mul_qt_qtqt(quat, quat1->quat, quat2->quat); + if (quat1 && quat2) { /* QUAT * QUAT (element-wise product) */ +#ifdef USE_MATHUTILS_ELEM_MUL + float quat[QUAT_SIZE]; + mul_vn_vnvn(quat, quat1->quat, quat2->quat, QUAT_SIZE); return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); +#endif } /* the only case this can happen (for a supported type is "FLOAT * QUAT") */ else if (quat2) { /* FLOAT * QUAT */ @@ -858,17 +861,96 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) return quat_mul_float(quat2, scalar); } } + else if (quat1) { /* QUAT * FLOAT */ + if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { + return quat_mul_float(quat1, scalar); + } + } + + PyErr_Format(PyExc_TypeError, + "Element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); + return NULL; +} +/*------------------------obj *= obj------------------------------ + * inplace multiplication */ +static PyObject *Quaternion_imul(PyObject *q1, PyObject *q2) +{ + float scalar; + QuaternionObject *quat1 = NULL, *quat2 = NULL; + + if (QuaternionObject_Check(q1)) { + quat1 = (QuaternionObject *)q1; + if (BaseMath_ReadCallback(quat1) == -1) + return NULL; + } + if (QuaternionObject_Check(q2)) { + quat2 = (QuaternionObject *)q2; + if (BaseMath_ReadCallback(quat2) == -1) + return NULL; + } + + if (quat1 && quat2) { /* QUAT *= QUAT (inplace element-wise product) */ +#ifdef USE_MATHUTILS_ELEM_MUL + mul_vn_vn(quat1->quat, quat2->quat, QUAT_SIZE); +#else + PyErr_Format(PyExc_TypeError, + "Inplace element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); + return NULL; +#endif + } + else if (quat1 && (((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { + /* QUAT *= FLOAT */ + mul_qt_fl(quat1->quat, scalar); + } + else { + PyErr_Format(PyExc_TypeError, + "Element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); + return NULL; + } + + (void)BaseMath_WriteCallback(quat1); + Py_INCREF(q1); + return q1; +} +/*------------------------obj @ obj------------------------------ + * quaternion multiplication */ +static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2) +{ + float quat[QUAT_SIZE]; + QuaternionObject *quat1 = NULL, *quat2 = NULL; + + if (QuaternionObject_Check(q1)) { + quat1 = (QuaternionObject *)q1; + if (BaseMath_ReadCallback(quat1) == -1) + return NULL; + } + if (QuaternionObject_Check(q2)) { + quat2 = (QuaternionObject *)q2; + if (BaseMath_ReadCallback(quat2) == -1) + return NULL; + } + + if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */ + mul_qt_qtqt(quat, quat1->quat, quat2->quat); + return Quaternion_CreatePyObject(quat, Py_TYPE(q1)); + } else if (quat1) { - /* QUAT * VEC */ + /* QUAT @ VEC */ if (VectorObject_Check(q2)) { VectorObject *vec2 = (VectorObject *)q2; float tvec[3]; if (vec2->size != 3) { PyErr_SetString(PyExc_ValueError, - "Vector multiplication: " - "only 3D vector rotations (with quats) " - "currently supported"); + "Vector multiplication: " + "only 3D vector rotations (with quats) " + "currently supported"); return NULL; } if (BaseMath_ReadCallback(vec2) == -1) { @@ -880,21 +962,48 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2) return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec2)); } - /* QUAT * FLOAT */ - else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) { - return quat_mul_float(quat1, scalar); - } - } - else { - BLI_assert(!"internal error"); } PyErr_Format(PyExc_TypeError, - "Quaternion multiplication: " - "not supported between '%.200s' and '%.200s' types", - Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); + "Quaternion multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); return NULL; } +/*------------------------obj @= obj------------------------------ + * inplace quaternion multiplication */ +static PyObject *Quaternion_imatmul(PyObject *q1, PyObject *q2) +{ + float quat[QUAT_SIZE]; + QuaternionObject *quat1 = NULL, *quat2 = NULL; + + if (QuaternionObject_Check(q1)) { + quat1 = (QuaternionObject *)q1; + if (BaseMath_ReadCallback(quat1) == -1) + return NULL; + } + if (QuaternionObject_Check(q2)) { + quat2 = (QuaternionObject *)q2; + if (BaseMath_ReadCallback(quat2) == -1) + return NULL; + } + + if (quat1 && quat2) { /* QUAT @ QUAT (cross product) */ + mul_qt_qtqt(quat, quat1->quat, quat2->quat); + copy_qt_qt(quat1->quat, quat); + } + else { + PyErr_Format(PyExc_TypeError, + "Inplace quaternion multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name); + return NULL; + } + + (void)BaseMath_WriteCallback(quat1); + Py_INCREF(q1); + return q1; +} /* -obj * returns the negative of this object*/ @@ -952,7 +1061,7 @@ static PyNumberMethods Quaternion_NumMethods = { NULL, /*nb_float*/ NULL, /* nb_inplace_add */ NULL, /* nb_inplace_subtract */ - NULL, /* nb_inplace_multiply */ + (binaryfunc) Quaternion_imul, /* nb_inplace_multiply */ NULL, /* nb_inplace_remainder */ NULL, /* nb_inplace_power */ NULL, /* nb_inplace_lshift */ @@ -965,6 +1074,8 @@ static PyNumberMethods Quaternion_NumMethods = { NULL, /* nb_inplace_floor_divide */ NULL, /* nb_inplace_true_divide */ NULL, /* nb_index */ + (binaryfunc) Quaternion_matmul, /* nb_matrix_multiply */ + (binaryfunc) Quaternion_imatmul, /* nb_inplace_matrix_multiply */ }; PyDoc_STRVAR(Quaternion_axis_doc, diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index 6a40f22d9df..dc05f463d22 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -1706,12 +1706,25 @@ static PyObject *vector_mul_float(VectorObject *vec, const float scalar) mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar); return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec)); } +#ifdef USE_MATHUTILS_ELEM_MUL +static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2) +{ + float *tvec = PyMem_Malloc(vec1->size * sizeof(float)); + if (tvec == NULL) { + PyErr_SetString(PyExc_MemoryError, + "vec * vec: " + "problem allocating pointer space"); + return NULL; + } + mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size); + return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1)); +} +#endif static PyObject *Vector_mul(PyObject *v1, PyObject *v2) { VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; - int vec_size; if (VectorObject_Check(v1)) { vec1 = (VectorObject *)v1; @@ -1729,6 +1742,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) /* make sure v1 is always the vector */ if (vec1 && vec2) { +#ifdef USE_MATHUTILS_ELEM_MUL if (vec1->size != vec2->size) { PyErr_SetString(PyExc_ValueError, "Vector multiplication: " @@ -1736,30 +1750,12 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) return NULL; } - /*dot product*/ - return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size)); + /* element-wise product */ + return vector_mul_vec(vec1, vec2); +#endif } else if (vec1) { - if (MatrixObject_Check(v2)) { - /* VEC * MATRIX */ - float tvec[MAX_DIMENSIONS]; - - if (BaseMath_ReadCallback((MatrixObject *)v2) == -1) - return NULL; - if (row_vector_multiplication(tvec, vec1, (MatrixObject *)v2) == -1) { - return NULL; - } - - if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) { - vec_size = 3; - } - else { - vec_size = ((MatrixObject *)v2)->num_col; - } - - return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1)); - } - else if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */ + if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */ return vector_mul_float(vec1, scalar); } } @@ -1768,12 +1764,9 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) return vector_mul_float(vec2, scalar); } } - else { - BLI_assert(!"internal error"); - } PyErr_Format(PyExc_TypeError, - "Vector multiplication: " + "Element-wise multiplication: " "not supported between '%.200s' and '%.200s' types", Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; @@ -1782,32 +1775,129 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2) /* multiplication in-place: obj *= obj */ static PyObject *Vector_imul(PyObject *v1, PyObject *v2) { - VectorObject *vec = (VectorObject *)v1; + VectorObject *vec1 = NULL, *vec2 = NULL; float scalar; - if (BaseMath_ReadCallback_ForWrite(vec) == -1) + if (VectorObject_Check(v1)) { + vec1 = (VectorObject *)v1; + if (BaseMath_ReadCallback(vec1) == -1) + return NULL; + } + if (VectorObject_Check(v2)) { + vec2 = (VectorObject *)v2; + if (BaseMath_ReadCallback(vec2) == -1) + return NULL; + } + + if (BaseMath_ReadCallback_ForWrite(vec1) == -1) return NULL; /* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */ - /* only support 'vec *= float' - * vec*=vec result is a float so that wont work */ - if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC *= FLOAT */ - mul_vn_fl(vec->vec, vec->size, scalar); + if (vec1 && vec2) { +#ifdef USE_MATHUTILS_ELEM_MUL + if (vec1->size != vec2->size) { + PyErr_SetString(PyExc_ValueError, + "Vector multiplication: " + "vectors must have the same dimensions for this operation"); + return NULL; + } + + /* element-wise product inplace */ + mul_vn_vn(vec1->vec, vec2->vec, vec1->size); +#else + PyErr_Format(PyExc_TypeError, + "Inplace element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); + return NULL; +#endif + } + else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0)) { /* VEC *= FLOAT */ + mul_vn_fl(vec1->vec, vec1->size, scalar); } else { PyErr_Format(PyExc_TypeError, - "Vector multiplication: (%s *= %s) " - "invalid type for this operation", - Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); + "Inplace element-wise multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); return NULL; } - (void)BaseMath_WriteCallback(vec); + (void)BaseMath_WriteCallback(vec1); Py_INCREF(v1); return v1; } +static PyObject *Vector_matmul(PyObject *v1, PyObject *v2) +{ + VectorObject *vec1 = NULL, *vec2 = NULL; + int vec_size; + + if (VectorObject_Check(v1)) { + vec1 = (VectorObject *)v1; + if (BaseMath_ReadCallback(vec1) == -1) + return NULL; + } + if (VectorObject_Check(v2)) { + vec2 = (VectorObject *)v2; + if (BaseMath_ReadCallback(vec2) == -1) + return NULL; + } + + + /* Intentionally don't support (Quaternion) here, uses reverse order instead. */ + + /* make sure v1 is always the vector */ + if (vec1 && vec2) { + if (vec1->size != vec2->size) { + PyErr_SetString(PyExc_ValueError, + "Vector multiplication: " + "vectors must have the same dimensions for this operation"); + return NULL; + } + + /*dot product*/ + return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size)); + } + else if (vec1) { + if (MatrixObject_Check(v2)) { + /* VEC @ MATRIX */ + float tvec[MAX_DIMENSIONS]; + + if (BaseMath_ReadCallback((MatrixObject *)v2) == -1) + return NULL; + if (row_vector_multiplication(tvec, vec1, (MatrixObject *)v2) == -1) { + return NULL; + } + + if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) { + vec_size = 3; + } + else { + vec_size = ((MatrixObject *)v2)->num_col; + } + + return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1)); + } + } + + PyErr_Format(PyExc_TypeError, + "Vector multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); + return NULL; +} + +static PyObject *Vector_imatmul(PyObject *v1, PyObject *v2) +{ + PyErr_Format(PyExc_TypeError, + "Inplace vector multiplication: " + "not supported between '%.200s' and '%.200s' types", + Py_TYPE(v1)->tp_name, Py_TYPE(v2)->tp_name); + return NULL; +} + /* divid: obj / obj */ static PyObject *Vector_div(PyObject *v1, PyObject *v2) { @@ -2119,6 +2209,8 @@ static PyNumberMethods Vector_NumMethods = { NULL, /* nb_inplace_floor_divide */ Vector_idiv, /* nb_inplace_true_divide */ NULL, /* nb_index */ + (binaryfunc) Vector_matmul, /* nb_matrix_multiply */ + (binaryfunc) Vector_imatmul, /* nb_inplace_matrix_multiply */ }; /*------------------PY_OBECT DEFINITION--------------------------*/ diff --git a/tests/python/bl_pyapi_mathutils.py b/tests/python/bl_pyapi_mathutils.py index 57bbbc7e73e..5aa95f9a5f7 100644 --- a/tests/python/bl_pyapi_mathutils.py +++ b/tests/python/bl_pyapi_mathutils.py @@ -104,7 +104,7 @@ class MatrixTesting(unittest.TestCase): self.assertEqual(mat[1][3], 2) self.assertEqual(mat[2][3], 3) - def test_non_square_mult(self): + def test_matrix_non_square_matmul(self): mat1 = Matrix(((1, 2, 3), (4, 5, 6))) mat2 = Matrix(((1, 2), @@ -117,10 +117,10 @@ class MatrixTesting(unittest.TestCase): (19, 26, 33), (29, 40, 51))) - self.assertEqual(mat1 * mat2, prod_mat1) - self.assertEqual(mat2 * mat1, prod_mat2) + self.assertEqual(mat1 @ mat2, prod_mat1) + self.assertEqual(mat2 @ mat1, prod_mat2) - def test_mat4x4_vec3D_mult(self): + def test_mat4x4_vec3D_matmul(self): mat = Matrix(((1, 0, 2, 0), (0, 6, 0, 0), (0, 0, 1, 1), @@ -131,23 +131,58 @@ class MatrixTesting(unittest.TestCase): prod_mat_vec = Vector((7, 12, 4)) prod_vec_mat = Vector((1, 12, 5)) - self.assertEqual(mat * vec, prod_mat_vec) - self.assertEqual(vec * mat, prod_vec_mat) + self.assertEqual(mat @ vec, prod_mat_vec) + self.assertEqual(vec @ mat, prod_vec_mat) - def test_mat_vec_mult(self): + def test_mat_vec_matmul(self): mat1 = Matrix() vec = Vector((1, 2)) - self.assertRaises(ValueError, mat1.__mul__, vec) - self.assertRaises(ValueError, vec.__mul__, mat1) + self.assertRaises(ValueError, mat1.__matmul__, vec) + self.assertRaises(ValueError, vec.__matmul__, mat1) mat2 = Matrix(((1, 2), (-2, 3))) prod = Vector((5, 4)) - self.assertEqual(mat2 * vec, prod) + self.assertEqual(mat2 @ vec, prod) + + def test_matrix_square_matmul(self): + mat1 = Matrix(((1, 0), + (1, 2))) + mat2 = Matrix(((1, 2), + (-2, 3))) + + prod1 = Matrix(((1, 2), + (-3, 8))) + prod2 = Matrix(((3, 4), + (1, 6))) + + self.assertEqual(mat1 @ mat2, prod1) + self.assertEqual(mat2 @ mat1, prod2) + + """ + # tests for element-wise multiplication + + def test_matrix_mul(self): + mat1 = Matrix(((1, 0), + (1, 2))) + mat2 = Matrix(((1, 2), + (-2, 3))) + mat3 = Matrix(((1, 0, 2, 0), + (0, 6, 0, 0), + (0, 0, 1, 1), + (0, 0, 0, 1))) + + prod = Matrix(((1, 0), + (-2, 6))) + + self.assertEqual(mat1 * mat2, prod) + self.assertEqual(mat2 * mat1, prod) + self.assertRaises(ValueError, mat1.__mul__, mat3) + """ def test_matrix_inverse(self): mat = Matrix(((1, 4, 0, -1), @@ -185,7 +220,7 @@ class MatrixTesting(unittest.TestCase): self.assertEqual(mat.inverted_safe(), inv_mat_safe) - def test_matrix_mult(self): + def test_matrix_matmult(self): mat = Matrix(((1, 4, 0, -1), (2, -1, 2, -2), (0, 3, 8, 3), @@ -196,7 +231,7 @@ class MatrixTesting(unittest.TestCase): (0, 48, 73, 18), (16, -14, 26, -13))) - self.assertEqual(mat * mat, prod_mat) + self.assertEqual(mat @ mat, prod_mat) class VectorTesting(unittest.TestCase): @@ -209,6 +244,49 @@ class VectorTesting(unittest.TestCase): if v.length_squared != 0.0: self.assertAlmostEqual(v.angle(v.orthogonal()), angle_90d) + def test_vector_matmul(self): + # produces dot product for vectors + vec1 = Vector((1, 3, 5)) + vec2 = Vector((1, 2)) + + self.assertRaises(ValueError, vec1.__matmul__, vec2) + self.assertEqual(vec1 @ vec1, 35) + self.assertEqual(vec2 @ vec2, 5) + + def test_vector_imatmul(self): + vec = Vector((1, 3, 5)) + + with self.assertRaises(TypeError): + vec @= vec + + """ + # tests for element-wise multiplication + + def test_vector_mul(self): + # element-wise multiplication + vec1 = Vector((1, 3, 5)) + vec2 = Vector((1, 2)) + + prod1 = Vector((1, 9, 25)) + prod2 = Vector((2, 6, 10)) + + self.assertRaises(ValueError, vec1.__mul__, vec2) + self.assertEqual(vec1 * vec1, prod1) + self.assertEqual(2 * vec1, prod2) + + def test_vector_imul(self): + # inplace element-wise multiplication + vec = Vector((1, 3, 5)) + prod1 = Vector((1, 9, 25)) + prod2 = Vector((2, 18, 50)) + + vec *= vec + self.assertEqual(vec, prod1) + + vec *= 2 + self.assertEqual(vec, prod2) + """ + class QuaternionTesting(unittest.TestCase): -- cgit v1.2.3 From e2f006949fbd68c77777b7cb8e7ad0d5e32340f7 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Fri, 10 Aug 2018 07:48:27 -0600 Subject: build_environment: update freetype to 2.9.1 --- build_files/build_environment/cmake/freetype.cmake | 8 ++++++++ build_files/build_environment/cmake/harvest.cmake | 2 -- build_files/build_environment/cmake/versions.cmake | 4 ++-- build_files/build_environment/patches/freetype.diff | 18 ++++++++++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 build_files/build_environment/patches/freetype.diff diff --git a/build_files/build_environment/cmake/freetype.cmake b/build_files/build_environment/cmake/freetype.cmake index 9afc902531b..1034e9f2029 100644 --- a/build_files/build_environment/cmake/freetype.cmake +++ b/build_files/build_environment/cmake/freetype.cmake @@ -32,5 +32,13 @@ ExternalProject_Add(external_freetype URL_HASH MD5=${FREETYPE_HASH} PREFIX ${BUILD_DIR}/freetype CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/freetype ${DEFAULT_CMAKE_FLAGS} ${FREETYPE_EXTRA_ARGS} + PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/freetype/src/external_freetype < ${PATCH_DIR}/freetype.diff INSTALL_DIR ${LIBDIR}/freetype ) + +if(BUILD_MODE STREQUAL Release AND WIN32) + ExternalProject_Add_Step(external_freetype after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype + DEPENDEES install + ) +endif() diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 9ebd5206d27..8519d981964 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -35,8 +35,6 @@ if(BUILD_MODE STREQUAL Release) # jpeg rename libfile + copy include ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpg/include/ ${HARVEST_TARGET}/jpeg/include/ && - # FreeType, straight up copy - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype && # pthreads, rename include dir ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/ && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib && diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 9a0c7c02d5a..eefc751a7a4 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -53,9 +53,9 @@ set(OPENEXR_VERSION 2.2.0) set(OPENEXR_URI http://download.savannah.nongnu.org/releases/openexr/openexr-2.2.0.tar.gz) set(OPENEXR_HASH b64e931c82aa3790329c21418373db4e) -set(FREETYPE_VERSION 263) +set(FREETYPE_VERSION 291) set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/ft${FREETYPE_VERSION}.zip) -set(FREETYPE_HASH 0db2a43301572e5c2b4a0864f237aeeb) +set(FREETYPE_HASH 6ca68fc28e443a05f756075d3b1dcb54) set(GLEW_VERSION 1.13.0) set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz) diff --git a/build_files/build_environment/patches/freetype.diff b/build_files/build_environment/patches/freetype.diff new file mode 100644 index 00000000000..cf952234795 --- /dev/null +++ b/build_files/build_environment/patches/freetype.diff @@ -0,0 +1,18 @@ +diff -NaurBb b/CMakeLists.txt a/CMakeLists.txt +--- b/CMakeLists.txt 2018-05-01 12:45:46 -0600 ++++ a/CMakeLists.txt 2018-08-08 13:03:22 -0600 +@@ -229,9 +229,12 @@ + endif () + string(REPLACE "/undef " "#undef " + FTCONFIG_H "${FTCONFIG_H}") +- file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h" +- "${FTCONFIG_H}") ++else() ++ file(READ "${PROJECT_SOURCE_DIR}/include/freetype/config/ftconfig.h" ++ FTCONFIG_H) + endif () ++file(WRITE "${PROJECT_BINARY_DIR}/include/freetype/config/ftconfig.h" ++ "${FTCONFIG_H}") + + + # Create the options file -- cgit v1.2.3 From c70350c68f8e609105eb995707282885a1e0b399 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 10 Aug 2018 15:57:45 +0200 Subject: GP: Set instance maximum value to something more logic --- source/blender/makesrna/intern/rna_gpencil_modifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index c137eec7568..d4252601c6a 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -860,7 +860,7 @@ static void rna_def_modifier_gpencilinstance(BlenderRNA *brna) prop = RNA_def_property(srna, "count", PROP_INT, PROP_XYZ); RNA_def_property_range(prop, 1, INT_MAX); - RNA_def_property_ui_range(prop, 1, 1000, 1, -1); + RNA_def_property_ui_range(prop, 1, 20, 1, -1); RNA_def_property_ui_text(prop, "Count", "Number of items"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); -- cgit v1.2.3 From c9bd61b37240ad000ae7ac4d49801e4afe3565b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 10 Aug 2018 14:24:31 +0200 Subject: UI: Fix nodelink not touching inputs when noodle_curving is 0 --- source/blender/editors/space_node/drawnode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index a48a6faf69f..4dfbb92971b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3353,7 +3353,16 @@ static bool node_link_bezier_handles(View2D *v2d, SpaceNode *snode, bNodeLink *l } /* may be called outside of drawing (so pass spacetype) */ - dist = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE) * 0.10f * fabsf(vec[0][0] - vec[3][0]); + int curving = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE); + + if (curving == 0) { + /* Straight line: align all points. */ + mid_v2_v2v2(vec[1], vec[0], vec[3]); + mid_v2_v2v2(vec[2], vec[1], vec[3]); + return 1; + } + + dist = curving * 0.10f * fabsf(vec[0][0] - vec[3][0]); deltax = vec[3][0] - vec[0][0]; deltay = vec[3][1] - vec[0][1]; /* check direction later, for top sockets */ -- cgit v1.2.3 From bf6a22ed6f6bbe7db3e7796e83d32e071aae93cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 10 Aug 2018 15:13:39 +0200 Subject: GPUMaterial: Group all colorband texture together This lower the use of texture samplers slots and let users use more real textures in their shaders. This patch also make the ramp texture 16 bit floating point. Meaning you can now use value greater than one in your color ramps. With the limit of 128 colorband per shader (a color band being either a color ramp, a wavelength node or a curve node (and maybe wavelength node in the future)). Only drawback with the current implementation is that it does not remove colorband from pruned GPUNodes but it shouldn't really matter in practice. This should fix T56010 --- source/blender/draw/intern/draw_manager_data.c | 4 +- source/blender/gpu/GPU_material.h | 3 +- source/blender/gpu/GPU_texture.h | 2 + source/blender/gpu/intern/gpu_codegen.c | 23 ++++---- source/blender/gpu/intern/gpu_codegen.h | 1 + source/blender/gpu/intern/gpu_material.c | 61 ++++++++++++++++++++-- source/blender/gpu/intern/gpu_texture.c | 7 +++ .../blender/gpu/shaders/gpu_shader_material.glsl | 48 ++++++++--------- .../nodes/shader/nodes/node_shader_blackbody.c | 7 ++- .../nodes/shader/nodes/node_shader_curves.c | 12 +++-- .../nodes/shader/nodes/node_shader_valToRgb.c | 5 +- .../shader/nodes/node_shader_volume_principled.c | 14 ++--- 12 files changed, 130 insertions(+), 57 deletions(-) diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 6b15803723b..b97101c0e6d 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -776,7 +776,9 @@ static DRWShadingGroup *drw_shgroup_material_inputs(DRWShadingGroup *grp, struct } /* Color Ramps */ else if (input->tex) { - DRW_shgroup_uniform_texture(grp, input->shadername, input->tex); + /* HACK : input->tex is a (GPUTexture **) in this case. */ + GPUTexture *tex = *((GPUTexture **)input->tex); + DRW_shgroup_uniform_texture(grp, input->shadername, tex); } /* Floats */ else { diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 9dcf308a414..6b0296361ec 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -80,6 +80,7 @@ typedef enum GPUType { GPU_MAT4 = 16, /* Values not in GPU_DATATYPE_STR */ + GPU_TEX1D_ARRAY = 1001, GPU_TEX2D = 1002, GPU_TEX3D = 1003, GPU_SHADOW2D = 1004, @@ -229,7 +230,7 @@ GPUNodeLink *GPU_uniform_buffer(float *num, GPUType gputype); GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data); GPUNodeLink *GPU_cube_map(struct Image *ima, struct ImageUser *iuser, bool is_data); GPUNodeLink *GPU_image_preview(struct PreviewImage *prv); -GPUNodeLink *GPU_texture(int size, float *pixels); +GPUNodeLink *GPU_texture_ramp(GPUMaterial *mat, int size, float *pixels, float *layer); GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, GPUDynamicType dynamictype, void *data); GPUNodeLink *GPU_builtin(GPUBuiltin builtin); GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin); diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 1ddf801e166..23b88645e33 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -163,6 +163,8 @@ GPUTexture *GPU_texture_create_nD( GPUTexture *GPU_texture_create_1D( int w, GPUTextureFormat data_type, const float *pixels, char err_out[256]); +GPUTexture *GPU_texture_create_1D_array( + int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D( int w, int h, GPUTextureFormat data_type, const float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D_multisample( diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index cc4b7cc8ebc..289befe674e 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -257,6 +257,9 @@ static void gpu_parse_functions_string(GHash *hash, char *code) if (!type && gpu_str_prefix(code, "sampler2DShadow")) { type = GPU_SHADOW2D; } + if (!type && gpu_str_prefix(code, "sampler1DArray")) { + type = GPU_TEX1D_ARRAY; + } if (!type && gpu_str_prefix(code, "sampler2D")) { type = GPU_TEX2D; } @@ -617,6 +620,7 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, DynStr *ds, if (codegen_input_has_texture(input) && input->bindtex) { BLI_dynstr_appendf( ds, "uniform %s samp%d;\n", + (input->textype == GPU_TEX1D_ARRAY) ? "sampler1DArray" : (input->textype == GPU_TEX2D) ? "sampler2D" : (input->textype == GPU_TEXCUBE) ? "samplerCube" : "sampler2DShadow", input->texid); @@ -1330,15 +1334,9 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType /* small texture created on the fly, like for colorbands */ input->type = GPU_VEC4; input->source = GPU_SOURCE_TEX; - input->textype = type; - -#if 0 - input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL); -#endif - input->tex = GPU_texture_create_2D(link->texturesize, 1, GPU_RGBA8, link->ptr1, NULL); - input->textarget = GL_TEXTURE_2D; - - MEM_freeN(link->ptr1); + input->textype = GPU_TEX1D_ARRAY; + input->tex = link->ptr1; /* HACK ptr1 is actually a (GPUTexture **). */ + input->textarget = GL_TEXTURE_1D_ARRAY; MEM_freeN(link); } else if (link->image) { @@ -1687,13 +1685,14 @@ GPUNodeLink *GPU_image_preview(PreviewImage *prv) } -GPUNodeLink *GPU_texture(int size, float *pixels) +GPUNodeLink *GPU_texture_ramp(GPUMaterial *mat, int size, float *pixels, float *row) { GPUNodeLink *link = GPU_node_link_create(); link->texture = true; - link->texturesize = size; - link->ptr1 = pixels; + link->ptr1 = gpu_material_ramp_texture_row_set(mat, size, pixels, row); + + MEM_freeN(pixels); return link; } diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h index 4af87c6a226..77e6e5cf4ef 100644 --- a/source/blender/gpu/intern/gpu_codegen.h +++ b/source/blender/gpu/intern/gpu_codegen.h @@ -197,6 +197,7 @@ void gpu_codegen_exit(void); const char *GPU_builtin_name(GPUBuiltin builtin); void gpu_material_add_node(struct GPUMaterial *material, struct GPUNode *node); +struct GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row); int GPU_link_changed(struct GPUNodeLink *link); #endif diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 69c3a3a73ba..b03df2c643c 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -63,6 +63,12 @@ #endif /* Structs */ +#define MAX_COLOR_BAND 128 + +typedef struct GPUColorBandBuilder { + float pixels[MAX_COLOR_BAND][CM_TABLE + 1][4]; + int current_layer; +} GPUColorBandBuilder; struct GPUMaterial { Scene *scene; /* DEPRECATED was only usefull for lamps */ @@ -125,6 +131,9 @@ struct GPUMaterial { float sss_sharpness; bool sss_dirty; + GPUTexture *coba_tex; /* 1D Texture array containing all color bands. */ + GPUColorBandBuilder *coba_builder; + #ifndef NDEBUG char name[64]; #endif @@ -138,6 +147,47 @@ enum { /* Functions */ +/* Returns the adress of the future pointer to coba_tex */ +GPUTexture **gpu_material_ramp_texture_row_set(GPUMaterial *mat, int size, float *pixels, float *row) +{ + /* In order to put all the colorbands into one 1D array texture, + * we need them to be the same size. */ + BLI_assert(size == CM_TABLE + 1); + + if (mat->coba_builder == NULL) { + mat->coba_builder = MEM_mallocN(sizeof(GPUColorBandBuilder), "GPUColorBandBuilder"); + mat->coba_builder->current_layer = 0; + } + + int layer = mat->coba_builder->current_layer; + *row = (float)layer; + + if (*row == MAX_COLOR_BAND) { + printf("Too many color band in shader! Remove some Curve, Black Body or Color Ramp Node.\n"); + } + else { + float *dst = (float *)mat->coba_builder->pixels[layer]; + memcpy(dst, pixels, sizeof(float) * (CM_TABLE + 1) * 4); + mat->coba_builder->current_layer += 1; + } + + return &mat->coba_tex; +} + +static void gpu_material_ramp_texture_build(GPUMaterial *mat) +{ + if (mat->coba_builder == NULL) + return; + + GPUColorBandBuilder *builder = mat->coba_builder; + + mat->coba_tex = GPU_texture_create_1D_array(CM_TABLE + 1, builder->current_layer, GPU_RGBA16F, + (float *)builder->pixels, NULL); + + MEM_freeN(builder); + mat->coba_builder = NULL; +} + static void gpu_material_free_single(GPUMaterial *material) { /* Cancel / wait any pending lazy compilation. */ @@ -146,20 +196,21 @@ static void gpu_material_free_single(GPUMaterial *material) GPU_pass_free_nodes(&material->nodes); GPU_inputs_free(&material->inputs); - if (material->pass) + if (material->pass != NULL) { GPU_pass_release(material->pass); - + } if (material->ubo != NULL) { GPU_uniformbuffer_free(material->ubo); } - if (material->sss_tex_profile != NULL) { GPU_texture_free(material->sss_tex_profile); } - if (material->sss_profile != NULL) { GPU_uniformbuffer_free(material->sss_profile); } + if (material->coba_tex != NULL) { + GPU_texture_free(material->coba_tex); + } } void GPU_material_free(ListBase *gpumaterial) @@ -622,6 +673,8 @@ GPUMaterial *GPU_material_from_nodetree( bNodeTree *localtree = ntreeLocalize(ntree); ntreeGPUMaterialNodes(localtree, mat, &has_surface_output, &has_volume_output); + gpu_material_ramp_texture_build(mat); + if (has_surface_output) { mat->domain |= GPU_DOMAIN_SURFACE; } diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index a5dfb6a6b73..2ccc9f10269 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -871,6 +871,13 @@ GPUTexture *GPU_texture_create_1D( return GPU_texture_create_nD(w, 0, 0, 1, pixels, tex_format, data_format, 0, false, err_out); } +GPUTexture *GPU_texture_create_1D_array( + int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256]) +{ + GPUDataFormat data_format = gpu_get_data_format_from_tex_format(tex_format); + return GPU_texture_create_nD(w, h, 0, 1, pixels, tex_format, data_format, 0, false, err_out); +} + GPUTexture *GPU_texture_create_2D( int w, int h, GPUTextureFormat tex_format, const float *pixels, char err_out[256]) { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 56fa6291c65..91104fe51bd 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -480,27 +480,26 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) outdot = dot(normalize(dir), nor); } -void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) +void curves_vec(float fac, vec3 vec, sampler1DArray curvemap, float layer, out vec3 outvec) { - outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; - outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y; - outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z; - - if (fac != 1.0) - outvec = (outvec * fac) + (vec * (1.0 - fac)); - + vec4 co = vec4(vec * 0.5 + 0.5, layer); + outvec.x = texture(curvemap, co.xw).x; + outvec.y = texture(curvemap, co.yw).y; + outvec.z = texture(curvemap, co.zw).z; + outvec = mix(vec, outvec, fac); } -void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol) +void curves_rgb(float fac, vec4 col, sampler1DArray curvemap, float layer, out vec4 outcol) { - outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; - outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; - outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; - - if (fac != 1.0) - outcol = (outcol * fac) + (col * (1.0 - fac)); - + vec4 co = vec4(col.rgb, layer); + co.x = texture(curvemap, co.xw).a; + co.y = texture(curvemap, co.yw).a; + co.z = texture(curvemap, co.zw).a; + outcol.r = texture(curvemap, co.xw).r; + outcol.g = texture(curvemap, co.yw).g; + outcol.b = texture(curvemap, co.zw).b; outcol.a = col.a; + outcol = mix(col, outcol, fac); } void set_value(float val, out float outval) @@ -813,9 +812,9 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol) outcol = col1 + fac * (2.0 * (col2 - vec4(0.5))); } -void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha) +void valtorgb(float fac, sampler1DArray colormap, float layer, out vec4 outcol, out float outalpha) { - outcol = texture(colormap, vec2(fac, 0.0)); + outcol = texture(colormap, vec2(fac, layer)); outalpha = outcol.a; } @@ -1464,17 +1463,17 @@ void node_volume_absorption(vec4 color, float density, out Closure result) #endif } -void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color) +void node_blackbody(float temperature, sampler1DArray spectrummap, float layer, out vec4 color) { - if(temperature >= 12000.0) { + if (temperature >= 12000.0) { color = vec4(0.826270103, 0.994478524, 1.56626022, 1.0); } - else if(temperature < 965.0) { + else if (temperature < 965.0) { color = vec4(4.70366907, 0.0, 0.0, 1.0); } else { float t = (temperature - 965.0) / (12000.0 - 965.0); - color = vec4(texture(spectrummap, vec2(t, 0.0)).rgb, 1.0); + color = vec4(texture(spectrummap, vec2(t, layer)).rgb, 1.0); } } @@ -1491,7 +1490,8 @@ void node_volume_principled( float density_attribute, vec4 color_attribute, float temperature_attribute, - sampler2D spectrummap, + sampler1DArray spectrummap, + float layer, out Closure result) { #ifdef VOLUMETRICS @@ -1533,7 +1533,7 @@ void node_volume_principled( if(intensity > 1e-5) { vec4 bb; - node_blackbody(T, spectrummap, bb); + node_blackbody(T, spectrummap, layer, bb); emission_coeff += bb.rgb * blackbody_tint.rgb * intensity; } } diff --git a/source/blender/nodes/shader/nodes/node_shader_blackbody.c b/source/blender/nodes/shader/nodes/node_shader_blackbody.c index 76291df41bc..e57f5e0d6cf 100644 --- a/source/blender/nodes/shader/nodes/node_shader_blackbody.c +++ b/source/blender/nodes/shader/nodes/node_shader_blackbody.c @@ -40,12 +40,15 @@ static bNodeSocketTemplate sh_node_blackbody_out[] = { static int node_shader_gpu_blackbody(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - const int size = 256; + const int size = CM_TABLE + 1; float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"); blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f); - return GPU_stack_link(mat, node, "node_blackbody", in, out, GPU_texture(size, data)); + float layer; + GPUNodeLink *ramp_texture = GPU_texture_ramp(mat, size, data, &layer); + + return GPU_stack_link(mat, node, "node_blackbody", in, out, ramp_texture, GPU_uniform(&layer)); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index d5932ff233a..21bdc3cd0d8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -62,11 +62,13 @@ static void node_shader_init_curve_vec(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_curve_vec(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + float *array, layer; int size; curvemapping_table_RGBA(node->storage, &array, &size); - return GPU_stack_link(mat, node, "curves_vec", in, out, GPU_texture(size, array)); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + + return GPU_stack_link(mat, node, "curves_vec", in, out, tex, GPU_uniform(&layer)); } void register_node_type_sh_curve_vec(void) @@ -119,12 +121,14 @@ static void node_shader_init_curve_rgb(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + float *array, layer; int size; curvemapping_initialize(node->storage); curvemapping_table_RGBA(node->storage, &array, &size); - return GPU_stack_link(mat, node, "curves_rgb", in, out, GPU_texture(size, array)); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + + return GPU_stack_link(mat, node, "curves_rgb", in, out, tex, GPU_uniform(&layer)); } void register_node_type_sh_curve_rgb(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c index b6581cb18cb..00940b5acaf 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c @@ -65,11 +65,12 @@ static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - float *array; + float *array, layer; int size; BKE_colorband_evaluate_table_rgba(node->storage, &array, &size); - return GPU_stack_link(mat, node, "valtorgb", in, out, GPU_texture(size, array)); + GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); + return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer)); } void register_node_type_sh_valtorgb(void) diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c index a88a7ebb21a..c946c42f9af 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.c @@ -132,19 +132,19 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNod } /* Create blackbody spectrum. */ - GPUNodeLink *spectrummap; + const int size = CM_TABLE + 1; + float *data, layer; if (use_blackbody) { - const int size = 256; - float *data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"); + data = MEM_mallocN(sizeof(float) * size * 4, "blackbody texture"); blackbody_temperature_to_rgb_table(data, size, 965.0f, 12000.0f); - spectrummap = GPU_texture(size, data); } else { - float *data = MEM_callocN(sizeof(float) * 4, "blackbody black"); - spectrummap = GPU_texture(1, data); + data = MEM_callocN(sizeof(float) * size * 4, "blackbody black"); } + GPUNodeLink *spectrummap = GPU_texture_ramp(mat, size, data, &layer); - return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap); + return GPU_stack_link(mat, node, "node_volume_principled", in, out, density, color, temperature, spectrummap, + GPU_uniform(&layer)); } /* node type definition */ -- cgit v1.2.3 From 2cbffc8e4088d0d6a88fe90d1095cc90d2fa2b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 10 Aug 2018 16:04:52 +0200 Subject: Eevee: Fix assert with object volume rendering --- source/blender/draw/engines/eevee/eevee_volumes.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 4f163af2202..f8bb8c6f1cf 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -481,6 +481,13 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize); + /* TODO(fclem) remove thoses "unecessary" UBOs */ + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", ob->imat); DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1); -- cgit v1.2.3 From 767386736070cfe7294e217f3734c1e7b736f4ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 10 Aug 2018 16:16:09 +0200 Subject: GPUMaterial: Fix color ramp node with constant interpolation Color ramp with constant interpolation must bypass texture filtering and use nearest neighboor sampling in order to appear correctly sharp. This patch use a GLSL hack to use nearest sampling on thoses particular color band. --- source/blender/gpu/shaders/gpu_shader_material.glsl | 6 ++++++ source/blender/nodes/shader/nodes/node_shader_valToRgb.c | 11 +++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 91104fe51bd..40aba1cc004 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -818,6 +818,12 @@ void valtorgb(float fac, sampler1DArray colormap, float layer, out vec4 outcol, outalpha = outcol.a; } +void valtorgb_nearest(float fac, sampler1DArray colormap, float layer, out vec4 outcol, out float outalpha) +{ + outcol = texelFetch(colormap, ivec2(fac * textureSize(colormap, 0).x, layer), 0); + outalpha = outcol.a; +} + void rgbtobw(vec4 color, out float outval) { vec3 factors = vec3(0.2126, 0.7152, 0.0722); diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c index 00940b5acaf..5f583e1e29b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c @@ -65,12 +65,19 @@ static void node_shader_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node) static int gpu_shader_valtorgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { + struct ColorBand *coba = node->storage; float *array, layer; int size; - BKE_colorband_evaluate_table_rgba(node->storage, &array, &size); + BKE_colorband_evaluate_table_rgba(coba, &array, &size); GPUNodeLink *tex = GPU_texture_ramp(mat, size, array, &layer); - return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer)); + + if (coba->ipotype == COLBAND_INTERP_CONSTANT) { + return GPU_stack_link(mat, node, "valtorgb_nearest", in, out, tex, GPU_uniform(&layer)); + } + else { + return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_uniform(&layer)); + } } void register_node_type_sh_valtorgb(void) -- cgit v1.2.3 From d9fc59c37c6e3b71c8a4b7b19cb1b4e44f64c26a Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 10 Aug 2018 16:59:29 +0200 Subject: Cleanup: Remove unused param --- source/blender/blenkernel/BKE_gpencil.h | 2 +- source/blender/blenkernel/intern/gpencil.c | 4 ++-- source/blender/blenkernel/intern/library.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index 532eaf9a0e7..b7bef9bbf4e 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -83,7 +83,7 @@ struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src); void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst); struct bGPDstroke *BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src); -void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag); +void BKE_gpencil_copy_data(struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag); struct bGPdata *BKE_gpencil_copy(struct Main *bmain, const struct bGPdata *gpd); struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy); diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 140e4a25882..fdb1123e1c7 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -673,7 +673,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src) * * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more). */ -void BKE_gpencil_copy_data(Main *UNUSED(bmain), bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag)) +void BKE_gpencil_copy_data(bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag)) { /* cache data is not duplicated */ gpd_dst->runtime.batch_cache_data = NULL; @@ -727,7 +727,7 @@ bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool in } /* Copy internal data (layers, etc.) */ - BKE_gpencil_copy_data(bmain, gpd_dst, gpd_src, 0); + BKE_gpencil_copy_data(gpd_dst, gpd_src, 0); /* return new */ return gpd_dst; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 75444ca3b2f..d81dddb2b98 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -633,7 +633,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con BKE_particlesettings_copy_data(bmain, (ParticleSettings *)*r_newid, (ParticleSettings *)id, flag); break; case ID_GD: - BKE_gpencil_copy_data(bmain, (bGPdata *)*r_newid, (bGPdata *)id, flag); + BKE_gpencil_copy_data((bGPdata *)*r_newid, (bGPdata *)id, flag); break; case ID_MC: BKE_movieclip_copy_data(bmain, (MovieClip *)*r_newid, (MovieClip *)id, flag); -- cgit v1.2.3 From 71bd30d8c02ab5670902f8955d24a5c127d76108 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 10 Aug 2018 17:00:35 +0200 Subject: Submodule commit generated by git tool This commit des not change nothing only is required by visual studio git tool --- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/tools | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index 1a5f14657ee..371960484a3 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 1a5f14657ee06ec2f520326032305dc1f2c5e2d5 +Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index b4496a81e4f..47470215783 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit b4496a81e4f3d607a692f7c2e12fce3dbd784de4 +Subproject commit 474702157831f1a58bb50f5240ab8b1b02b6ba37 diff --git a/source/tools b/source/tools index 11656ebaf7f..87f7038ee8c 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 11656ebaf7f912cdb1b5eb39c5d0a3b5d492c1aa +Subproject commit 87f7038ee8c4b46a5e73a1a9065e2a9b7367f594 -- cgit v1.2.3 From d0e083a60d8223acf77ee3913dd050d0c66f6e53 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Fri, 10 Aug 2018 09:13:48 -0600 Subject: build_environment: remove unneeded boost patch on windows. --- build_files/build_environment/cmake/boost.cmake | 1 - build_files/build_environment/patches/boost.diff | 37 ------------------------ 2 files changed, 38 deletions(-) delete mode 100644 build_files/build_environment/patches/boost.diff diff --git a/build_files/build_environment/cmake/boost.cmake b/build_files/build_environment/cmake/boost.cmake index f5e4d08289a..363b552f901 100644 --- a/build_files/build_environment/cmake/boost.cmake +++ b/build_files/build_environment/cmake/boost.cmake @@ -53,7 +53,6 @@ if(WIN32) if(BUILD_MODE STREQUAL Release) set(BOOST_HARVEST_CMD ${BOOST_HARVEST_CMD} && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/include/boost-1_60/ ${HARVEST_TARGET}/boost/include/) endif() - set(BOOST_PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/boost/src/external_boost < ${PATCH_DIR}/boost.diff) elseif(APPLE) set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh) diff --git a/build_files/build_environment/patches/boost.diff b/build_files/build_environment/patches/boost.diff deleted file mode 100644 index 41b40d7a915..00000000000 --- a/build_files/build_environment/patches/boost.diff +++ /dev/null @@ -1,37 +0,0 @@ ---- a/boost/config/compiler/visualc.hpp 2015-12-08 11:55:19 -0700 -+++ b/boost/config/compiler/visualc.hpp 2018-03-17 10:29:52 -0600 -@@ -287,12 +287,3 @@ - # define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) - #endif - --// --// last known and checked version is 19.00.23026 (VC++ 2015 RTM): --#if (_MSC_VER > 1900) --# if defined(BOOST_ASSERT_CONFIG) --# error "Unknown compiler version - please run the configure tests and report the results" --# else --# pragma message("Unknown compiler version - please run the configure tests and report the results") --# endif --#endif ---- a/boost/type_traits/has_nothrow_assign.hpp 2015-12-13 05:49:42 -0700 -+++ b/boost/type_traits/has_nothrow_assign.hpp 2018-05-27 11:11:02 -0600 -@@ -24,7 +24,7 @@ - #include - #endif - #endif --#if defined(__GNUC__) || defined(__SUNPRO_CC) -+#if defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__clang__) - #include - #include - #include ---- a/boost/type_traits/has_nothrow_constructor.hpp 2015-12-13 05:49:42 -0700 -+++ b/boost/type_traits/has_nothrow_constructor.hpp 2018-05-27 11:11:02 -0600 -@@ -17,7 +17,7 @@ - #if defined(BOOST_MSVC) || defined(BOOST_INTEL) - #include - #endif --#if defined(__GNUC__ ) || defined(__SUNPRO_CC) -+#if defined(__GNUC__ ) || defined(__SUNPRO_CC) || defined(__clang__) - #include - #endif - -- cgit v1.2.3 From 92217a81b59a4908811348467906e980ed774a85 Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Fri, 10 Aug 2018 18:50:15 +0300 Subject: update image libraries, D3005 with few mods --- build_files/build_environment/CMakeLists.txt | 23 +++++---- build_files/build_environment/cmake/ffmpeg.cmake | 11 ++--- build_files/build_environment/cmake/harvest.cmake | 4 +- build_files/build_environment/cmake/jpeg.cmake | 2 +- .../build_environment/cmake/openimageio.cmake | 4 +- build_files/build_environment/cmake/openjpeg.cmake | 2 +- build_files/build_environment/cmake/orc.cmake | 32 ------------- .../build_environment/cmake/schroedinger.cmake | 48 ------------------- .../build_environment/cmake/setup_mingw32.cmake | 12 ++--- .../build_environment/cmake/setup_mingw64.cmake | 11 +++-- build_files/build_environment/cmake/versions.cmake | 49 +++++++++----------- build_files/build_environment/patches/ffmpeg.diff | 27 ++--------- .../build_environment/patches/schroedinger.diff | 54 ---------------------- build_files/cmake/platform/platform_apple.cmake | 7 ++- 14 files changed, 62 insertions(+), 224 deletions(-) delete mode 100644 build_files/build_environment/cmake/orc.cmake delete mode 100644 build_files/build_environment/cmake/schroedinger.cmake delete mode 100644 build_files/build_environment/patches/schroedinger.diff diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 4643c48fa72..1ca102508e1 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -45,6 +45,17 @@ cmake_minimum_required(VERSION 3.5) include(ExternalProject) include(cmake/options.cmake) include(cmake/versions.cmake) + +if(ENABLE_MINGW64) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + include(cmake/setup_mingw64.cmake) + else() + include(cmake/setup_mingw32.cmake) + endif() +else() + set(mingw_LIBDIR ${LIBDIR}) +endif() + include(cmake/zlib.cmake) include(cmake/blendthumb.cmake) include(cmake/openal.cmake) @@ -88,16 +99,6 @@ if(WIN32) include(cmake/hidapi.cmake) endif() -if(ENABLE_MINGW64) - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - include(cmake/setup_mingw64.cmake) - else() - include(cmake/setup_mingw32.cmake) - endif() -else() - set(mingw_LIBDIR ${LIBDIR}) -endif() - if(NOT WIN32 OR ENABLE_MINGW64) include(cmake/openjpeg.cmake) if(BUILD_MODE STREQUAL Release) @@ -109,8 +110,6 @@ if(NOT WIN32 OR ENABLE_MINGW64) include(cmake/vorbis.cmake) include(cmake/theora.cmake) include(cmake/vpx.cmake) - include(cmake/orc.cmake) - include(cmake/schroedinger.cmake) include(cmake/x264.cmake) include(cmake/xvidcore.cmake) include(cmake/faad.cmake) diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake index 3ea1b282d9a..42504e8120b 100644 --- a/build_files/build_environment/cmake/ffmpeg.cmake +++ b/build_files/build_environment/cmake/ffmpeg.cmake @@ -16,10 +16,10 @@ # # ***** END GPL LICENSE BLOCK ***** -set(FFMPEG_CFLAGS "-I${mingw_LIBDIR}/lame/include -I${mingw_LIBDIR}/openjpeg/include/ -I${mingw_LIBDIR}/ogg/include -I${mingw_LIBDIR}/vorbis/include -I${mingw_LIBDIR}/theora/include -I${mingw_LIBDIR}/vpx/include -I${mingw_LIBDIR}/x264/include -I${mingw_LIBDIR}/xvidcore/include -I${mingw_LIBDIR}/dirac/include/dirac -I${mingw_LIBDIR}/schroedinger/include/schroedinger-1.0 -I${mingw_LIBDIR}/zlib/include") -set(FFMPEG_LDFLAGS "-L${mingw_LIBDIR}/lame/lib -L${mingw_LIBDIR}/openjpeg/lib -L${mingw_LIBDIR}/ogg/lib -L${mingw_LIBDIR}/vorbis/lib -L${mingw_LIBDIR}/theora/lib -L${mingw_LIBDIR}/vpx/lib -L${mingw_LIBDIR}/x264/lib -L${mingw_LIBDIR}/xvidcore/lib -L${mingw_LIBDIR}/dirac/lib -L${mingw_LIBDIR}/schroedinger/lib -L${mingw_LIBDIR}/orc/lib -L${mingw_LIBDIR}/zlib/lib") +set(FFMPEG_CFLAGS "-I${mingw_LIBDIR}/lame/include -I${mingw_LIBDIR}/openjpeg/include/ -I${mingw_LIBDIR}/ogg/include -I${mingw_LIBDIR}/vorbis/include -I${mingw_LIBDIR}/theora/include -I${mingw_LIBDIR}/vpx/include -I${mingw_LIBDIR}/x264/include -I${mingw_LIBDIR}/xvidcore/include -I${mingw_LIBDIR}/zlib/include") +set(FFMPEG_LDFLAGS "-L${mingw_LIBDIR}/lame/lib -L${mingw_LIBDIR}/openjpeg/lib -L${mingw_LIBDIR}/ogg/lib -L${mingw_LIBDIR}/vorbis/lib -L${mingw_LIBDIR}/theora/lib -L${mingw_LIBDIR}/vpx/lib -L${mingw_LIBDIR}/x264/lib -L${mingw_LIBDIR}/xvidcore/lib -L${mingw_LIBDIR}/zlib/lib") set(FFMPEG_EXTRA_FLAGS --extra-cflags=${FFMPEG_CFLAGS} --extra-ldflags=${FFMPEG_LDFLAGS}) -set(FFMPEG_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/schroedinger/lib/pkgconfig:${mingw_LIBDIR}/orc/lib/pkgconfig:${mingw_LIBDIR}/x264/lib/pkgconfig:${mingw_LIBDIR}) +set(FFMPEG_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/x264/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}) if(WIN32) set(FFMPEG_ENV set ${FFMPEG_ENV} &&) @@ -63,7 +63,6 @@ ExternalProject_Add(external_ffmpeg --disable-libspeex --enable-libvpx --prefix=${LIBDIR}/ffmpeg - --enable-libschroedinger --enable-libtheora --enable-libvorbis --enable-zlib @@ -73,7 +72,6 @@ ExternalProject_Add(external_ffmpeg --disable-nonfree --enable-gpl --disable-postproc - --disable-x11grab --enable-libmp3lame --disable-librtmp --enable-libx264 @@ -91,7 +89,7 @@ ExternalProject_Add(external_ffmpeg --disable-securetransport --disable-indev=avfoundation --disable-indev=qtkit - --disable-sdl + --disable-sdl2 --disable-gnutls --disable-vda --disable-videotoolbox @@ -122,7 +120,6 @@ add_dependencies( external_openjpeg external_xvidcore external_x264 - external_schroedinger external_vpx external_theora external_vorbis diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 8519d981964..7395490e107 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -236,13 +236,12 @@ harvest(openimageio/bin openimageio/bin "maketx") harvest(openimageio/bin openimageio/bin "oiiotool") harvest(openimageio/include openimageio/include "*") harvest(openimageio/lib openimageio/lib "*.a") -harvest(openjpeg/include/openjpeg-1.5 openjpeg/include "*.h") +harvest(openjpeg/include/openjpeg-2.3 openjpeg/include "*.h") harvest(openjpeg/lib openjpeg/lib "*.a") harvest(opensubdiv/include opensubdiv/include "*.h") harvest(opensubdiv/lib opensubdiv/lib "*.a") harvest(openvdb/include/openvdb/openvdb openvdb/include/openvdb "*.h") harvest(openvdb/lib openvdb/lib "*.a") -harvest(orc/lib/liborc-0.4.a ffmpeg/lib/liborc.a) harvest(osl/bin osl/bin "oslc") harvest(osl/include osl/include "*.h") harvest(osl/lib osl/lib "*.a") @@ -252,7 +251,6 @@ harvest(png/lib png/lib "*.a") harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}m") harvest(python/include python/include "*h") harvest(python/lib python/lib "*") -harvest(schroedinger/lib/libschroedinger-1.0.a ffmpeg/lib/libschroedinger.a) harvest(sdl/include/SDL2 sdl/include "*.h") harvest(sdl/lib sdl/lib "libSDL2.a") harvest(sndfile/include sndfile/include "*.h") diff --git a/build_files/build_environment/cmake/jpeg.cmake b/build_files/build_environment/cmake/jpeg.cmake index 1f2b04387f0..9975bb9c4f6 100644 --- a/build_files/build_environment/cmake/jpeg.cmake +++ b/build_files/build_environment/cmake/jpeg.cmake @@ -18,7 +18,7 @@ if(WIN32) # cmake for windows - set(JPEG_EXTRA_ARGS -DWITH_JPEG8=ON -DCMAKE_DEBUG_POSTFIX=d) + set(JPEG_EXTRA_ARGS -DNASM=${NASM_PATH} -DWITH_JPEG8=ON -DCMAKE_DEBUG_POSTFIX=d) ExternalProject_Add(external_jpeg URL ${JPEG_URI} diff --git a/build_files/build_environment/cmake/openimageio.cmake b/build_files/build_environment/cmake/openimageio.cmake index fdc71508e47..5e7449fe079 100644 --- a/build_files/build_environment/cmake/openimageio.cmake +++ b/build_files/build_environment/cmake/openimageio.cmake @@ -51,8 +51,8 @@ if(MSVC) set(OPENJPEG_FLAGS -DOPENJPEG_HOME=${LIBDIR}/openjpeg_msvc -DOPENJPEG_INCLUDE_DIR=${LIBDIR}/openjpeg_msvc/include/openjpeg-${OPENJPEG_SHORT_VERSION} - -DOPENJPEG_LIBRARY=${LIBDIR}/openjpeg_msvc/lib/openjpeg${LIBEXT} - -DOPENJPEG_LIBRARY_DEBUG=${LIBDIR}/openjpeg_msvc/lib/openjpeg${LIBEXT} + -DOPENJPEG_LIBRARY=${LIBDIR}/openjpeg_msvc/lib/openjp2${LIBEXT} + -DOPENJPEG_LIBRARY_DEBUG=${LIBDIR}/openjpeg_msvc/lib/openjp2${LIBEXT} ) else() set(OPENJPEG_FLAGS diff --git a/build_files/build_environment/cmake/openjpeg.cmake b/build_files/build_environment/cmake/openjpeg.cmake index 5cc49b1e519..df30783de40 100644 --- a/build_files/build_environment/cmake/openjpeg.cmake +++ b/build_files/build_environment/cmake/openjpeg.cmake @@ -58,7 +58,7 @@ if(MSVC) endif() endif() -set(OPENJPEG_LIBRARY libopenjpeg${LIBEXT}) +set(OPENJPEG_LIBRARY libopenjp2${LIBEXT}) if(MSVC) set_target_properties(external_openjpeg PROPERTIES FOLDER Mingw) endif() diff --git a/build_files/build_environment/cmake/orc.cmake b/build_files/build_environment/cmake/orc.cmake deleted file mode 100644 index aac7884f49e..00000000000 --- a/build_files/build_environment/cmake/orc.cmake +++ /dev/null @@ -1,32 +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. -# -# ***** END GPL LICENSE BLOCK ***** - -ExternalProject_Add(external_orc - URL ${ORC_URI} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH SHA256=${ORC_HASH} - PREFIX ${BUILD_DIR}/orc - CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/orc --disable-shared --enable-static - BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && make -j${MAKE_THREADS} - INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && make install - INSTALL_DIR ${LIBDIR}/orc -) - -if(MSVC) - set_target_properties(external_orc PROPERTIES FOLDER Mingw) -endif() diff --git a/build_files/build_environment/cmake/schroedinger.cmake b/build_files/build_environment/cmake/schroedinger.cmake deleted file mode 100644 index 80bf84b06d7..00000000000 --- a/build_files/build_environment/cmake/schroedinger.cmake +++ /dev/null @@ -1,48 +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. -# -# ***** END GPL LICENSE BLOCK ***** - -if(WIN32) - set(SCHROEDINGER_EXTRA_FLAGS "CFLAGS=-g -I./ -I${LIBDIR}/orc/include/orc-0.4" "LDFLAGS=-Wl,--as-needed -static-libgcc -L${LIBDIR}/orc/lib" ORC_CFLAGS=-I${LIBDIR}/orc/include/orc-0.4 ORC_LDFLAGS=-L${LIBDIR}/orc/lib ORC_LIBS=${LIBDIR}/orc/lib/liborc-0.4.a ORCC=${LIBDIR}/orc/bin/orcc.exe) -else() - set(SCHROEDINGER_CFLAGS "${PLATFORM_CFLAGS} -I./ -I${LIBDIR}/orc/include/orc-0.4") - set(SCHROEDINGER_LDFLAGS "${PLATFORM_LDFLAGS} -L${LIBDIR}/orc/lib") - set(SCHROEDINGER_EXTRA_FLAGS CFLAGS=${SCHROEDINGER_CFLAGS} LDFLAGS=${SCHROEDINGER_LDFLAGS} ORC_CFLAGS=-I${LIBDIR}/orc/include/orc-0.4 ORC_LDFLAGS=-L${LIBDIR}/orc/lib ORCC=${LIBDIR}/orc/bin/orcc) # ORC_LIBS=${LIBDIR}/orc/lib/liborc-0.4.a -endif() - -ExternalProject_Add(external_schroedinger - URL ${SCHROEDINGER_URI} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH SHA256=${SCHROEDINGER_HASH} - PREFIX ${BUILD_DIR}/schroedinger - PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/schroedinger/src/external_schroedinger < ${PATCH_DIR}/schroedinger.diff - CONFIGURE_COMMAND ${CONFIGURE_ENV} && - cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ && - ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/schroedinger --disable-shared --enable-static ${SCHROEDINGER_EXTRA_FLAGS} - BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ && make -j${MAKE_THREADS} - INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ && make install - INSTALL_DIR ${LIBDIR}/schroedinger -) - -add_dependencies( - external_schroedinger - external_orc -) - -if(MSVC) - set_target_properties(external_schroedinger PROPERTIES FOLDER Mingw) -endif() diff --git a/build_files/build_environment/cmake/setup_mingw32.cmake b/build_files/build_environment/cmake/setup_mingw32.cmake index 96221bb5e10..b3df59f93c8 100644 --- a/build_files/build_environment/cmake/setup_mingw32.cmake +++ b/build_files/build_environment/cmake/setup_mingw32.cmake @@ -78,24 +78,24 @@ if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe") AND (EXISTS " endif() message("Checking for nasm") -if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip") +if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip") message("Downloading nasm") - file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win32/nasm-2.12.01-win32.zip" "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip") + file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/win32/nasm-2.13.02-win32.zip" "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip") endif() # extract nasm -if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip")) +if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip")) message("Extracting nasm") execute_process( - COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip" + COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.13.02-win32.zip" WORKING_DIRECTORY ${DOWNLOAD_DIR}/ ) execute_process( - COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.12.01/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe" + COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.13.02/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe" ) endif() - +SET(NASM_PATH ${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe) message("Checking for mingwGet") if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip") message("Downloading mingw-get") diff --git a/build_files/build_environment/cmake/setup_mingw64.cmake b/build_files/build_environment/cmake/setup_mingw64.cmake index 9a45051ebf6..fbc0c91404c 100644 --- a/build_files/build_environment/cmake/setup_mingw64.cmake +++ b/build_files/build_environment/cmake/setup_mingw64.cmake @@ -78,23 +78,24 @@ if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/pkg-config.exe") AND (EXISTS " endif() message("Checking for nasm") -if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip") +if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win64.zip") message("Downloading nasm") - file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip" "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip") + file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/win64/nasm-2.13.02-win64.zip" "${DOWNLOAD_DIR}/nasm-2.13.02-win64.zip") endif() # extract nasm -if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip")) +if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.13.02-win64.zip")) message("Extracting nasm") execute_process( - COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip" + COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.13.02-win64.zip" WORKING_DIRECTORY ${DOWNLOAD_DIR}/ ) execute_process( - COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.12.01/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe" + COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.13.02/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe" ) endif() +SET(NASM_PATH ${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe) message("Checking for mingwGet") if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip") diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index eefc751a7a4..36d58090c75 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -24,13 +24,13 @@ set(OPENAL_VERSION 1.17.2) set(OPENAL_URI http://kcat.strangesoft.net/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2) set(OPENAL_HASH 1764e0d8fec499589b47ebc724e0913d) -set(PNG_VERSION 1.6.21) -set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.gz) -set(PNG_HASH aca36ec8e0a3b406a5912243bc243717) +set(PNG_VERSION 1.6.35) +set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.xz) +set(PNG_HASH 678b7e696a62a193ed3503b04bf449d6) -set(JPEG_VERSION 1.4.2) +set(JPEG_VERSION 1.5.3) set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz) -set(JPEG_HASH f9804884c1c41eb7f4febb9353a2cb27) +set(JPEG_HASH 5b7549d440b86c98a517355c102d155e) set(BOOST_VERSION 1.68.0) set(BOOST_VERSION_NODOTS 1_68_0) @@ -45,13 +45,13 @@ set(PTHREADS_VERSION 2-9-1) set(PTHREADS_URI ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-${PTHREADS_VERSION}-release.tar.gz) set(PTHREADS_SHA512 9c06e85310766834370c3dceb83faafd397da18a32411ca7645c8eb6b9495fea54ca2872f4a3e8d83cb5fdc5dea7f3f0464be5bb9af3222a6534574a184bd551) -set(ILMBASE_VERSION 2.2.0) +set(ILMBASE_VERSION 2.2.1) set(ILMBASE_URI http://download.savannah.nongnu.org/releases/openexr/ilmbase-${ILMBASE_VERSION}.tar.gz) -set(ILMBASE_HASH b540db502c5fa42078249f43d18a4652) +set(ILMBASE_HASH 7b86128b04f0541b6bb33633e299cb44) -set(OPENEXR_VERSION 2.2.0) -set(OPENEXR_URI http://download.savannah.nongnu.org/releases/openexr/openexr-2.2.0.tar.gz) -set(OPENEXR_HASH b64e931c82aa3790329c21418373db4e) +set(OPENEXR_VERSION 2.2.1) +set(OPENEXR_URI http://download.savannah.nongnu.org/releases/openexr/openexr-${OPENEXR_VERSION}.tar.gz) +set(OPENEXR_HASH 421815c32989e1b98fc4798ee754c433) set(FREETYPE_VERSION 291) set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/ft${FREETYPE_VERSION}.zip) @@ -122,9 +122,9 @@ set(OPENIMAGEIO_HASH_1715 e2ece0f62c013d64c478f82265988b0b) set(OPENIMAGEIO_HASH ${OPENIMAGEIO_HASH_1715}) -set(TIFF_VERSION 4.0.6) +set(TIFF_VERSION 4.0.9) set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz) -set(TIFF_HASH d1d2e940dea0b5ad435f21f03d96dd72) +set(TIFF_HASH 54bad211279cc93eb4fca31ba9bfdc79) set(FLEXBISON_VERSION 2.5.5) set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison//win_flex_bison-2.5.5.zip) @@ -190,14 +190,6 @@ set(VPX_VERSION 1.5.0) set(VPX_URI http://storage.googleapis.com/downloads.webmproject.org/releases/webm/libvpx-${VPX_VERSION}.tar.bz2) set(VPX_HASH 306d67908625675f8e188d37a81fbfafdf5068b09d9aa52702b6fbe601c76797) -set(ORC_VERSION 0.4.25) -set(ORC_URI https://gstreamer.freedesktop.org/src/orc/orc-${ORC_VERSION}.tar.xz) -set(ORC_HASH c1b1d54a58f26d483f0b3881538984789fe5d5460ab8fab74a1cacbd3d1c53d1) - -set(SCHROEDINGER_VERSION 1.0.11) -set(SCHROEDINGER_URI https://download.videolan.org/contrib/schroedinger/schroedinger-${SCHROEDINGER_VERSION}.tar.gz) -set(SCHROEDINGER_HASH 1e572a0735b92aca5746c4528f9bebd35aa0ccf8619b22fa2756137a8cc9f912) - set(X264_URI http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20160401-2245-stable.tar.bz2) set(X264_HASH 1e9a7b835e80313aade53a9b6ff353e099de3856bf5f30a4d8dfc91281f786f5) @@ -206,18 +198,19 @@ set(XVIDCORE_URI http://downloads.xvid.org/downloads/xvidcore-${XVIDCORE_VERSION set(XVIDCORE_HASH 4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f) #this has to be in sync with the version in blenders /extern folder -set(OPENJPEG_VERSION 1.5.2) -set(OPENJPEG_SHORT_VERSION 1.5) -set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/version.${OPENJPEG_VERSION}.tar.gz) -set(OPENJPEG_HASH 3734e95edd0bef6e056815591755efd822228dc3cd866894e00a2c929026b16d) +set(OPENJPEG_VERSION 2.3.0) +set(OPENJPEG_SHORT_VERSION 2.3) +# Use slightly newer commit after release which includes a cmake fix +set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/66297f07a43.zip) +set(OPENJPEG_HASH 8242b18d908c7c42174e4231a741cfa7ce7c26b6ed5c9644feb9df7b3054310b) set(FAAD_VERSION 2-2.7) set(FAAD_URI http://downloads.sourceforge.net/faac/faad${FAAD_VERSION}.tar.bz2) set(FAAD_HASH 4c332fa23febc0e4648064685a3d4332) -set(FFMPEG_VERSION 3.2.1) +set(FFMPEG_VERSION 3.4.1) set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2) -set(FFMPEG_HASH cede174178e61f882844f5870c35ce72) +set(FFMPEG_HASH bbf3fcded80c33968c91bf323a744286) set(FFTW_VERSION 3.3.4) set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz) @@ -243,9 +236,9 @@ set(HIDAPI_UID 89a6c75dc6f45ecabd4ddfbd2bf5ba6ad8ba38b5) set(HIDAPI_URI https://github.com/TheOnlyJoey/hidapi/archive/${HIDAPI_UID}.zip) set(HIDAPI_HASH b6e22f6b514f8bcf594989f20ffc46fb) -set(WEBP_VERSION 0.5.1) +set(WEBP_VERSION 0.6.1) set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz) -set(WEBP_HASH 3d7db92ebba5b4f679413d25c6040881) +set(WEBP_HASH b49ce9c3e3e9acae4d91bca44bb85a72) set(SPNAV_VERSION 0.2.3) set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz) diff --git a/build_files/build_environment/patches/ffmpeg.diff b/build_files/build_environment/patches/ffmpeg.diff index 75fc6490031..6e925399c95 100644 --- a/build_files/build_environment/patches/ffmpeg.diff +++ b/build_files/build_environment/patches/ffmpeg.diff @@ -1,32 +1,11 @@ ---- libavutil/common.h 2016-02-14 19:29:42 -0700 -+++ libavutil/common.h 2016-03-30 09:50:29 -0600 -@@ -99,6 +99,11 @@ - #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) - #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) - -+//msvc helper -+#ifdef _MSC_VER -+#define inline __inline -+#endif -+ - /* misc math functions */ - - #ifdef HAVE_AV_CONFIG_H --- configure 2016-11-26 03:12:05.000000000 +0100 +++ configure 2017-04-05 03:24:35.000000000 +0200 -@@ -1899,7 +1899,6 @@ - access - aligned_malloc - arc4random -- clock_gettime - closesocket - CommandLineToArgvW - CoTaskMemFree -@@ -5494,7 +5493,6 @@ +@@ -5494,7 +5493,5 @@ check_func access check_func_headers stdlib.h arc4random --check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; } +-check_func_headers time.h clock_gettime || +- { check_lib clock_gettime time.h clock_gettime -lrt && LIBRT="-lrt"; } check_func fcntl check_func fork check_func gethrtime diff --git a/build_files/build_environment/patches/schroedinger.diff b/build_files/build_environment/patches/schroedinger.diff deleted file mode 100644 index 6acb35f2a7b..00000000000 --- a/build_files/build_environment/patches/schroedinger.diff +++ /dev/null @@ -1,54 +0,0 @@ ---- configure.orig 2012-01-22 19:06:43 -0700 -+++ configure 2016-04-06 20:00:50 -0600 -@@ -16492,10 +16492,10 @@ - HAVE_ORC=yes - fi - if test "x${HAVE_ORC}" != xyes ; then -- as_fn_error $? "orc-0.4 >= $ORC_VER is required" "$LINENO" 5 -+ $as_echo "orc-0.4 >= $ORC_VER is required" - fi - SCHRO_PKG_DEPS="$SCHRO_PKG_DEPS orc-0.4 >= $ORC_VER" --ORCC=`$PKG_CONFIG --variable=orcc orc-0.4` -+#ORCC=`$PKG_CONFIG --variable=orcc orc-0.4` - - if test "x$cross_compiling" != xyes; then - HAVE_ORCC_TRUE= ---- Makefile.in 2012-01-22 18:06:42 -0700 -+++ Makefile.in 2016-04-06 20:30:09 -0600 -@@ -291,7 +291,7 @@ - top_builddir = @top_builddir@ - top_srcdir = @top_srcdir@ - AUTOMAKE_OPTIONS = foreign --SUBDIRS = schroedinger doc tools testsuite -+SUBDIRS = schroedinger doc tools - DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc - DIST_SUBDIRS = schroedinger doc tools testsuite - EXTRA_DIST = COPYING COPYING.GPL COPYING.LGPL COPYING.MIT COPYING.MPL \ - ---- schroedinger.pc.in 2011-03-21 17:08:39 -0600 -+++ schroedinger.pc.in 2016-04-08 13:30:42 -0600 -@@ -7,9 +7,9 @@ - - Name: schroedinger-@SCHRO_MAJORMINOR@ - Description: Dirac codec library --Requires.private: @SCHRO_PKG_DEPS@ -+Requires: @SCHRO_PKG_DEPS@ - Version: @VERSION@ --Libs: -L${libdir} -lschroedinger-@SCHRO_MAJORMINOR@ -+Libs: -L${libdir} -lschroedinger-@SCHRO_MAJORMINOR@ -lorc-0.4 - Libs.private: @PTHREAD_LIBS@ @LIBM@ - Cflags: -I${includedir} - ---- ./schroedinger/schrodecoder.c 2012-01-23 00:38:57.000000000 +0100 -+++ ./schroedinger/schrodecoder.c 2016-05-15 06:07:24.000000000 +0200 -@@ -70,8 +70,8 @@ - }; - - --int _schro_decode_prediction_only; --int _schro_telemetry; -+int _schro_decode_prediction_only = 0; -+int _schro_telemetry = 0; - - static void schro_decoder_x_decode_motion (SchroAsyncStage * stage); - static void schro_decoder_x_render_motion (SchroAsyncStage * stage); diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 93d7220c884..faed0cf25fc 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -159,7 +159,10 @@ if(WITH_CODEC_FFMPEG) set(FFMPEG_LIBRARIES avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg - ) + ) + # commenting out until libs are updated on svn. schroedinger and orc + # will be removed then + # set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} vpx webp swresample) set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx webp swresample) set(FFMPEG_LIBPATH ${FFMPEG}/lib) endif() @@ -169,6 +172,8 @@ if(WITH_IMAGE_OPENJPEG OR WITH_CODEC_FFMPEG) set(OPENJPEG ${LIBDIR}/openjpeg) set(WITH_SYSTEM_OPENJPEG ON) set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include) + # same as with ffmpeg libs, update when svn are updated + #set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/libopenjp2.a) set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/libopenjpeg.a) endif() -- cgit v1.2.3 From 367ada71a0d1fab75701c30895726e3f7f315f3a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 7 Aug 2018 10:23:07 +0200 Subject: Cleanup: move most outliner drag & drop code into one file. --- .../blender/editors/space_outliner/CMakeLists.txt | 1 + .../editors/space_outliner/outliner_dragdrop.c | 1115 ++++++++++++++++++++ .../blender/editors/space_outliner/outliner_edit.c | 533 ---------- .../editors/space_outliner/outliner_intern.h | 23 +- .../blender/editors/space_outliner/outliner_ops.c | 347 ------ .../editors/space_outliner/space_outliner.c | 190 ---- 6 files changed, 1131 insertions(+), 1078 deletions(-) create mode 100644 source/blender/editors/space_outliner/outliner_dragdrop.c diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 96d27c6fd89..796e8732fca 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -39,6 +39,7 @@ set(INC_SYS set(SRC outliner_collections.c + outliner_dragdrop.c outliner_draw.c outliner_edit.c outliner_ops.c diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c new file mode 100644 index 00000000000..f37cd7fa5e4 --- /dev/null +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -0,0 +1,1115 @@ +/* + * ***** 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) 2004 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_outliner/outliner_dragdrop.c + * \ingroup spoutliner + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_group_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_space_types.h" + +#include "BLI_listbase.h" + +#include "BLT_translation.h" + +#include "BKE_collection.h" +#include "BKE_context.h" +#include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_report.h" +#include "BKE_scene.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" + +#include "ED_object.h" +#include "ED_outliner.h" +#include "ED_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "GPU_state.h" + +#include "RNA_access.h" +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "outliner_intern.h" + +/* ******************** Drop Target Find *********************** */ + +static TreeElement *outliner_dropzone_element(TreeElement *te, const float fmval[2], const bool children) +{ + if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) { + /* name and first icon */ + if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) + return te; + } + /* Not it. Let's look at its children. */ + if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) { + for (te = te->subtree.first; te; te = te->next) { + TreeElement *te_valid = outliner_dropzone_element(te, fmval, children); + if (te_valid) + return te_valid; + } + } + return NULL; +} + +/* Find tree element to drop into. */ +static TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const bool children) +{ + TreeElement *te; + + for (te = soops->tree.first; te; te = te->next) { + TreeElement *te_valid = outliner_dropzone_element(te, fmval, children); + if (te_valid) + return te_valid; + } + return NULL; +} + +/* ******************** Parent Drop Operator *********************** */ + +static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (drag->type == WM_DRAG_ID) { + ID *id = drag->poin; + if (GS(id->name) == ID_OB) { + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_dropzone_find(soops, fmval, true); + TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + + if (!te) { + /* pass */ + } + else if (te->idcode == ID_OB && tselem->type == 0) { + Scene *scene; + ID *te_id = tselem->id; + + /* check if dropping self or parent */ + if (te_id == id || (Object *)te_id == ((Object *)id)->parent) + return 0; + + /* check that parent/child are both in the same scene */ + scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + + /* currently outliner organized in a way that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + if (!scene) { + return 1; + } + else { + for (ViewLayer *view_layer = scene->view_layers.first; + view_layer; + view_layer = view_layer->next) + { + if (BKE_view_layer_base_find(view_layer, (Object *)id)) { + return 1; + } + } + } + } + } + } + return 0; +} + +static void parent_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = drag->poin; + + RNA_string_set(drop->ptr, "child", id->name + 2); +} + +static int parent_drop_exec(bContext *C, wmOperator *op) +{ + Object *par = NULL, *ob = NULL; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + int partype = -1; + char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; + + partype = RNA_enum_get(op->ptr, "type"); + RNA_string_get(op->ptr, "parent", parname); + par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); + RNA_string_get(op->ptr, "child", childname); + ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); + + if (ID_IS_LINKED(ob)) { + BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); + return OPERATOR_CANCELLED; + } + + ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); + + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); + + return OPERATOR_FINISHED; +} + +static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *par = NULL; + Object *ob = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + Main *bmain = CTX_data_main(C); + Scene *scene = NULL; + TreeElement *te = NULL; + char childname[MAX_ID_NAME]; + char parname[MAX_ID_NAME]; + int partype = 0; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + te = outliner_dropzone_find(soops, fmval, true); + + if (te) { + RNA_string_set(op->ptr, "parent", te->name); + /* Identify parent and child */ + RNA_string_get(op->ptr, "child", childname); + ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); + RNA_string_get(op->ptr, "parent", parname); + par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); + + if (ELEM(NULL, ob, par)) { + if (par == NULL) printf("par==NULL\n"); + return OPERATOR_CANCELLED; + } + if (ob == par) { + return OPERATOR_CANCELLED; + } + if (ID_IS_LINKED(ob)) { + BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); + return OPERATOR_CANCELLED; + } + + scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + + if (scene == NULL) { + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + + scene = CTX_data_scene(C); + } + + if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { + if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); + } + } + else { + /* Menu creation */ + wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); + PointerRNA ptr; + + /* Cannot use uiItemEnumO()... have multiple properties to set. */ + uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_OBJECT); + + /* par becomes parent, make the associated menus */ + if (par->type == OB_ARMATURE) { + uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE); + + uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); + + uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); + + uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); + + uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_BONE); + } + else if (par->type == OB_CURVE) { + uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_CURVE); + + uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_FOLLOW); + + uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_PATH_CONST); + } + else if (par->type == OB_LATTICE) { + uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_LATTICE); + } + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; + } + } + else { + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_parent_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Drop to Set Parent"; + ot->description = "Drag to parent in Outliner"; + ot->idname = "OUTLINER_OT_parent_drop"; + + /* api callbacks */ + ot->invoke = parent_drop_invoke; + ot->exec = parent_drop_exec; + + ot->poll = ED_operator_outliner_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + /* properties */ + RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); + RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object"); + RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); +} + +static bool parenting_poll(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + + if (soops) { + if (soops->outlinevis == SO_SCENES) { + return true; + } + else if ((soops->outlinevis == SO_VIEW_LAYER) && + (soops->filter & SO_FILTER_NO_COLLECTION)) + { + return true; + } + } + + return false; +} + +/* ******************** Parent Clear Operator *********************** */ + +static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te = NULL; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) { + return false; + } + + if (drag->type == WM_DRAG_ID) { + ID *id = drag->poin; + if (GS(id->name) == ID_OB) { + if (((Object *)id)->parent) { + if ((te = outliner_dropzone_find(soops, fmval, true))) { + TreeStoreElem *tselem = TREESTORE(te); + + switch (te->idcode) { + case ID_SCE: + return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); + case ID_OB: + return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); + /* Other codes to ignore? */ + } + } + return (te == NULL); + } + } + } + return 0; +} + +static void parent_clear_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = drag->poin; + RNA_string_set(drop->ptr, "dragged_obj", id->name + 2); + + /* Set to simple parent clear type. Avoid menus for drag and drop if possible. + * If desired, user can toggle the different "Clear Parent" types in the operator + * menu on tool shelf. */ + RNA_enum_set(drop->ptr, "type", 0); +} + +static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Main *bmain = CTX_data_main(C); + Object *ob = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + char obname[MAX_ID_NAME]; + + RNA_string_get(op->ptr, "dragged_obj", obname); + ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); + + /* search forwards to find the object */ + outliner_find_id(soops, &soops->tree, (ID *)ob); + + ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); + + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Drop to Clear Parent"; + ot->description = "Drag to clear parent in Outliner"; + ot->idname = "OUTLINER_OT_parent_clear"; + + /* api callbacks */ + ot->invoke = parent_clear_invoke; + + ot->poll = parenting_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + /* properties */ + RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object"); + RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); +} + +/* ******************** Scene Drop Operator *********************** */ + +static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (drag->type == WM_DRAG_ID) { + ID *id = drag->poin; + if (GS(id->name) == ID_OB) { + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_dropzone_find(soops, fmval, false); + return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0); + } + } + return 0; +} + +static void scene_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = drag->poin; + + RNA_string_set(drop->ptr, "object", id->name + 2); +} + +static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Scene *scene = NULL; + Object *ob = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + Main *bmain = CTX_data_main(C); + TreeElement *te = NULL; + char obname[MAX_ID_NAME]; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + te = outliner_dropzone_find(soops, fmval, false); + + if (te) { + RNA_string_set(op->ptr, "scene", te->name); + scene = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, te->name); + + RNA_string_get(op->ptr, "object", obname); + ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); + + if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { + return OPERATOR_CANCELLED; + } + + if (BKE_scene_has_object(scene, ob)) { + return OPERATOR_CANCELLED; + } + + Collection *collection; + if (scene != CTX_data_scene(C)) { + /* when linking to an inactive scene link to the master collection */ + collection = BKE_collection_master(scene); + } + else { + collection = CTX_data_collection(C); + } + + BKE_collection_object_add(bmain, collection, ob); + + for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base) { + ED_object_base_select(base, BA_SELECT); + } + } + + DEG_relations_tag_update(bmain); + + DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void OUTLINER_OT_scene_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Drop Object to Scene"; + ot->description = "Drag object to scene in Outliner"; + ot->idname = "OUTLINER_OT_scene_drop"; + + /* api callbacks */ + ot->invoke = scene_drop_invoke; + + ot->poll = ED_operator_outliner_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + /* properties */ + RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); + RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene"); +} + +/* ******************** Material Drop Operator *********************** */ + +static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (drag->type == WM_DRAG_ID) { + ID *id = drag->poin; + if (GS(id->name) == ID_MA) { + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_dropzone_find(soops, fmval, true); + return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0); + } + } + return 0; +} + +static void material_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = drag->poin; + + RNA_string_set(drop->ptr, "material", id->name + 2); +} + +static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Material *ma = NULL; + Object *ob = NULL; + Main *bmain = CTX_data_main(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + TreeElement *te = NULL; + char mat_name[MAX_ID_NAME - 2]; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + te = outliner_dropzone_find(soops, fmval, true); + + if (te) { + RNA_string_set(op->ptr, "object", te->name); + ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, te->name); + + RNA_string_get(op->ptr, "material", mat_name); + ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, mat_name); + + if (ELEM(NULL, ob, ma)) { + return OPERATOR_CANCELLED; + } + + assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void OUTLINER_OT_material_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Drop Material on Object"; + ot->description = "Drag material to object in Outliner"; + ot->idname = "OUTLINER_OT_material_drop"; + + /* api callbacks */ + ot->invoke = material_drop_invoke; + + ot->poll = ED_operator_outliner_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + /* properties */ + RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); + RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material"); +} + +/* ******************** Collection Drop Operator *********************** */ + +static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + float fmval[2]; + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + if (drag->type == WM_DRAG_ID) { + ID *id = drag->poin; + if (ELEM(GS(id->name), ID_OB, ID_GR)) { + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_dropzone_find(soops, fmval, true); + return (te && outliner_is_collection_tree_element(te)); + } + } + return 0; +} + +static void collection_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = drag->poin; + RNA_string_set(drop->ptr, "child", id->name + 2); +} + +static int collection_drop_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) +{ + /* TODO: implement */ +#if 0 + Object *par = NULL, *ob = NULL; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + int partype = -1; + char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; + + RNA_string_get(op->ptr, "parent", parname); + par = (Object *)BKE_libblock_find_name(ID_OB, parname); + RNA_string_get(op->ptr, "child", childname); + ob = (Object *)BKE_libblock_find_name(ID_OB, childname); + + if (ID_IS_LINKED(ob)) { + BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); + return OPERATOR_CANCELLED; + } + + ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); + + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); +#endif + + return OPERATOR_FINISHED; +} + +static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + Main *bmain = CTX_data_main(C); + char childname[MAX_ID_NAME]; + float fmval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + + /* Find object hovered over */ + TreeElement *te = outliner_dropzone_find(soops, fmval, true); + + if (!te || !outliner_is_collection_tree_element(te)) { + return OPERATOR_CANCELLED; + } + + Collection *collection = outliner_collection_from_tree_element(te); + + // TODO: don't use scene, makes no sense anymore + // TODO: move rather than link, change hover text + Scene *scene = BKE_scene_find_from_collection(bmain, collection); + BLI_assert(scene); + RNA_string_get(op->ptr, "child", childname); + Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); + BKE_collection_object_add(bmain, collection, ob); + + DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_drop(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Link to Collection"; // TODO: rename to move? + ot->description = "Drag to move to collection in Outliner"; + ot->idname = "OUTLINER_OT_collection_drop"; + + /* api callbacks */ + ot->invoke = collection_drop_invoke; + ot->exec = collection_drop_exec; + + ot->poll = ED_operator_outliner_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + /* properties */ + RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); + RNA_def_string(ot->srna, "parent", "Collection", MAX_ID_NAME, "Parent", "Parent Collection"); +} + +/* ********************* Outliner Drag Operator ******************** */ + +typedef struct OutlinerDragDropTooltip { + TreeElement *te; + void *handle; +} OutlinerDragDropTooltip; + +static bool outliner_item_drag_drop_poll(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + return ED_operator_outliner_active(C) && + /* Only collection display modes supported for now. Others need more design work */ + ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES); +} + +static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) +{ + /* note: using EVT_TWEAK_ events to trigger dragging is fine, + * it sends coordinates from where dragging was started */ + const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]); + return outliner_find_item_at_y(soops, &soops->tree, my); +} + +static void outliner_item_drag_end(wmWindow *win, OutlinerDragDropTooltip *data) +{ + MEM_SAFE_FREE(data->te->drag_data); + + if (data->handle) { + WM_draw_cb_exit(win, data->handle); + } + + MEM_SAFE_FREE(data); +} + +static void outliner_item_drag_get_insert_data( + const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged, + TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type) +{ + TreeElement *te_hovered; + float view_mval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]); + te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]); + + if (te_hovered) { + /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */ + + if (te_hovered == te_dragged) { + *r_te_insert_handle = te_dragged; + } + else if (te_hovered != te_dragged) { + const float margin = UI_UNIT_Y * (1.0f / 4); + + *r_te_insert_handle = te_hovered; + if (view_mval[1] < (te_hovered->ys + margin)) { + if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) { + /* inserting after a open item means we insert into it, but as first child */ + if (BLI_listbase_is_empty(&te_hovered->subtree)) { + *r_insert_type = TE_INSERT_INTO; + } + else { + *r_insert_type = TE_INSERT_BEFORE; + *r_te_insert_handle = te_hovered->subtree.first; + } + } + else { + *r_insert_type = TE_INSERT_AFTER; + } + } + else if (view_mval[1] > (te_hovered->ys + (3 * margin))) { + *r_insert_type = TE_INSERT_BEFORE; + } + else { + *r_insert_type = TE_INSERT_INTO; + } + } + } + else { + /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */ + + TreeElement *first = soops->tree.first; + TreeElement *last = soops->tree.last; + + if (view_mval[1] < last->ys) { + *r_te_insert_handle = last; + *r_insert_type = TE_INSERT_AFTER; + } + else if (view_mval[1] > (first->ys + UI_UNIT_Y)) { + *r_te_insert_handle = first; + *r_insert_type = TE_INSERT_BEFORE; + } + else { + BLI_assert(0); + } + } +} + +static void outliner_item_drag_handle( + SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged) +{ + TreeElement *te_insert_handle; + TreeElementInsertType insert_type; + + outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type); + + if (!te_dragged->reinsert_poll && + /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */ + (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) && + te_dragged->reinsert) + { + /* pass */ + } + else if (te_dragged == te_insert_handle) { + /* nothing will happen anyway, no need to do poll check */ + } + else if (!te_dragged->reinsert_poll || + !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type)) + { + te_insert_handle = NULL; + } + te_dragged->drag_data->insert_type = insert_type; + te_dragged->drag_data->insert_handle = te_insert_handle; +} + +/** + * Returns true if it is a collection and empty. + */ +static bool is_empty_collection(TreeElement *te) +{ + Collection *collection = outliner_collection_from_tree_element(te); + + if (!collection) { + return false; + } + + return BLI_listbase_is_empty(&collection->gobject) && + BLI_listbase_is_empty(&collection->children); +} + +static bool outliner_item_drag_drop_apply( + Main *bmain, + Scene *scene, + SpaceOops *soops, + OutlinerDragDropTooltip *data, + const wmEvent *event) +{ + TreeElement *dragged_te = data->te; + TreeElement *insert_handle = dragged_te->drag_data->insert_handle; + TreeElementInsertType insert_type = dragged_te->drag_data->insert_type; + + if ((insert_handle == dragged_te) || !insert_handle) { + /* No need to do anything */ + } + else if (dragged_te->reinsert) { + BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle, + &insert_type)); + /* call of assert above should not have changed insert_handle and insert_type at this point */ + BLI_assert(dragged_te->drag_data->insert_handle == insert_handle && + dragged_te->drag_data->insert_type == insert_type); + + /* If the collection was just created and you moved objects/collections inside it, + * it is strange to have it closed and we not see the newly dragged elements. */ + const bool should_open_collection = (insert_type == TE_INSERT_INTO) && is_empty_collection(insert_handle); + + dragged_te->reinsert(bmain, scene, soops, dragged_te, insert_handle, insert_type, event); + + if (should_open_collection && !is_empty_collection(insert_handle)) { + TREESTORE(insert_handle)->flag &= ~TSE_CLOSED; + } + return true; + } + + return false; +} + +static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + OutlinerDragDropTooltip *data = op->customdata; + TreeElement *te_dragged = data->te; + int retval = OPERATOR_RUNNING_MODAL; + bool redraw = false; + bool skip_rebuild = true; + + switch (event->type) { + case EVT_MODAL_MAP: + if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) { + if (outliner_item_drag_drop_apply(bmain, scene, soops, data, event)) { + skip_rebuild = false; + } + retval = OPERATOR_FINISHED; + } + else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) { + retval = OPERATOR_CANCELLED; + } + else { + BLI_assert(0); + } + WM_event_add_mousemove(C); /* update highlight */ + outliner_item_drag_end(CTX_wm_window(C), data); + redraw = true; + break; + case MOUSEMOVE: + outliner_item_drag_handle(soops, ar, event, te_dragged); + redraw = true; + break; + } + + if (redraw) { + if (skip_rebuild) { + ED_region_tag_redraw_no_rebuild(ar); + } + else { + ED_region_tag_redraw(ar); + } + } + + return retval; +} + +static const char *outliner_drag_drop_tooltip_get( + const TreeElement *te_float) +{ + const char *name = NULL; + + const TreeElement *te_insert = te_float->drag_data->insert_handle; + if (te_float && outliner_is_collection_tree_element(te_float)) { + if (te_insert == NULL) { + name = TIP_("Move collection"); + } + else { + switch (te_float->drag_data->insert_type) { + case TE_INSERT_BEFORE: + if (te_insert->prev && outliner_is_collection_tree_element(te_insert->prev)) { + name = TIP_("Move between collections"); + } + else { + name = TIP_("Move before collection"); + } + break; + case TE_INSERT_AFTER: + if (te_insert->next && outliner_is_collection_tree_element(te_insert->next)) { + name = TIP_("Move between collections"); + } + else { + name = TIP_("Move after collection"); + } + break; + case TE_INSERT_INTO: + name = TIP_("Move inside collection"); + break; + } + } + } + else if ((TREESTORE(te_float)->type == 0) && (te_float->idcode == ID_OB)) { + name = TIP_("Move to collection (Ctrl to link)"); + } + + return name; +} + +static void outliner_drag_drop_tooltip_cb(const wmWindow *win, void *vdata) +{ + OutlinerDragDropTooltip *data = vdata; + const char *tooltip; + + int cursorx, cursory; + int x, y; + + tooltip = outliner_drag_drop_tooltip_get(data->te); + if (tooltip == NULL) { + return; + } + + cursorx = win->eventstate->x; + cursory = win->eventstate->y; + + x = cursorx + U.widget_unit; + y = cursory - U.widget_unit; + + /* Drawing. */ + const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; + + const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f}; + + GPU_blend(true); + UI_fontstyle_draw_simple_backdrop(fstyle, x, y, tooltip, col_fg, col_bg); + GPU_blend(false); +} + +static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event); + + if (!te_dragged) { + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + } + + OutlinerDragDropTooltip *data = MEM_mallocN(sizeof(OutlinerDragDropTooltip), __func__); + data->te = te_dragged; + + op->customdata = data; + te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__); + /* by default we don't change the item position */ + te_dragged->drag_data->insert_handle = te_dragged; + /* unset highlighted tree element, dragged one will be highlighted instead */ + outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false); + + ED_region_tag_redraw_no_rebuild(ar); + + WM_event_add_modal_handler(C, op); + + data->handle = WM_draw_cb_activate(CTX_wm_window(C), outliner_drag_drop_tooltip_cb, data); + + return OPERATOR_RUNNING_MODAL; +} + +/** + * Notes about Outliner Item Drag 'n Drop: + * Right now only collections display mode is supported. But ideally all/most modes would support this. There are + * just some open design questions that have to be answered: do we want to allow mixing order of different data types + * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ... + */ +void OUTLINER_OT_item_drag_drop(wmOperatorType *ot) +{ + ot->name = "Drag and Drop"; + ot->idname = "OUTLINER_OT_item_drag_drop"; + ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop"; + + ot->invoke = outliner_item_drag_drop_invoke; + ot->modal = outliner_item_drag_drop_modal; + + ot->poll = outliner_item_drag_drop_poll; + + ot->flag = OPTYPE_UNDO; +} + +/* *************************** Drop Boxes ************************** */ + +/* region dropbox definition */ +void outliner_dropboxes(void) +{ + ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, parent_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, parent_clear_copy); + WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, scene_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, material_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, collection_drop_copy); +} diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index d9bcf05fa29..6316b65fefb 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -89,68 +89,6 @@ #include "outliner_intern.h" -/* ************************************************************** */ -/* Unused Utilities */ -// XXX: where to place these? - -/* This is not used anywhere at the moment */ -#if 0 -static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found) -{ - TreeElement *te; - TreeStoreElem *tselem; - - for (te = lb->first; te; te = te->next) { - /* check if this tree-element was the one we're seeking */ - if (te == teFind) { - *found = 1; - return; - } - - /* try to see if sub-tree contains it then */ - outliner_open_reveal(soops, &te->subtree, teFind, found); - if (*found) { - tselem = TREESTORE(te); - if (tselem->flag & TSE_CLOSED) - tselem->flag &= ~TSE_CLOSED; - return; - } - } -} -#endif - -static TreeElement *outliner_dropzone_element(TreeElement *te, const float fmval[2], const bool children) -{ - if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) { - /* name and first icon */ - if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) - return te; - } - /* Not it. Let's look at its children. */ - if (children && (TREESTORE(te)->flag & TSE_CLOSED) == 0 && (te->subtree.first)) { - for (te = te->subtree.first; te; te = te->next) { - TreeElement *te_valid = outliner_dropzone_element(te, fmval, children); - if (te_valid) - return te_valid; - } - } - return NULL; -} - -/* Used for drag and drop parenting */ -TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const bool children) -{ - TreeElement *te; - - for (te = soops->tree.first; te; te = te->next) { - TreeElement *te_valid = outliner_dropzone_element(te, fmval, children); - if (te_valid) - return te_valid; - } - return NULL; -} - - /* ************************************************************** */ /* Highlight --------------------------------------------------- */ @@ -1951,474 +1889,3 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } - -/* ************************************************************** */ -/* DRAG AND DROP OPERATORS */ - -/* ******************** Parent Drop Operator *********************** */ - -static int parent_drop_exec(bContext *C, wmOperator *op) -{ - Object *par = NULL, *ob = NULL; - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - int partype = -1; - char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; - - partype = RNA_enum_get(op->ptr, "type"); - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); - - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; - } - - ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); - - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); - - return OPERATOR_FINISHED; -} - -static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Object *par = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - Main *bmain = CTX_data_main(C); - Scene *scene = NULL; - TreeElement *te = NULL; - char childname[MAX_ID_NAME]; - char parname[MAX_ID_NAME]; - int partype = 0; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); - - if (te) { - RNA_string_set(op->ptr, "parent", te->name); - /* Identify parent and child */ - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); - - if (ELEM(NULL, ob, par)) { - if (par == NULL) printf("par==NULL\n"); - return OPERATOR_CANCELLED; - } - if (ob == par) { - return OPERATOR_CANCELLED; - } - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; - } - - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - - if (scene == NULL) { - /* currently outlier organized in a way, that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ - - scene = CTX_data_scene(C); - } - - if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { - if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); - } - } - else { - /* Menu creation */ - wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); - uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); - uiLayout *layout = UI_popup_menu_layout(pup); - PointerRNA ptr; - - /* Cannot use uiItemEnumO()... have multiple properties to set. */ - uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_OBJECT); - - /* par becomes parent, make the associated menus */ - if (par->type == OB_ARMATURE) { - uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - - uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_BONE); - } - else if (par->type == OB_CURVE) { - uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_CURVE); - - uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_FOLLOW); - - uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_PATH_CONST); - } - else if (par->type == OB_LATTICE) { - uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_LATTICE); - } - - UI_popup_menu_end(C, pup); - - return OPERATOR_INTERFACE; - } - } - else { - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_parent_drop(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Drop to Set Parent"; - ot->description = "Drag to parent in Outliner"; - ot->idname = "OUTLINER_OT_parent_drop"; - - /* api callbacks */ - ot->invoke = parent_drop_invoke; - ot->exec = parent_drop_exec; - - ot->poll = ED_operator_outliner_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_string(ot->srna, "parent", "Object", MAX_ID_NAME, "Parent", "Parent Object"); - RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", ""); -} - -static bool outliner_parenting_poll(bContext *C) -{ - SpaceOops *soops = CTX_wm_space_outliner(C); - - if (soops) { - if (soops->outlinevis == SO_SCENES) { - return true; - } - else if ((soops->outlinevis == SO_VIEW_LAYER) && - (soops->filter & SO_FILTER_NO_COLLECTION)) - { - return true; - } - } - - return false; -} - -static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - Main *bmain = CTX_data_main(C); - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - char obname[MAX_ID_NAME]; - - RNA_string_get(op->ptr, "dragged_obj", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - /* search forwards to find the object */ - outliner_find_id(soops, &soops->tree, (ID *)ob); - - ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); - - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_parent_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Drop to Clear Parent"; - ot->description = "Drag to clear parent in Outliner"; - ot->idname = "OUTLINER_OT_parent_clear"; - - /* api callbacks */ - ot->invoke = parent_clear_invoke; - - ot->poll = outliner_parenting_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); -} - -static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Scene *scene = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - Main *bmain = CTX_data_main(C); - TreeElement *te = NULL; - char obname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, false); - - if (te) { - RNA_string_set(op->ptr, "scene", te->name); - scene = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, te->name); - - RNA_string_get(op->ptr, "object", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { - return OPERATOR_CANCELLED; - } - - if (BKE_scene_has_object(scene, ob)) { - return OPERATOR_CANCELLED; - } - - Collection *collection; - if (scene != CTX_data_scene(C)) { - /* when linking to an inactive scene link to the master collection */ - collection = BKE_collection_master(scene); - } - else { - collection = CTX_data_collection(C); - } - - BKE_collection_object_add(bmain, collection, ob); - - for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { - Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base) { - ED_object_base_select(base, BA_SELECT); - } - } - - DEG_relations_tag_update(bmain); - - DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); - WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void OUTLINER_OT_scene_drop(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Drop Object to Scene"; - ot->description = "Drag object to scene in Outliner"; - ot->idname = "OUTLINER_OT_scene_drop"; - - /* api callbacks */ - ot->invoke = scene_drop_invoke; - - ot->poll = ED_operator_outliner_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene"); -} - -static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Material *ma = NULL; - Object *ob = NULL; - Main *bmain = CTX_data_main(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - TreeElement *te = NULL; - char mat_name[MAX_ID_NAME - 2]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); - - if (te) { - RNA_string_set(op->ptr, "object", te->name); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, te->name); - - RNA_string_get(op->ptr, "material", mat_name); - ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, mat_name); - - if (ELEM(NULL, ob, ma)) { - return OPERATOR_CANCELLED; - } - - assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); - - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); - - return OPERATOR_FINISHED; - } - - return OPERATOR_CANCELLED; -} - -void OUTLINER_OT_material_drop(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Drop Material on Object"; - ot->description = "Drag material to object in Outliner"; - ot->idname = "OUTLINER_OT_material_drop"; - - /* api callbacks */ - ot->invoke = material_drop_invoke; - - ot->poll = ED_operator_outliner_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material"); -} - -/* ******************** Collection Drop Operator *********************** */ - -static int collection_drop_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) -{ - /* TODO: implement */ -#if 0 - Object *par = NULL, *ob = NULL; - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - int partype = -1; - char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; - - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(ID_OB, parname); - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(ID_OB, childname); - - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; - } - - ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); - - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); -#endif - - return OPERATOR_FINISHED; -} - -static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - Main *bmain = CTX_data_main(C); - char childname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - - if (!te || !outliner_is_collection_tree_element(te)) { - return OPERATOR_CANCELLED; - } - - Collection *collection = outliner_collection_from_tree_element(te); - - // TODO: don't use scene, makes no sense anymore - // TODO: move rather than link, change hover text - Scene *scene = BKE_scene_find_from_collection(bmain, collection); - BLI_assert(scene); - RNA_string_get(op->ptr, "child", childname); - Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); - BKE_collection_object_add(bmain, collection, ob); - - DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); - - return OPERATOR_FINISHED; -} - -void OUTLINER_OT_collection_drop(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Link to Collection"; // TODO: rename to move? - ot->description = "Drag to move to collection in Outliner"; - ot->idname = "OUTLINER_OT_collection_drop"; - - /* api callbacks */ - ot->invoke = collection_drop_invoke; - ot->exec = collection_drop_exec; - - ot->poll = ED_operator_outliner_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_string(ot->srna, "parent", "Collection", MAX_ID_NAME, "Parent", "Parent Collection"); -} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 461d4bd7c56..ecc092358d6 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -284,10 +284,23 @@ void item_object_mode_exit_cb( struct bContext *C, struct ReportList *reports, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem, void *user_data); -TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children); - void outliner_set_coordinates(struct ARegion *ar, struct SpaceOops *soops); +/* outliner_dragdrop.c */ +enum { + OUTLINER_ITEM_DRAG_CANCEL, + OUTLINER_ITEM_DRAG_CONFIRM, +}; + +void outliner_dropboxes(void); + +void OUTLINER_OT_item_drag_drop(struct wmOperatorType *ot); +void OUTLINER_OT_parent_drop(struct wmOperatorType *ot); +void OUTLINER_OT_parent_clear(struct wmOperatorType *ot); +void OUTLINER_OT_scene_drop(struct wmOperatorType *ot); +void OUTLINER_OT_material_drop(struct wmOperatorType *ot); +void OUTLINER_OT_collection_drop(struct wmOperatorType *ot); + /* ...................................................... */ void OUTLINER_OT_highlight_update(struct wmOperatorType *ot); @@ -319,12 +332,6 @@ void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot); void OUTLINER_OT_orphans_purge(struct wmOperatorType *ot); -void OUTLINER_OT_parent_drop(struct wmOperatorType *ot); -void OUTLINER_OT_parent_clear(struct wmOperatorType *ot); -void OUTLINER_OT_scene_drop(struct wmOperatorType *ot); -void OUTLINER_OT_material_drop(struct wmOperatorType *ot); -void OUTLINER_OT_collection_drop(struct wmOperatorType *ot); - /* outliner_tools.c ---------------------------------------------- */ void OUTLINER_OT_operation(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 576038979d3..a4aad11a821 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -55,353 +55,6 @@ #include "outliner_intern.h" -typedef struct OutlinerDragDropTooltip { - TreeElement *te; - void *handle; -} OutlinerDragDropTooltip; - -enum { - OUTLINER_ITEM_DRAG_CANCEL, - OUTLINER_ITEM_DRAG_CONFIRM, -}; - -static bool outliner_item_drag_drop_poll(bContext *C) -{ - SpaceOops *soops = CTX_wm_space_outliner(C); - return ED_operator_outliner_active(C) && - /* Only collection display modes supported for now. Others need more design work */ - ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES); -} - -static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) -{ - /* note: using EVT_TWEAK_ events to trigger dragging is fine, - * it sends coordinates from where dragging was started */ - const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]); - return outliner_find_item_at_y(soops, &soops->tree, my); -} - -static void outliner_item_drag_end(wmWindow *win, OutlinerDragDropTooltip *data) -{ - MEM_SAFE_FREE(data->te->drag_data); - - if (data->handle) { - WM_draw_cb_exit(win, data->handle); - } - - MEM_SAFE_FREE(data); -} - -static void outliner_item_drag_get_insert_data( - const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged, - TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type) -{ - TreeElement *te_hovered; - float view_mval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]); - te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]); - - if (te_hovered) { - /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */ - - if (te_hovered == te_dragged) { - *r_te_insert_handle = te_dragged; - } - else if (te_hovered != te_dragged) { - const float margin = UI_UNIT_Y * (1.0f / 4); - - *r_te_insert_handle = te_hovered; - if (view_mval[1] < (te_hovered->ys + margin)) { - if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) { - /* inserting after a open item means we insert into it, but as first child */ - if (BLI_listbase_is_empty(&te_hovered->subtree)) { - *r_insert_type = TE_INSERT_INTO; - } - else { - *r_insert_type = TE_INSERT_BEFORE; - *r_te_insert_handle = te_hovered->subtree.first; - } - } - else { - *r_insert_type = TE_INSERT_AFTER; - } - } - else if (view_mval[1] > (te_hovered->ys + (3 * margin))) { - *r_insert_type = TE_INSERT_BEFORE; - } - else { - *r_insert_type = TE_INSERT_INTO; - } - } - } - else { - /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */ - - TreeElement *first = soops->tree.first; - TreeElement *last = soops->tree.last; - - if (view_mval[1] < last->ys) { - *r_te_insert_handle = last; - *r_insert_type = TE_INSERT_AFTER; - } - else if (view_mval[1] > (first->ys + UI_UNIT_Y)) { - *r_te_insert_handle = first; - *r_insert_type = TE_INSERT_BEFORE; - } - else { - BLI_assert(0); - } - } -} - -static void outliner_item_drag_handle( - SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged) -{ - TreeElement *te_insert_handle; - TreeElementInsertType insert_type; - - outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type); - - if (!te_dragged->reinsert_poll && - /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */ - (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) && - te_dragged->reinsert) - { - /* pass */ - } - else if (te_dragged == te_insert_handle) { - /* nothing will happen anyway, no need to do poll check */ - } - else if (!te_dragged->reinsert_poll || - !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type)) - { - te_insert_handle = NULL; - } - te_dragged->drag_data->insert_type = insert_type; - te_dragged->drag_data->insert_handle = te_insert_handle; -} - -/** - * Returns true if it is a collection and empty. - */ -static bool is_empty_collection(TreeElement *te) -{ - Collection *collection = outliner_collection_from_tree_element(te); - - if (!collection) { - return false; - } - - return BLI_listbase_is_empty(&collection->gobject) && - BLI_listbase_is_empty(&collection->children); -} - -static bool outliner_item_drag_drop_apply( - Main *bmain, - Scene *scene, - SpaceOops *soops, - OutlinerDragDropTooltip *data, - const wmEvent *event) -{ - TreeElement *dragged_te = data->te; - TreeElement *insert_handle = dragged_te->drag_data->insert_handle; - TreeElementInsertType insert_type = dragged_te->drag_data->insert_type; - - if ((insert_handle == dragged_te) || !insert_handle) { - /* No need to do anything */ - } - else if (dragged_te->reinsert) { - BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle, - &insert_type)); - /* call of assert above should not have changed insert_handle and insert_type at this point */ - BLI_assert(dragged_te->drag_data->insert_handle == insert_handle && - dragged_te->drag_data->insert_type == insert_type); - - /* If the collection was just created and you moved objects/collections inside it, - * it is strange to have it closed and we not see the newly dragged elements. */ - const bool should_open_collection = (insert_type == TE_INSERT_INTO) && is_empty_collection(insert_handle); - - dragged_te->reinsert(bmain, scene, soops, dragged_te, insert_handle, insert_type, event); - - if (should_open_collection && !is_empty_collection(insert_handle)) { - TREESTORE(insert_handle)->flag &= ~TSE_CLOSED; - } - return true; - } - - return false; -} - -static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - OutlinerDragDropTooltip *data = op->customdata; - TreeElement *te_dragged = data->te; - int retval = OPERATOR_RUNNING_MODAL; - bool redraw = false; - bool skip_rebuild = true; - - switch (event->type) { - case EVT_MODAL_MAP: - if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) { - if (outliner_item_drag_drop_apply(bmain, scene, soops, data, event)) { - skip_rebuild = false; - } - retval = OPERATOR_FINISHED; - } - else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) { - retval = OPERATOR_CANCELLED; - } - else { - BLI_assert(0); - } - WM_event_add_mousemove(C); /* update highlight */ - outliner_item_drag_end(CTX_wm_window(C), data); - redraw = true; - break; - case MOUSEMOVE: - outliner_item_drag_handle(soops, ar, event, te_dragged); - redraw = true; - break; - } - - if (redraw) { - if (skip_rebuild) { - ED_region_tag_redraw_no_rebuild(ar); - } - else { - ED_region_tag_redraw(ar); - } - } - - return retval; -} - -static const char *outliner_drag_drop_tooltip_get( - const TreeElement *te_float) -{ - const char *name = NULL; - - const TreeElement *te_insert = te_float->drag_data->insert_handle; - if (te_float && outliner_is_collection_tree_element(te_float)) { - if (te_insert == NULL) { - name = TIP_("Move collection"); - } - else { - switch (te_float->drag_data->insert_type) { - case TE_INSERT_BEFORE: - if (te_insert->prev && outliner_is_collection_tree_element(te_insert->prev)) { - name = TIP_("Move between collections"); - } - else { - name = TIP_("Move before collection"); - } - break; - case TE_INSERT_AFTER: - if (te_insert->next && outliner_is_collection_tree_element(te_insert->next)) { - name = TIP_("Move between collections"); - } - else { - name = TIP_("Move after collection"); - } - break; - case TE_INSERT_INTO: - name = TIP_("Move inside collection"); - break; - } - } - } - else if ((TREESTORE(te_float)->type == 0) && (te_float->idcode == ID_OB)) { - name = TIP_("Move to collection (Ctrl to link)"); - } - - return name; -} - -static void outliner_drag_drop_tooltip_cb(const wmWindow *win, void *vdata) -{ - OutlinerDragDropTooltip *data = vdata; - const char *tooltip; - - int cursorx, cursory; - int x, y; - - tooltip = outliner_drag_drop_tooltip_get(data->te); - if (tooltip == NULL) { - return; - } - - cursorx = win->eventstate->x; - cursory = win->eventstate->y; - - x = cursorx + U.widget_unit; - y = cursory - U.widget_unit; - - /* Drawing. */ - const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; - - const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f}; - - GPU_blend(true); - UI_fontstyle_draw_simple_backdrop(fstyle, x, y, tooltip, col_fg, col_bg); - GPU_blend(false); -} - -static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event); - - if (!te_dragged) { - return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); - } - - OutlinerDragDropTooltip *data = MEM_mallocN(sizeof(OutlinerDragDropTooltip), __func__); - data->te = te_dragged; - - op->customdata = data; - te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__); - /* by default we don't change the item position */ - te_dragged->drag_data->insert_handle = te_dragged; - /* unset highlighted tree element, dragged one will be highlighted instead */ - outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false); - - ED_region_tag_redraw_no_rebuild(ar); - - WM_event_add_modal_handler(C, op); - - data->handle = WM_draw_cb_activate(CTX_wm_window(C), outliner_drag_drop_tooltip_cb, data); - - return OPERATOR_RUNNING_MODAL; -} - -/** - * Notes about Outliner Item Drag 'n Drop: - * Right now only collections display mode is supported. But ideally all/most modes would support this. There are - * just some open design questions that have to be answered: do we want to allow mixing order of different data types - * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ... - */ -static void OUTLINER_OT_item_drag_drop(wmOperatorType *ot) -{ - ot->name = "Drag and Drop"; - ot->idname = "OUTLINER_OT_item_drag_drop"; - ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop"; - - ot->invoke = outliner_item_drag_drop_invoke; - ot->modal = outliner_item_drag_drop_modal; - - ot->poll = outliner_item_drag_drop_poll; - - ot->flag = OPTYPE_UNDO; -} - - /* ************************** registration **********************************/ void outliner_operatortypes(void) diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index e4e99f88bf4..b0d63aee7c0 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -93,196 +93,6 @@ static void outliner_main_region_init(wmWindowManager *wm, ARegion *ar) WM_event_add_dropbox_handler(&ar->handlers, lb); } -static bool outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; - - if (!te) { - /* pass */ - } - else if (te->idcode == ID_OB && tselem->type == 0) { - Scene *scene; - ID *te_id = tselem->id; - - /* check if dropping self or parent */ - if (te_id == id || (Object *)te_id == ((Object *)id)->parent) - return 0; - - /* check that parent/child are both in the same scene */ - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - - /* currently outliner organized in a way that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ - if (!scene) { - return 1; - } - else { - for (ViewLayer *view_layer = scene->view_layers.first; - view_layer; - view_layer = view_layer->next) - { - if (BKE_view_layer_base_find(view_layer, (Object *)id)) { - return 1; - } - } - } - } - } - } - return 0; -} - -static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "child", id->name + 2); -} - -static bool outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te = NULL; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) { - return false; - } - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - if (((Object *)id)->parent) { - if ((te = outliner_dropzone_find(soops, fmval, true))) { - TreeStoreElem *tselem = TREESTORE(te); - - switch (te->idcode) { - case ID_SCE: - return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); - case ID_OB: - return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); - /* Other codes to ignore? */ - } - } - return (te == NULL); - } - } - } - return 0; -} - -static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "dragged_obj", id->name + 2); - - /* Set to simple parent clear type. Avoid menus for drag and drop if possible. - * If desired, user can toggle the different "Clear Parent" types in the operator - * menu on tool shelf. */ - RNA_enum_set(drop->ptr, "type", 0); -} - -static bool outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, false); - return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0); - } - } - return 0; -} - -static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "object", id->name + 2); -} - -static bool outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MA) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0); - } - } - return 0; -} - -static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "material", id->name + 2); -} - -static bool outliner_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) -{ - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (ELEM(GS(id->name), ID_OB, ID_GR)) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && outliner_is_collection_tree_element(te)); - } - } - return 0; -} - -static void outliner_collection_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "child", id->name + 2); -} - -/* region dropbox definition */ -static void outliner_dropboxes(void) -{ - ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); - - WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy); - WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_material_drop", outliner_material_drop_poll, outliner_material_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", outliner_collection_drop_poll, outliner_collection_drop_copy); -} - static void outliner_main_region_draw(const bContext *C, ARegion *ar) { View2D *v2d = &ar->v2d; -- cgit v1.2.3 From 9e83283f7312c565e32c68bb544177bbfec7ceb2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 7 Aug 2018 10:55:03 +0200 Subject: Cleanup: decouple outliner tree element icon retrieving from drawing. --- .../blender/editors/space_outliner/outliner_draw.c | 386 ++++++++++----------- .../editors/space_outliner/outliner_intern.h | 7 + 2 files changed, 196 insertions(+), 197 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index c52214b9846..5672351d62f 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -850,94 +850,45 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre /* ****************************************************** */ /* Normal Drawing... */ -/* make function calls a bit compacter */ -struct DrawIconArg { - uiBlock *block; - ID *id; - float xmax, x, y, xb, yb; - float alpha; -}; - -static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) +TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) { - /* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */ - if (arg->x >= arg->xmax) { - GPU_blend(true); - UI_icon_draw_alpha(arg->x, arg->y, icon, arg->alpha); - GPU_blend(false); - } - else { - uiBut *but = uiDefIconBut( - arg->block, UI_BTYPE_LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, - 0.0, 0.0, 1.0, arg->alpha, - (arg->id && ID_IS_LINKED(arg->id)) ? arg->id->lib->name : ""); - - if (arg->id) - UI_but_drag_set_id(but, arg->id); - } - -} - -static void tselem_draw_icon( - uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, - float alpha, const bool is_clickable) -{ - struct DrawIconArg arg; - float aspect; - - /* make function calls a bit compacter */ - arg.block = block; - arg.id = tselem->id; - arg.xmax = xmax; - arg.xb = x; /* for ui buttons */ - arg.yb = y; - arg.alpha = alpha; - - /* placement of icons, copied from interface_widgets.c */ - aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT; - x += 2.0f * aspect; - y += 2.0f * aspect; - arg.x = x; - arg.y = y; - -#define ICON_DRAW(_icon) UI_icon_draw_alpha(x, y, _icon, alpha) -#define ICON_CLICK_DRAW(_icon) if (!is_clickable) ICON_DRAW(_icon); else tselem_draw_icon_uibut(&arg, _icon) + TreeElementIcon data = {0}; if (tselem->type) { switch (tselem->type) { case TSE_ANIM_DATA: - ICON_DRAW(ICON_ANIM_DATA); /* XXX */ + data.icon = ICON_ANIM_DATA; /* XXX */ break; case TSE_NLA: - ICON_DRAW(ICON_NLA); + data.icon = ICON_NLA; break; case TSE_NLA_TRACK: - ICON_DRAW(ICON_NLA); /* XXX */ + data.icon = ICON_NLA; /* XXX */ break; case TSE_NLA_ACTION: - ICON_DRAW(ICON_ACTION); + data.icon = ICON_ACTION; break; case TSE_DRIVER_BASE: - ICON_DRAW(ICON_DRIVER); + data.icon = ICON_DRIVER; break; case TSE_DEFGROUP_BASE: - ICON_DRAW(ICON_GROUP_VERTEX); + data.icon = ICON_GROUP_VERTEX; break; case TSE_BONE: case TSE_EBONE: - ICON_DRAW(ICON_BONE_DATA); + data.icon = ICON_BONE_DATA; break; case TSE_CONSTRAINT_BASE: - ICON_DRAW(ICON_CONSTRAINT); + data.icon = ICON_CONSTRAINT; break; case TSE_MODIFIER_BASE: - ICON_DRAW(ICON_MODIFIER); + data.icon = ICON_MODIFIER; break; case TSE_LINKED_OB: - ICON_DRAW(ICON_OBJECT_DATA); + data.icon = ICON_OBJECT_DATA; break; case TSE_LINKED_PSYS: - ICON_DRAW(ICON_PARTICLES); + data.icon = ICON_PARTICLES; break; case TSE_MODIFIER: { @@ -946,154 +897,154 @@ static void tselem_draw_icon( ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr); switch ((ModifierType)md->type) { case eModifierType_Subsurf: - ICON_DRAW(ICON_MOD_SUBSURF); + data.icon = ICON_MOD_SUBSURF; break; case eModifierType_Armature: - ICON_DRAW(ICON_MOD_ARMATURE); + data.icon = ICON_MOD_ARMATURE; break; case eModifierType_Lattice: - ICON_DRAW(ICON_MOD_LATTICE); + data.icon = ICON_MOD_LATTICE; break; case eModifierType_Curve: - ICON_DRAW(ICON_MOD_CURVE); + data.icon = ICON_MOD_CURVE; break; case eModifierType_Build: - ICON_DRAW(ICON_MOD_BUILD); + data.icon = ICON_MOD_BUILD; break; case eModifierType_Mirror: - ICON_DRAW(ICON_MOD_MIRROR); + data.icon = ICON_MOD_MIRROR; break; case eModifierType_Decimate: - ICON_DRAW(ICON_MOD_DECIM); + data.icon = ICON_MOD_DECIM; break; case eModifierType_Wave: - ICON_DRAW(ICON_MOD_WAVE); + data.icon = ICON_MOD_WAVE; break; case eModifierType_Hook: - ICON_DRAW(ICON_HOOK); + data.icon = ICON_HOOK; break; case eModifierType_Softbody: - ICON_DRAW(ICON_MOD_SOFT); + data.icon = ICON_MOD_SOFT; break; case eModifierType_Boolean: - ICON_DRAW(ICON_MOD_BOOLEAN); + data.icon = ICON_MOD_BOOLEAN; break; case eModifierType_ParticleSystem: - ICON_DRAW(ICON_MOD_PARTICLES); + data.icon = ICON_MOD_PARTICLES; break; case eModifierType_ParticleInstance: - ICON_DRAW(ICON_MOD_PARTICLES); + data.icon = ICON_MOD_PARTICLES; break; case eModifierType_EdgeSplit: - ICON_DRAW(ICON_MOD_EDGESPLIT); + data.icon = ICON_MOD_EDGESPLIT; break; case eModifierType_Array: - ICON_DRAW(ICON_MOD_ARRAY); + data.icon = ICON_MOD_ARRAY; break; case eModifierType_UVProject: case eModifierType_UVWarp: /* TODO, get own icon */ - ICON_DRAW(ICON_MOD_UVPROJECT); + data.icon = ICON_MOD_UVPROJECT; break; case eModifierType_Displace: - ICON_DRAW(ICON_MOD_DISPLACE); + data.icon = ICON_MOD_DISPLACE; break; case eModifierType_Shrinkwrap: - ICON_DRAW(ICON_MOD_SHRINKWRAP); + data.icon = ICON_MOD_SHRINKWRAP; break; case eModifierType_Cast: - ICON_DRAW(ICON_MOD_CAST); + data.icon = ICON_MOD_CAST; break; case eModifierType_MeshDeform: case eModifierType_SurfaceDeform: - ICON_DRAW(ICON_MOD_MESHDEFORM); + data.icon = ICON_MOD_MESHDEFORM; break; case eModifierType_Bevel: - ICON_DRAW(ICON_MOD_BEVEL); + data.icon = ICON_MOD_BEVEL; break; case eModifierType_Smooth: case eModifierType_LaplacianSmooth: case eModifierType_CorrectiveSmooth: - ICON_DRAW(ICON_MOD_SMOOTH); + data.icon = ICON_MOD_SMOOTH; break; case eModifierType_SimpleDeform: - ICON_DRAW(ICON_MOD_SIMPLEDEFORM); + data.icon = ICON_MOD_SIMPLEDEFORM; break; case eModifierType_Mask: - ICON_DRAW(ICON_MOD_MASK); + data.icon = ICON_MOD_MASK; break; case eModifierType_Cloth: - ICON_DRAW(ICON_MOD_CLOTH); + data.icon = ICON_MOD_CLOTH; break; case eModifierType_Explode: - ICON_DRAW(ICON_MOD_EXPLODE); + data.icon = ICON_MOD_EXPLODE; break; case eModifierType_Collision: case eModifierType_Surface: - ICON_DRAW(ICON_MOD_PHYSICS); + data.icon = ICON_MOD_PHYSICS; break; case eModifierType_Fluidsim: - ICON_DRAW(ICON_MOD_FLUIDSIM); + data.icon = ICON_MOD_FLUIDSIM; break; case eModifierType_Multires: - ICON_DRAW(ICON_MOD_MULTIRES); + data.icon = ICON_MOD_MULTIRES; break; case eModifierType_Smoke: - ICON_DRAW(ICON_MOD_SMOKE); + data.icon = ICON_MOD_SMOKE; break; case eModifierType_Solidify: - ICON_DRAW(ICON_MOD_SOLIDIFY); + data.icon = ICON_MOD_SOLIDIFY; break; case eModifierType_Screw: - ICON_DRAW(ICON_MOD_SCREW); + data.icon = ICON_MOD_SCREW; break; case eModifierType_Remesh: - ICON_DRAW(ICON_MOD_REMESH); + data.icon = ICON_MOD_REMESH; break; case eModifierType_WeightVGEdit: case eModifierType_WeightVGMix: case eModifierType_WeightVGProximity: - ICON_DRAW(ICON_MOD_VERTEX_WEIGHT); + data.icon = ICON_MOD_VERTEX_WEIGHT; break; case eModifierType_DynamicPaint: - ICON_DRAW(ICON_MOD_DYNAMICPAINT); + data.icon = ICON_MOD_DYNAMICPAINT; break; case eModifierType_Ocean: - ICON_DRAW(ICON_MOD_OCEAN); + data.icon = ICON_MOD_OCEAN; break; case eModifierType_Warp: - ICON_DRAW(ICON_MOD_WARP); + data.icon = ICON_MOD_WARP; break; case eModifierType_Skin: - ICON_DRAW(ICON_MOD_SKIN); + data.icon = ICON_MOD_SKIN; break; case eModifierType_Triangulate: - ICON_DRAW(ICON_MOD_TRIANGULATE); + data.icon = ICON_MOD_TRIANGULATE; break; case eModifierType_MeshCache: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */ break; case eModifierType_MeshSequenceCache: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */ break; case eModifierType_Wireframe: - ICON_DRAW(ICON_MOD_WIREFRAME); + data.icon = ICON_MOD_WIREFRAME; break; case eModifierType_LaplacianDeform: - ICON_DRAW(ICON_MOD_MESHDEFORM); /* XXX, needs own icon */ + data.icon = ICON_MOD_MESHDEFORM; /* XXX, needs own icon */ break; case eModifierType_DataTransfer: - ICON_DRAW(ICON_MOD_DATA_TRANSFER); + data.icon = ICON_MOD_DATA_TRANSFER; break; case eModifierType_NormalEdit: case eModifierType_WeightedNormal: - ICON_DRAW(ICON_MOD_NORMALEDIT); + data.icon = ICON_MOD_NORMALEDIT; break; /* Default */ case eModifierType_None: case eModifierType_ShapeKey: case NUM_MODIFIER_TYPES: - ICON_DRAW(ICON_DOT); + data.icon = ICON_DOT; break; } } @@ -1102,172 +1053,182 @@ static void tselem_draw_icon( GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr); switch ((GpencilModifierType)md->type) { case eGpencilModifierType_Noise: - ICON_DRAW(ICON_RNDCURVE); + data.icon = ICON_RNDCURVE; break; case eGpencilModifierType_Subdiv: - ICON_DRAW(ICON_MOD_SUBSURF); + data.icon = ICON_MOD_SUBSURF; break; case eGpencilModifierType_Thick: - ICON_DRAW(ICON_MAN_ROT); + data.icon = ICON_MAN_ROT; break; case eGpencilModifierType_Tint: - ICON_DRAW(ICON_COLOR); + data.icon = ICON_COLOR; break; case eGpencilModifierType_Instance: - ICON_DRAW(ICON_MOD_ARRAY); + data.icon = ICON_MOD_ARRAY; break; case eGpencilModifierType_Build: - ICON_DRAW(ICON_MOD_BUILD); + data.icon = ICON_MOD_BUILD; break; case eGpencilModifierType_Opacity: - ICON_DRAW(ICON_MOD_MASK); + data.icon = ICON_MOD_MASK; break; case eGpencilModifierType_Color: - ICON_DRAW(ICON_GROUP_VCOL); + data.icon = ICON_GROUP_VCOL; break; case eGpencilModifierType_Lattice: - ICON_DRAW(ICON_MOD_LATTICE); + data.icon = ICON_MOD_LATTICE; break; case eGpencilModifierType_Mirror: - ICON_DRAW(ICON_MOD_MIRROR); + data.icon = ICON_MOD_MIRROR; break; case eGpencilModifierType_Simplify: - ICON_DRAW(ICON_MOD_DECIM); + data.icon = ICON_MOD_DECIM; break; case eGpencilModifierType_Smooth: - ICON_DRAW(ICON_MOD_SMOOTH); + data.icon = ICON_MOD_SMOOTH; break; case eGpencilModifierType_Hook: - ICON_DRAW(ICON_HOOK); + data.icon = ICON_HOOK; break; case eGpencilModifierType_Offset: - ICON_DRAW(ICON_MOD_DISPLACE); + data.icon = ICON_MOD_DISPLACE; break; /* Default */ default: - ICON_DRAW(ICON_DOT); + data.icon = ICON_DOT; break; } } break; } case TSE_POSE_BASE: - ICON_DRAW(ICON_ARMATURE_DATA); + data.icon = ICON_ARMATURE_DATA; break; case TSE_POSE_CHANNEL: - ICON_DRAW(ICON_BONE_DATA); + data.icon = ICON_BONE_DATA; break; case TSE_PROXY: - ICON_DRAW(ICON_GHOST); + data.icon = ICON_GHOST; break; case TSE_R_LAYER_BASE: - ICON_DRAW(ICON_RENDERLAYERS); + data.icon = ICON_RENDERLAYERS; break; case TSE_SCENE_OBJECTS_BASE: - ICON_DRAW(ICON_OUTLINER_OB_GROUP_INSTANCE); + data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE; break; case TSE_R_LAYER: - ICON_DRAW(ICON_RENDER_RESULT); + data.icon = ICON_RENDER_RESULT; break; case TSE_LINKED_LAMP: - ICON_DRAW(ICON_LIGHT_DATA); + data.icon = ICON_LIGHT_DATA; break; case TSE_LINKED_MAT: - ICON_DRAW(ICON_MATERIAL_DATA); + data.icon = ICON_MATERIAL_DATA; break; case TSE_POSEGRP_BASE: - ICON_DRAW(ICON_GROUP_BONE); + data.icon = ICON_GROUP_BONE; break; case TSE_SEQUENCE: if (te->idcode == SEQ_TYPE_MOVIE) - ICON_DRAW(ICON_SEQUENCE); + data.icon = ICON_SEQUENCE; else if (te->idcode == SEQ_TYPE_META) - ICON_DRAW(ICON_DOT); + data.icon = ICON_DOT; else if (te->idcode == SEQ_TYPE_SCENE) - ICON_DRAW(ICON_SCENE); + data.icon = ICON_SCENE; else if (te->idcode == SEQ_TYPE_SOUND_RAM) - ICON_DRAW(ICON_SOUND); + data.icon = ICON_SOUND; else if (te->idcode == SEQ_TYPE_IMAGE) - ICON_DRAW(ICON_IMAGE_COL); + data.icon = ICON_IMAGE_COL; else - ICON_DRAW(ICON_PARTICLES); + data.icon = ICON_PARTICLES; break; case TSE_SEQ_STRIP: - ICON_DRAW(ICON_LIBRARY_DATA_DIRECT); + data.icon = ICON_LIBRARY_DATA_DIRECT; break; case TSE_SEQUENCE_DUP: - ICON_DRAW(ICON_OBJECT_DATA); + data.icon = ICON_OBJECT_DATA; break; case TSE_RNA_STRUCT: if (RNA_struct_is_ID(te->rnaptr.type)) { - arg.id = (ID *)te->rnaptr.data; - tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type)); + data.drag_id = (ID *)te->rnaptr.data; + data.icon = RNA_struct_ui_icon(te->rnaptr.type); } else { - int icon = RNA_struct_ui_icon(te->rnaptr.type); - ICON_DRAW(icon); + data.icon = RNA_struct_ui_icon(te->rnaptr.type); } break; case TSE_LAYER_COLLECTION: case TSE_SCENE_COLLECTION_BASE: case TSE_VIEW_COLLECTION_BASE: - ICON_DRAW(ICON_GROUP); + { + Collection *collection = outliner_collection_from_tree_element(te); + if (collection && !(collection->flag & COLLECTION_IS_MASTER)) { + data.drag_id = tselem->id; + data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL; + } + + data.icon = ICON_GROUP; break; + } /* Removed the icons from outliner. Need a better structure with Layers, Palettes and Colors */ case TSE_GP_LAYER: { /* indicate whether layer is active */ bGPDlayer *gpl = te->directdata; if (gpl->flag & GP_LAYER_ACTIVE) { - ICON_DRAW(ICON_GREASEPENCIL); + data.icon = ICON_GREASEPENCIL; } else { - ICON_DRAW(ICON_DOT); + data.icon = ICON_DOT; } break; } default: - ICON_DRAW(ICON_DOT); + data.icon = ICON_DOT; break; } } else if (tselem->id) { + data.drag_id = tselem->id; + data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL; + if (GS(tselem->id->name) == ID_OB) { Object *ob = (Object *)tselem->id; switch (ob->type) { case OB_LAMP: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_LIGHT); break; + data.icon = ICON_OUTLINER_OB_LIGHT; break; case OB_MESH: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_MESH); break; + data.icon = ICON_OUTLINER_OB_MESH; break; case OB_CAMERA: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_CAMERA); break; + data.icon = ICON_OUTLINER_OB_CAMERA; break; case OB_CURVE: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_CURVE); break; + data.icon = ICON_OUTLINER_OB_CURVE; break; case OB_MBALL: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_META); break; + data.icon = ICON_OUTLINER_OB_META; break; case OB_LATTICE: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_LATTICE); break; + data.icon = ICON_OUTLINER_OB_LATTICE; break; case OB_ARMATURE: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_ARMATURE); break; + data.icon = ICON_OUTLINER_OB_ARMATURE; break; case OB_FONT: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_FONT); break; + data.icon = ICON_OUTLINER_OB_FONT; break; case OB_SURF: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_SURFACE); break; + data.icon = ICON_OUTLINER_OB_SURFACE; break; case OB_SPEAKER: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_SPEAKER); break; + data.icon = ICON_OUTLINER_OB_SPEAKER; break; case OB_LIGHTPROBE: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_LIGHTPROBE); break; + data.icon = ICON_OUTLINER_OB_LIGHTPROBE; break; case OB_EMPTY: if (ob->dup_group) { - ICON_CLICK_DRAW(ICON_OUTLINER_OB_GROUP_INSTANCE); + data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE; } else { - ICON_CLICK_DRAW(ICON_OUTLINER_OB_EMPTY); + data.icon = ICON_OUTLINER_OB_EMPTY; } break; case OB_GPENCIL: - ICON_CLICK_DRAW(ICON_OUTLINER_OB_GREASEPENCIL); break; + data.icon = ICON_OUTLINER_OB_GREASEPENCIL; break; break; } } @@ -1277,101 +1238,132 @@ static void tselem_draw_icon( */ switch ((short)GS(tselem->id->name)) { case ID_SCE: - tselem_draw_icon_uibut(&arg, ICON_SCENE_DATA); break; + data.icon = ICON_SCENE_DATA; break; case ID_ME: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_MESH); break; + data.icon = ICON_OUTLINER_DATA_MESH; break; case ID_CU: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CURVE); break; + data.icon = ICON_OUTLINER_DATA_CURVE; break; case ID_MB: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_META); break; + data.icon = ICON_OUTLINER_DATA_META; break; case ID_LT: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LATTICE); break; + data.icon = ICON_OUTLINER_DATA_LATTICE; break; case ID_LA: { Lamp *la = (Lamp *)tselem->id; switch (la->type) { case LA_LOCAL: - tselem_draw_icon_uibut(&arg, ICON_LIGHT_POINT); break; + data.icon = ICON_LIGHT_POINT; break; case LA_SUN: - tselem_draw_icon_uibut(&arg, ICON_LIGHT_SUN); break; + data.icon = ICON_LIGHT_SUN; break; case LA_SPOT: - tselem_draw_icon_uibut(&arg, ICON_LIGHT_SPOT); break; + data.icon = ICON_LIGHT_SPOT; break; case LA_HEMI: - tselem_draw_icon_uibut(&arg, ICON_LIGHT_HEMI); break; + data.icon = ICON_LIGHT_HEMI; break; case LA_AREA: - tselem_draw_icon_uibut(&arg, ICON_LIGHT_AREA); break; + data.icon = ICON_LIGHT_AREA; break; default: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LIGHT); break; + data.icon = ICON_OUTLINER_DATA_LIGHT; break; } break; } case ID_MA: - tselem_draw_icon_uibut(&arg, ICON_MATERIAL_DATA); break; + data.icon = ICON_MATERIAL_DATA; break; case ID_TE: - tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break; + data.icon = ICON_TEXTURE_DATA; break; case ID_IM: - tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break; + data.icon = ICON_IMAGE_DATA; break; case ID_SPK: case ID_SO: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_SPEAKER); break; + data.icon = ICON_OUTLINER_DATA_SPEAKER; break; case ID_AR: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_ARMATURE); break; + data.icon = ICON_OUTLINER_DATA_ARMATURE; break; case ID_CA: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CAMERA); break; + data.icon = ICON_OUTLINER_DATA_CAMERA; break; case ID_KE: - tselem_draw_icon_uibut(&arg, ICON_SHAPEKEY_DATA); break; + data.icon = ICON_SHAPEKEY_DATA; break; case ID_WO: - tselem_draw_icon_uibut(&arg, ICON_WORLD_DATA); break; + data.icon = ICON_WORLD_DATA; break; case ID_AC: - tselem_draw_icon_uibut(&arg, ICON_ACTION); break; + data.icon = ICON_ACTION; break; case ID_NLA: - tselem_draw_icon_uibut(&arg, ICON_NLA); break; + data.icon = ICON_NLA; break; case ID_TXT: - tselem_draw_icon_uibut(&arg, ICON_SCRIPT); break; + data.icon = ICON_SCRIPT; break; case ID_GR: - tselem_draw_icon_uibut(&arg, ICON_GROUP); break; + data.icon = ICON_GROUP; break; case ID_LI: if (tselem->id->tag & LIB_TAG_MISSING) { - tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_BROKEN); + data.icon = ICON_LIBRARY_DATA_BROKEN; } else if (((Library *)tselem->id)->parent) { - tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_INDIRECT); + data.icon = ICON_LIBRARY_DATA_INDIRECT; } else { - tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); + data.icon = ICON_LIBRARY_DATA_DIRECT; } break; case ID_LS: - tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break; + data.icon = ICON_LINE_DATA; break; case ID_GD: - tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_GREASEPENCIL); break; + data.icon = ICON_OUTLINER_DATA_GREASEPENCIL; break; case ID_LP: { LightProbe * lp = (LightProbe *)tselem->id; switch (lp->type) { case LIGHTPROBE_TYPE_CUBE: - tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_CUBEMAP); break; + data.icon = ICON_LIGHTPROBE_CUBEMAP; break; case LIGHTPROBE_TYPE_PLANAR: - tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_PLANAR); break; + data.icon = ICON_LIGHTPROBE_PLANAR; break; case LIGHTPROBE_TYPE_GRID: - tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_GRID); break; + data.icon = ICON_LIGHTPROBE_GRID; break; default: - tselem_draw_icon_uibut(&arg, ICON_LIGHTPROBE_CUBEMAP); break; + data.icon = ICON_LIGHTPROBE_CUBEMAP; break; } break; } case ID_BR: - tselem_draw_icon_uibut(&arg, ICON_BRUSH_DATA); break; + data.icon = ICON_BRUSH_DATA; break; case ID_SCR: case ID_WS: - tselem_draw_icon_uibut(&arg, ICON_SPLITSCREEN); break; + data.icon = ICON_SPLITSCREEN; break; default: break; } } } -#undef ICON_DRAW + return data; +} + +static void tselem_draw_icon( + uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, + float alpha, const bool is_clickable) +{ + TreeElementIcon data = tree_element_get_icon(tselem, te); + + if (data.icon == 0) { + return; + } + + if (!is_clickable || x >= xmax) { + /* placement of icons, copied from interface_widgets.c */ + float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT; + x += 2.0f * aspect; + y += 2.0f * aspect; + + /* restrict column clip... it has been coded by simply overdrawing, + * doesnt work for buttons */ + UI_icon_draw_alpha(x, y, data.icon, alpha); + } + else { + uiBut *but = uiDefIconBut( + block, UI_BTYPE_LABEL, 0, data.icon, x, y, UI_UNIT_X, UI_UNIT_Y, NULL, + 0.0, 0.0, 1.0, alpha, + (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : ""); + + if (data.drag_id) + UI_but_drag_set_id(but, data.drag_id); + } } /** diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index ecc092358d6..e5ed7de2a24 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -112,6 +112,11 @@ typedef struct TreeElement { } *drag_data; } TreeElement; +typedef struct TreeElementIcon { + struct ID *drag_id, *drag_parent; + int icon; +} TreeElementIcon; + #define TREESTORE_ID_TYPE(_id) \ (ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_NT, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \ ELEM(GS((_id)->name), ID_KE, ID_WO, ID_SPK, ID_GR, ID_AR, ID_AC, ID_BR, ID_PA, ID_GD, ID_LS, ID_LP) || \ @@ -209,6 +214,8 @@ TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void void draw_outliner(const struct bContext *C); void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag); +TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te); + /* outliner_select.c -------------------------------------------- */ eOLDrawState tree_element_type_active( struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOops *soops, -- cgit v1.2.3 From 74016d73dbebd8c8a0e1aed70295d1a09037d7eb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 7 Aug 2018 10:38:20 +0200 Subject: WM: drag and drop poll functions can now specify a custom tooltip. --- source/blender/editors/include/UI_interface.h | 2 +- source/blender/editors/interface/interface_ops.c | 2 +- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/editors/space_clip/space_clip.c | 2 +- source/blender/editors/space_console/space_console.c | 4 ++-- source/blender/editors/space_file/space_file.c | 2 +- source/blender/editors/space_image/space_image.c | 2 +- source/blender/editors/space_node/space_node.c | 4 ++-- .../editors/space_outliner/outliner_dragdrop.c | 10 +++++----- .../editors/space_sequencer/space_sequencer.c | 6 +++--- source/blender/editors/space_text/space_text.c | 4 ++-- source/blender/editors/space_view3d/space_view3d.c | 20 ++++++++++---------- source/blender/windowmanager/WM_api.h | 3 ++- source/blender/windowmanager/WM_types.h | 2 +- source/blender/windowmanager/intern/wm_dragdrop.c | 9 ++++++--- .../blender/windowmanager/intern/wm_event_system.c | 3 ++- 16 files changed, 41 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index d174a78ee23..824920bce73 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1201,7 +1201,7 @@ void ED_operatortypes_ui(void); void ED_keymap_ui(struct wmKeyConfig *keyconf); void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop); -bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event); +bool UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event, const char **tooltip); bool UI_context_copy_to_selected_list( struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index ec10fc9d494..ae0fe912f95 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -1243,7 +1243,7 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot) ot->exec = reloadtranslation_exec; } -bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) +bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { /* should only return true for regions that include buttons, for now * return true always */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 50ac5dfd224..c8ad2b954a5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4826,7 +4826,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf) } -static bool open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_PATH) { if (drag->icon == ICON_FILE_BLEND) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 725c2b7fa6d..4f9fd9c65d7 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -847,7 +847,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul } /* dropboxes */ -static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_PATH) if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */ diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 3a48d5ad7dd..ce87ad3b177 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -170,7 +170,7 @@ static void console_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* ************* dropboxes ************* */ -static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { // SpaceConsole *sc = CTX_wm_space_console(C); if (drag->type == WM_DRAG_ID) @@ -189,7 +189,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop) MEM_freeN(text); } -static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { // SpaceConsole *sc = CTX_wm_space_console(C); if (drag->type == WM_DRAG_PATH) diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 116cd700cc0..cb21659dbb8 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -720,7 +720,7 @@ static void file_ui_region_listener( } } -static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) +static bool filepath_drop_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_PATH) { SpaceFile *sfile = CTX_wm_space_file(C); diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index d87bfbe00ce..69bedf7c442 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -387,7 +387,7 @@ static void image_keymap(struct wmKeyConfig *keyconf) } /* dropboxes */ -static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_PATH) if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 10f337440d4..74c036883e6 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -675,7 +675,7 @@ static void node_main_region_draw(const bContext *C, ARegion *ar) /* ************* dropboxes ************* */ -static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -689,7 +689,7 @@ static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent return 0; } -static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index f37cd7fa5e4..c53a431a017 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -107,7 +107,7 @@ static TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float f /* ******************** Parent Drop Operator *********************** */ -static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); @@ -367,7 +367,7 @@ static bool parenting_poll(bContext *C) /* ******************** Parent Clear Operator *********************** */ -static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); @@ -456,7 +456,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot) /* ******************** Scene Drop Operator *********************** */ -static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); @@ -563,7 +563,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot) /* ******************** Material Drop Operator *********************** */ -static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); @@ -648,7 +648,7 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot) /* ******************** Collection Drop Operator *********************** */ -static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 8fb526bf502..11517d64d7a 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -366,7 +366,7 @@ static void sequencer_listener( /* ************* dropboxes ************* */ -static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -380,7 +380,7 @@ static bool image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) return 0; } -static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); @@ -393,7 +393,7 @@ static bool movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) return 0; } -static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index ac43d7de408..53272ee9ed9 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -474,7 +474,7 @@ static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* ************* dropboxes ************* */ -static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_PATH) { /* rule might not work? */ @@ -491,7 +491,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop) RNA_string_set(drop->ptr, "filepath", drag->path); } -static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) return true; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index eaa6f03c533..62adca6af6b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -554,7 +554,7 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar) } } -static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -564,7 +564,7 @@ static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent return 0; } -static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -574,7 +574,7 @@ static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const return 0; } -static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -584,7 +584,7 @@ static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEven return 0; } -static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { if (drag->type == WM_DRAG_ID) { ID *id = drag->poin; @@ -610,19 +610,19 @@ static bool view3d_ima_bg_is_camera_view(bContext *C) return false; } -static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip) { if (view3d_ima_bg_is_camera_view(C)) { return true; } if (!ED_view3d_give_base_under_cursor(C, event->mval)) { - return view3d_ima_drop_poll(C, drag, event); + return view3d_ima_drop_poll(C, drag, event, tooltip); } return 0; } -static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip) { if (!view3d_ima_bg_is_camera_view(C)) { return true; @@ -634,18 +634,18 @@ static bool view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent if ((base == NULL) || ((base != NULL) && base->object->type == OB_EMPTY)) { - return view3d_ima_drop_poll(C, drag, event); + return view3d_ima_drop_poll(C, drag, event, tooltip); } return 0; } -static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) +static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip) { Base *base = ED_view3d_give_base_under_cursor(C, event->mval); if (base && base->object->type == OB_MESH) - return view3d_ima_drop_poll(C, drag, event); + return view3d_ima_drop_poll(C, drag, event, tooltip); return 0; } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 67ca5f8a08a..3521c4d1bd5 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -485,7 +485,8 @@ void WM_drag_free(struct wmDrag *drag); void WM_drag_free_list(struct ListBase *lb); struct wmDropBox *WM_dropbox_add( - ListBase *lb, const char *idname, bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event), + ListBase *lb, const char *idname, + bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), void (*copy)(struct wmDrag *, struct wmDropBox *)); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 6b1bb8f4806..809588b1a36 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -682,7 +682,7 @@ typedef struct wmDropBox { struct wmDropBox *next, *prev; /* test if the dropbox is active, then can print optype name */ - bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *); + bool (*poll)(struct bContext *, struct wmDrag *, const wmEvent *, const char **); /* before exec, this copies drag info to wmDrop properties */ void (*copy)(struct wmDrag *, struct wmDropBox *); diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index eca3a838c0f..0ae51cc922b 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -98,7 +98,8 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid) wmDropBox *WM_dropbox_add( - ListBase *lb, const char *idname, bool (*poll)(bContext *, wmDrag *, const wmEvent *), + ListBase *lb, const char *idname, + bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **), void (*copy)(wmDrag *, wmDropBox *)) { wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox"); @@ -195,10 +196,12 @@ static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, if (handler->dropboxes) { wmDropBox *drop = handler->dropboxes->first; for (; drop; drop = drop->next) { - if (drop->poll(C, drag, event)) + const char *tooltip = NULL; + if (drop->poll(C, drag, event, &tooltip)) { /* XXX Doing translation here might not be ideal, but later we have no more * access to ot (and hence op context)... */ - return RNA_struct_ui_name(drop->ot->srna); + return (tooltip) ? tooltip : RNA_struct_ui_name(drop->ot->srna); + } } } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 8b1cce27502..5d343c5e0fe 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2368,7 +2368,8 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers wmDrag *drag; for (drag = lb->first; drag; drag = drag->next) { - if (drop->poll(C, drag, event)) { + const char *tooltip = NULL; + if (drop->poll(C, drag, event, &tooltip)) { drop->copy(drag, drop); /* free the drags before calling operator */ -- cgit v1.2.3 From 86c363a02706b1a5d3cb18d17b4b37bd78461ded Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 7 Aug 2018 10:57:09 +0200 Subject: WM: pass on wmDrag to drop operators, so they can get the data directly. Currently drop operators work mostly by specifying the name of the datablock. However there can be datablocks with the same name in different libraries, so this gives wrong results in some cases. Currently only outliner drop operators have been updated to use this mechanism. --- .../blender/editors/space_console/space_console.c | 15 +- source/blender/editors/space_node/space_node.c | 19 +- .../editors/space_outliner/outliner_dragdrop.c | 642 ++++++++------------- source/blender/editors/space_text/space_text.c | 5 +- source/blender/editors/space_view3d/space_view3d.c | 33 +- source/blender/windowmanager/WM_api.h | 3 + source/blender/windowmanager/intern/wm_dragdrop.c | 21 + .../blender/windowmanager/intern/wm_event_system.c | 73 ++- 8 files changed, 324 insertions(+), 487 deletions(-) diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index ce87ad3b177..3429d726349 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -172,29 +172,22 @@ static void console_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) static bool id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { -// SpaceConsole *sc = CTX_wm_space_console(C); - if (drag->type == WM_DRAG_ID) - return 1; - return 0; + return WM_drag_ID(drag, 0) != NULL; } static void id_drop_copy(wmDrag *drag, wmDropBox *drop) { - char *text; - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); /* copy drag path to properties */ - text = RNA_path_full_ID_py(id); + char *text = RNA_path_full_ID_py(id); RNA_string_set(drop->ptr, "text", text); MEM_freeN(text); } static bool path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - // SpaceConsole *sc = CTX_wm_space_console(C); - if (drag->type == WM_DRAG_PATH) - return 1; - return 0; + return (drag->type == WM_DRAG_PATH); } static void path_drop_copy(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 74c036883e6..2b2e659d151 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -677,26 +677,17 @@ static void node_main_region_draw(const bContext *C, ARegion *ar) static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_IM) - return 1; + if (drag->type == WM_DRAG_PATH) { + return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */ } - else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ - return 1; + else { + return WM_drag_ID(drag, ID_IM) != NULL; } - return 0; } static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MSK) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_MSK) != NULL; } static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index c53a431a017..f9a4fda0c45 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -39,6 +39,7 @@ #include "DNA_space_types.h" #include "BLI_listbase.h" +#include "BLI_string.h" #include "BLT_translation.h" @@ -105,64 +106,77 @@ static TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float f return NULL; } -/* ******************** Parent Drop Operator *********************** */ - -static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) +static TreeElement *outliner_drop_find(bContext *C, const wmEvent *event) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); float fmval[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + return outliner_dropzone_find(soops, fmval, true); +} - if (!te) { - /* pass */ - } - else if (te->idcode == ID_OB && tselem->type == 0) { - Scene *scene; - ID *te_id = tselem->id; - - /* check if dropping self or parent */ - if (te_id == id || (Object *)te_id == ((Object *)id)->parent) - return 0; - - /* check that parent/child are both in the same scene */ - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - - /* currently outliner organized in a way that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ - if (!scene) { - return 1; - } - else { - for (ViewLayer *view_layer = scene->view_layers.first; - view_layer; - view_layer = view_layer->next) - { - if (BKE_view_layer_base_find(view_layer, (Object *)id)) { - return 1; - } - } - } - } - } +static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode) +{ + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = (te) ? TREESTORE(te) : NULL; + + if (te && te->idcode == idcode && tselem->type == 0) { + return tselem->id; + } + else { + return NULL; } - return 0; } -static void parent_drop_copy(wmDrag *drag, wmDropBox *drop) +/* ******************** Parent Drop Operator *********************** */ + +static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ID *id = drag->poin; + SpaceOops *soops = CTX_wm_space_outliner(C); + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + if (!ob) { + return false; + } + + /* Ensure item under cursor is valid drop target */ + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + + if (!te) { + /* pass */ + } + else if (te->idcode == ID_OB && tselem->type == 0) { + Scene *scene; + ID *te_id = tselem->id; + + /* check if dropping self or parent */ + if (te_id == &ob->id || (Object *)te_id == ob->parent) + return false; + + /* check that parent/child are both in the same scene */ + scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + + /* currently outliner organized in a way that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + if (!scene) { + return true; + } + else { + for (ViewLayer *view_layer = scene->view_layers.first; + view_layer; + view_layer = view_layer->next) + { + if (BKE_view_layer_base_find(view_layer, ob)) { + return true; + } + } + } + } - RNA_string_set(drop->ptr, "child", id->name + 2); + return false; } static int parent_drop_exec(bContext *C, wmOperator *op) @@ -195,131 +209,121 @@ static int parent_drop_exec(bContext *C, wmOperator *op) static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Object *par = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - Scene *scene = NULL; - TreeElement *te = NULL; + SpaceOops *soops = CTX_wm_space_outliner(C); + TreeElement *te = outliner_drop_find(C, event); + TreeStoreElem *tselem = te ? TREESTORE(te) : NULL; + + if (!(te && te->idcode == ID_OB && tselem->type == 0)) { + return OPERATOR_CANCELLED; + } + + Object *par = (Object *)tselem->id; + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + + if (ELEM(NULL, ob, par)) { + return OPERATOR_CANCELLED; + } + if (ob == par) { + return OPERATOR_CANCELLED; + } + if (ID_IS_LINKED(ob)) { + BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); + return OPERATOR_CANCELLED; + } + char childname[MAX_ID_NAME]; char parname[MAX_ID_NAME]; - int partype = 0; - float fmval[2]; + STRNCPY(childname, ob->id.name); + STRNCPY(parname, par->id.name); + RNA_string_set(op->ptr, "child", childname); + RNA_string_set(op->ptr, "parent", parname); - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + Scene *scene = (Scene *)outliner_search_back(soops, te, ID_SCE); - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); + if (scene == NULL) { + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ - if (te) { - RNA_string_set(op->ptr, "parent", te->name); - /* Identify parent and child */ - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(bmain, ID_OB, parname); - - if (ELEM(NULL, ob, par)) { - if (par == NULL) printf("par==NULL\n"); - return OPERATOR_CANCELLED; - } - if (ob == par) { - return OPERATOR_CANCELLED; - } - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; + scene = CTX_data_scene(C); + } + + if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { + int partype = 0; + if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); } + } + else { + /* Menu creation */ + wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); + uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); + uiLayout *layout = UI_popup_menu_layout(pup); + PointerRNA ptr; + + /* Cannot use uiItemEnumO()... have multiple properties to set. */ + uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_OBJECT); + + /* par becomes parent, make the associated menus */ + if (par->type == OB_ARMATURE) { + uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE); - scene = (Scene *)outliner_search_back(soops, te, ID_SCE); + uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - if (scene == NULL) { - /* currently outlier organized in a way, that if there's no parent scene - * element for object it means that all displayed objects belong to - * active scene and parenting them is allowed (sergey) - */ + uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - scene = CTX_data_scene(C); - } + uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { - if (ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL)) { - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); - } + uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_BONE); } - else { - /* Menu creation */ - wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false); - uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE); - uiLayout *layout = UI_popup_menu_layout(pup); - PointerRNA ptr; - - /* Cannot use uiItemEnumO()... have multiple properties to set. */ - uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + else if (par->type == OB_CURVE) { + uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_OBJECT); - - /* par becomes parent, make the associated menus */ - if (par->type == OB_ARMATURE) { - uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - - uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - - uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_BONE); - } - else if (par->type == OB_CURVE) { - uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_CURVE); - - uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_FOLLOW); - - uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_PATH_CONST); - } - else if (par->type == OB_LATTICE) { - uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); - RNA_string_set(&ptr, "parent", parname); - RNA_string_set(&ptr, "child", childname); - RNA_enum_set(&ptr, "type", PAR_LATTICE); - } + RNA_enum_set(&ptr, "type", PAR_CURVE); - UI_popup_menu_end(C, pup); + uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_FOLLOW); - return OPERATOR_INTERFACE; + uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_PATH_CONST); } - } - else { - return OPERATOR_CANCELLED; + else if (par->type == OB_LATTICE) { + uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); + RNA_string_set(&ptr, "parent", parname); + RNA_string_set(&ptr, "child", childname); + RNA_enum_set(&ptr, "type", PAR_LATTICE); + } + + UI_popup_menu_end(C, pup); + + return OPERATOR_INTERFACE; } return OPERATOR_FINISHED; @@ -369,64 +373,42 @@ static bool parenting_poll(bContext *C) static bool parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te = NULL; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); if (!ELEM(soops->outlinevis, SO_VIEW_LAYER)) { return false; } - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - if (((Object *)id)->parent) { - if ((te = outliner_dropzone_find(soops, fmval, true))) { - TreeStoreElem *tselem = TREESTORE(te); - - switch (te->idcode) { - case ID_SCE: - return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); - case ID_OB: - return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); - /* Other codes to ignore? */ - } - } - return (te == NULL); - } - } + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + if (!(ob && ob->parent)) { + return false; } - return 0; -} - -static void parent_clear_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "dragged_obj", id->name + 2); - /* Set to simple parent clear type. Avoid menus for drag and drop if possible. - * If desired, user can toggle the different "Clear Parent" types in the operator - * menu on tool shelf. */ - RNA_enum_set(drop->ptr, "type", 0); + TreeElement *te = outliner_drop_find(C, event); + if (te) { + TreeStoreElem *tselem = TREESTORE(te); + + switch (te->idcode) { + case ID_SCE: + return (ELEM(tselem->type, TSE_R_LAYER_BASE, TSE_R_LAYER)); + case ID_OB: + return (ELEM(tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE)); + /* Other codes to ignore? */ + } + } + return (te == NULL); } -static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { Main *bmain = CTX_data_main(C); - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - char obname[MAX_ID_NAME]; + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); - RNA_string_get(op->ptr, "dragged_obj", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - /* search forwards to find the object */ - outliner_find_id(soops, &soops->tree, (ID *)ob); + if (ob == NULL) { + return OPERATOR_CANCELLED; + } - ED_object_parent_clear(ob, RNA_enum_get(op->ptr, "type")); + ED_object_parent_clear(ob, 0); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -448,97 +430,55 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); } /* ******************** Scene Drop Operator *********************** */ static bool scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, false); - return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0); - } - } - return 0; -} - -static void scene_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "object", id->name + 2); + /* Ensure item under cursor is valid drop target */ + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + return (ob && (outliner_ID_drop_find(C, event, ID_SCE) != NULL)); } -static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int scene_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - Scene *scene = NULL; - Object *ob = NULL; - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - TreeElement *te = NULL; - char obname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, false); + Scene *scene = (Scene *)outliner_ID_drop_find(C, event, ID_SCE); + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); - if (te) { - RNA_string_set(op->ptr, "scene", te->name); - scene = (Scene *)BKE_libblock_find_name(bmain, ID_SCE, te->name); - - RNA_string_get(op->ptr, "object", obname); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, obname); - - if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { - return OPERATOR_CANCELLED; - } + if (ELEM(NULL, ob, scene) || ID_IS_LINKED(scene)) { + return OPERATOR_CANCELLED; + } - if (BKE_scene_has_object(scene, ob)) { - return OPERATOR_CANCELLED; - } + if (BKE_scene_has_object(scene, ob)) { + return OPERATOR_CANCELLED; + } - Collection *collection; - if (scene != CTX_data_scene(C)) { - /* when linking to an inactive scene link to the master collection */ - collection = BKE_collection_master(scene); - } - else { - collection = CTX_data_collection(C); - } + Collection *collection; + if (scene != CTX_data_scene(C)) { + /* when linking to an inactive scene link to the master collection */ + collection = BKE_collection_master(scene); + } + else { + collection = CTX_data_collection(C); + } - BKE_collection_object_add(bmain, collection, ob); + BKE_collection_object_add(bmain, collection, ob); - for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { - Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base) { - ED_object_base_select(base, BA_SELECT); - } + for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base) { + ED_object_base_select(base, BA_SELECT); } + } - DEG_relations_tag_update(bmain); - - DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); - WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); + DEG_relations_tag_update(bmain); - return OPERATOR_FINISHED; - } + DEG_id_tag_update(&scene->id, DEG_TAG_SELECT_UPDATE); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OUTLINER_OT_scene_drop(wmOperatorType *ot) @@ -555,75 +495,33 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene"); } /* ******************** Material Drop Operator *********************** */ static bool material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MA) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0); - } - } - return 0; + /* Ensure item under cursor is valid drop target */ + Material *ma = (Material *)WM_drag_ID(drag, ID_MA); + return (ma && (outliner_ID_drop_find(C, event, ID_OB) != NULL)); } -static void material_drop_copy(wmDrag *drag, wmDropBox *drop) +static int material_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - ID *id = drag->poin; - - RNA_string_set(drop->ptr, "material", id->name + 2); -} - -static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - Material *ma = NULL; - Object *ob = NULL; Main *bmain = CTX_data_main(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); - TreeElement *te = NULL; - char mat_name[MAX_ID_NAME - 2]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - te = outliner_dropzone_find(soops, fmval, true); - - if (te) { - RNA_string_set(op->ptr, "object", te->name); - ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, te->name); + Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB); + Material *ma = (Material *)WM_drag_ID_from_event(event, ID_MA); - RNA_string_get(op->ptr, "material", mat_name); - ma = (Material *)BKE_libblock_find_name(bmain, ID_MA, mat_name); - - if (ELEM(NULL, ob, ma)) { - return OPERATOR_CANCELLED; - } - - assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); + if (ELEM(NULL, ob, ma)) { + return OPERATOR_CANCELLED; + } - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); + assign_material(bmain, ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); - return OPERATOR_FINISHED; - } + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); - return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } void OUTLINER_OT_material_drop(wmOperatorType *ot) @@ -640,80 +538,28 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); - RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material"); } /* ******************** Collection Drop Operator *********************** */ static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) { - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - float fmval[2]; - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); + Object *ob = (Object *)WM_drag_ID(drag, ID_OB); + Collection *collection = (Collection *)WM_drag_ID(drag, ID_GR); - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (ELEM(GS(id->name), ID_OB, ID_GR)) { - /* Ensure item under cursor is valid drop target */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); - return (te && outliner_is_collection_tree_element(te)); - } + if (ob || collection) { + TreeElement *te = outliner_drop_find(C, event); + return (te && outliner_is_collection_tree_element(te)); } - return 0; -} - -static void collection_drop_copy(wmDrag *drag, wmDropBox *drop) -{ - ID *id = drag->poin; - RNA_string_set(drop->ptr, "child", id->name + 2); -} - -static int collection_drop_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) -{ - /* TODO: implement */ -#if 0 - Object *par = NULL, *ob = NULL; - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - int partype = -1; - char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; - - RNA_string_get(op->ptr, "parent", parname); - par = (Object *)BKE_libblock_find_name(ID_OB, parname); - RNA_string_get(op->ptr, "child", childname); - ob = (Object *)BKE_libblock_find_name(ID_OB, childname); - - if (ID_IS_LINKED(ob)) { - BKE_report(op->reports, RPT_INFO, "Can't edit library linked object"); - return OPERATOR_CANCELLED; + else { + return false; } - - ED_object_parent_set(op->reports, C, scene, ob, par, partype, false, false, NULL); - - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); - WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); -#endif - - return OPERATOR_FINISHED; } -static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - SpaceOops *soops = CTX_wm_space_outliner(C); - ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); - char childname[MAX_ID_NAME]; - float fmval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); - - /* Find object hovered over */ - TreeElement *te = outliner_dropzone_find(soops, fmval, true); + TreeElement *te = outliner_drop_find(C, event); if (!te || !outliner_is_collection_tree_element(te)) { return OPERATOR_CANCELLED; @@ -724,9 +570,11 @@ static int collection_drop_invoke(bContext *C, wmOperator *op, const wmEvent *ev // TODO: don't use scene, makes no sense anymore // TODO: move rather than link, change hover text Scene *scene = BKE_scene_find_from_collection(bmain, collection); - BLI_assert(scene); - RNA_string_get(op->ptr, "child", childname); - Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, childname); + Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); + if (ELEM(NULL, ob, scene, collection)) { + return OPERATOR_CANCELLED; + } + BKE_collection_object_add(bmain, collection, ob); DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); @@ -745,16 +593,10 @@ void OUTLINER_OT_collection_drop(wmOperatorType *ot) /* api callbacks */ ot->invoke = collection_drop_invoke; - ot->exec = collection_drop_exec; - ot->poll = ED_operator_outliner_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - /* properties */ - RNA_def_string(ot->srna, "child", "Object", MAX_ID_NAME, "Child", "Child Object"); - RNA_def_string(ot->srna, "parent", "Collection", MAX_ID_NAME, "Parent", "Parent Collection"); } /* ********************* Outliner Drag Operator ******************** */ @@ -1107,9 +949,9 @@ void outliner_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Outliner", SPACE_OUTLINER, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, parent_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, parent_clear_copy); - WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, scene_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, material_drop_copy); - WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, collection_drop_copy); + WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", parent_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL); + WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL); } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 53272ee9ed9..469e1b84c29 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -493,10 +493,7 @@ static void text_drop_copy(wmDrag *drag, wmDropBox *drop) static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) - return true; - - return false; + return (drag->type == WM_DRAG_ID); } static void text_drop_paste(wmDrag *drag, wmDropBox *drop) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 62adca6af6b..68ea59859da 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -556,46 +556,27 @@ static void view3d_main_region_exit(wmWindowManager *wm, ARegion *ar) static bool view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_OB) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_OB) != NULL; } static bool view3d_collection_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_GR) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_GR) != NULL; } static bool view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_MA) - return 1; - } - return 0; + return WM_drag_ID(drag, ID_MA) != NULL; } static bool view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_ID) { - ID *id = drag->poin; - if (GS(id->name) == ID_IM) - return 1; + if (drag->type == WM_DRAG_PATH) { + return (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)); /* rule might not work? */ } - else if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */ - return 1; + else { + return WM_drag_ID(drag, ID_IM) != NULL; } - return 0; } static bool view3d_ima_bg_is_camera_view(bContext *C) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 3521c4d1bd5..d175b11fe5c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -484,6 +484,9 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx void WM_drag_free(struct wmDrag *drag); void WM_drag_free_list(struct ListBase *lb); +struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode); +struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode); + struct wmDropBox *WM_dropbox_add( ListBase *lb, const char *idname, bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 0ae51cc922b..6b9a7fb5430 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -189,6 +189,27 @@ void WM_drag_free_list(struct ListBase *lb) } } + +ID *WM_drag_ID(const wmDrag *drag, short idcode) +{ + if (drag->type != WM_DRAG_ID) { + return NULL; + } + + ID *id = drag->poin; + return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; +} + +ID *WM_drag_ID_from_event(const wmEvent *event, short idcode) +{ + if (event->custom != EVT_DATA_DRAGDROP) { + return NULL; + } + + ListBase *lb = event->customdata; + return WM_drag_ID(lb->first, idcode); +} + static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, const wmEvent *event) { wmEventHandler *handler = handlers->first; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 5d343c5e0fe..0581d41ea04 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -98,7 +98,7 @@ static void wm_notifier_clear(wmNotifier *note); static void update_tablet_data(wmWindow *win, wmEvent *event); static int wm_operator_call_internal(bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only); + const short context, const bool poll_only, wmEvent *event); /* ************ event management ************** */ @@ -638,7 +638,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot) /* sets up the new context and calls 'wm_operator_invoke()' with poll_only */ bool WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context) { - return wm_operator_call_internal(C, ot, NULL, NULL, context, true); + return wm_operator_call_internal(C, ot, NULL, NULL, context, true, NULL); } bool WM_operator_check_ui_empty(wmOperatorType *ot) @@ -1431,10 +1431,8 @@ static int wm_operator_invoke( */ static int wm_operator_call_internal( bContext *C, wmOperatorType *ot, PointerRNA *properties, ReportList *reports, - const short context, const bool poll_only) + const short context, const bool poll_only, wmEvent *event) { - wmEvent *event; - int retval; CTX_wm_operator_poll_msg_set(C, NULL); @@ -1443,27 +1441,29 @@ static int wm_operator_call_internal( if (ot) { wmWindow *window = CTX_wm_window(C); - switch (context) { - case WM_OP_INVOKE_DEFAULT: - case WM_OP_INVOKE_REGION_WIN: - case WM_OP_INVOKE_REGION_PREVIEW: - case WM_OP_INVOKE_REGION_CHANNELS: - case WM_OP_INVOKE_AREA: - case WM_OP_INVOKE_SCREEN: - /* window is needed for invoke, cancel operator */ - if (window == NULL) { - if (poll_only) { - CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + if (event == NULL) { + switch (context) { + case WM_OP_INVOKE_DEFAULT: + case WM_OP_INVOKE_REGION_WIN: + case WM_OP_INVOKE_REGION_PREVIEW: + case WM_OP_INVOKE_REGION_CHANNELS: + case WM_OP_INVOKE_AREA: + case WM_OP_INVOKE_SCREEN: + /* window is needed for invoke, cancel operator */ + if (window == NULL) { + if (poll_only) { + CTX_wm_operator_poll_msg_set(C, "Missing 'window' in context"); + } + return 0; } - return 0; - } - else { - event = window->eventstate; - } - break; - default: - event = NULL; - break; + else { + event = window->eventstate; + } + break; + default: + event = NULL; + break; + } } switch (context) { @@ -1561,7 +1561,7 @@ static int wm_operator_call_internal( int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties) { BLI_assert(ot == WM_operatortype_find(ot->idname, true)); - return wm_operator_call_internal(C, ot, properties, NULL, context, false); + return wm_operator_call_internal(C, ot, properties, NULL, context, false, NULL); } int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties) { @@ -1627,7 +1627,7 @@ int WM_operator_call_py( wmWindowManager *wm = CTX_wm_manager(C); if (!is_undo && wm) wm->op_undo_depth++; - retval = wm_operator_call_internal(C, ot, properties, reports, context, false); + retval = wm_operator_call_internal(C, ot, properties, reports, context, false, NULL); if (!is_undo && wm && (wm == CTX_wm_manager(C))) wm->op_undo_depth--; @@ -2370,17 +2370,26 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers for (drag = lb->first; drag; drag = drag->next) { const char *tooltip = NULL; if (drop->poll(C, drag, event, &tooltip)) { - drop->copy(drag, drop); + /* Optionally copy drag information to operator properties. */ + if (drop->copy) { + drop->copy(drag, drop); + } - /* free the drags before calling operator */ + /* Pass single matched wmDrag onto the operator. */ + BLI_remlink(lb, drag); + ListBase single_lb = {drag, drag}; + event->customdata = &single_lb; + + wm_operator_call_internal(C, drop->ot, drop->ptr, NULL, drop->opcontext, false, event); + action |= WM_HANDLER_BREAK; + + /* free the drags */ WM_drag_free_list(lb); + WM_drag_free_list(&single_lb); event->customdata = NULL; event->custom = 0; - WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr); - action |= WM_HANDLER_BREAK; - /* XXX fileread case */ if (CTX_wm_window(C) == NULL) return action; -- cgit v1.2.3 From 4375e7ff0b74f96447e27f78a0d9245353d36865 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 5 Aug 2018 12:14:55 +0200 Subject: WM: internal changes to support dragging multiple IDs. To be used by the outliner. --- source/blender/editors/space_node/space_node.c | 4 +- source/blender/editors/space_text/space_text.c | 2 +- source/blender/editors/space_view3d/space_view3d.c | 8 +- source/blender/windowmanager/WM_api.h | 8 +- source/blender/windowmanager/WM_types.h | 9 ++ source/blender/windowmanager/intern/wm_dragdrop.c | 95 ++++++++++++++++------ 6 files changed, 92 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 2b2e659d151..51ba3a62d1b 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -692,14 +692,14 @@ static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); RNA_string_set(drop->ptr, "name", id->name + 2); } static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 469e1b84c29..f3c55aa3474 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -499,7 +499,7 @@ static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEven static void text_drop_paste(wmDrag *drag, wmDropBox *drop) { char *text; - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); /* copy drag path to properties */ text = RNA_path_full_ID_py(id); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 68ea59859da..98c5c4e604d 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -632,14 +632,14 @@ static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent * static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, ID_OB); RNA_string_set(drop->ptr, "name", id->name + 2); } static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, ID_GR); drop->opcontext = WM_OP_EXEC_DEFAULT; RNA_string_set(drop->ptr, "name", id->name + 2); @@ -647,14 +647,14 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop) static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); RNA_string_set(drop->ptr, "name", id->name + 2); } static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { - ID *id = drag->poin; + ID *id = WM_drag_ID(drag, 0); if (id) { RNA_string_set(drop->ptr, "name", id->name + 2); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index d175b11fe5c..b15ce2d11ad 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -484,15 +484,17 @@ void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx void WM_drag_free(struct wmDrag *drag); void WM_drag_free_list(struct ListBase *lb); -struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode); -struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode); - struct wmDropBox *WM_dropbox_add( ListBase *lb, const char *idname, bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **), void (*copy)(struct wmDrag *, struct wmDropBox *)); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); + /* ID drag and drop */ +void WM_drag_add_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent); +struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode); +struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode); + /* Set OpenGL viewport and scissor */ void wmViewport(const struct rcti *rect); void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 809588b1a36..4882741680a 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -111,6 +111,7 @@ struct wmEvent; struct wmWindowManager; struct wmMsgBus; struct wmOperator; +struct ID; struct ImBuf; #include "RNA_types.h" @@ -660,6 +661,12 @@ typedef enum wmDragFlags { /* note: structs need not exported? */ +typedef struct wmDragID { + struct wmDragID *next, *prev; + struct ID *id; + struct ID *from_parent; +} wmDragID; + typedef struct wmDrag { struct wmDrag *next, *prev; @@ -674,6 +681,8 @@ typedef struct wmDrag { char opname[200]; /* if set, draws operator name*/ unsigned int flags; + + ListBase ids; /* List of wmDragIDs, all are guaranteed to have the same ID type. */ } wmDrag; /* dropboxes are like keymaps, part of the screen/area/region definition */ diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 6b9a7fb5430..0c77ad89292 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -45,6 +45,7 @@ #include "BIF_glutil.h" #include "BKE_context.h" +#include "BKE_idcode.h" #include "GPU_shader.h" @@ -155,10 +156,17 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, drag->flags = flags; drag->icon = icon; drag->type = type; - if (type == WM_DRAG_PATH) + if (type == WM_DRAG_PATH) { BLI_strncpy(drag->path, poin, FILE_MAX); - else + } + else if (type == WM_DRAG_ID) { + if (poin) { + WM_drag_add_ID(drag, poin, NULL); + } + } + else { drag->poin = poin; + } drag->value = value; return drag; @@ -178,6 +186,7 @@ void WM_drag_free(wmDrag *drag) MEM_freeN(drag->poin); } + BLI_freelistN(&drag->ids); MEM_freeN(drag); } @@ -190,26 +199,6 @@ void WM_drag_free_list(struct ListBase *lb) } -ID *WM_drag_ID(const wmDrag *drag, short idcode) -{ - if (drag->type != WM_DRAG_ID) { - return NULL; - } - - ID *id = drag->poin; - return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; -} - -ID *WM_drag_ID_from_event(const wmEvent *event, short idcode) -{ - if (event->custom != EVT_DATA_DRAGDROP) { - return NULL; - } - - ListBase *lb = event->customdata; - return WM_drag_ID(lb->first, idcode); -} - static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, const wmEvent *event) { wmEventHandler *handler = handlers->first; @@ -290,6 +279,57 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event) } } +/* ************** IDs ***************** */ + +void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent) +{ + /* Don't drag the same ID twice. */ + for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) { + if (drag_id->id == id) { + if (drag_id->from_parent == NULL) { + drag_id->from_parent = from_parent; + } + return; + } + else if (GS(drag_id->id->name) != GS(id->name)) { + BLI_assert(!"All dragged IDs must have the same type"); + return; + } + } + + /* Add to list. */ + wmDragID *drag_id = MEM_callocN(sizeof(wmDragID), __func__); + drag_id->id = id; + drag_id->from_parent = from_parent; + BLI_addtail(&drag->ids, drag_id); +} + +ID *WM_drag_ID(const wmDrag *drag, short idcode) +{ + if (drag->type != WM_DRAG_ID) { + return NULL; + } + + wmDragID *drag_id = drag->ids.first; + if (!drag_id) { + return NULL; + } + + ID *id = drag_id->id; + return (idcode == 0 || GS(id->name) == idcode) ? id : NULL; + +} + +ID *WM_drag_ID_from_event(const wmEvent *event, short idcode) +{ + if (event->custom != EVT_DATA_DRAGDROP) { + return NULL; + } + + ListBase *lb = event->customdata; + return WM_drag_ID(lb->first, idcode); +} + /* ************** draw ***************** */ static void wm_drop_operator_draw(const char *name, int x, int y) @@ -306,8 +346,15 @@ static const char *wm_drag_name(wmDrag *drag) switch (drag->type) { case WM_DRAG_ID: { - ID *id = drag->poin; - return id->name + 2; + ID *id = WM_drag_ID(drag, 0); + bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1); + + if (single) { + return id->name + 2; + } + else { + return BKE_idcode_to_name_plural(GS(id->name)); + } } case WM_DRAG_PATH: case WM_DRAG_NAME: -- cgit v1.2.3 From d7b5e2fa72c91b603713b52eec22af9ae131926d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 10 Aug 2018 17:04:05 +0200 Subject: Outliner: use generic WM drag and drop system for collections. * Drag and drop between multiple outliners now works. * Dragging the icon and text now give the same results. * Fixes various crashes. --- .../editors/space_outliner/outliner_collections.c | 18 + .../editors/space_outliner/outliner_dragdrop.c | 625 ++++++++++----------- .../blender/editors/space_outliner/outliner_draw.c | 118 ++-- .../blender/editors/space_outliner/outliner_edit.c | 8 +- .../editors/space_outliner/outliner_intern.h | 34 +- .../blender/editors/space_outliner/outliner_ops.c | 32 -- .../blender/editors/space_outliner/outliner_tree.c | 177 ------ source/blender/makesdna/DNA_outliner_types.h | 4 + source/blender/windowmanager/intern/wm_dragdrop.c | 3 +- 9 files changed, 385 insertions(+), 634 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 946d2b019a9..d4c85ce28bd 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -99,6 +99,24 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) return NULL; } +TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) +{ + struct ObjectsSelectedData *data = customdata; + TreeStoreElem *tselem = TREESTORE(te); + + if (outliner_is_collection_tree_element(te)) { + return TRAVERSE_CONTINUE; + } + + if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) { + return TRAVERSE_SKIP_CHILDS; + } + + BLI_addtail(&data->objects_selected_array, BLI_genericNodeN(te)); + + return TRAVERSE_CONTINUE; +} + /* -------------------------------------------------------------------- */ /* Poll functions. */ diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c index f9a4fda0c45..55b9a561503 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.c +++ b/source/blender/editors/space_outliner/outliner_dragdrop.c @@ -129,6 +129,101 @@ static ID *outliner_ID_drop_find(bContext *C, const wmEvent *event, short idcode } } +/* Find tree element to drop into, with additional before and after reorder support. */ +static TreeElement *outliner_drop_insert_find( + bContext *C, const wmEvent *event, + TreeElementInsertType *r_insert_type) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + TreeElement *te_hovered; + float view_mval[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]); + te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]); + + if (te_hovered) { + /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */ + const float margin = UI_UNIT_Y * (1.0f / 4); + + if (view_mval[1] < (te_hovered->ys + margin)) { + if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) { + /* inserting after a open item means we insert into it, but as first child */ + if (BLI_listbase_is_empty(&te_hovered->subtree)) { + *r_insert_type = TE_INSERT_INTO; + return te_hovered; + } + else { + *r_insert_type = TE_INSERT_BEFORE; + return te_hovered->subtree.first; + } + } + else { + *r_insert_type = TE_INSERT_AFTER; + return te_hovered; + } + } + else if (view_mval[1] > (te_hovered->ys + (3 * margin))) { + *r_insert_type = TE_INSERT_BEFORE; + return te_hovered; + } + else { + *r_insert_type = TE_INSERT_INTO; + return te_hovered; + } + } + else { + /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */ + TreeElement *first = soops->tree.first; + TreeElement *last = soops->tree.last; + + if (view_mval[1] < last->ys) { + *r_insert_type = TE_INSERT_AFTER; + return last; + } + else if (view_mval[1] > (first->ys + UI_UNIT_Y)) { + *r_insert_type = TE_INSERT_BEFORE; + return first; + } + else { + BLI_assert(0); + return NULL; + } + } +} + +static TreeElement *outliner_drop_insert_collection_find( + bContext *C, const wmEvent *event, + TreeElementInsertType *r_insert_type) +{ + TreeElement *te = outliner_drop_insert_find(C, event, r_insert_type); + if (!te) { + return NULL; + } + + Collection *collection = outliner_collection_from_tree_element(te); + if (!collection) { + return NULL; + } + + /* We can't insert/before after master collection. */ + if (collection->flag & COLLECTION_IS_MASTER) { + if (*r_insert_type == TE_INSERT_BEFORE) { + /* can't go higher than master collection, insert into it */ + *r_insert_type = TE_INSERT_INTO; + } + else if (*r_insert_type == TE_INSERT_AFTER) { + te = te->subtree.last; + collection = outliner_collection_from_tree_element(te); + if (!collection) { + return NULL; + } + } + } + + return te; +} + /* ******************** Parent Drop Operator *********************** */ static bool parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) @@ -542,404 +637,306 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot) /* ******************** Collection Drop Operator *********************** */ -static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **UNUSED(tooltip)) -{ - Object *ob = (Object *)WM_drag_ID(drag, ID_OB); - Collection *collection = (Collection *)WM_drag_ID(drag, ID_GR); +typedef struct CollectionDrop { + Collection *from; + Collection *to; - if (ob || collection) { - TreeElement *te = outliner_drop_find(C, event); - return (te && outliner_is_collection_tree_element(te)); - } - else { - return false; - } -} + TreeElement *te; + TreeElementInsertType insert_type; +} CollectionDrop; -static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static Collection *collection_parent_from_ID(ID *id) { - Main *bmain = CTX_data_main(C); - TreeElement *te = outliner_drop_find(C, event); - - if (!te || !outliner_is_collection_tree_element(te)) { - return OPERATOR_CANCELLED; + /* Can't change linked parent collections. */ + if (!id || ID_IS_LINKED(id)) { + return NULL; } - Collection *collection = outliner_collection_from_tree_element(te); - - // TODO: don't use scene, makes no sense anymore - // TODO: move rather than link, change hover text - Scene *scene = BKE_scene_find_from_collection(bmain, collection); - Object *ob = (Object *)WM_drag_ID_from_event(event, ID_OB); - if (ELEM(NULL, ob, scene, collection)) { - return OPERATOR_CANCELLED; + /* Also support dropping into/from scene collection. */ + if (GS(id->name) == ID_SCE) { + return ((Scene *)id)->master_collection; + } + else if (GS(id->name) == ID_GR) { + return (Collection *)id; } - BKE_collection_object_add(bmain, collection, ob); - - DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE); - DEG_relations_tag_update(bmain); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); - - return OPERATOR_FINISHED; + return NULL; } -void OUTLINER_OT_collection_drop(wmOperatorType *ot) +static bool collection_drop_init(bContext *C, wmDrag *drag, const wmEvent *event, CollectionDrop *data) { - /* identifiers */ - ot->name = "Link to Collection"; // TODO: rename to move? - ot->description = "Drag to move to collection in Outliner"; - ot->idname = "OUTLINER_OT_collection_drop"; - - /* api callbacks */ - ot->invoke = collection_drop_invoke; - ot->poll = ED_operator_outliner_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; -} + /* Get collection to drop into. */ + TreeElementInsertType insert_type; + TreeElement *te = outliner_drop_insert_collection_find(C, event, &insert_type); + if (!te) { + return false; + } -/* ********************* Outliner Drag Operator ******************** */ + Collection *to_collection = outliner_collection_from_tree_element(te); + if (ID_IS_LINKED(to_collection)) { + return false; + } -typedef struct OutlinerDragDropTooltip { - TreeElement *te; - void *handle; -} OutlinerDragDropTooltip; + /* Get drag datablocks. */ + if (drag->type != WM_DRAG_ID) { + return false; + } -static bool outliner_item_drag_drop_poll(bContext *C) -{ - SpaceOops *soops = CTX_wm_space_outliner(C); - return ED_operator_outliner_active(C) && - /* Only collection display modes supported for now. Others need more design work */ - ELEM(soops->outlinevis, SO_VIEW_LAYER, SO_LIBRARIES); -} + wmDragID *drag_id = drag->ids.first; + if (drag_id == NULL) { + return false; + } -static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) -{ - /* note: using EVT_TWEAK_ events to trigger dragging is fine, - * it sends coordinates from where dragging was started */ - const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]); - return outliner_find_item_at_y(soops, &soops->tree, my); -} + ID *id = drag_id->id; + if (!(id && ELEM(GS(id->name), ID_GR, ID_OB))) { + return false; + } -static void outliner_item_drag_end(wmWindow *win, OutlinerDragDropTooltip *data) -{ - MEM_SAFE_FREE(data->te->drag_data); + /* Get collection to drag out of. */ + ID *parent = drag_id->from_parent; + Collection *from_collection = collection_parent_from_ID(parent); + if (event->ctrl) { + from_collection = NULL; + } - if (data->handle) { - WM_draw_cb_exit(win, data->handle); + /* Get collections. */ + if (GS(id->name) == ID_GR) { + if (id == &to_collection->id) { + return false; + } + } + else { + insert_type = TE_INSERT_INTO; } - MEM_SAFE_FREE(data); + data->from = from_collection; + data->to = to_collection; + data->te = te; + data->insert_type = insert_type; + + return true; } -static void outliner_item_drag_get_insert_data( - const SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged, - TreeElement **r_te_insert_handle, TreeElementInsertType *r_insert_type) +static bool collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event, const char **tooltip) { - TreeElement *te_hovered; - float view_mval[2]; - - UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]); - te_hovered = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]); - - if (te_hovered) { - /* mouse hovers an element (ignoring x-axis), now find out how to insert the dragged item exactly */ + SpaceOops *soops = CTX_wm_space_outliner(C); + ARegion *ar = CTX_wm_region(C); + bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false); - if (te_hovered == te_dragged) { - *r_te_insert_handle = te_dragged; + CollectionDrop data; + if (collection_drop_init(C, drag, event, &data)) { + if (!data.from || event->ctrl) { + *tooltip = IFACE_("Link inside Collection"); } - else if (te_hovered != te_dragged) { - const float margin = UI_UNIT_Y * (1.0f / 4); - - *r_te_insert_handle = te_hovered; - if (view_mval[1] < (te_hovered->ys + margin)) { - if (TSELEM_OPEN(TREESTORE(te_hovered), soops)) { - /* inserting after a open item means we insert into it, but as first child */ - if (BLI_listbase_is_empty(&te_hovered->subtree)) { - *r_insert_type = TE_INSERT_INTO; + else { + TreeElement *te = data.te; + TreeStoreElem *tselem = TREESTORE(te); + + switch (data.insert_type) { + case TE_INSERT_BEFORE: + tselem->flag |= TSE_DRAG_BEFORE; + changed = true; + if (te->prev && outliner_is_collection_tree_element(te->prev)) { + *tooltip = TIP_("Move between collections"); } else { - *r_insert_type = TE_INSERT_BEFORE; - *r_te_insert_handle = te_hovered->subtree.first; + *tooltip = TIP_("Move before collection"); } - } - else { - *r_insert_type = TE_INSERT_AFTER; - } - } - else if (view_mval[1] > (te_hovered->ys + (3 * margin))) { - *r_insert_type = TE_INSERT_BEFORE; - } - else { - *r_insert_type = TE_INSERT_INTO; + break; + case TE_INSERT_AFTER: + tselem->flag |= TSE_DRAG_AFTER; + changed = true; + if (te->next && outliner_is_collection_tree_element(te->next)) { + *tooltip = TIP_("Move between collections"); + } + else { + *tooltip = TIP_("Move after collection"); + } + break; + case TE_INSERT_INTO: + tselem->flag |= TSE_DRAG_INTO; + changed = true; + *tooltip = TIP_("Move inside collection (Ctrl to link)"); + break; } } } - else { - /* mouse doesn't hover any item (ignoring x-axis), so it's either above list bounds or below. */ - TreeElement *first = soops->tree.first; - TreeElement *last = soops->tree.last; - - if (view_mval[1] < last->ys) { - *r_te_insert_handle = last; - *r_insert_type = TE_INSERT_AFTER; - } - else if (view_mval[1] > (first->ys + UI_UNIT_Y)) { - *r_te_insert_handle = first; - *r_insert_type = TE_INSERT_BEFORE; - } - else { - BLI_assert(0); - } + if (changed) { + ED_region_tag_redraw_no_rebuild(ar); } + + return true; } -static void outliner_item_drag_handle( - SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged) +static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - TreeElement *te_insert_handle; - TreeElementInsertType insert_type; - - outliner_item_drag_get_insert_data(soops, ar, event, te_dragged, &te_insert_handle, &insert_type); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); - if (!te_dragged->reinsert_poll && - /* there is no reinsert_poll, so we do some generic checks (same types and reinsert callback is available) */ - (TREESTORE(te_dragged)->type == TREESTORE(te_insert_handle)->type) && - te_dragged->reinsert) - { - /* pass */ - } - else if (te_dragged == te_insert_handle) { - /* nothing will happen anyway, no need to do poll check */ - } - else if (!te_dragged->reinsert_poll || - !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type)) - { - te_insert_handle = NULL; + if (event->custom != EVT_DATA_DRAGDROP) { + return OPERATOR_CANCELLED; } - te_dragged->drag_data->insert_type = insert_type; - te_dragged->drag_data->insert_handle = te_insert_handle; -} -/** - * Returns true if it is a collection and empty. - */ -static bool is_empty_collection(TreeElement *te) -{ - Collection *collection = outliner_collection_from_tree_element(te); + ListBase *lb = event->customdata; + wmDrag *drag = lb->first; - if (!collection) { - return false; + CollectionDrop data; + if (!collection_drop_init(C, drag, event, &data)) { + return OPERATOR_CANCELLED; } - return BLI_listbase_is_empty(&collection->gobject) && - BLI_listbase_is_empty(&collection->children); -} - -static bool outliner_item_drag_drop_apply( - Main *bmain, - Scene *scene, - SpaceOops *soops, - OutlinerDragDropTooltip *data, - const wmEvent *event) -{ - TreeElement *dragged_te = data->te; - TreeElement *insert_handle = dragged_te->drag_data->insert_handle; - TreeElementInsertType insert_type = dragged_te->drag_data->insert_type; + /* Before/after insert handling. */ + Collection *relative = NULL; + bool relative_after = false; - if ((insert_handle == dragged_te) || !insert_handle) { - /* No need to do anything */ - } - else if (dragged_te->reinsert) { - BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle, - &insert_type)); - /* call of assert above should not have changed insert_handle and insert_type at this point */ - BLI_assert(dragged_te->drag_data->insert_handle == insert_handle && - dragged_te->drag_data->insert_type == insert_type); + if (ELEM(data.insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) { + SpaceOops *soops = CTX_wm_space_outliner(C); - /* If the collection was just created and you moved objects/collections inside it, - * it is strange to have it closed and we not see the newly dragged elements. */ - const bool should_open_collection = (insert_type == TE_INSERT_INTO) && is_empty_collection(insert_handle); + relative = data.to; + relative_after = (data.insert_type == TE_INSERT_AFTER); - dragged_te->reinsert(bmain, scene, soops, dragged_te, insert_handle, insert_type, event); + TreeElement *parent_te = outliner_find_parent_element(&soops->tree, NULL, data.te); + data.to = (parent_te) ? outliner_collection_from_tree_element(parent_te) : NULL; + } - if (should_open_collection && !is_empty_collection(insert_handle)) { - TREESTORE(insert_handle)->flag &= ~TSE_CLOSED; - } - return true; + if (!data.to) { + return OPERATOR_CANCELLED; } - return false; -} + for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) { + /* Ctrl enables linking, so we don't need a from collection then. */ + Collection *from = (event->ctrl) ? NULL : collection_parent_from_ID(drag_id->from_parent); -static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - ARegion *ar = CTX_wm_region(C); - SpaceOops *soops = CTX_wm_space_outliner(C); - OutlinerDragDropTooltip *data = op->customdata; - TreeElement *te_dragged = data->te; - int retval = OPERATOR_RUNNING_MODAL; - bool redraw = false; - bool skip_rebuild = true; - - switch (event->type) { - case EVT_MODAL_MAP: - if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) { - if (outliner_item_drag_drop_apply(bmain, scene, soops, data, event)) { - skip_rebuild = false; - } - retval = OPERATOR_FINISHED; - } - else if (event->val == OUTLINER_ITEM_DRAG_CANCEL) { - retval = OPERATOR_CANCELLED; + if (GS(drag_id->id->name) == ID_OB) { + /* Move/link object into collection. */ + Object *object = (Object *)drag_id->id; + + if (from) { + BKE_collection_object_move(bmain, scene, data.to, from, object); } else { - BLI_assert(0); + BKE_collection_object_add(bmain, data.to, object); } - WM_event_add_mousemove(C); /* update highlight */ - outliner_item_drag_end(CTX_wm_window(C), data); - redraw = true; - break; - case MOUSEMOVE: - outliner_item_drag_handle(soops, ar, event, te_dragged); - redraw = true; - break; - } - - if (redraw) { - if (skip_rebuild) { - ED_region_tag_redraw_no_rebuild(ar); - } - else { - ED_region_tag_redraw(ar); } - } - - return retval; -} - -static const char *outliner_drag_drop_tooltip_get( - const TreeElement *te_float) -{ - const char *name = NULL; + else if (GS(drag_id->id->name) == ID_GR) { + /* Move/link collection into collection. */ + Collection *collection = (Collection *)drag_id->id; - const TreeElement *te_insert = te_float->drag_data->insert_handle; - if (te_float && outliner_is_collection_tree_element(te_float)) { - if (te_insert == NULL) { - name = TIP_("Move collection"); - } - else { - switch (te_float->drag_data->insert_type) { - case TE_INSERT_BEFORE: - if (te_insert->prev && outliner_is_collection_tree_element(te_insert->prev)) { - name = TIP_("Move between collections"); - } - else { - name = TIP_("Move before collection"); - } - break; - case TE_INSERT_AFTER: - if (te_insert->next && outliner_is_collection_tree_element(te_insert->next)) { - name = TIP_("Move between collections"); - } - else { - name = TIP_("Move after collection"); - } - break; - case TE_INSERT_INTO: - name = TIP_("Move inside collection"); - break; + if (collection != from) { + BKE_collection_move(bmain, data.to, from, relative, relative_after, collection); } } - } - else if ((TREESTORE(te_float)->type == 0) && (te_float->idcode == ID_OB)) { - name = TIP_("Move to collection (Ctrl to link)"); + + if (from) { + DEG_id_tag_update(&from->id, DEG_TAG_COPY_ON_WRITE); + } } - return name; + /* Update dependency graph. */ + DEG_id_tag_update(&data.to->id, DEG_TAG_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); + + return OPERATOR_FINISHED; } -static void outliner_drag_drop_tooltip_cb(const wmWindow *win, void *vdata) +void OUTLINER_OT_collection_drop(wmOperatorType *ot) { - OutlinerDragDropTooltip *data = vdata; - const char *tooltip; - - int cursorx, cursory; - int x, y; - - tooltip = outliner_drag_drop_tooltip_get(data->te); - if (tooltip == NULL) { - return; - } - - cursorx = win->eventstate->x; - cursory = win->eventstate->y; + /* identifiers */ + ot->name = "Move to Collection"; + ot->description = "Drag to move to collection in Outliner"; + ot->idname = "OUTLINER_OT_collection_drop"; - x = cursorx + U.widget_unit; - y = cursory - U.widget_unit; + /* api callbacks */ + ot->invoke = collection_drop_invoke; + ot->poll = ED_operator_outliner_active; - /* Drawing. */ - const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; +} - const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f}; +/* ********************* Outliner Drag Operator ******************** */ - GPU_blend(true); - UI_fontstyle_draw_simple_backdrop(fstyle, x, y, tooltip, col_fg, col_bg); - GPU_blend(false); +static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event) +{ + /* note: using EVT_TWEAK_ events to trigger dragging is fine, + * it sends coordinates from where dragging was started */ + const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]); + return outliner_find_item_at_y(soops, &soops->tree, my); } -static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); - TreeElement *te_dragged = outliner_item_drag_element_find(soops, ar, event); + TreeElement *te = outliner_item_drag_element_find(soops, ar, event); - if (!te_dragged) { - return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + if (!te) { + return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); + } + + TreeElementIcon data = tree_element_get_icon(TREESTORE(te), te); + if (!data.drag_id) { + return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); } - OutlinerDragDropTooltip *data = MEM_mallocN(sizeof(OutlinerDragDropTooltip), __func__); - data->te = te_dragged; + wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP); - op->customdata = data; - te_dragged->drag_data = MEM_callocN(sizeof(*te_dragged->drag_data), __func__); - /* by default we don't change the item position */ - te_dragged->drag_data->insert_handle = te_dragged; - /* unset highlighted tree element, dragged one will be highlighted instead */ - outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false); + if (GS(data.drag_id->name) == ID_OB) { + /* For objects we cheat and drag all selected objects. */ + TREESTORE(te)->flag |= TSE_SELECTED; - ED_region_tag_redraw_no_rebuild(ar); + struct ObjectsSelectedData selected = { + .objects_selected_array = {NULL, NULL}, + }; - WM_event_add_modal_handler(C, op); + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &selected); + LISTBASE_FOREACH (LinkData *, link, &selected.objects_selected_array) { + TreeElement *ten_selected = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(ten_selected)->id; - data->handle = WM_draw_cb_activate(CTX_wm_window(C), outliner_drag_drop_tooltip_cb, data); + /* Find parent collection of object. */ + Collection *parent = NULL; - return OPERATOR_RUNNING_MODAL; + if (ten_selected->parent) { + for (TreeElement *te_ob_parent = ten_selected->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) { + if (outliner_is_collection_tree_element(te_ob_parent)) { + parent = outliner_collection_from_tree_element(te_ob_parent); + break; + } + } + } + else { + Scene *scene = CTX_data_scene(C); + parent = BKE_collection_master(scene); + } + + WM_drag_add_ID(drag, &ob->id, &parent->id); + } + + BLI_freelistN(&selected.objects_selected_array); + } + else { + /* Add single ID. */ + WM_drag_add_ID(drag, data.drag_id, data.drag_parent); + } + + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); } -/** - * Notes about Outliner Item Drag 'n Drop: - * Right now only collections display mode is supported. But ideally all/most modes would support this. There are - * just some open design questions that have to be answered: do we want to allow mixing order of different data types - * (like render-layers and objects)? Would that be a purely visual change or would that have any other effect? ... - */ +/* Outliner drag and drop. This operator mostly exists to support dragging + * from outliner text instead of only from the icon, and also to show a + * hint in the statusbar keymap. */ + void OUTLINER_OT_item_drag_drop(wmOperatorType *ot) { ot->name = "Drag and Drop"; ot->idname = "OUTLINER_OT_item_drag_drop"; - ot->description = "Change the hierarchical position of an item by repositioning it using drag and drop"; + ot->description = "Drag and drop element to another place"; ot->invoke = outliner_item_drag_drop_invoke; - ot->modal = outliner_item_drag_drop_modal; - - ot->poll = outliner_item_drag_drop_poll; - - ot->flag = OPTYPE_UNDO; + ot->poll = ED_operator_outliner_active; } /* *************************** Drop Boxes ************************** */ diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 5672351d62f..211c9e1a392 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -1356,13 +1356,10 @@ static void tselem_draw_icon( UI_icon_draw_alpha(x, y, data.icon, alpha); } else { - uiBut *but = uiDefIconBut( + uiDefIconBut( block, UI_BTYPE_LABEL, 0, data.icon, x, y, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, alpha, (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->name : ""); - - if (data.drag_id) - UI_but_drag_set_id(but, data.drag_id); } } @@ -1578,7 +1575,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta static void outliner_draw_tree_element( bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ViewLayer *view_layer, ARegion *ar, SpaceOops *soops, TreeElement *te, bool draw_grayed_out, - int startx, int *starty, TreeElement **te_edit, TreeElement **te_floating) + int startx, int *starty, TreeElement **te_edit) { TreeStoreElem *tselem; float ufac = UI_UNIT_X / 20.0f; @@ -1595,9 +1592,6 @@ static void outliner_draw_tree_element( if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) { *te_edit = te; } - if ((te->drag_data != NULL) && (*te_floating == NULL)) { - *te_floating = te; - } /* icons can be ui buts, we don't want it to overlap with restrict */ if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) @@ -1799,11 +1793,11 @@ static void outliner_draw_tree_element( for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) { /* check if element needs to be drawn grayed out, but also gray out * childs of a grayed out parent (pass on draw_grayed_out to childs) */ - bool draw_childs_grayed_out = draw_grayed_out || (ten->drag_data != NULL); + bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING); outliner_draw_tree_element( C, block, fstyle, scene, view_layer, ar, soops, ten, draw_childs_grayed_out, - startx + UI_UNIT_X, starty, te_edit, te_floating); + startx + UI_UNIT_X, starty, te_edit); } } else { @@ -1815,54 +1809,6 @@ static void outliner_draw_tree_element( } } -static void outliner_draw_tree_element_floating( - const ARegion *ar, const TreeElement *te_floating) -{ - const TreeElement *te_insert = te_floating->drag_data->insert_handle; - const int line_width = 2; - - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - int coord_y = te_insert->ys; - int coord_x = te_insert->xs; - float col[4]; - - if (te_insert == te_floating) { - /* don't draw anything */ - return; - } - - UI_GetThemeColorShade4fv(TH_BACK, -40, col); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); - - if (ELEM(te_floating->drag_data->insert_type, TE_INSERT_BEFORE, TE_INSERT_AFTER)) { - if (te_floating->drag_data->insert_type == TE_INSERT_BEFORE) { - coord_y += UI_UNIT_Y; - } - immUniformColor4fv(col); - GPU_line_width(line_width); - - immBegin(GPU_PRIM_LINE_STRIP, 2); - immVertex2f(pos, coord_x, coord_y); - immVertex2f(pos, ar->v2d.cur.xmax, coord_y); - immEnd(); - } - else { - BLI_assert(te_floating->drag_data->insert_type == TE_INSERT_INTO); - immUniformColor3fvAlpha(col, col[3] * 0.5f); - - immBegin(GPU_PRIM_TRI_STRIP, 4); - immVertex2f(pos, coord_x, coord_y + UI_UNIT_Y); - immVertex2f(pos, coord_x, coord_y); - immVertex2f(pos, ar->v2d.cur.xmax, coord_y + UI_UNIT_Y); - immVertex2f(pos, ar->v2d.cur.xmax, coord_y); - immEnd(); - } - - GPU_blend(false); - immUnbindProgram(); -} - static void outliner_draw_hierarchy_lines_recursive( unsigned pos, SpaceOops *soops, ListBase *lb, int startx, const unsigned char col[4], bool draw_grayed_out, @@ -1880,7 +1826,7 @@ static void outliner_draw_hierarchy_lines_recursive( /* For vertical lines between objects. */ y1 = y2 = *starty; for (te = lb->first; te; te = te->next) { - bool draw_childs_grayed_out = draw_grayed_out || (te->drag_data != NULL); + bool draw_childs_grayed_out = draw_grayed_out || (te->flag & TE_DRAGGING); TreeStoreElem *tselem = TREESTORE(te); if (draw_childs_grayed_out) { @@ -1997,18 +1943,42 @@ static void outliner_draw_highlights_recursive( immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1); } - /* search match highlights - * we don't expand items when searching in the datablocks but we - * still want to highlight any filter matches. */ - if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) { - immUniformColor4fv(col_searchmatch); - immRecti(pos, start_x, start_y + 1, ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1); - } + /* highlights */ + if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) { + const int end_x = (int)ar->v2d.cur.xmax; - /* mouse hover highlights */ - if ((tselem->flag & TSE_HIGHLIGHTED) || (te->drag_data != NULL)) { - immUniformColor4fv(col_highlight); - immRecti(pos, 0, start_y + 1, (int)ar->v2d.cur.xmax, start_y + UI_UNIT_Y - 1); + if (tselem->flag & TSE_DRAG_ANY) { + /* drag and drop highlight */ + float col[4]; + UI_GetThemeColorShade4fv(TH_BACK, -40, col); + + if (tselem->flag & TSE_DRAG_BEFORE) { + immUniformColor4fv(col); + immRecti(pos, start_x, start_y + UI_UNIT_Y - 1, end_x, start_y + UI_UNIT_Y + 1); + } + else if (tselem->flag & TSE_DRAG_AFTER) { + immUniformColor4fv(col); + immRecti(pos, start_x, start_y - 1, end_x, start_y + 1); + } + else { + immUniformColor3fvAlpha(col, col[3] * 0.5f); + immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1); + } + } + else { + if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) { + /* search match highlights + * we don't expand items when searching in the datablocks but we + * still want to highlight any filter matches. */ + immUniformColor4fv(col_searchmatch); + immRecti(pos, start_x, start_y + 1, end_x, start_y + UI_UNIT_Y - 1); + } + else if (tselem->flag & TSE_HIGHLIGHTED) { + /* mouse hover highlight */ + immUniformColor4fv(col_highlight); + immRecti(pos, 0, start_y + 1, end_x, start_y + UI_UNIT_Y - 1); + } + } } *io_start_y -= UI_UNIT_Y; @@ -2047,7 +2017,6 @@ static void outliner_draw_tree( TreeElement **te_edit) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; - TreeElement *te_floating = NULL; int starty, startx; GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // only once @@ -2085,11 +2054,8 @@ static void outliner_draw_tree( for (TreeElement *te = soops->tree.first; te; te = te->next) { outliner_draw_tree_element( C, block, fstyle, scene, view_layer, - ar, soops, te, te->drag_data != NULL, - startx, &starty, te_edit, &te_floating); - } - if (te_floating && te_floating->drag_data->insert_handle) { - outliner_draw_tree_element_floating(ar, te_floating); + ar, soops, te, (te->flag & TE_DRAGGING) != 0, + startx, &starty, te_edit); } if (has_restrict_icons) { diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 6316b65fefb..e895ff53bc5 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -95,6 +95,12 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { + /* Drag and drop does own highlighting. */ + wmWindowManager *wm = CTX_wm_manager(C); + if (wm->drags.first) { + return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH); + } + ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]); @@ -103,7 +109,7 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const bool changed = false; if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) { - changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false); + changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false); if (hovered_te) { hovered_te->store_elem->flag |= TSE_HIGHLIGHTED; changed = true; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index e5ed7de2a24..f8dc41b8d37 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -67,23 +67,6 @@ typedef enum TreeTraversalAction { TRAVERSE_SKIP_CHILDS, } TreeTraversalAction; -/** - * Callback type for reinserting elements at a different position, used to allow user customizable element order. - */ -typedef void (*TreeElementReinsertFunc)(struct Main *bmain, - struct Scene *scene, - struct SpaceOops *soops, - struct TreeElement *insert_element, - struct TreeElement *insert_handle, - TreeElementInsertType action, - const struct wmEvent *event); -/** - * Executed on (almost) each mouse move while dragging. It's supposed to give info - * if reinserting insert_element before/after/into insert_handle would be allowed. - * It's allowed to change the reinsert info here for non const pointers. - */ -typedef bool (*TreeElementReinsertPollFunc)(const struct TreeElement *insert_element, - struct TreeElement **io_insert_handle, TreeElementInsertType *io_action); typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata); @@ -99,17 +82,6 @@ typedef struct TreeElement { const char *name; void *directdata; // Armature Bones, Base, Sequence, Strip... PointerRNA rnaptr; // RNA Pointer - - /* callbacks - TODO should be moved into a type (like TreeElementType) */ - TreeElementReinsertFunc reinsert; - TreeElementReinsertPollFunc reinsert_poll; - - struct { - TreeElementInsertType insert_type; - /* the element before/after/into which we may insert the dragged one (NULL to insert at top) */ - struct TreeElement *insert_handle; - void *tooltip_draw_handle; - } *drag_data; } TreeElement; typedef struct TreeElementIcon { @@ -131,6 +103,7 @@ enum { TE_LAZY_CLOSED = (1 << 2), TE_FREE_NAME = (1 << 3), TE_DISABLED = (1 << 4), + TE_DRAGGING = (1 << 5), }; /* button events */ @@ -294,11 +267,6 @@ void item_object_mode_exit_cb( void outliner_set_coordinates(struct ARegion *ar, struct SpaceOops *soops); /* outliner_dragdrop.c */ -enum { - OUTLINER_ITEM_DRAG_CANCEL, - OUTLINER_ITEM_DRAG_CONFIRM, -}; - void outliner_dropboxes(void); void OUTLINER_OT_item_drag_drop(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index a4aad11a821..34d79ea5a61 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -117,36 +117,6 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear); } -static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) -{ - static EnumPropertyItem modal_items[] = { - {OUTLINER_ITEM_DRAG_CANCEL, "CANCEL", 0, "Cancel", ""}, - {OUTLINER_ITEM_DRAG_CONFIRM, "CONFIRM", 0, "Confirm/Drop", ""}, - {0, NULL, 0, NULL, NULL} - }; - const char *map_name = "Outliner Item Drag & Drop Modal Map"; - - wmKeyMap *keymap = WM_modalkeymap_get(keyconf, map_name); - - /* this function is called for each spacetype, only needs to add map once */ - if (keymap && keymap->modal_items) - return NULL; - - keymap = WM_modalkeymap_add(keyconf, map_name, modal_items); - - /* items for modal map */ - WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL); - WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, OUTLINER_ITEM_DRAG_CANCEL); - - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM); - WM_modalkeymap_add_item(keymap, RETKEY, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM); - WM_modalkeymap_add_item(keymap, PADENTER, KM_RELEASE, KM_ANY, 0, OUTLINER_ITEM_DRAG_CONFIRM); - - WM_modalkeymap_assign(keymap, "OUTLINER_OT_item_drag_drop"); - - return keymap; -} - void outliner_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap = WM_keymap_find(keyconf, "Outliner", SPACE_OUTLINER, 0); @@ -236,6 +206,4 @@ void outliner_keymap(wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "unselected", false); kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "unselected", true); - - outliner_item_drag_drop_modal_keymap(keyconf); } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 539df3aa085..55a437d6ad5 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -321,108 +321,9 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s } -TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) -{ - struct ObjectsSelectedData *data = customdata; - TreeStoreElem *tselem = TREESTORE(te); - - if (outliner_is_collection_tree_element(te)) { - return TRAVERSE_CONTINUE; - } - - if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) { - return TRAVERSE_SKIP_CHILDS; - } - - BLI_addtail(&data->objects_selected_array, BLI_genericNodeN(te)); - - return TRAVERSE_CONTINUE; -} - -/** - * Move objects from a collection to another. - * We ignore the original object being inserted, we used it for polling only. - * Instead we move all the selected objects around. - */ -static void outliner_object_reorder( - Main *bmain, Scene *scene, - SpaceOops *soops, - TreeElement *insert_element, - TreeElement *insert_handle, TreeElementInsertType action, - const wmEvent *event) -{ - Collection *collection = outliner_collection_from_tree_element(insert_handle); - Collection *collection_ob_parent = NULL; - ID *id = insert_handle->store_elem->id; - - BLI_assert(action == TE_INSERT_INTO); - UNUSED_VARS_NDEBUG(action); - - struct ObjectsSelectedData data = { - .objects_selected_array = {NULL, NULL}, - }; - - const bool is_append = event->ctrl; - - /* Make sure we include the originally inserted element as well. */ - TREESTORE(insert_element)->flag |= TSE_SELECTED; - - outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); - LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { - TreeElement *ten_selected = (TreeElement *)link->data; - Object *ob = (Object *)TREESTORE(ten_selected)->id; - - if (is_append) { - BKE_collection_object_add(bmain, collection, ob); - continue; - } - - /* Find parent collection of object. */ - if (ten_selected->parent) { - for (TreeElement *te_ob_parent = ten_selected->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) { - if (outliner_is_collection_tree_element(te_ob_parent)) { - collection_ob_parent = outliner_collection_from_tree_element(te_ob_parent); - break; - } - } - } - else { - collection_ob_parent = BKE_collection_master(scene); - } - - BKE_collection_object_move(bmain, scene, collection, collection_ob_parent, ob); - } - - BLI_freelistN(&data.objects_selected_array); - - DEG_relations_tag_update(bmain); - - /* TODO(sergey): Use proper flag for tagging here. */ - DEG_id_tag_update(id, 0); - - WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); -} - -static bool outliner_object_reorder_poll( - const TreeElement *insert_element, - TreeElement **io_insert_handle, TreeElementInsertType *io_action) -{ - if (outliner_is_collection_tree_element(*io_insert_handle) && - (insert_element->parent != *io_insert_handle)) - { - *io_action = TE_INSERT_INTO; - return true; - } - - return false; -} - // can be inlined if necessary static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob) { - te->reinsert = outliner_object_reorder; - te->reinsert_poll = outliner_object_reorder_poll; - if (outliner_animdata_test(ob->adt)) outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0); @@ -1385,80 +1286,6 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) } } -static void outliner_collections_reorder( - Main *bmain, - Scene *UNUSED(scene), - SpaceOops *soops, - TreeElement *insert_element, - TreeElement *insert_handle, - TreeElementInsertType action, - const wmEvent *UNUSED(event)) -{ - TreeElement *from_parent_te, *to_parent_te; - Collection *from_parent, *to_parent; - - Collection *collection = outliner_collection_from_tree_element(insert_element); - Collection *relative = NULL; - bool relative_after = false; - - from_parent_te = outliner_find_parent_element(&soops->tree, NULL, insert_element); - from_parent = (from_parent_te) ? outliner_collection_from_tree_element(from_parent_te) : NULL; - - if (ELEM(action, TE_INSERT_BEFORE, TE_INSERT_AFTER)) { - to_parent_te = outliner_find_parent_element(&soops->tree, NULL, insert_handle); - to_parent = (to_parent_te) ? outliner_collection_from_tree_element(to_parent_te) : NULL; - - relative = outliner_collection_from_tree_element(insert_handle); - relative_after = (action == TE_INSERT_AFTER); - } - else if (action == TE_INSERT_INTO) { - to_parent = outliner_collection_from_tree_element(insert_handle); - } - else { - BLI_assert(0); - return; - } - - if (!to_parent) { - return; - } - - BKE_collection_move(bmain, to_parent, from_parent, relative, relative_after, collection); - - DEG_relations_tag_update(bmain); -} - -static bool outliner_collections_reorder_poll( - const TreeElement *insert_element, - TreeElement **io_insert_handle, - TreeElementInsertType *io_action) -{ - /* Can't move master collection. */ - Collection *collection = outliner_collection_from_tree_element(insert_element); - if (collection->flag & COLLECTION_IS_MASTER) { - return false; - } - - /* Can only move into collections. */ - Collection *collection_handle = outliner_collection_from_tree_element(*io_insert_handle); - if (collection_handle == NULL) { - return false; - } - - /* We can't insert/before after master collection. */ - if (collection_handle->flag & COLLECTION_IS_MASTER) { - if (*io_action == TE_INSERT_BEFORE) { - /* can't go higher than master collection, insert into it */ - *io_action = TE_INSERT_INTO; - } - else if (*io_action == TE_INSERT_AFTER) { - *io_insert_handle = (*io_insert_handle)->subtree.last; - } - } - - return true; -} - static void outliner_add_layer_collection_objects( SpaceOops *soops, ListBase *tree, ViewLayer *layer, LayerCollection *lc, TreeElement *ten) @@ -1485,8 +1312,6 @@ static void outliner_add_layer_collections_recursive( ten->name = id->name + 2; ten->directdata = lc; - ten->reinsert = outliner_collections_reorder; - ten->reinsert_poll = outliner_collections_reorder_poll; const bool exclude = (lc->flag & LAYER_COLLECTION_EXCLUDE) != 0; if (exclude || @@ -1528,8 +1353,6 @@ BLI_INLINE void outliner_add_collection_init(TreeElement *te, Collection *collec } te->directdata = collection; - te->reinsert = outliner_collections_reorder; - te->reinsert_poll = outliner_collections_reorder_poll; } BLI_INLINE void outliner_add_collection_objects( diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h index 449f71905f0..75d0ce493f5 100644 --- a/source/blender/makesdna/DNA_outliner_types.h +++ b/source/blender/makesdna/DNA_outliner_types.h @@ -60,6 +60,10 @@ enum { TSE_CHILDSEARCH = (1 << 3), TSE_SEARCHMATCH = (1 << 4), TSE_HIGHLIGHTED = (1 << 5), + TSE_DRAG_INTO = (1 << 6), + TSE_DRAG_BEFORE = (1 << 7), + TSE_DRAG_AFTER = (1 << 8), + TSE_DRAG_ANY = (TSE_DRAG_INTO | TSE_DRAG_BEFORE | TSE_DRAG_AFTER), }; /* TreeStoreElem->types */ diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 0c77ad89292..73748ba6322 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -352,9 +352,10 @@ static const char *wm_drag_name(wmDrag *drag) if (single) { return id->name + 2; } - else { + else if (id) { return BKE_idcode_to_name_plural(GS(id->name)); } + break; } case WM_DRAG_PATH: case WM_DRAG_NAME: -- cgit v1.2.3 From 7daf62950bb5b85dc6acb459800c854692838631 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Fri, 10 Aug 2018 10:35:42 -0600 Subject: build_environment: python 3.7.0 + numpy 1.15.0 --- build_files/build_environment/cmake/boost.cmake | 6 ---- build_files/build_environment/cmake/harvest.cmake | 6 ---- build_files/build_environment/cmake/numpy.cmake | 8 ++++- build_files/build_environment/cmake/python.cmake | 39 +++++++++++----------- build_files/build_environment/cmake/versions.cmake | 16 ++++----- build_files/build_environment/patches/numpy.diff | 23 ------------- 6 files changed, 34 insertions(+), 64 deletions(-) delete mode 100644 build_files/build_environment/patches/numpy.diff diff --git a/build_files/build_environment/cmake/boost.cmake b/build_files/build_environment/cmake/boost.cmake index 363b552f901..9be6ea9f011 100644 --- a/build_files/build_environment/cmake/boost.cmake +++ b/build_files/build_environment/cmake/boost.cmake @@ -26,15 +26,9 @@ if(WIN32) set(PYTHON_ARCH2 win32) set(PYTHON_OUTPUTDIR ${BUILD_DIR}/python/src/external_python/pcbuild/win32/) endif() - if(MSVC12) - set(BOOST_TOOLSET toolset=msvc-12.0) - set(BOOST_COMPILER_STRING -vc120) - set(PYTHON_COMPILER_STRING v120) - endif() if(MSVC14) set(BOOST_TOOLSET toolset=msvc-14.0) set(BOOST_COMPILER_STRING -vc140) - set(PYTHON_COMPILER_STRING v140) endif() set(JAM_FILE ${BUILD_DIR}/boost/src/external_boost/user-config.jam) set(semi_path "${PATCH_DIR}/semi.txt") diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 7395490e107..4bbe01974f6 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -96,17 +96,11 @@ if(BUILD_MODE STREQUAL Release) ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencollada/ ${HARVEST_TARGET}/opencollada/ && # opensubdiv ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opensubdiv ${HARVEST_TARGET}/opensubdiv && - # python - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/python/ ${HARVEST_TARGET}/python/ && # alembic ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/alembic ${HARVEST_TARGET}/alembic && # BlendThumb ${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb64/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb64.dll && ${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb32/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb.dll && - # python - ${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz && - # numpy - ${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz && # hidapi ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hidapi/ ${HARVEST_TARGET}/hidapi/ && # webp, straight up copy diff --git a/build_files/build_environment/cmake/numpy.cmake b/build_files/build_environment/cmake/numpy.cmake index 0d5d8abf7ab..fa8d9ebccba 100644 --- a/build_files/build_environment/cmake/numpy.cmake +++ b/build_files/build_environment/cmake/numpy.cmake @@ -36,7 +36,6 @@ if(WIN32) ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-${PYTHON_SHORT_VERSION}${NUMPY_DIR_POSTFIX}" ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}${NUMPY_ARCHIVE_POSTFIX}.tar.gz" "." ) - set(NUMPY_PATCH ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff ) else() set(NUMPY_INSTALL echo .) set(NUMPY_PATCH echo .) @@ -54,6 +53,13 @@ ExternalProject_Add(external_numpy INSTALL_COMMAND ${NUMPY_INSTALL} ) +if(WIN32) + ExternalProject_Add_Step(external_numpy after_install + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz + DEPENDEES install + ) +endif() + add_dependencies( external_numpy Make_Python_Environment diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake index 693ab1896ba..6b3c25d32bf 100644 --- a/build_files/build_environment/cmake/python.cmake +++ b/build_files/build_environment/cmake/python.cmake @@ -46,13 +46,12 @@ if(WIN32) PREFIX ${BUILD_DIR}/python PATCH_COMMAND echo mklink /D "${PYTHON_EXTERNALS_FOLDER_DOS}" "${DOWNLOADS_EXTERNALS_FOLDER_DOS}" && - mklink /D "${PYTHON_EXTERNALS_FOLDER_DOS}" "${DOWNLOADS_EXTERNALS_FOLDER_DOS}" && - ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python.diff && - ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/pc < ${PATCH_DIR}/pyshell.diff + mklink /D "${PYTHON_EXTERNALS_FOLDER_DOS}" "${DOWNLOADS_EXTERNALS_FOLDER_DOS}" CONFIGURE_COMMAND "" - BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p ${PYTHON_ARCH} -c ${BUILD_MODE} -k ${PYTHON_COMPILER_STRING} + BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p ${PYTHON_ARCH} -c ${BUILD_MODE} INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll && + ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.pdb ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.pdb && ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib && ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.exp ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.exp && ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${LIBDIR}/python/include/Python${PYTHON_SHORT_VERSION} && @@ -92,39 +91,40 @@ if(MSVC) OUTPUT ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz OUTPUT ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/lib ${BUILD_DIR}/python/src/external_python/redist/lib - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_asyncio${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_asyncio${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_bz2${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_bz2${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_hashlib${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_hashlib${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_lzma${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_lzma${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_sqlite3${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_sqlite3${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ssl${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ssl${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/pyexpat${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/pyexpat${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/select${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/select${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/unicodedata${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/unicodedata${PYTHON_POSTFIX}.pyd - COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/winsound${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/winsound${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_contextvars${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_contextvars${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ctypes${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ctypes${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ctypes_test${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ctypes_test${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_decimal${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_decimal${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_distutils_findvs${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_distutils_findvs${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_elementtree${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_elementtree${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_hashlib${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_hashlib${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_lzma${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_lzma${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_msi${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_msi${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_multiprocessing${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_multiprocessing${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_overlapped${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_overlapped${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_queue${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_queue${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_socket${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_socket${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_sqlite3${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_sqlite3${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ssl${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ssl${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testbuffer${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testbuffer${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testcapi${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testcapi${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testimportmultiple${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testimportmultiple${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testmultiphase${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testmultiphase${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/pyexpat${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/pyexpat${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/select${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/select${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/unicodedata${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/unicodedata${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/winsound${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/winsound${PYTHON_POSTFIX}.pyd + COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/xxlimited${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/xxlimited${PYTHON_POSTFIX}.pyd COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/python/src/external_python/redist" ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz" "." + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/python/ ${HARVEST_TARGET}/python/ + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz ) add_custom_target(Package_Python ALL DEPENDS external_python ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe) - if(MSVC12) - set(PYTHON_DISTUTIL_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/run/lib/distutils < ${PATCH_DIR}/python_runtime_vc2013.diff) - else() - set(PYTHON_DISTUTIL_PATCH echo "No patch needed") - endif() - add_custom_command(OUTPUT ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/redist ${BUILD_DIR}/python/src/external_python/run COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${BUILD_DIR}/python/src/external_python/run/include @@ -134,7 +134,6 @@ if(MSVC) COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib #other things like numpy still want it though. COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe COMMAND ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe -m ensurepip --upgrade - COMMAND ${PYTHON_DISTUTIL_PATCH} ) add_custom_target(Make_Python_Environment ALL DEPENDS ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe Package_Python) endif() diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 36d58090c75..242dc4debad 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -134,11 +134,11 @@ set(OSL_VERSION 1.7.5) set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.zip) set(OSL_HASH 6924dd5d453159e7b6eb106a08c358cf) -set(PYTHON_VERSION 3.6.2) -set(PYTHON_SHORT_VERSION 3.6) -set(PYTHON_SHORT_VERSION_NO_DOTS 36) +set(PYTHON_VERSION 3.7.0) +set(PYTHON_SHORT_VERSION 3.7) +set(PYTHON_SHORT_VERSION_NO_DOTS 37) set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz) -set(PYTHON_HASH 2c68846471994897278364fc18730dd9) +set(PYTHON_HASH eb8c2a6b1447d50813c02714af4681f3) if(UNIX AND NOT APPLE) # Needed to be compatible with GCC 7, other platforms can upgrade later @@ -161,10 +161,10 @@ set(URLLIB3_VERSION 1.22) set(CERTIFI_VERSION 2017.7.27.1) set(REQUESTS_VERSION 2.18.4) -set(NUMPY_VERSION v1.13.1) -set(NUMPY_SHORT_VERSION 1.13) -set(NUMPY_URI https://pypi.python.org/packages/c0/3a/40967d9f5675fbb097ffec170f59c2ba19fc96373e73ad47c2cae9a30aed/numpy-1.13.1.zip) -set(NUMPY_HASH 2c3c0f4edf720c3a7b525dacc825b9ae) +set(NUMPY_VERSION v1.15.0) +set(NUMPY_SHORT_VERSION 1.15) +set(NUMPY_URI https://files.pythonhosted.org/packages/3a/20/c81632328b1a4e1db65f45c0a1350a9c5341fd4bbb8ea66cdd98da56fe2e/numpy-1.15.0.zip) +set(NUMPY_HASH 20e13185089011116a98e11c9bf8aa07) set(LAME_VERSION 3.99.5) set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.99/lame-${LAME_VERSION}.tar.gz) diff --git a/build_files/build_environment/patches/numpy.diff b/build_files/build_environment/patches/numpy.diff deleted file mode 100644 index c4c57222838..00000000000 --- a/build_files/build_environment/patches/numpy.diff +++ /dev/null @@ -1,23 +0,0 @@ -diff -Naur numpy-1.11.1/numpy/distutils/ccompiler.py numpy-1.11.1/numpy/distutils/ccompiler.py ---- numpy-1.11.1/numpy/distutils/ccompiler.py 2016-06-25 08:38:34 -0600 -+++ numpy-1.11.1/numpy/distutils/ccompiler.py 2016-08-04 12:33:43 -0600 -@@ -29,6 +29,7 @@ - - # Using customized CCompiler.spawn. - def CCompiler_spawn(self, cmd, display=None): -+ cmd = quote_args(cmd) - """ - Execute a command in a sub-process. - -diff -Naur numpy-1.11.1/numpy/distutils/misc_util.py numpy-1.11.1/numpy/distutils/misc_util.py ---- numpy-1.11.1/numpy/distutils/misc_util.py 2016-06-25 08:38:34 -0600 -+++ numpy-1.11.1/numpy/distutils/misc_util.py 2016-08-04 12:34:56 -0600 -@@ -116,7 +116,7 @@ - args = list(args) - for i in range(len(args)): - a = args[i] -- if ' ' in a and a[0] not in '"\'': -+ if ' ' in a and a[0] not in '"\'' and a[len(a)-1] not in '"\'': - args[i] = '"%s"' % (a) - return args - -- cgit v1.2.3 From 92f3671fe0c31921ce1ff28d6163dedfcdf57ebc Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Fri, 10 Aug 2018 21:17:45 +0300 Subject: deplibs: let cmake do normal install on webp --- build_files/build_environment/cmake/webp.cmake | 9 --------- 1 file changed, 9 deletions(-) diff --git a/build_files/build_environment/cmake/webp.cmake b/build_files/build_environment/cmake/webp.cmake index 0504988a088..92cd41b96ff 100644 --- a/build_files/build_environment/cmake/webp.cmake +++ b/build_files/build_environment/cmake/webp.cmake @@ -37,14 +37,5 @@ ExternalProject_Add(external_webp URL_HASH MD5=${WEBP_HASH} PREFIX ${BUILD_DIR}/webp CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/webp -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${WEBP_EXTRA_ARGS} - INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp-build/${WEBP_BUILD_DIR}${LIBPREFIX}webp${LIBEXT} ${LIBDIR}/webp/lib/${LIBPREFIX}webp${LIBEXT} && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/decode.h ${LIBDIR}/webp/include/webp/decode.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/encode.h ${LIBDIR}/webp/include/webp/encode.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/demux.h ${LIBDIR}/webp/include/webp/demux.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/extras.h ${LIBDIR}/webp/include/webp/extras.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/format_constants.h ${LIBDIR}/webp/include/webp/format_constants.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/mux.h ${LIBDIR}/webp/include/webp/mux.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/mux_types.h ${LIBDIR}/webp/include/webp/mux_types.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/types.h ${LIBDIR}/webp/include/webp/types.h INSTALL_DIR ${LIBDIR}/webp ) -- cgit v1.2.3 From eae4539bddda1561e6a24790b2ef62a2576746a9 Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Fri, 10 Aug 2018 23:31:27 +0300 Subject: deplibs: get freetype tar.gz rather than zip to get unix line endings --- build_files/build_environment/cmake/versions.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 242dc4debad..eac8e94b539 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -53,9 +53,9 @@ set(OPENEXR_VERSION 2.2.1) set(OPENEXR_URI http://download.savannah.nongnu.org/releases/openexr/openexr-${OPENEXR_VERSION}.tar.gz) set(OPENEXR_HASH 421815c32989e1b98fc4798ee754c433) -set(FREETYPE_VERSION 291) -set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/ft${FREETYPE_VERSION}.zip) -set(FREETYPE_HASH 6ca68fc28e443a05f756075d3b1dcb54) +set(FREETYPE_VERSION 2.9.1) +set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.gz) +set(FREETYPE_HASH 3adb0e35d3c100c456357345ccfa8056) set(GLEW_VERSION 1.13.0) set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz) -- cgit v1.2.3 From 544bd49e63a199a917767f735ab1fb989c83742a Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Sat, 11 Aug 2018 01:45:46 +0300 Subject: deplibs: python use pkg-config from homebrew for ssl + xz --- build_files/build_environment/cmake/python.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake index 6b3c25d32bf..d24cfa1f590 100644 --- a/build_files/build_environment/cmake/python.cmake +++ b/build_files/build_environment/cmake/python.cmake @@ -61,12 +61,12 @@ if(WIN32) message("POutput = ${PYTHON_OUTPUTDIR}") else() if(APPLE) - # we need to manually add homebrew headers to get ssl module building - set(PYTHON_CFLAGS "-I/usr/local/opt/openssl/include -I${OSX_SYSROOT}/usr/include ${PLATFORM_CFLAGS}") - set(PYTHON_LDFLAGS "-L/usr/local/opt/openssl/lib ${PLATFORM_LDFLAGS}") - set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && export CFLAGS=${PYTHON_CFLAGS} && export LDFLAGS=${PYTHON_LDFLAGS}) + # we need to add homebrew pkgconfig directories to get ssl, xz + + set(BREW_PKG_CONFIG "/usr/local/opt/openssl/lib/pkgconfig:/usr/local/opt/xz/lib/pkgconfig") + set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && export PKG_CONFIG_PATH=${BREW_PKG_CONFIG}) set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python.exe) - set(PYTHON_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_apple.diff) + set(PYTHON_PATCH echo .) else() set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV}) set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python) -- cgit v1.2.3 From 92b12d914ff4360cae9e816319e7f1b3e9173e71 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Fri, 10 Aug 2018 21:32:25 +0200 Subject: Cleanup GP instance: Remove element 0 because is duplicated --- .../draw/engines/gpencil/gpencil_draw_utils.c | 142 +++++++++++---------- 1 file changed, 73 insertions(+), 69 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index f8a04a06d80..6e2ab5a5ea2 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1200,91 +1200,91 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene ToolSettings *ts = scene->toolsettings; bGPDframe *derived_gpf = NULL; const bool main_onion = v3d != NULL ? ((v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) == 0) : true; - const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion; - const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; +const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion; +const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; - /* check if playing animation */ - bool playing = stl->storage->is_playing; +/* check if playing animation */ +bool playing = stl->storage->is_playing; - GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); - cache->cache_idx = 0; +GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); +cache->cache_idx = 0; - /* init general modifiers data */ - if (!stl->storage->simplify_modif) { - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_init(ob); - } +/* init general modifiers data */ +if (!stl->storage->simplify_modif) { + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_init(ob); + } +} +/* draw normal strokes */ +for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* don't draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; + + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); + if (gpf == NULL) + continue; + + /* create GHash if need */ + if (gpl->runtime.derived_data == NULL) { + gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); } - /* draw normal strokes */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* don't draw layer if hidden */ - if (gpl->flag & GP_LAYER_HIDE) - continue; - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); - if (gpf == NULL) - continue; + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); + } + else { + derived_gpf = NULL; + } - /* create GHash if need */ - if (gpl->runtime.derived_data == NULL) { - gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); - } + if (derived_gpf == NULL) { + cache->is_dirty = true; + } + if (cache->is_dirty) { + if (derived_gpf != NULL) { + /* first clear temp data */ + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); + } - if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); + BKE_gpencil_free_frame_runtime_data(derived_gpf); } - else { - derived_gpf = NULL; - } - - if (derived_gpf == NULL) { - cache->is_dirty = true; + /* create new data */ + derived_gpf = BKE_gpencil_frame_duplicate(gpf); + if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); } - if (cache->is_dirty) { - if (derived_gpf != NULL) { - /* first clear temp data */ - if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); - } - - BKE_gpencil_free_frame_runtime_data(derived_gpf); - } - /* create new data */ - derived_gpf = BKE_gpencil_frame_duplicate(gpf); - if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); - } - else { - BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL); - } + else { + BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL); } + } - /* draw onion skins */ - if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && - (!no_onion) && (overlay) && - (gpl->onion_flag & GP_LAYER_ONIONSKIN) && - ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + /* draw onion skins */ + if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && + (!no_onion) && (overlay) && + (gpl->onion_flag & GP_LAYER_ONIONSKIN) && + ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + { + if ((!stl->storage->is_render) || + ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { - if ((!stl->storage->is_render) || - ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) - { - gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); - } + gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); } + } - /* draw normal strokes */ - gpencil_draw_strokes( - cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf, - gpl->opacity, gpl->tintcolor, false); + /* draw normal strokes */ + gpencil_draw_strokes( + cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf, + gpl->opacity, gpl->tintcolor, false); - } +} - /* clear any lattice data */ - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_clear(ob); - } +/* clear any lattice data */ +if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_clear(ob); +} - cache->is_dirty = false; +cache->is_dirty = false; } /* Helper for gpencil_instance_modifiers() @@ -1300,8 +1300,11 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object for (int x = 0; x < mmd->count[0]; x++) { for (int y = 0; y < mmd->count[1]; y++) { for (int z = 0; z < mmd->count[2]; z++) { - Object *newob; + if ((x == 0) && (y == 0) && (z == 0)) { + continue; + } + Object *newob = NULL; const int elem_idx[3] = {x, y, z}; float mat[4][4]; int sh; @@ -1316,6 +1319,7 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object /* add object to cache */ newob = MEM_dupallocN(ob); + printf("Dupli %p\n", &newob); /* Create a unique name or the object hash used in draw will fail. * the name must be unique in the hash, not in the scene because -- cgit v1.2.3 From f22d8ee94ced099500813f29ac4df38a5a7ab480 Mon Sep 17 00:00:00 2001 From: Antonioya Date: Sat, 11 Aug 2018 10:03:06 +0200 Subject: Cleanup: Remove debug print --- source/blender/draw/engines/gpencil/gpencil_draw_utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 6e2ab5a5ea2..1d2b172a5b1 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1319,7 +1319,6 @@ static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object /* add object to cache */ newob = MEM_dupallocN(ob); - printf("Dupli %p\n", &newob); /* Create a unique name or the object hash used in draw will fail. * the name must be unique in the hash, not in the scene because -- cgit v1.2.3 From 1f33075ef043f0281c69a261c53eda0ce8334cbe Mon Sep 17 00:00:00 2001 From: Arto Kitula Date: Sat, 11 Aug 2018 13:59:13 +0300 Subject: deplibs: disable functions that can be found on 10.13 sdk but aren't available on 10.9 target --- build_files/build_environment/cmake/python.cmake | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake index d24cfa1f590..7de498bc126 100644 --- a/build_files/build_environment/cmake/python.cmake +++ b/build_files/build_environment/cmake/python.cmake @@ -64,8 +64,23 @@ else() # we need to add homebrew pkgconfig directories to get ssl, xz set(BREW_PKG_CONFIG "/usr/local/opt/openssl/lib/pkgconfig:/usr/local/opt/xz/lib/pkgconfig") - set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && export PKG_CONFIG_PATH=${BREW_PKG_CONFIG}) + # disable functions that can be in 10.13 sdk but aren't available on 10.9 target + set(PYTHON_FUNC_CONFIGS + export ac_cv_func_futimens=no && + export ac_cv_func_utimensat=no && + export ac_cv_func_basename_r=no && + export ac_cv_func_clock_getres=no && + export ac_cv_func_clock_gettime=no && + export ac_cv_func_clock_settime=no && + export ac_cv_func_dirname_r=no && + export ac_cv_func_getentropy=no && + export ac_cv_func_mkostemp=no && + export ac_cv_func_mkostemps=no && + export ac_cv_func_timingsafe_bcmp=no) + + set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && export PKG_CONFIG_PATH=${BREW_PKG_CONFIG} && ${PYTHON_FUNC_CONFIGS}) set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python.exe) + #set(PYTHON_PATCH ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_apple.diff) set(PYTHON_PATCH echo .) else() set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV}) -- cgit v1.2.3 From 91acff132008ef19d0ff878aae0280b7da709634 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sat, 11 Aug 2018 15:35:22 +0200 Subject: Fix T56293: Particle Instance Modifier Axis Buttons UX. Those axis buttons indeed affect instances orientation even when Create Along Path is not defined... --- .../startup/bl_ui/properties_data_modifier.py | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index a147950a36d..1a80a160ea5 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -734,23 +734,25 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row.prop(md, "particle_amount", text="Amount") row.prop(md, "particle_offset", text="Offset") + row = layout.row(align=True) + row.prop(md, "axis", expand=True) + layout.separator() layout.prop(md, "use_path", text="Create Along Paths") - split = layout.split() - split.active = md.use_path - col = split.column() - col.row().prop(md, "axis", expand=True) + col = layout.column() + col.active = md.use_path col.prop(md, "use_preserve_shape") - col = split.column() - col2 = col.column(align=True) - col2.prop(md, "position", slider=True) - col2.prop(md, "random_position", text="Random", slider=True) - col2 = col.column(align=True) - col2.prop(md, "rotation", slider=True) - col2.prop(md, "random_rotation", text="Random", slider=True) + row = col.row(align=True) + row.prop(md, "position", slider=True) + row.prop(md, "random_position", text="Random", slider=True) + row = col.row(align=True) + row.prop(md, "rotation", slider=True) + row.prop(md, "random_rotation", text="Random", slider=True) + + layout.separator() col = layout.column() col.prop_search(md, "index_layer_name", ob.data, "vertex_colors", text="Index Layer") -- cgit v1.2.3 From b4b8d3ab0e4519e1eeb4663070aa6c429bde370f Mon Sep 17 00:00:00 2001 From: Antonioya Date: Sat, 11 Aug 2018 20:54:13 +0200 Subject: Cleanup: Fix wrong formatting For unknown reasons, visual studio unformat a section of the code. --- .../draw/engines/gpencil/gpencil_draw_utils.c | 136 ++++++++++----------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 1d2b172a5b1..401934b35a7 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1200,91 +1200,91 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene ToolSettings *ts = scene->toolsettings; bGPDframe *derived_gpf = NULL; const bool main_onion = v3d != NULL ? ((v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) == 0) : true; -const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion; -const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; + const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion; + const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; -/* check if playing animation */ -bool playing = stl->storage->is_playing; - -GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); -cache->cache_idx = 0; + /* check if playing animation */ + bool playing = stl->storage->is_playing; -/* init general modifiers data */ -if (!stl->storage->simplify_modif) { - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_init(ob); - } -} -/* draw normal strokes */ -for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - /* don't draw layer if hidden */ - if (gpl->flag & GP_LAYER_HIDE) - continue; - - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); - if (gpf == NULL) - continue; - - /* create GHash if need */ - if (gpl->runtime.derived_data == NULL) { - gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); - } + GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval); + cache->cache_idx = 0; - if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); - } - else { - derived_gpf = NULL; + /* init general modifiers data */ + if (!stl->storage->simplify_modif) { + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_init(ob); + } } + /* draw normal strokes */ + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* don't draw layer if hidden */ + if (gpl->flag & GP_LAYER_HIDE) + continue; - if (derived_gpf == NULL) { - cache->is_dirty = true; - } - if (cache->is_dirty) { - if (derived_gpf != NULL) { - /* first clear temp data */ - if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); - } + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, 0); + if (gpf == NULL) + continue; - BKE_gpencil_free_frame_runtime_data(derived_gpf); + /* create GHash if need */ + if (gpl->runtime.derived_data == NULL) { + gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info); } - /* create new data */ - derived_gpf = BKE_gpencil_frame_duplicate(gpf); - if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { - BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); + + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name); } else { - BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL); + derived_gpf = NULL; } - } - /* draw onion skins */ - if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && - (!no_onion) && (overlay) && - (gpl->onion_flag & GP_LAYER_ONIONSKIN) && - ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) - { - if ((!stl->storage->is_render) || - ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + if (derived_gpf == NULL) { + cache->is_dirty = true; + } + if (cache->is_dirty) { + if (derived_gpf != NULL) { + /* first clear temp data */ + if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL); + } + + BKE_gpencil_free_frame_runtime_data(derived_gpf); + } + /* create new data */ + derived_gpf = BKE_gpencil_frame_duplicate(gpf); + if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) { + BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf); + } + else { + BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL); + } + } + + /* draw onion skins */ + if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) && + (!no_onion) && (overlay) && + (gpl->onion_flag & GP_LAYER_ONIONSKIN) && + ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { - gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); + if ((!stl->storage->is_render) || + ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) + { + gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf); + } } - } - /* draw normal strokes */ - gpencil_draw_strokes( - cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf, - gpl->opacity, gpl->tintcolor, false); + /* draw normal strokes */ + gpencil_draw_strokes( + cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf, + gpl->opacity, gpl->tintcolor, false); -} + } -/* clear any lattice data */ -if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_clear(ob); -} + /* clear any lattice data */ + if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { + BKE_gpencil_lattice_clear(ob); + } -cache->is_dirty = false; + cache->is_dirty = false; } /* Helper for gpencil_instance_modifiers() -- cgit v1.2.3 From 444a0202d40705b6a6f21e59e883518be577cf4e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Aug 2018 13:17:10 +1000 Subject: Gizmo: add blank gizmo definition Missed from 98c304e865f by accident. --- .../gizmo_library/gizmo_types/blank3d_gizmo.c | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c index 4dcdb7b7b3f..0c67e8c606d 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/blank3d_gizmo.c @@ -23,6 +23,14 @@ * ***** END GPL LICENSE BLOCK ***** */ +/** \file blank3d_gizmo.c + * \ingroup wm + * + * \name Blank Gizmo + * + * \brief Gizmo to use as a fallback (catch events). + */ + #include "BLI_math.h" #include "BKE_context.h" @@ -37,6 +45,45 @@ #include "../gizmo_geometry.h" #include "../gizmo_library_intern.h" + +static void gizmo_blank_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz)) +{ + /* pass */ +} + +static int gizmo_blank_invoke( + bContext *UNUSED(C), wmGizmo *UNUSED(gz), const wmEvent *UNUSED(event)) +{ + return OPERATOR_RUNNING_MODAL; +} + +static int gizmo_blank_test_select( + bContext *UNUSED(C), wmGizmo *UNUSED(gz), const int UNUSED(mval[2])) +{ + return 0; +} + +/* -------------------------------------------------------------------- */ +/** \name Blank Gizmo API + * + * \{ */ + +static void GIZMO_GT_blank_3d(wmGizmoType *gzt) +{ + /* identifiers */ + gzt->idname = "GIZMO_GT_blank_3d"; + + /* api callbacks */ + gzt->draw = gizmo_blank_draw; + gzt->invoke = gizmo_blank_invoke; + gzt->test_select = gizmo_blank_test_select; + + gzt->struct_size = sizeof(wmGizmo); +} + void ED_gizmotypes_blank_3d(void) { + WM_gizmotype_append(GIZMO_GT_blank_3d); } + +/** \} */ -- cgit v1.2.3 From 4b6fa4d897a0bb3252b16383492b526d2cef3920 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 12 Aug 2018 15:01:26 +1000 Subject: PyAPI: update scripts for matrix multiply operator Operators: - add torus - align objects - bake physics - make dupli faces - smart project Templates: - 3D view ray cast Other: - Methods for bones/edit-bones --- release/scripts/modules/bpy_extras/object_utils.py | 2 +- release/scripts/modules/bpy_extras/view3d_utils.py | 4 ++-- release/scripts/modules/bpy_types.py | 14 +++++++------- release/scripts/startup/bl_operators/add_mesh_torus.py | 9 +++++---- release/scripts/startup/bl_operators/clip.py | 12 +++++++----- release/scripts/startup/bl_operators/object.py | 2 +- release/scripts/startup/bl_operators/object_align.py | 8 ++++---- release/scripts/startup/bl_operators/rigidbody.py | 2 +- .../scripts/startup/bl_operators/uvcalc_smart_project.py | 8 ++++---- 9 files changed, 32 insertions(+), 29 deletions(-) diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index fff73a4285a..c9ea684862d 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -100,7 +100,7 @@ def add_object_align_init(context, operator): if operator: properties.rotation = rotation.to_euler() - return location * rotation + return location @ rotation def object_data_add(context, obdata, operator=None, name=None): diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py index a4834a4531c..a2e394b270f 100644 --- a/release/scripts/modules/bpy_extras/view3d_utils.py +++ b/release/scripts/modules/bpy_extras/view3d_utils.py @@ -54,7 +54,7 @@ def region_2d_to_vector_3d(region, rv3d, coord): w = out.dot(persinv[3].xyz) + persinv[3][3] - view_vector = ((persinv * out) / w) - viewinv.translation + view_vector = ((persinv @ out) / w) - viewinv.translation else: view_vector = -viewinv.col[2].xyz @@ -179,7 +179,7 @@ def location_3d_to_region_2d(region, rv3d, coord, default=None): """ from mathutils import Vector - prj = rv3d.perspective_matrix * Vector((coord[0], coord[1], coord[2], 1.0)) + prj = rv3d.perspective_matrix @ Vector((coord[0], coord[1], coord[2], 1.0)) if prj.w > 0.0: width_half = region.width / 2.0 height_half = region.height / 2.0 diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index d6d4ecd6fce..96193b047c6 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -205,21 +205,21 @@ class _GenericBone: """ Vector pointing down the x-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((1.0, 0.0, 0.0)) + return self.matrix.to_3x3() @ Vector((1.0, 0.0, 0.0)) @property def y_axis(self): """ Vector pointing down the y-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0)) + return self.matrix.to_3x3() @ Vector((0.0, 1.0, 0.0)) @property def z_axis(self): """ Vector pointing down the z-axis of the bone. """ from mathutils import Vector - return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0)) + return self.matrix.to_3x3() @ Vector((0.0, 0.0, 1.0)) @property def basename(self): @@ -378,9 +378,9 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup): :type roll: bool """ from mathutils import Vector - z_vec = self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0)) - self.tail = matrix * self.tail - self.head = matrix * self.head + z_vec = self.matrix.to_3x3() @ Vector((0.0, 0.0, 1.0)) + self.tail = matrix @ self.tail + self.head = matrix @ self.head if scale: scalar = matrix.median_scale @@ -388,7 +388,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup): self.tail_radius *= scalar if roll: - self.align_roll(matrix * z_vec) + self.align_roll(matrix @ z_vec) def ord_ind(i1, i2): diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 4460af173ff..68f49acc186 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -46,10 +46,11 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg): for minor_index in range(minor_seg): angle = pi_2 * minor_index / minor_seg - vec = matrix * Vector((major_rad + (cos(angle) * minor_rad), - 0.0, - sin(angle) * minor_rad, - )) + vec = matrix @ Vector(( + major_rad + (cos(angle) * minor_rad), + 0.0, + sin(angle) * minor_rad, + )) verts.extend(vec[:]) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index a94076ab61b..d05082b0dd8 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -300,7 +300,7 @@ class CLIP_OT_bundles_to_mesh(Operator): reconstruction = tracking_object.reconstruction framenr = scene.frame_current - clip.frame_start + 1 reconstructed_matrix = reconstruction.cameras.matrix_from_frame(framenr) - matrix = camera.matrix_world * reconstructed_matrix.inverted() + matrix = camera.matrix_world @ reconstructed_matrix.inverted() for track in tracking_object.tracks: if track.has_bundle and track.select: @@ -580,10 +580,12 @@ class CLIP_OT_setup_tracking_scene(Operator): scene.camera = camob - camob.matrix_local = (Matrix.Translation((7.481, -6.508, 5.344)) * - Matrix.Rotation(0.815, 4, 'Z') * - Matrix.Rotation(0.011, 4, 'Y') * - Matrix.Rotation(1.109, 4, 'X')) + camob.matrix_local = ( + Matrix.Translation((7.481, -6.508, 5.344)) @ + Matrix.Rotation(0.815, 4, 'Z') @ + Matrix.Rotation(0.011, 4, 'Y') @ + Matrix.Rotation(1.109, 4, 'X') + ) return camob diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index be379ec6089..c49591ff300 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -599,7 +599,7 @@ class MakeDupliFace(Operator): trans = matrix.to_translation() rot = matrix.to_3x3() # also contains scale - return [(rot * b) + trans for b in base_tri] + return [(rot @ b) + trans for b in base_tri] scene = context.scene linked = {} for obj in context.selected_objects: diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py index f627fd30162..60fb360480f 100644 --- a/release/scripts/startup/bl_operators/object_align.py +++ b/release/scripts/startup/bl_operators/object_align.py @@ -75,7 +75,7 @@ def worldspace_bounds_from_object_data(scene, obj): me = obj.to_mesh(scene=scene, apply_modifiers=True, settings='PREVIEW') verts = me.vertices - val = matrix_world * (verts[-1].co if verts else Vector((0.0, 0.0, 0.0))) + val = matrix_world @ (verts[-1].co if verts else Vector((0.0, 0.0, 0.0))) left, right, front, back, down, up = ( val[0], @@ -88,7 +88,7 @@ def worldspace_bounds_from_object_data(scene, obj): # Test against all other verts for v in verts: - vco = matrix_world * v.co + vco = matrix_world @ v.co # X Range val = vco[0] @@ -146,7 +146,7 @@ def align_objects(context, for obj in context.selected_objects: matrix_world = obj.matrix_world.copy() - bb_world = [matrix_world * Vector(v) for v in obj.bound_box] + bb_world = [matrix_world @ Vector(v) for v in obj.bound_box] objects.append((obj, bb_world)) if not objects: @@ -216,7 +216,7 @@ def align_objects(context, for obj, bb_world in objects: matrix_world = obj.matrix_world.copy() - bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box] + bb_world = [matrix_world @ Vector(v[:]) for v in obj.bound_box] if bb_quality and obj.type == 'MESH': GBB = worldspace_bounds_from_object_data(scene, obj) diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index 6b76fb96b62..46f3d0a1436 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -149,7 +149,7 @@ class BakeToKeyframes(Operator): mat = bake[i][j] # convert world space transform to parent space, so parented objects don't get offset after baking if (obj.parent): - mat = obj.matrix_parent_inverse.inverted() * obj.parent.matrix_world.inverted() * mat + mat = obj.matrix_parent_inverse.inverted() @ obj.parent.matrix_world.inverted() @ mat obj.location = mat.to_translation() diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index fe15b9fa345..b01a50d5d6a 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -89,7 +89,7 @@ def pointInTri2D(v, v1, v2, v3): dict_matrix[key] = mtx - uvw = (v - v1) * mtx + uvw = (v - v1) @ mtx return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1 @@ -258,7 +258,7 @@ def rotate_uvs(uv_points, angle): if angle != 0.0: mat = Matrix.Rotation(angle, 2) for uv in uv_points: - uv[:] = mat * uv + uv[:] = mat @ uv def optiRotateUvIsland(faces): @@ -858,7 +858,7 @@ def main(context, # Initialize projectVecs if USER_VIEW_INIT: # Generate Projection - projectVecs = [Vector(Window.GetViewVector()) * ob.matrix_world.inverted().to_3x3()] # We add to this along the way + projectVecs = [Vector(Window.GetViewVector()) @ ob.matrix_world.inverted().to_3x3()] # We add to this along the way else: projectVecs = [] @@ -975,7 +975,7 @@ def main(context, f_uv = f.uv for j, v in enumerate(f.v): # XXX - note, between mathutils in 2.4 and 2.5 the order changed. - f_uv[j][:] = (MatQuat * v.co).xy + f_uv[j][:] = (MatQuat @ v.co).xy if USER_SHARE_SPACE: # Should we collect and pack later? -- cgit v1.2.3